123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- #include "base/CCStencilStateManager.h"
- #include "base/CCDirector.h"
- #include "renderer/CCGLProgramCache.h"
- #include "renderer/ccGLStateCache.h"
- #include "renderer/CCRenderer.h"
- #include "renderer/CCRenderState.h"
- #if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
- #define CC_CLIPPING_NODE_OPENGLES 0
- #else
- #define CC_CLIPPING_NODE_OPENGLES 1
- #endif
- NS_CC_BEGIN
- GLint StencilStateManager::s_layer = -1;
- StencilStateManager::StencilStateManager()
- : _alphaThreshold(1.0f)
- , _inverted(false)
- , _currentStencilEnabled(GL_FALSE)
- , _currentStencilWriteMask(~0)
- , _currentStencilFunc(GL_ALWAYS)
- , _currentStencilRef(0)
- , _currentStencilValueMask(~0)
- , _currentStencilFail(GL_KEEP)
- , _currentStencilPassDepthFail(GL_KEEP)
- , _currentStencilPassDepthPass(GL_KEEP)
- , _currentDepthWriteMask(GL_TRUE)
- , _currentAlphaTestEnabled(GL_FALSE)
- , _currentAlphaTestFunc(GL_ALWAYS)
- , _currentAlphaTestRef(1)
- {
- }
- void StencilStateManager::drawFullScreenQuadClearStencil()
- {
- Director* director = Director::getInstance();
- CCASSERT(nullptr != director, "Director is null when setting matrix stack");
-
- director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
- director->loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
-
- director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
- director->loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
-
- Vec2 vertices[] = {
- Vec2(-1.0f, -1.0f),
- Vec2(1.0f, -1.0f),
- Vec2(1.0f, 1.0f),
- Vec2(-1.0f, 1.0f)
- };
-
- auto glProgram = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_U_COLOR);
-
- int colorLocation = glProgram->getUniformLocation("u_color");
- CHECK_GL_ERROR_DEBUG();
-
- Color4F color(1, 1, 1, 1);
-
- glProgram->use();
- glProgram->setUniformsForBuiltins();
- glProgram->setUniformLocationWith4fv(colorLocation, (GLfloat*) &color.r, 1);
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POSITION );
- glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, 4);
-
- director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
- director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
- }
- void StencilStateManager::setAlphaThreshold(GLfloat alphaThreshold)
- {
- _alphaThreshold = alphaThreshold;
- }
- GLfloat StencilStateManager::getAlphaThreshold()const
- {
- return _alphaThreshold;
- }
- void StencilStateManager::setInverted(bool inverted)
- {
- _inverted = inverted;
- }
- bool StencilStateManager::isInverted()const
- {
- return _inverted;
- }
- void StencilStateManager::onBeforeVisit()
- {
-
-
-
-
- s_layer++;
-
-
- GLint mask_layer = 0x1 << s_layer;
-
- GLint mask_layer_l = mask_layer - 1;
-
- _mask_layer_le = mask_layer | mask_layer_l;
-
-
-
- _currentStencilEnabled = glIsEnabled(GL_STENCIL_TEST);
- glGetIntegerv(GL_STENCIL_WRITEMASK, (GLint *)&_currentStencilWriteMask);
- glGetIntegerv(GL_STENCIL_FUNC, (GLint *)&_currentStencilFunc);
- glGetIntegerv(GL_STENCIL_REF, &_currentStencilRef);
- glGetIntegerv(GL_STENCIL_VALUE_MASK, (GLint *)&_currentStencilValueMask);
- glGetIntegerv(GL_STENCIL_FAIL, (GLint *)&_currentStencilFail);
- glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, (GLint *)&_currentStencilPassDepthFail);
- glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, (GLint *)&_currentStencilPassDepthPass);
-
-
- glEnable(GL_STENCIL_TEST);
-
-
-
- CHECK_GL_ERROR_DEBUG();
-
-
-
- glStencilMask(mask_layer);
-
-
-
-
- glGetBooleanv(GL_DEPTH_WRITEMASK, &_currentDepthWriteMask);
-
-
-
-
-
-
-
- glDepthMask(GL_FALSE);
- RenderState::StateBlock::_defaultState->setDepthWrite(false);
-
-
-
-
-
-
-
-
-
-
- glStencilFunc(GL_NEVER, mask_layer, mask_layer);
- glStencilOp(!_inverted ? GL_ZERO : GL_REPLACE, GL_KEEP, GL_KEEP);
-
-
-
- drawFullScreenQuadClearStencil();
-
-
-
-
-
-
-
-
-
- glStencilFunc(GL_NEVER, mask_layer, mask_layer);
-
-
- glStencilOp(!_inverted ? GL_REPLACE : GL_ZERO, GL_KEEP, GL_KEEP);
-
-
-
-
-
-
-
-
- if (_alphaThreshold < 1) {
- #if !CC_CLIPPING_NODE_OPENGLES
-
- _currentAlphaTestEnabled = glIsEnabled(GL_ALPHA_TEST);
- glGetIntegerv(GL_ALPHA_TEST_FUNC, (GLint *)&_currentAlphaTestFunc);
- glGetFloatv(GL_ALPHA_TEST_REF, &_currentAlphaTestRef);
-
- glEnable(GL_ALPHA_TEST);
-
- CHECK_GL_ERROR_DEBUG();
-
- glAlphaFunc(GL_GREATER, _alphaThreshold);
- #endif
- }
-
-
- }
- void StencilStateManager::onAfterDrawStencil()
- {
-
- if (_alphaThreshold < 1)
- {
- #if CC_CLIPPING_NODE_OPENGLES
-
- #else
-
- glAlphaFunc(_currentAlphaTestFunc, _currentAlphaTestRef);
- if (!_currentAlphaTestEnabled)
- {
- glDisable(GL_ALPHA_TEST);
- }
- #endif
- }
-
-
- glDepthMask(_currentDepthWriteMask);
- RenderState::StateBlock::_defaultState->setDepthWrite(_currentDepthWriteMask != 0);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- glStencilFunc(GL_EQUAL, _mask_layer_le, _mask_layer_le);
-
-
- glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
-
-
-
- }
- void StencilStateManager::onAfterVisit()
- {
-
-
-
-
- glStencilFunc(_currentStencilFunc, _currentStencilRef, _currentStencilValueMask);
-
-
- glStencilOp(_currentStencilFail, _currentStencilPassDepthFail, _currentStencilPassDepthPass);
-
-
-
-
- glStencilMask(_currentStencilWriteMask);
- if (!_currentStencilEnabled)
- {
- glDisable(GL_STENCIL_TEST);
-
- }
-
-
- s_layer--;
- }
- NS_CC_END
|