Difference between revisions of "Sprite:setStencilOperation"
From GiderosMobile
(7 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
__NOTOC__ | __NOTOC__ | ||
− | + | '''Available since:''' Gideros 2017.6<br/> | |
− | ''' | + | '''Class:''' [[Sprite]]<br/> |
− | ''' | + | |
− | === | + | === Description === |
− | + | Allows to set a stencil operation to be used when drawing this sprite. | |
− | + | <syntaxhighlight lang="lua"> | |
− | + | Sprite:setStencilOperation(op) | |
− | + | </syntaxhighlight> | |
− | + | ||
− | + | ||
− | + | The '''op''' table can contain the following fields: | |
− | + | *'''stencilClear''': (boolean) whether the stencil should be cleared beforehand | |
− | + | *'''stencilMask''': (integer) the mask value used in stencil operations | |
− | + | *'''stencilWriteMask''': (integer) the mask value used when writing to stencil | |
− | + | *'''stencilClearValue''': (integer) the value used to fill then stencil when clearing | |
− | + | *'''stencilRef''': (integer) the reference value used in stencil operations | |
− | + | *'''stencilFunc''': (integer) the stencil function to use | |
− | < | + | *'''stencilFail''': (integer) the stencil operation when stencil test failed |
− | + | *'''depthFail''': (integer) the stencil operation when depth test failed | |
− | + | *'''depthPass''': (integer) the stencil operation when depth test has passed | |
− | === < | + | *'''depthMask''': (boolean) whether depth buffer should be written or not (true by default) |
− | ''' | + | |
+ | Stencil function and operations code are defined in Sprite.STENCIL_xxx fields and correspond to the GL_xxx relevant values in OpenGL stencil documentation https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glStencilFunc.xhtml. | ||
+ | |||
+ | === Parameters === | ||
+ | '''op''': (table) a table containing the stencil operation settings, or nil to disable stencil | ||
+ | |||
+ | === Examples === | ||
+ | '''A glowing ticket effect''': | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | -- STENCILOPERATION @hgy29 | ||
+ | local bg = Bitmap.new(Texture.new("gfx/vip/background.png")) | ||
+ | local ticket = Bitmap.new(Texture.new("gfx/vip/ticket.png")) | ||
+ | local text = Bitmap.new(Texture.new("gfx/vip/text.png")) | ||
+ | local fx1 = Bitmap.new(Texture.new("gfx/vip/fx1.png")) | ||
+ | local fx2 = Bitmap.new(Texture.new("gfx/vip/fx2.png")) | ||
+ | |||
+ | stage:addChild(bg) bg:setScale(0.5) | ||
+ | stage:addChild(ticket) ticket:setPosition(80,20) ticket:setScale(0.5) | ||
+ | ticket:addChild(fx1) fx1:setX(-100) | ||
+ | fx1:addChild(fx2) fx2:setX(-100) | ||
+ | ticket:addChild(text) | ||
+ | |||
+ | -- Use auto layout on ticket to center text automatically | ||
+ | ticket:setLayoutParameters{ rowWeights = {1}, columnWeights = {1} } | ||
+ | text:setLayoutConstraints{} | ||
+ | |||
+ | -- Use stencil for masking glow: | ||
+ | -- 1) Clear stencil and set it to '1' for every pixel drawn on 'ticket' | ||
+ | ticket:setStencilOperation{ | ||
+ | stencilClear = true, stenciMask = 1, stencilWriteMask = 1, stencilRef = 1, | ||
+ | stencilFunc = Sprite.STENCIL_ALWAYS, depthPass = Sprite.STENCIL_REPLACE | ||
+ | } | ||
+ | --2) Only draw fx1/fx2 if stencil isn't 0 | ||
+ | fx1:setStencilOperation{ | ||
+ | stencilClear = false, stencilMask = 1, stencilRef = 0, | ||
+ | stencilFunc = Sprite.STENCIL_NOTEQUAL | ||
+ | } | ||
+ | |||
+ | local dir = 1 | ||
+ | stage:addEventListener(Event.ENTER_FRAME, function() | ||
+ | if fx1:getX() > 450 then dir = -1 | ||
+ | elseif fx1:getX() < -100 then dir = 1 | ||
+ | end | ||
+ | fx1:setX(fx1:getX() + dir*5) | ||
+ | end) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | '''Fill sprite with color''': | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | local star=Bitmap.new(Texture.new("gfx/clock_hand_m.png",true)) | ||
+ | stage:addChild(star) | ||
+ | |||
+ | local bluestar_tex=RenderTarget.new(star:getWidth(),star:getHeight()) | ||
+ | local bluestar=Bitmap.new(bluestar_tex) | ||
+ | stage:addChild(bluestar) bluestar:setX(160) | ||
+ | |||
+ | --Here is the magic | ||
+ | -- Clear our render target to all alpha | ||
+ | bluestar_tex:clear(0x000000,0) | ||
+ | --[[Gideros don't draw pixels with alpha value of 0, | ||
+ | they are discarded at early stage. Use the stencil to get a | ||
+ | footprint of visible pixels of source image]] | ||
+ | star:setStencilOperation{ stencilClear=true, stencilWriteMask=1, | ||
+ | stencilFunc=Sprite.STENCIL_ALWAYS,depthPass=Sprite.STENCIL_INCR } | ||
+ | bluestar_tex:draw(star) | ||
+ | --Render the footprint in the color we want | ||
+ | local mask=Pixel.new(0x0000FF,1,star:getWidth(),star:getHeight()) | ||
+ | mask:setStencilOperation{ stencilClear=false, stencilMask=1, stencilWriteMask=1, | ||
+ | stencilRef=0, stencilFunc=Sprite.STENCIL_NOTEQUAL, | ||
+ | depthPass=Sprite.STENCIL_KEEP, | ||
+ | stencilFail=Sprite.STENCIL_KEEP} | ||
+ | bluestar_tex:draw(mask) | ||
+ | |||
+ | --[[ The result is possibly enough here, but we lost the smoothed edges of | ||
+ | the original texture in the process. We can restore them with a smart alpha | ||
+ | blending trick:]] | ||
+ | star:setBlendMode(Sprite.ZERO,Sprite.SRC_ALPHA) | ||
+ | bluestar_tex:draw(star) | ||
+ | |||
+ | --Restore our initial bitmap blending mode, to show it on screen as usual | ||
+ | star:setBlendMode(Sprite.ALPHA) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | {{Sprite}} |
Latest revision as of 09:53, 7 November 2023
Available since: Gideros 2017.6
Class: Sprite
Description
Allows to set a stencil operation to be used when drawing this sprite.
Sprite:setStencilOperation(op)
The op table can contain the following fields:
- stencilClear: (boolean) whether the stencil should be cleared beforehand
- stencilMask: (integer) the mask value used in stencil operations
- stencilWriteMask: (integer) the mask value used when writing to stencil
- stencilClearValue: (integer) the value used to fill then stencil when clearing
- stencilRef: (integer) the reference value used in stencil operations
- stencilFunc: (integer) the stencil function to use
- stencilFail: (integer) the stencil operation when stencil test failed
- depthFail: (integer) the stencil operation when depth test failed
- depthPass: (integer) the stencil operation when depth test has passed
- depthMask: (boolean) whether depth buffer should be written or not (true by default)
Stencil function and operations code are defined in Sprite.STENCIL_xxx fields and correspond to the GL_xxx relevant values in OpenGL stencil documentation https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glStencilFunc.xhtml.
Parameters
op: (table) a table containing the stencil operation settings, or nil to disable stencil
Examples
A glowing ticket effect:
-- STENCILOPERATION @hgy29
local bg = Bitmap.new(Texture.new("gfx/vip/background.png"))
local ticket = Bitmap.new(Texture.new("gfx/vip/ticket.png"))
local text = Bitmap.new(Texture.new("gfx/vip/text.png"))
local fx1 = Bitmap.new(Texture.new("gfx/vip/fx1.png"))
local fx2 = Bitmap.new(Texture.new("gfx/vip/fx2.png"))
stage:addChild(bg) bg:setScale(0.5)
stage:addChild(ticket) ticket:setPosition(80,20) ticket:setScale(0.5)
ticket:addChild(fx1) fx1:setX(-100)
fx1:addChild(fx2) fx2:setX(-100)
ticket:addChild(text)
-- Use auto layout on ticket to center text automatically
ticket:setLayoutParameters{ rowWeights = {1}, columnWeights = {1} }
text:setLayoutConstraints{}
-- Use stencil for masking glow:
-- 1) Clear stencil and set it to '1' for every pixel drawn on 'ticket'
ticket:setStencilOperation{
stencilClear = true, stenciMask = 1, stencilWriteMask = 1, stencilRef = 1,
stencilFunc = Sprite.STENCIL_ALWAYS, depthPass = Sprite.STENCIL_REPLACE
}
--2) Only draw fx1/fx2 if stencil isn't 0
fx1:setStencilOperation{
stencilClear = false, stencilMask = 1, stencilRef = 0,
stencilFunc = Sprite.STENCIL_NOTEQUAL
}
local dir = 1
stage:addEventListener(Event.ENTER_FRAME, function()
if fx1:getX() > 450 then dir = -1
elseif fx1:getX() < -100 then dir = 1
end
fx1:setX(fx1:getX() + dir*5)
end)
Fill sprite with color:
local star=Bitmap.new(Texture.new("gfx/clock_hand_m.png",true))
stage:addChild(star)
local bluestar_tex=RenderTarget.new(star:getWidth(),star:getHeight())
local bluestar=Bitmap.new(bluestar_tex)
stage:addChild(bluestar) bluestar:setX(160)
--Here is the magic
-- Clear our render target to all alpha
bluestar_tex:clear(0x000000,0)
--[[Gideros don't draw pixels with alpha value of 0,
they are discarded at early stage. Use the stencil to get a
footprint of visible pixels of source image]]
star:setStencilOperation{ stencilClear=true, stencilWriteMask=1,
stencilFunc=Sprite.STENCIL_ALWAYS,depthPass=Sprite.STENCIL_INCR }
bluestar_tex:draw(star)
--Render the footprint in the color we want
local mask=Pixel.new(0x0000FF,1,star:getWidth(),star:getHeight())
mask:setStencilOperation{ stencilClear=false, stencilMask=1, stencilWriteMask=1,
stencilRef=0, stencilFunc=Sprite.STENCIL_NOTEQUAL,
depthPass=Sprite.STENCIL_KEEP,
stencilFail=Sprite.STENCIL_KEEP}
bluestar_tex:draw(mask)
--[[ The result is possibly enough here, but we lost the smoothed edges of
the original texture in the process. We can restore them with a smart alpha
blending trick:]]
star:setBlendMode(Sprite.ZERO,Sprite.SRC_ALPHA)
bluestar_tex:draw(star)
--Restore our initial bitmap blending mode, to show it on screen as usual
star:setBlendMode(Sprite.ALPHA)
- Sprite:addChild
- Sprite:addChildAt
- Sprite:clearBlendMode
- Sprite:clone
- Sprite:contains
- Sprite:get
- Sprite:getAlpha
- Sprite:getAnchorPoint
- Sprite:getAnchorPosition
- Sprite:getBounds
- Sprite:getChildAt
- Sprite:getChildIndex
- Sprite:getChildrenAtPoint
- Sprite:getClip
- Sprite:getColorTransform
- Sprite:getDrawCount
- Sprite:getHeight
- Sprite:getLayoutConstraints
- Sprite:getLayoutInfo
- Sprite:getLayoutParameters
- Sprite:getMatrix
- Sprite:getNumChildren
- Sprite:getParent
- Sprite:getPosition
- Sprite:getRotation
- Sprite:getRotationX
- Sprite:getRotationY
- Sprite:getScale
- Sprite:getScaleX
- Sprite:getScaleY
- Sprite:getScaleZ
- Sprite:getSize
- Sprite:getSkew
- Sprite:getSkewX
- Sprite:getSkewY
- Sprite:getWidth
- Sprite:getX
- Sprite:getY
- Sprite:getZ
- Sprite:globalToLocal
- Sprite:hitTestPoint
- Sprite:isVisible
- Sprite:localToGlobal
- Sprite:redrawEffects
- Sprite:removeChild
- Sprite:removeChildAt
- Sprite:removeFromParent
- Sprite:set
- Sprite:setAlpha
- Sprite:setAnchorPoint
- Sprite:setAnchorPosition
- Sprite:setBlendMode
- Sprite:setClip
- Sprite:setColorTransform
- Sprite:setEffectConstant
- Sprite:setEffectStack
- Sprite:setGhosts
- Sprite:setLayoutConstraints
- Sprite:setLayoutParameters
- Sprite:setMatrix
- Sprite:setPosition
- Sprite:setRotation
- Sprite:setRotationX
- Sprite:setRotationY
- Sprite:setScale
- Sprite:setScaleX
- Sprite:setScaleY
- Sprite:setScaleZ
- Sprite:setShader
- Sprite:setShaderConstant
- Sprite:setSkew
- Sprite:setSkewX
- Sprite:setSkewY
- Sprite:setStencilOperation
- Sprite:setStopEventPropagation
- Sprite:setVisible
- Sprite:setX
- Sprite:setY
- Sprite:setZ
- Sprite:spriteToLocal
- Sprite:swapChildren
- Sprite:swapChildrenAt
- Sprite.ADD
- Sprite.ALPHA
- Sprite.EFFECT MODE AUTOMATIC
- Sprite.EFFECT MODE CONTINUOUS
- Sprite.EFFECT MODE TRIGGERED
- Sprite.LAYOUT ANCHOR CENTER
- Sprite.LAYOUT ANCHOR EAST
- Sprite.LAYOUT ANCHOR NORTH
- Sprite.LAYOUT ANCHOR NORTHEAST
- Sprite.LAYOUT ANCHOR NORTHWEST
- Sprite.LAYOUT ANCHOR SOUTH
- Sprite.LAYOUT ANCHOR SOUTHEAST
- Sprite.LAYOUT ANCHOR SOUTHWEST
- Sprite.LAYOUT ANCHOR WEST
- Sprite.LAYOUT FILL BOTH
- Sprite.LAYOUT FILL HORIZONTAL
- Sprite.LAYOUT FILL NONE
- Sprite.LAYOUT FILL VERTICAL
- Sprite.MULTIPLY
- Sprite.NO ALPHA
- Sprite.SCREEN
- Sprite.new
- Event.ADDED_TO_STAGE
- Event.ENTER_FRAME
- Event.KEY_CHAR
- Event.KEY_DOWN
- Event.KEY_UP
- Event.LAYOUT_RESIZED
- Event.MOUSE_DOWN
- Event.MOUSE_ENTER
- Event.MOUSE_HOVER
- Event.MOUSE_LEAVE
- Event.MOUSE_MOVE
- Event.MOUSE_UP
- Event.MOUSE_WHEEL
- Event.REMOVED_FROM_STAGE
- Event.TOUCHES_BEGIN
- Event.TOUCHES_CANCEL
- Event.TOUCHES_END
- Event.TOUCHES_MOVE