Garry's Mod Wiki

Revision Difference

render.SetStencilWriteMask#513034

<function name="SetStencilWriteMask" parent="render" type="libraryfunc">⤶ <description>Sets the unsigned 8-bit write bitflag mask to be used for any writes to the stencil buffer.</description>⤶ <realm>Client</realm>⤶ <args>⤶ <arg name="mask" type="number">The mask bitflag.</arg>⤶ </args>⤶ </function>⤶ ⤶ <example>⤶ <description>A brief demonstration of masks</description>⤶ <code>⤶ hook.Add( "PostDrawOpaqueRenderables", "Stencil Tutorial Example", function()⤶ --<page>⤶ To understand this tutorial you need to already understand the basics⤶ of binary and bitwise operations.⤶ ⤶ It would also help to understand hexadecimal notation, since Lua⤶ doesn't have a bitmask input, but I will include binary notation in⤶ comments to help.⤶ --</page>⤶ ⤶ -- Reset everything to known good⤶ -- render.SetStencilWriteMask( 0xFF )⤶ -- render.SetStencilTestMask( 0xFF )⤶ render.SetStencilReferenceValue( 0 )⤶ -- render.SetStencilCompareFunction( STENCIL_ALWAYS )⤶ render.SetStencilPassOperation( STENCIL_KEEP )⤶ -- render.SetStencilFailOperation( STENCIL_KEEP )⤶ render.SetStencilZFailOperation( STENCIL_KEEP )⤶ render.ClearStencil()⤶ ⤶ -- Enable stencils⤶ render.SetStencilEnable( true )⤶ -- Force everything to fail⤶ render.SetStencilCompareFunction( STENCIL_NEVER )⤶ -- Save all the things we don't draw⤶ render.SetStencilFailOperation( STENCIL_REPLACE )⤶ ⤶ -- Set the reference value to 00011100⤶ render.SetStencilReferenceValue( 0x1C )⤶ -- Set the write mask to 01010101⤶ -- Any writes to the stencil buffer will be bitwise ANDed with this mask.⤶ -- With our current reference value, the result will be 00010100.⤶ render.SetStencilWriteMask( 0x55 )⤶ ⤶ -- Fail to draw our entities.⤶ for _, ent in ipairs( ents.FindByClass( "sent_stencil_test" ) ) do⤶ ent:DrawModel()⤶ end⤶ ⤶ -- Set the test mask to 11110011.⤶ -- Any time a pixel is read out of the stencil buffer it will be bitwise ANDed with this mask.⤶ render.SetStencilTestMask( 0xF3 )⤶ -- Set the reference value to 00011100 &amp; 01010101 &amp; 11110011⤶ render.SetStencilReferenceValue( 0x10 )⤶ -- Pass if the masked buffer value matches the unmasked reference value⤶ render.SetStencilCompareFunction( STENCIL_EQUAL )⤶ ⤶ -- Draw our entities⤶ render.ClearBuffersObeyStencil( 0, 148, 133, 255, false );⤶ ⤶ -- Let everything render normally again⤶ render.SetStencilEnable( false )⤶ end )⤶ </code>⤶ ⤶ </example>⤶ ⤶ ⤶ <example>⤶ <description>A somewhat more complicated mask example</description>⤶ <code>⤶ hook.Add( "PostDrawOpaqueRenderables", "Stencil Tutorial Example", function()⤶ --<page>⤶ To understand this tutorial you need to already understand the basics⤶ of binary and bitwise operations.⤶ ⤶ It would also help to understand hexadecimal notation, since Lua⤶ doesn't have a bitmask input, but I will include binary notation in⤶ comments to help.⤶ --</page>⤶ ⤶ -- Reset everything to known good⤶ -- render.SetStencilWriteMask( 0xFF )⤶ -- render.SetStencilTestMask( 0xFF )⤶ render.SetStencilReferenceValue( 0 )⤶ -- render.SetStencilCompareFunction( STENCIL_ALWAYS )⤶ render.SetStencilPassOperation( STENCIL_KEEP )⤶ -- render.SetStencilFailOperation( STENCIL_KEEP )⤶ render.SetStencilZFailOperation( STENCIL_KEEP )⤶ render.ClearStencil()⤶ ⤶ -- Enable stencils⤶ render.SetStencilEnable( true )⤶ ⤶ -- Only write to the upper 4 bits of the stencil buffer⤶ render.SetStencilWriteMask( 0xF0 )⤶ -- Wipe the stencil buffer to be 0001111. This is not affected by the write mask.⤶ render.ClearStencilBufferRectangle( 0, 0, ScrW(), ScrH(), 0x0F )⤶ ⤶ -- Always fail⤶ render.SetStencilCompareFunction( STENCIL_NEVER )⤶ -- Don't read any bits from the stencil buffer⤶ render.SetStencilTestMask( 0x00 )⤶ -- When an operation fails, read the current value from the stencil buffer, add⤶ -- one to it and then write it back to the buffer⤶ -- This is not affected by the test mask, but it is affected by the write mask⤶ -- This means we will read 00001111, then write 00010000.⤶ -- However, due to the write mask, this won't affect the last four bits already⤶ -- in the buffer, resulting in 00011111.⤶ render.SetStencilFailOperation( STENCIL_INCR )⤶ ⤶ -- Add something interesting to the stencil buffer⤶ for _, ent in ipairs( ents.FindByClass( "sent_stencil_test" ) ) do⤶ ent:DrawModel()⤶ end⤶ ⤶ ⤶ -- Go back to reading the full value from the stencil buffer⤶ render.SetStencilTestMask( 0xFF )⤶ -- Set the reference value to 00011111⤶ render.SetStencilReferenceValue( 0x1F )⤶ -- Render the result⤶ render.SetStencilCompareFunction( STENCIL_EQUAL )⤶ render.ClearBuffersObeyStencil( 0, 148, 133, 255, false );⤶ ⤶ -- Let everything render normally again⤶ render.SetStencilEnable( false )⤶ end )⤶ </code>⤶ ⤶ </example>