mirror of https://github.com/axmolengine/axmol.git
151 lines
5.2 KiB
C++
151 lines
5.2 KiB
C++
|
#include "DepthStencilStateGL.h"
|
||
|
#include "platform/CCGL.h"
|
||
|
|
||
|
#include "base/ccMacros.h"
|
||
|
|
||
|
CC_BACKEND_BEGIN
|
||
|
|
||
|
namespace
|
||
|
{
|
||
|
GLenum toGLComareFunction(CompareFunction compareFunction)
|
||
|
{
|
||
|
GLenum ret = GL_ALWAYS;
|
||
|
switch (compareFunction)
|
||
|
{
|
||
|
case CompareFunction::NEVER:
|
||
|
ret = GL_NEVER;
|
||
|
break;
|
||
|
case CompareFunction::LESS:
|
||
|
ret = GL_LESS;
|
||
|
break;
|
||
|
case CompareFunction::LESS_EQUAL:
|
||
|
ret = GL_LEQUAL;
|
||
|
break;
|
||
|
case CompareFunction::GREATER:
|
||
|
ret = GL_GREATER;
|
||
|
break;
|
||
|
case CompareFunction::GREATER_EQUAL:
|
||
|
ret = GL_GEQUAL;
|
||
|
break;
|
||
|
case CompareFunction::NOT_EQUAL:
|
||
|
ret = GL_NOTEQUAL;
|
||
|
break;
|
||
|
case CompareFunction::EQUAL:
|
||
|
ret = GL_EQUAL;
|
||
|
break;
|
||
|
case CompareFunction::ALWAYS:
|
||
|
ret = GL_ALWAYS;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
GLenum toGLStencilOperation(StencilOperation stencilOperation)
|
||
|
{
|
||
|
GLenum ret = GL_KEEP;
|
||
|
switch (stencilOperation)
|
||
|
{
|
||
|
case StencilOperation::KEEP:
|
||
|
ret = GL_KEEP;
|
||
|
break;
|
||
|
case StencilOperation::ZERO:
|
||
|
ret = GL_ZERO;
|
||
|
break;
|
||
|
case StencilOperation::REPLACE:
|
||
|
ret = GL_REPLACE;
|
||
|
break;
|
||
|
case StencilOperation::INVERT:
|
||
|
ret = GL_INVERT;
|
||
|
break;
|
||
|
case StencilOperation::INCREMENT_WRAP:
|
||
|
ret = GL_INCR_WRAP;
|
||
|
break;
|
||
|
case StencilOperation::DECREMENT_WRAP:
|
||
|
ret = GL_DECR_WRAP;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void DepthStencilStateGL::reset()
|
||
|
{
|
||
|
glDisable(GL_DEPTH_TEST);
|
||
|
glDisable(GL_STENCIL_TEST);
|
||
|
}
|
||
|
|
||
|
DepthStencilStateGL::DepthStencilStateGL(const DepthStencilDescriptor& descriptor)
|
||
|
: DepthStencilState(descriptor)
|
||
|
{}
|
||
|
|
||
|
void DepthStencilStateGL::apply(unsigned int stencilReferenceValueFront, unsigned int stencilReferenceValueBack) const
|
||
|
{
|
||
|
// depth test
|
||
|
|
||
|
if (_depthStencilInfo.depthCompareFunction == CompareFunction::ALWAYS &&
|
||
|
!_depthStencilInfo.depthWriteEnabled)
|
||
|
{
|
||
|
glDisable(GL_DEPTH_TEST);
|
||
|
}
|
||
|
else
|
||
|
glEnable(GL_DEPTH_TEST);
|
||
|
|
||
|
if (_depthStencilInfo.depthWriteEnabled)
|
||
|
glDepthMask(GL_TRUE);
|
||
|
else
|
||
|
glDepthMask(GL_FALSE);
|
||
|
|
||
|
glDepthFunc(toGLComareFunction(_depthStencilInfo.depthCompareFunction));
|
||
|
|
||
|
if (_depthStencilInfo.depthTestEnabled)
|
||
|
glEnable(GL_STENCIL_TEST);
|
||
|
else
|
||
|
glDisable(GL_STENCIL_TEST);
|
||
|
|
||
|
// stencil test
|
||
|
if (_depthStencilInfo.stencilTestEnabled)
|
||
|
{
|
||
|
if (_isBackFrontStencilEqual)
|
||
|
{
|
||
|
glStencilFunc(toGLComareFunction(_depthStencilInfo.frontFaceStencil.stencilCompareFunction),
|
||
|
stencilReferenceValueFront,
|
||
|
_depthStencilInfo.frontFaceStencil.readMask);
|
||
|
glStencilOp(toGLStencilOperation(_depthStencilInfo.frontFaceStencil.stencilFailureOperation),
|
||
|
toGLStencilOperation(_depthStencilInfo.frontFaceStencil.depthFailureOperation),
|
||
|
toGLStencilOperation(_depthStencilInfo.frontFaceStencil.depthStencilPassOperation));
|
||
|
glStencilMask(_depthStencilInfo.frontFaceStencil.writeMask);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
glStencilFuncSeparate(GL_BACK,
|
||
|
toGLComareFunction(_depthStencilInfo.backFaceStencil.stencilCompareFunction),
|
||
|
stencilReferenceValueBack,
|
||
|
_depthStencilInfo.backFaceStencil.readMask);
|
||
|
glStencilFuncSeparate(GL_FRONT,
|
||
|
toGLComareFunction(_depthStencilInfo.frontFaceStencil.stencilCompareFunction),
|
||
|
stencilReferenceValueFront,
|
||
|
_depthStencilInfo.frontFaceStencil.readMask);
|
||
|
|
||
|
glStencilOpSeparate(GL_BACK,
|
||
|
toGLStencilOperation(_depthStencilInfo.backFaceStencil.stencilFailureOperation),
|
||
|
toGLStencilOperation(_depthStencilInfo.backFaceStencil.depthFailureOperation),
|
||
|
toGLStencilOperation(_depthStencilInfo.backFaceStencil.depthStencilPassOperation));
|
||
|
glStencilOpSeparate(GL_FRONT,
|
||
|
toGLStencilOperation(_depthStencilInfo.frontFaceStencil.stencilFailureOperation),
|
||
|
toGLStencilOperation(_depthStencilInfo.frontFaceStencil.depthFailureOperation),
|
||
|
toGLStencilOperation(_depthStencilInfo.frontFaceStencil.depthStencilPassOperation));
|
||
|
|
||
|
glStencilMaskSeparate(GL_BACK, _depthStencilInfo.backFaceStencil.writeMask);
|
||
|
glStencilMaskSeparate(GL_FRONT, _depthStencilInfo.frontFaceStencil.writeMask);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CHECK_GL_ERROR_DEBUG();
|
||
|
}
|
||
|
|
||
|
CC_BACKEND_END
|