- Overview
- clear attachment
- 深度测试
- 模板测试
- Viewport
- Scissor
- CullMode
- Winding
- Set render target
Overview
V4 中改变全局状态的唯一途径就是通过 Renderer 对象。如开启深度测试。接下来将逐一分析如何通过 Renderer 设置全局状态及固定管线函数。
clear attachment
通过 ClearFlag 指定需要清空的缓冲区
_renderer->clear(ClearFlag::ALL, // Clear color, depth and stencil buffer._clearColor, // the color value used when the color buffer is cleared1, // the depth value used when the depth buffer is cleared0, // the index used when the stencil buffer is cleared-10000.0); // specifies the globalOrder value
深度测试
在初始化函数中,设置回调函数,用于保存和恢复原先的全局状态。
void Demo::init(){_customCommand.setBeforeCallback(CC_CALLBACK_0(Demo::onBeforeDraw, this));_customCommand.setAfterCallback(CC_CALLBACK_0(Demo::onAfterDraw, this));}
- onBeforeDraw
void Demo::onBeforeDraw(){auto renderer = Director::getInstance()->getRenderer();// manually save the global state_oldDepthTestEnabled = renderer->getDepthTest();_oldDepthWriteMask = renderer->getDepthWrite();_oldDepthCmpFunc = renderer->getDepthCompareFunction();... //store other global state, such as cull mode.renderer->setDepthTest(true);renderer->setDepthWrite(true);renderer->setDepthCompareFunction(backend::CompareFunction::LESS_EQUAL);... //do additional operations.}
- onAfterDraw
void Demo::onAfterDraw(){auto renderer = Director::getInstance()->getRenderer();// manually restore the global staterenderer->setDepthTest(_oldDepthTestEnabled);renderer->setDepthWrite(_oldDepthWriteMask);renderer->setDepthCompareFunction(_oldDepthCmpFunc);... //restore other global state}
模板测试
与深度测试一样,设置用于保存和恢复原先全局状态的回调函数。
void Demo::init(){_customCommand.setBeforeCallback(CC_CALLBACK_0(Demo::onBeforeDraw, this));_customCommand.setAfterCallback(CC_CALLBACK_0(Demo::onAfterDraw, this));}
- onBeforeDraw
void Demo::onBeforeDraw(){auto renderer = Director::getInstance()->getRenderer();// manually save the stencil state_oldStencilEnabled = renderer->getStencilTest();_oldStencilWriteMask = renderer->getStencilWriteMask();_oldStencilFunc = renderer->getStencilCompareFunction();_oldStencilRef = renderer->getStencilReferenceValue();_oldStencilReadMask = renderer->getStencilReadMask();_oldStencilFail = renderer->getStencilFailureOperation();_oldStencilPassDepthFail = renderer->getStencilPassDepthFailureOperation();_oldStencilPassDepthPass = renderer->getStencilDepthPassOperation();... // save other global states// set stencil statesrenderer->setStencilTest(true);renderer->setStencilWriteMask(_writeMask);renderer->setStencilCompareFunction(_compareFunction,_refValue,_readMask);renderer->setStencilOperation(_sfailOp,_zfailOp,_zpassOp);}
- onAfterDraw
void StencilStateManager::onAfterVisit(){// manually restore the stencil stateauto renderer = Director::getInstance()->getRenderer();renderer->setStencilCompareFunction(_oldStencilFunc,_oldStencilRef,_oldStencilReadMask);renderer->setStencilOperation(_oldFail,_oldPassDepthFail,_oldPassDepthPass);renderer->setStencilWriteMask(_oldStencilWriteMask);if (!_oldStencilEnabled){renderer->setStencilTest(false);}}
Viewport
//保存当前 viewport_oldViewport = renderer->getViewport();renderer->setViewPort(viewport.origin.x,viewport.origin.y,viewport.size.width,viewport.size.height);
Scissor
//save scissor test status_oldScissorTest = renderer->getScissorTest();_oldScissorRect = renderer->getScissorRect();//set scissor testrenderer->setScissorTest(true);renderer->setScissorRect(x, y, width, height);//restore scissor test statusrenderer->setScissorTest(_oldScissorTest);renderer->setScissorRect(_oldScissorRect.x,_oldScissorRect.y,_oldScissorRect.width,_oldScissorRect.height);
CullMode
_oldCullMode = renderer->getCullMode();renderer->setCullMode(cullMode);
Winding
_oldWinding = renderer->getWinding();renderer->setWinding(winding);
Set render target
设置用于保存和恢复 attachment 的回调函数。
void Demo::init(){_beginCallbackCommand.func = CC_CALLBACK_0(RenderTexture::onBegin, this);_endCallbackCommand.func = CC_CALLBACK_0(RenderTexture::onEnd, this);}
- onBegin
//save attachemnt status_oldColorAttachment = renderer->getColorAttachment();_oldDepthAttachment = renderer->getDepthAttachment();_oldStencilAttachment = renderer->getStencilAttachment();_oldRenderTargetFlag = renderer->getRenderTargetFlag();renderer->setRenderTarget(_renderTargetFlags, // indicate which attachment to be replaced_texture2D,_depthTexture,_stencilTexture);
- onEnd
renderer->setRenderTarget(_oldRenderTargetFlag,_oldColorAttachment,_oldDepthAttachment,_oldStencilAttachment);
