mirror of https://github.com/axmolengine/axmol.git
Merge pull request #12324 from ricardoquesada/state_buffer_fixes
State buffer fixes
This commit is contained in:
commit
97c1d29af9
|
@ -33,6 +33,7 @@
|
|||
#include "renderer/CCGLProgramCache.h"
|
||||
#include "renderer/ccGLStateCache.h"
|
||||
#include "renderer/CCFrameBuffer.h"
|
||||
#include "renderer/CCRenderState.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
|
@ -409,12 +410,20 @@ void Camera::clearBackground(float depth)
|
|||
{
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
glStencilMask(0);
|
||||
RenderState::StateBlock::_defaultState->setStencilWrite(0);
|
||||
|
||||
oldDepthTest = glIsEnabled(GL_DEPTH_TEST);
|
||||
glGetIntegerv(GL_DEPTH_FUNC, &oldDepthFunc);
|
||||
glGetBooleanv(GL_DEPTH_WRITEMASK, &oldDepthMask);
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
RenderState::StateBlock::_defaultState->setDepthWrite(true);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
RenderState::StateBlock::_defaultState->setDepthTest(true);
|
||||
|
||||
glDepthFunc(GL_ALWAYS);
|
||||
RenderState::StateBlock::_defaultState->setDepthFunction(RenderState::DEPTH_ALWAYS);
|
||||
}
|
||||
|
||||
//draw
|
||||
|
@ -461,14 +470,18 @@ void Camera::clearBackground(float depth)
|
|||
if(GL_FALSE == oldDepthTest)
|
||||
{
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
RenderState::StateBlock::_defaultState->setDepthTest(false);
|
||||
}
|
||||
glDepthFunc(oldDepthFunc);
|
||||
if(GL_FALSE == oldDepthMask)
|
||||
{
|
||||
glDepthMask(GL_FALSE);
|
||||
RenderState::StateBlock::_defaultState->setDepthWrite(false);
|
||||
}
|
||||
|
||||
glStencilMask(0xFFFFF);
|
||||
RenderState::StateBlock::_defaultState->setStencilWrite(0xFFFFF);
|
||||
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "renderer/CCGLProgramCache.h"
|
||||
#include "renderer/ccGLStateCache.h"
|
||||
#include "renderer/CCRenderer.h"
|
||||
#include "renderer/CCRenderState.h"
|
||||
#include "base/CCDirector.h"
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
|
||||
|
@ -395,12 +396,15 @@ void ClippingNode::onBeforeVisit()
|
|||
|
||||
// enable stencil use
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
RenderState::StateBlock::_defaultState->setStencilTest(true);
|
||||
|
||||
// check for OpenGL error while enabling stencil test
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
|
||||
// all bits on the stencil buffer are readonly, except the current layer bit,
|
||||
// this means that operation like glClear or glStencilOp will be masked with this value
|
||||
glStencilMask(mask_layer);
|
||||
RenderState::StateBlock::_defaultState->setStencilWrite(mask_layer);
|
||||
|
||||
// manually save the depth test state
|
||||
|
||||
|
@ -413,6 +417,7 @@ void ClippingNode::onBeforeVisit()
|
|||
// it should never prevent something else to be drawn,
|
||||
// only disabling depth buffer update should do
|
||||
glDepthMask(GL_FALSE);
|
||||
RenderState::StateBlock::_defaultState->setDepthWrite(false);
|
||||
|
||||
///////////////////////////////////
|
||||
// CLEAR STENCIL BUFFER
|
||||
|
@ -424,7 +429,13 @@ void ClippingNode::onBeforeVisit()
|
|||
// if not in inverted mode: set the current layer value to 0 in the stencil buffer
|
||||
// if in inverted mode: set the current layer value to 1 in the stencil buffer
|
||||
glStencilFunc(GL_NEVER, mask_layer, mask_layer);
|
||||
RenderState::StateBlock::_defaultState->setStencilFunction(RenderState::STENCIL_NEVER, mask_layer, mask_layer);
|
||||
|
||||
glStencilOp(!_inverted ? GL_ZERO : GL_REPLACE, GL_KEEP, GL_KEEP);
|
||||
RenderState::StateBlock::_defaultState->setStencilOperation(
|
||||
!_inverted ? RenderState::STENCIL_OP_ZERO : RenderState::STENCIL_OP_REPLACE,
|
||||
RenderState::STENCIL_OP_KEEP,
|
||||
RenderState::STENCIL_OP_KEEP);
|
||||
|
||||
// draw a fullscreen solid rectangle to clear the stencil buffer
|
||||
//ccDrawSolidRect(Vec2::ZERO, ccpFromSize([[Director sharedDirector] winSize]), Color4F(1, 1, 1, 1));
|
||||
|
@ -439,7 +450,14 @@ void ClippingNode::onBeforeVisit()
|
|||
// if not in inverted mode: set the current layer value to 1 in the stencil buffer
|
||||
// if in inverted mode: set the current layer value to 0 in the stencil buffer
|
||||
glStencilFunc(GL_NEVER, mask_layer, mask_layer);
|
||||
RenderState::StateBlock::_defaultState->setStencilFunction(RenderState::STENCIL_NEVER, mask_layer, mask_layer);
|
||||
|
||||
glStencilOp(!_inverted ? GL_REPLACE : GL_ZERO, GL_KEEP, GL_KEEP);
|
||||
RenderState::StateBlock::_defaultState->setStencilOperation(
|
||||
!_inverted ? RenderState::STENCIL_OP_REPLACE : RenderState::STENCIL_OP_ZERO,
|
||||
RenderState::STENCIL_OP_KEEP,
|
||||
RenderState::STENCIL_OP_KEEP);
|
||||
|
||||
|
||||
// enable alpha test only if the alpha threshold < 1,
|
||||
// indeed if alpha threshold == 1, every pixel will be drawn anyways
|
||||
|
@ -480,6 +498,8 @@ void ClippingNode::onAfterDrawStencil()
|
|||
|
||||
// restore the depth test state
|
||||
glDepthMask(_currentDepthWriteMask);
|
||||
RenderState::StateBlock::_defaultState->setDepthWrite(_currentDepthWriteMask);
|
||||
|
||||
//if (currentDepthTestEnabled) {
|
||||
// glEnable(GL_DEPTH_TEST);
|
||||
//}
|
||||
|
@ -494,7 +514,10 @@ void ClippingNode::onAfterDrawStencil()
|
|||
// else
|
||||
// do not draw the pixel but keep the current layer in the stencil buffer
|
||||
glStencilFunc(GL_EQUAL, _mask_layer_le, _mask_layer_le);
|
||||
RenderState::StateBlock::_defaultState->setStencilFunction(RenderState::STENCIL_EQUAL, _mask_layer_le, _mask_layer_le);
|
||||
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
RenderState::StateBlock::_defaultState->setStencilOperation(RenderState::STENCIL_OP_KEEP, RenderState::STENCIL_OP_KEEP, RenderState::STENCIL_OP_KEEP);
|
||||
|
||||
// draw (according to the stencil test func) this node and its childs
|
||||
}
|
||||
|
@ -507,11 +530,18 @@ void ClippingNode::onAfterVisit()
|
|||
|
||||
// manually restore the stencil state
|
||||
glStencilFunc(_currentStencilFunc, _currentStencilRef, _currentStencilValueMask);
|
||||
RenderState::StateBlock::_defaultState->setStencilFunction((RenderState::StencilFunction)_currentStencilFunc, _currentStencilRef, _currentStencilValueMask);
|
||||
|
||||
glStencilOp(_currentStencilFail, _currentStencilPassDepthFail, _currentStencilPassDepthPass);
|
||||
RenderState::StateBlock::_defaultState->setStencilOperation((RenderState::StencilOperation)_currentStencilFail,
|
||||
(RenderState::StencilOperation)_currentStencilPassDepthFail,
|
||||
(RenderState::StencilOperation)_currentStencilPassDepthPass);
|
||||
|
||||
glStencilMask(_currentStencilWriteMask);
|
||||
if (!_currentStencilEnabled)
|
||||
{
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
RenderState::StateBlock::_defaultState->setStencilTest(false);
|
||||
}
|
||||
|
||||
// we are done using this layer, decrement
|
||||
|
|
|
@ -33,6 +33,7 @@ THE SOFTWARE.
|
|||
#include "renderer/CCGLProgramCache.h"
|
||||
#include "renderer/ccGLStateCache.h"
|
||||
#include "renderer/CCRenderer.h"
|
||||
#include "renderer/CCRenderState.h"
|
||||
#include "renderer/CCTexture2D.h"
|
||||
#include "platform/CCGL.h"
|
||||
#include "2d/CCCamera.h"
|
||||
|
@ -327,8 +328,12 @@ void Grid3D::beforeBlit()
|
|||
glGetBooleanv(GL_DEPTH_WRITEMASK, &depthWriteMask);
|
||||
_oldDepthWriteValue = depthWriteMask != GL_FALSE;
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
RenderState::StateBlock::_defaultState->setDepthTest(true);
|
||||
|
||||
glDepthMask(true);
|
||||
RenderState::StateBlock::_defaultState->setDepthWrite(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -340,8 +345,10 @@ void Grid3D::afterBlit()
|
|||
glEnable(GL_DEPTH_TEST);
|
||||
else
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
RenderState::StateBlock::_defaultState->setDepthTest(_oldDepthTestValue);
|
||||
|
||||
glDepthMask(_oldDepthWriteValue);
|
||||
RenderState::StateBlock::_defaultState->setDepthWrite(_oldDepthWriteValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "renderer/CCGLProgramCache.h"
|
||||
#include "renderer/CCGLProgramState.h"
|
||||
#include "renderer/CCRenderer.h"
|
||||
#include "renderer/CCRenderState.h"
|
||||
#include "3d/CCSkybox.h"
|
||||
#include "3d/CCTextureCube.h"
|
||||
|
||||
|
@ -183,14 +184,21 @@ void Skybox::onDraw(const Mat4& transform, uint32_t flags)
|
|||
glGetIntegerv(GL_DEPTH_FUNC, &depthFunc);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
RenderState::StateBlock::_defaultState->setDepthTest(true);
|
||||
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
RenderState::StateBlock::_defaultState->setDepthFunction(RenderState::DEPTH_LEQUAL);
|
||||
|
||||
|
||||
GLboolean cullFlag = glIsEnabled(GL_CULL_FACE);
|
||||
GLint cullMode;
|
||||
glGetIntegerv(GL_CULL_FACE_MODE, &cullMode);
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
RenderState::StateBlock::_defaultState->setCullFace(true);
|
||||
|
||||
glCullFace(GL_BACK);
|
||||
RenderState::StateBlock::_defaultState->setCullFaceSide(RenderState::CULL_FACE_SIDE_BACK);
|
||||
|
||||
if (Configuration::getInstance()->supportsShareableVAO())
|
||||
{
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "base/CCDirector.h"
|
||||
#include "renderer/CCGLProgram.h"
|
||||
#include "renderer/CCRenderer.h"
|
||||
#include "renderer/CCRenderState.h"
|
||||
#include "renderer/ccGLStateCache.h"
|
||||
#include "renderer/CCGLProgramCache.h"
|
||||
|
||||
|
@ -131,6 +132,8 @@ void Physics3DDebugDrawer::drawImplementation( const Mat4 &transform, uint32_t f
|
|||
_program->use();
|
||||
_program->setUniformsForBuiltins(transform);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
RenderState::StateBlock::_defaultState->setDepthTest(true);
|
||||
|
||||
GL::blendFunc(_blendFunc.src, _blendFunc.dst);
|
||||
|
||||
if (_dirty)
|
||||
|
@ -158,7 +161,9 @@ void Physics3DDebugDrawer::drawImplementation( const Mat4 &transform, uint32_t f
|
|||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,_bufferCount);
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
RenderState::StateBlock::_defaultState->setDepthTest(false);
|
||||
}
|
||||
|
||||
void Physics3DDebugDrawer::init()
|
||||
|
|
|
@ -37,25 +37,6 @@ NS_CC_BEGIN
|
|||
|
||||
RenderState::StateBlock* RenderState::StateBlock::_defaultState = nullptr;
|
||||
|
||||
// Render state override bits
|
||||
enum
|
||||
{
|
||||
RS_BLEND = (1 << 0),
|
||||
RS_BLEND_FUNC = (1 << 1),
|
||||
RS_CULL_FACE = (1 << 2),
|
||||
RS_DEPTH_TEST = (1 << 3),
|
||||
RS_DEPTH_WRITE = (1 << 4),
|
||||
RS_DEPTH_FUNC = (1 << 5),
|
||||
RS_CULL_FACE_SIDE = (1 << 6),
|
||||
RS_STENCIL_TEST = (1 << 7),
|
||||
RS_STENCIL_WRITE = (1 << 8),
|
||||
RS_STENCIL_FUNC = (1 << 9),
|
||||
RS_STENCIL_OP = (1 << 10),
|
||||
RS_FRONT_FACE = (1 << 11),
|
||||
|
||||
RS_ALL_ONES = 0xFFFFFFFF,
|
||||
};
|
||||
|
||||
|
||||
RenderState::RenderState()
|
||||
: _texture(nullptr)
|
||||
|
@ -731,6 +712,14 @@ uint32_t RenderState::StateBlock::getHash() const
|
|||
return 0x12345678;
|
||||
}
|
||||
|
||||
void RenderState::StateBlock::invalidate(long stateBits)
|
||||
{
|
||||
CCASSERT(_defaultState, "_default state not created yet. Cannot be invalidated");
|
||||
|
||||
_defaultState->_bits = stateBits;
|
||||
_defaultState->restore(0);
|
||||
}
|
||||
|
||||
void RenderState::StateBlock::setBlend(bool enabled)
|
||||
{
|
||||
_blendEnabled = enabled;
|
||||
|
|
|
@ -188,7 +188,7 @@ public:
|
|||
* Defines a block of fixed-function render states that can be applied to a
|
||||
* RenderState object.
|
||||
*/
|
||||
class StateBlock : public Ref
|
||||
class CC_DLL StateBlock : public Ref
|
||||
{
|
||||
friend class RenderState;
|
||||
friend class Pass;
|
||||
|
@ -349,6 +349,37 @@ public:
|
|||
uint32_t getHash() const;
|
||||
bool isDirty() const;
|
||||
|
||||
/** StateBlock bits to be used with invalidate */
|
||||
enum
|
||||
{
|
||||
RS_BLEND = (1 << 0),
|
||||
RS_BLEND_FUNC = (1 << 1),
|
||||
RS_CULL_FACE = (1 << 2),
|
||||
RS_DEPTH_TEST = (1 << 3),
|
||||
RS_DEPTH_WRITE = (1 << 4),
|
||||
RS_DEPTH_FUNC = (1 << 5),
|
||||
RS_CULL_FACE_SIDE = (1 << 6),
|
||||
RS_STENCIL_TEST = (1 << 7),
|
||||
RS_STENCIL_WRITE = (1 << 8),
|
||||
RS_STENCIL_FUNC = (1 << 9),
|
||||
RS_STENCIL_OP = (1 << 10),
|
||||
RS_FRONT_FACE = (1 << 11),
|
||||
|
||||
RS_ALL_ONES = 0xFFFFFFFF,
|
||||
};
|
||||
|
||||
/**
|
||||
* Invalidates the default StateBlock.
|
||||
*
|
||||
* Only call it if you are calling GL calls directly. Invoke this function
|
||||
* at the end of your custom draw call.
|
||||
* This function restores the default render state its defaults values.
|
||||
* Since this function might call GL calls, it must be called in a GL context is present.
|
||||
*
|
||||
* @param stateBits Bitwise-OR of the states that needs to be invalidated
|
||||
*/
|
||||
static void invalidate(long stateBits);
|
||||
|
||||
static StateBlock* _defaultState;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -28,6 +28,7 @@ THE SOFTWARE.
|
|||
#include "renderer/CCGLProgram.h"
|
||||
#include "renderer/CCGLProgramCache.h"
|
||||
#include "renderer/ccGLStateCache.h"
|
||||
#include "renderer/CCRenderState.h"
|
||||
#include "base/CCDirector.h"
|
||||
#include "2d/CCDrawingPrimitives.h"
|
||||
#include "renderer/CCRenderer.h"
|
||||
|
@ -335,17 +336,43 @@ void Layout::onBeforeVisitStencil()
|
|||
glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, (GLint *)&_currentStencilPassDepthPass);
|
||||
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
RenderState::StateBlock::_defaultState->setStencilTest(true);
|
||||
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
glStencilMask(mask_layer);
|
||||
RenderState::StateBlock::_defaultState->setStencilWrite(mask_layer);
|
||||
|
||||
glGetBooleanv(GL_DEPTH_WRITEMASK, &_currentDepthWriteMask);
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
RenderState::StateBlock::_defaultState->setDepthWrite(false);
|
||||
|
||||
glStencilFunc(GL_NEVER, mask_layer, mask_layer);
|
||||
RenderState::StateBlock::_defaultState->setStencilFunction(
|
||||
RenderState::STENCIL_NEVER,
|
||||
mask_layer,
|
||||
mask_layer);
|
||||
|
||||
glStencilOp(GL_ZERO, GL_KEEP, GL_KEEP);
|
||||
RenderState::StateBlock::_defaultState->setStencilOperation(
|
||||
RenderState::STENCIL_OP_ZERO,
|
||||
RenderState::STENCIL_OP_KEEP,
|
||||
RenderState::STENCIL_OP_KEEP);
|
||||
|
||||
|
||||
this->drawFullScreenQuadClearStencil();
|
||||
|
||||
glStencilFunc(GL_NEVER, mask_layer, mask_layer);
|
||||
RenderState::StateBlock::_defaultState->setStencilFunction(
|
||||
RenderState::STENCIL_NEVER,
|
||||
mask_layer,
|
||||
mask_layer);
|
||||
|
||||
glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);
|
||||
RenderState::StateBlock::_defaultState->setStencilOperation(
|
||||
RenderState::STENCIL_OP_REPLACE,
|
||||
RenderState::STENCIL_OP_KEEP,
|
||||
RenderState::STENCIL_OP_KEEP);
|
||||
}
|
||||
|
||||
void Layout::drawFullScreenQuadClearStencil()
|
||||
|
@ -392,19 +419,42 @@ void Layout::drawFullScreenQuadClearStencil()
|
|||
void Layout::onAfterDrawStencil()
|
||||
{
|
||||
glDepthMask(_currentDepthWriteMask);
|
||||
RenderState::StateBlock::_defaultState->setDepthWrite(_currentDepthWriteMask);
|
||||
|
||||
glStencilFunc(GL_EQUAL, _mask_layer_le, _mask_layer_le);
|
||||
RenderState::StateBlock::_defaultState->setStencilFunction(
|
||||
RenderState::STENCIL_EQUAL,
|
||||
_mask_layer_le,
|
||||
_mask_layer_le);
|
||||
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
RenderState::StateBlock::_defaultState->setStencilOperation(
|
||||
RenderState::STENCIL_OP_KEEP,
|
||||
RenderState::STENCIL_OP_KEEP,
|
||||
RenderState::STENCIL_OP_KEEP);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Layout::onAfterVisitStencil()
|
||||
{
|
||||
glStencilFunc(_currentStencilFunc, _currentStencilRef, _currentStencilValueMask);
|
||||
RenderState::StateBlock::_defaultState->setStencilFunction(
|
||||
(RenderState::StencilFunction)_currentStencilFunc,
|
||||
_currentStencilRef,
|
||||
_currentStencilValueMask);
|
||||
|
||||
glStencilOp(_currentStencilFail, _currentStencilPassDepthFail, _currentStencilPassDepthPass);
|
||||
RenderState::StateBlock::_defaultState->setStencilOperation(
|
||||
(RenderState::StencilOperation)_currentStencilFail,
|
||||
(RenderState::StencilOperation)_currentStencilPassDepthFail,
|
||||
(RenderState::StencilOperation)_currentStencilPassDepthPass);
|
||||
|
||||
glStencilMask(_currentStencilWriteMask);
|
||||
if (!_currentStencilEnabled)
|
||||
{
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
RenderState::StateBlock::_defaultState->setStencilTest(false);
|
||||
}
|
||||
s_layer--;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "MaterialSystemTest.h"
|
||||
|
||||
#include <ctime>
|
||||
#include <spine/spine-cocos2dx.h>
|
||||
|
||||
#include "../testResource.h"
|
||||
#include "cocos2d.h"
|
||||
|
@ -47,6 +48,7 @@ MaterialSystemTest::MaterialSystemTest()
|
|||
ADD_TEST_CASE(Material_MultipleSprite3D);
|
||||
ADD_TEST_CASE(Material_Sprite3DTest);
|
||||
ADD_TEST_CASE(Material_parsePerformance);
|
||||
ADD_TEST_CASE(Material_invalidate);
|
||||
}
|
||||
|
||||
std::string MaterialSystemBaseTest::title() const
|
||||
|
@ -380,6 +382,74 @@ std::string Material_parsePerformance::subtitle() const
|
|||
{
|
||||
return "Testing parsing performance";
|
||||
}
|
||||
//
|
||||
//
|
||||
//
|
||||
void Material_invalidate::onEnter()
|
||||
{
|
||||
MaterialSystemBaseTest::onEnter();
|
||||
|
||||
// ORC
|
||||
auto sprite = Sprite3D::create("Sprite3DTest/orc.c3b");
|
||||
sprite->setScale(5);
|
||||
sprite->setRotation3D(Vec3(0,180,0));
|
||||
addChild(sprite);
|
||||
sprite->setNormalizedPosition(Vec2(0.3,0.3));
|
||||
|
||||
auto rotate = RotateBy::create(5, Vec3(0,360,0));
|
||||
auto repeat = RepeatForever::create(rotate);
|
||||
sprite->runAction(repeat);
|
||||
|
||||
// SPINE
|
||||
auto skeletonNode = spine::SkeletonAnimation::createWithFile("spine/goblins-ffd.json", "spine/goblins-ffd.atlas", 1.5f);
|
||||
skeletonNode->setAnimation(0, "walk", true);
|
||||
skeletonNode->setSkin("goblin");
|
||||
|
||||
skeletonNode->setScale(0.25);
|
||||
skeletonNode->setNormalizedPosition(Vec2(0.6,0.3));
|
||||
this->addChild(skeletonNode);
|
||||
}
|
||||
|
||||
std::string Material_invalidate::subtitle() const
|
||||
{
|
||||
return "Testing RenderState::StateBlock::invalidate()";
|
||||
}
|
||||
|
||||
void Material_invalidate::draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t flags)
|
||||
{
|
||||
_customCommand.init(_globalZOrder, transform, flags);
|
||||
_customCommand.func = []() {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
|
||||
glDepthMask(false);
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
|
||||
glCullFace((GLenum)GL_FRONT);
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
|
||||
glFrontFace((GLenum)GL_CW);
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
|
||||
// a non-optimal way is to pass all bits, but that would be very inefficient
|
||||
// RenderState::StateBlock::invalidate(RenderState::StateBlock::RS_ALL_ONES);
|
||||
|
||||
RenderState::StateBlock::invalidate(RenderState::StateBlock::RS_DEPTH_TEST |
|
||||
RenderState::StateBlock::RS_DEPTH_WRITE |
|
||||
RenderState::StateBlock::RS_CULL_FACE |
|
||||
RenderState::StateBlock::RS_CULL_FACE_SIDE |
|
||||
RenderState::StateBlock::RS_FRONT_FACE |
|
||||
RenderState::StateBlock::RS_BLEND);
|
||||
};
|
||||
|
||||
renderer->addCommand(&_customCommand);
|
||||
}
|
||||
|
||||
// MARK: Helper functions
|
||||
|
||||
|
|
|
@ -111,4 +111,17 @@ public:
|
|||
virtual std::string subtitle() const override;
|
||||
};
|
||||
|
||||
class Material_invalidate : public MaterialSystemBaseTest
|
||||
{
|
||||
public:
|
||||
CREATE_FUNC(Material_invalidate);
|
||||
|
||||
virtual void onEnter() override;
|
||||
virtual std::string subtitle() const override;
|
||||
|
||||
virtual void draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t flags) override;
|
||||
|
||||
cocos2d::CustomCommand _customCommand;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -463,6 +463,10 @@ void RenderTextureTestDepthStencil::draw(Renderer *renderer, const Mat4 &transfo
|
|||
void RenderTextureTestDepthStencil::onBeforeClear()
|
||||
{
|
||||
glStencilMask(0xFF);
|
||||
|
||||
// Since cocos2d-x v3.7, users should avoid calling GL directly because it will break the internal GL state
|
||||
// But if users must call GL directly, they should update the state manually,
|
||||
RenderState::StateBlock::_defaultState->setStencilWrite(0xFF);
|
||||
}
|
||||
|
||||
void RenderTextureTestDepthStencil::onBeforeStencil()
|
||||
|
@ -471,16 +475,30 @@ void RenderTextureTestDepthStencil::onBeforeStencil()
|
|||
glEnable(GL_STENCIL_TEST);
|
||||
glStencilFunc(GL_NEVER, 1, 0xFF);
|
||||
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
|
||||
|
||||
// Since cocos2d-x v3.7, users should avoid calling GL directly because it will break the internal GL state
|
||||
// But if users must call GL directly, they should update the state manually,
|
||||
RenderState::StateBlock::_defaultState->setStencilTest(true);
|
||||
RenderState::StateBlock::_defaultState->setStencilFunction(RenderState::STENCIL_NEVER, 1, 0xFF);
|
||||
RenderState::StateBlock::_defaultState->setStencilOperation(RenderState::STENCIL_OP_REPLACE, RenderState::STENCIL_OP_REPLACE, RenderState::STENCIL_OP_REPLACE);
|
||||
}
|
||||
|
||||
void RenderTextureTestDepthStencil::onBeforDraw()
|
||||
{
|
||||
glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
|
||||
|
||||
// Since cocos2d-x v3.7, users should avoid calling GL directly because it will break the internal GL state
|
||||
// But if users must call GL directly, they should update the state manually,
|
||||
RenderState::StateBlock::_defaultState->setStencilFunction(RenderState::STENCIL_NOTEQUAL, 1, 0xFF);
|
||||
}
|
||||
|
||||
void RenderTextureTestDepthStencil::onAfterDraw()
|
||||
{
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
|
||||
// Since cocos2d-x v3.7, users should avoid calling GL directly because it will break the internal GL state
|
||||
// But if users must call GL directly, they should update the state manually,
|
||||
RenderState::StateBlock::_defaultState->setStencilTest(false);
|
||||
}
|
||||
|
||||
std::string RenderTextureTestDepthStencil::title() const
|
||||
|
|
|
@ -1054,9 +1054,16 @@ void Effect3DOutline::draw(const Mat4 &transform)
|
|||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glCullFace(GL_BACK);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
// Since cocos2d-x v3.7, users should avoid calling GL directly because it will break the internal GL state
|
||||
// But if users must call GL directly, they should update the state manually,
|
||||
RenderState::StateBlock::_defaultState->setDepthTest(false);
|
||||
RenderState::StateBlock::_defaultState->setCullFaceSide(RenderState::CULL_FACE_SIDE_BACK);
|
||||
RenderState::StateBlock::_defaultState->setCullFace(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue