Made stencil per face side
Former-commit-id: 093f2125886d47ebc79f97aaecfad3a5216f399a
This commit is contained in:
parent
1ed8ea8ad5
commit
d4abb8fc49
|
|
@ -17,20 +17,26 @@ struct NzRenderStates
|
||||||
|
|
||||||
NzRenderStates& operator=(const NzRenderStates& states);
|
NzRenderStates& operator=(const NzRenderStates& states);
|
||||||
|
|
||||||
|
struct Face
|
||||||
|
{
|
||||||
|
nzRendererComparison stencilCompare;
|
||||||
|
nzStencilOperation stencilFail;
|
||||||
|
nzStencilOperation stencilPass;
|
||||||
|
nzStencilOperation stencilZFail;
|
||||||
|
nzUInt32 stencilMask;
|
||||||
|
unsigned int stencilReference;
|
||||||
|
};
|
||||||
|
|
||||||
|
Face backFace;
|
||||||
|
Face frontFace;
|
||||||
nzBlendFunc dstBlend;
|
nzBlendFunc dstBlend;
|
||||||
nzBlendFunc srcBlend;
|
nzBlendFunc srcBlend;
|
||||||
nzFaceFilling faceFilling;
|
nzFaceFilling faceFilling;
|
||||||
nzFaceSide faceCulling;
|
nzFaceSide faceCulling;
|
||||||
nzRendererComparison depthFunc;
|
nzRendererComparison depthFunc;
|
||||||
nzRendererComparison stencilCompare;
|
|
||||||
nzStencilOperation stencilFail;
|
|
||||||
nzStencilOperation stencilPass;
|
|
||||||
nzStencilOperation stencilZFail;
|
|
||||||
nzUInt32 stencilMask;
|
|
||||||
bool parameters[nzRendererParameter_Max+1];
|
bool parameters[nzRendererParameter_Max+1];
|
||||||
float lineWidth;
|
float lineWidth;
|
||||||
float pointSize;
|
float pointSize;
|
||||||
unsigned int stencilReference;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#include <Nazara/Renderer/RenderStates.inl>
|
#include <Nazara/Renderer/RenderStates.inl>
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,8 @@ srcBlend(nzBlendFunc_One),
|
||||||
faceFilling(nzFaceFilling_Fill),
|
faceFilling(nzFaceFilling_Fill),
|
||||||
faceCulling(nzFaceSide_Back),
|
faceCulling(nzFaceSide_Back),
|
||||||
depthFunc(nzRendererComparison_Less),
|
depthFunc(nzRendererComparison_Less),
|
||||||
stencilCompare(nzRendererComparison_Always),
|
|
||||||
stencilFail(nzStencilOperation_Keep),
|
|
||||||
stencilPass(nzStencilOperation_Keep),
|
|
||||||
stencilZFail(nzStencilOperation_Keep),
|
|
||||||
stencilMask(0xFFFFFFFF),
|
|
||||||
lineWidth(1.f),
|
lineWidth(1.f),
|
||||||
pointSize(1.f),
|
pointSize(1.f)
|
||||||
stencilReference(0)
|
|
||||||
{
|
{
|
||||||
parameters[nzRendererParameter_Blend] = false;
|
parameters[nzRendererParameter_Blend] = false;
|
||||||
parameters[nzRendererParameter_ColorWrite] = true;
|
parameters[nzRendererParameter_ColorWrite] = true;
|
||||||
|
|
@ -27,6 +21,18 @@ stencilReference(0)
|
||||||
parameters[nzRendererParameter_FaceCulling] = false;
|
parameters[nzRendererParameter_FaceCulling] = false;
|
||||||
parameters[nzRendererParameter_ScissorTest] = false;
|
parameters[nzRendererParameter_ScissorTest] = false;
|
||||||
parameters[nzRendererParameter_StencilTest] = false;
|
parameters[nzRendererParameter_StencilTest] = false;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < 2; ++i)
|
||||||
|
{
|
||||||
|
Face& face = (i == 0) ? backFace : frontFace;
|
||||||
|
|
||||||
|
face.stencilCompare = nzRendererComparison_Always;
|
||||||
|
face.stencilFail = nzStencilOperation_Keep;
|
||||||
|
face.stencilMask = 0xFFFFFFFF;
|
||||||
|
face.stencilPass = nzStencilOperation_Keep;
|
||||||
|
face.stencilReference = 0;
|
||||||
|
face.stencilZFail = nzStencilOperation_Keep;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline NzRenderStates::NzRenderStates(const NzRenderStates& states)
|
inline NzRenderStates::NzRenderStates(const NzRenderStates& states)
|
||||||
|
|
|
||||||
|
|
@ -88,12 +88,12 @@ class NAZARA_API NzRenderer
|
||||||
static void SetRenderStates(const NzRenderStates& states);
|
static void SetRenderStates(const NzRenderStates& states);
|
||||||
static void SetScissorRect(const NzRecti& rect);
|
static void SetScissorRect(const NzRecti& rect);
|
||||||
static void SetShaderProgram(const NzShaderProgram* shader);
|
static void SetShaderProgram(const NzShaderProgram* shader);
|
||||||
static void SetStencilCompareFunction(nzRendererComparison compareFunc);
|
static void SetStencilCompareFunction(nzRendererComparison compareFunc, nzFaceSide faceSide = nzFaceSide_FrontAndBack);
|
||||||
static void SetStencilFailOperation(nzStencilOperation failOperation);
|
static void SetStencilFailOperation(nzStencilOperation failOperation, nzFaceSide faceSide = nzFaceSide_FrontAndBack);
|
||||||
static void SetStencilMask(nzUInt32 mask);
|
static void SetStencilMask(nzUInt32 mask, nzFaceSide faceSide = nzFaceSide_FrontAndBack);
|
||||||
static void SetStencilPassOperation(nzStencilOperation passOperation);
|
static void SetStencilPassOperation(nzStencilOperation passOperation, nzFaceSide faceSide = nzFaceSide_FrontAndBack);
|
||||||
static void SetStencilReferenceValue(unsigned int refValue);
|
static void SetStencilReferenceValue(unsigned int refValue, nzFaceSide faceSide = nzFaceSide_FrontAndBack);
|
||||||
static void SetStencilZFailOperation(nzStencilOperation zfailOperation);
|
static void SetStencilZFailOperation(nzStencilOperation zfailOperation, nzFaceSide faceSide = nzFaceSide_FrontAndBack);
|
||||||
static bool SetTarget(const NzRenderTarget* target);
|
static bool SetTarget(const NzRenderTarget* target);
|
||||||
static void SetTexture(nzUInt8 unit, const NzTexture* texture);
|
static void SetTexture(nzUInt8 unit, const NzTexture* texture);
|
||||||
static void SetTextureSampler(nzUInt8 textureUnit, const NzTextureSampler& sampler);
|
static void SetTextureSampler(nzUInt8 textureUnit, const NzTextureSampler& sampler);
|
||||||
|
|
|
||||||
|
|
@ -191,25 +191,32 @@ void NzOpenGL::ApplyStates(const NzRenderStates& states)
|
||||||
// Ici encore, ça ne sert à rien de se soucier des fonctions de stencil sans qu'il soit activé
|
// Ici encore, ça ne sert à rien de se soucier des fonctions de stencil sans qu'il soit activé
|
||||||
if (states.parameters[nzRendererParameter_StencilTest])
|
if (states.parameters[nzRendererParameter_StencilTest])
|
||||||
{
|
{
|
||||||
if (currentRenderStates.stencilCompare != states.stencilCompare ||
|
for (unsigned int i = 0; i < 2; ++i)
|
||||||
currentRenderStates.stencilMask != states.stencilMask ||
|
|
||||||
currentRenderStates.stencilReference != states.stencilReference)
|
|
||||||
{
|
{
|
||||||
glStencilFunc(RendererComparison[states.stencilCompare], states.stencilReference, states.stencilMask);
|
GLenum face = (i == 0) ? GL_BACK : GL_FRONT;
|
||||||
currentRenderStates.stencilCompare = states.stencilCompare;
|
const NzRenderStates::Face& srcStates = (i == 0) ? states.backFace : states.frontFace;
|
||||||
currentRenderStates.stencilMask = states.stencilMask;
|
NzRenderStates::Face& dstStates = (i == 0) ? currentRenderStates.backFace : currentRenderStates.frontFace;
|
||||||
currentRenderStates.stencilReference = states.stencilReference;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ici encore, ça ne sert à rien de se soucier des fonctions de stencil sans qu'il soit activé
|
if (dstStates.stencilCompare != srcStates.stencilCompare ||
|
||||||
if (currentRenderStates.stencilFail != states.stencilFail ||
|
dstStates.stencilMask != srcStates.stencilMask ||
|
||||||
currentRenderStates.stencilPass != states.stencilPass ||
|
dstStates.stencilReference != srcStates.stencilReference)
|
||||||
currentRenderStates.stencilZFail != states.stencilZFail)
|
{
|
||||||
{
|
glStencilFuncSeparate(face, RendererComparison[srcStates.stencilCompare], srcStates.stencilReference, srcStates.stencilMask);
|
||||||
glStencilOp(StencilOperation[states.stencilFail], StencilOperation[states.stencilZFail], StencilOperation[states.stencilPass]);
|
dstStates.stencilCompare = srcStates.stencilCompare;
|
||||||
currentRenderStates.stencilFail = states.stencilFail;
|
dstStates.stencilMask = srcStates.stencilMask;
|
||||||
currentRenderStates.stencilPass = states.stencilPass;
|
dstStates.stencilReference = srcStates.stencilReference;
|
||||||
currentRenderStates.stencilZFail = states.stencilZFail;
|
}
|
||||||
|
|
||||||
|
// Ici encore, ça ne sert à rien de se soucier des fonctions de stencil sans qu'il soit activé
|
||||||
|
if (dstStates.stencilFail != srcStates.stencilFail ||
|
||||||
|
dstStates.stencilPass != srcStates.stencilPass ||
|
||||||
|
dstStates.stencilZFail != srcStates.stencilZFail)
|
||||||
|
{
|
||||||
|
glStencilOpSeparate(face, StencilOperation[srcStates.stencilFail], StencilOperation[srcStates.stencilZFail], StencilOperation[srcStates.stencilPass]);
|
||||||
|
dstStates.stencilFail = srcStates.stencilFail;
|
||||||
|
dstStates.stencilPass = srcStates.stencilPass;
|
||||||
|
dstStates.stencilZFail = srcStates.stencilZFail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1259,19 +1266,6 @@ void NzOpenGL::SetBuffer(nzBufferType type, GLuint id)
|
||||||
s_contextStates->buffersBinding[type] = id;
|
s_contextStates->buffersBinding[type] = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzOpenGL::SetProgram(GLuint id)
|
|
||||||
{
|
|
||||||
#ifdef NAZARA_DEBUG
|
|
||||||
if (!s_contextStates)
|
|
||||||
{
|
|
||||||
NazaraError("No context activated");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
s_contextStates->currentProgram = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NzOpenGL::SetScissorBox(const NzRecti& scissorBox)
|
void NzOpenGL::SetScissorBox(const NzRecti& scissorBox)
|
||||||
{
|
{
|
||||||
#ifdef NAZARA_DEBUG
|
#ifdef NAZARA_DEBUG
|
||||||
|
|
@ -1285,6 +1279,19 @@ void NzOpenGL::SetScissorBox(const NzRecti& scissorBox)
|
||||||
s_contextStates->currentScissorBox = scissorBox;
|
s_contextStates->currentScissorBox = scissorBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NzOpenGL::SetProgram(GLuint id)
|
||||||
|
{
|
||||||
|
#ifdef NAZARA_DEBUG
|
||||||
|
if (!s_contextStates)
|
||||||
|
{
|
||||||
|
NazaraError("No context activated");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
s_contextStates->currentProgram = id;
|
||||||
|
}
|
||||||
|
|
||||||
void NzOpenGL::SetTarget(const NzRenderTarget* renderTarget)
|
void NzOpenGL::SetTarget(const NzRenderTarget* renderTarget)
|
||||||
{
|
{
|
||||||
#ifdef NAZARA_DEBUG
|
#ifdef NAZARA_DEBUG
|
||||||
|
|
|
||||||
|
|
@ -1051,7 +1051,7 @@ void NzRenderer::SetShaderProgram(const NzShaderProgram* program)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzRenderer::SetStencilCompareFunction(nzRendererComparison compareFunc)
|
void NzRenderer::SetStencilCompareFunction(nzRendererComparison compareFunc, nzFaceSide faceSide)
|
||||||
{
|
{
|
||||||
#ifdef NAZARA_DEBUG
|
#ifdef NAZARA_DEBUG
|
||||||
if (compareFunc > nzRendererComparison_Max)
|
if (compareFunc > nzRendererComparison_Max)
|
||||||
|
|
@ -1059,12 +1059,32 @@ void NzRenderer::SetStencilCompareFunction(nzRendererComparison compareFunc)
|
||||||
NazaraError("Renderer comparison out of enum");
|
NazaraError("Renderer comparison out of enum");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (faceSide > nzFaceSide_Max)
|
||||||
|
{
|
||||||
|
NazaraError("Face side out of enum");
|
||||||
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s_states.stencilCompare = compareFunc;
|
switch (faceSide)
|
||||||
|
{
|
||||||
|
case nzFaceSide_Back:
|
||||||
|
s_states.backFace.stencilCompare = compareFunc;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nzFaceSide_Front:
|
||||||
|
s_states.frontFace.stencilCompare = compareFunc;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nzFaceSide_FrontAndBack:
|
||||||
|
s_states.backFace.stencilCompare = compareFunc;
|
||||||
|
s_states.frontFace.stencilCompare = compareFunc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzRenderer::SetStencilFailOperation(nzStencilOperation failOperation)
|
void NzRenderer::SetStencilFailOperation(nzStencilOperation failOperation, nzFaceSide faceSide)
|
||||||
{
|
{
|
||||||
#ifdef NAZARA_DEBUG
|
#ifdef NAZARA_DEBUG
|
||||||
if (failOperation > nzStencilOperation_Max)
|
if (failOperation > nzStencilOperation_Max)
|
||||||
|
|
@ -1072,17 +1092,59 @@ void NzRenderer::SetStencilFailOperation(nzStencilOperation failOperation)
|
||||||
NazaraError("Stencil fail operation out of enum");
|
NazaraError("Stencil fail operation out of enum");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (faceSide > nzFaceSide_Max)
|
||||||
|
{
|
||||||
|
NazaraError("Face side out of enum");
|
||||||
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s_states.stencilFail = failOperation;
|
switch (faceSide)
|
||||||
|
{
|
||||||
|
case nzFaceSide_Back:
|
||||||
|
s_states.backFace.stencilFail = failOperation;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nzFaceSide_Front:
|
||||||
|
s_states.frontFace.stencilFail = failOperation;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nzFaceSide_FrontAndBack:
|
||||||
|
s_states.backFace.stencilFail = failOperation;
|
||||||
|
s_states.frontFace.stencilFail = failOperation;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzRenderer::SetStencilMask(nzUInt32 mask)
|
void NzRenderer::SetStencilMask(nzUInt32 mask, nzFaceSide faceSide)
|
||||||
{
|
{
|
||||||
s_states.stencilMask = mask;
|
#ifdef NAZARA_DEBUG
|
||||||
|
if (faceSide > nzFaceSide_Max)
|
||||||
|
{
|
||||||
|
NazaraError("Face side out of enum");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (faceSide)
|
||||||
|
{
|
||||||
|
case nzFaceSide_Back:
|
||||||
|
s_states.backFace.stencilMask = mask;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nzFaceSide_Front:
|
||||||
|
s_states.frontFace.stencilMask = mask;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nzFaceSide_FrontAndBack:
|
||||||
|
s_states.backFace.stencilMask = mask;
|
||||||
|
s_states.frontFace.stencilMask = mask;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzRenderer::SetStencilPassOperation(nzStencilOperation passOperation)
|
void NzRenderer::SetStencilPassOperation(nzStencilOperation passOperation, nzFaceSide faceSide)
|
||||||
{
|
{
|
||||||
#ifdef NAZARA_DEBUG
|
#ifdef NAZARA_DEBUG
|
||||||
if (passOperation > nzStencilOperation_Max)
|
if (passOperation > nzStencilOperation_Max)
|
||||||
|
|
@ -1090,27 +1152,89 @@ void NzRenderer::SetStencilPassOperation(nzStencilOperation passOperation)
|
||||||
NazaraError("Stencil pass operation out of enum");
|
NazaraError("Stencil pass operation out of enum");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
s_states.stencilPass = passOperation;
|
if (faceSide > nzFaceSide_Max)
|
||||||
}
|
|
||||||
|
|
||||||
void NzRenderer::SetStencilReferenceValue(unsigned int refValue)
|
|
||||||
{
|
|
||||||
s_states.stencilReference = refValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NzRenderer::SetStencilZFailOperation(nzStencilOperation zfailOperation)
|
|
||||||
{
|
|
||||||
#ifdef NAZARA_DEBUG
|
|
||||||
if (zfailOperation > nzStencilOperation_Max)
|
|
||||||
{
|
{
|
||||||
NazaraError("Stencil zfail operation out of enum");
|
NazaraError("Face side out of enum");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s_states.stencilZFail = zfailOperation;
|
switch (faceSide)
|
||||||
|
{
|
||||||
|
case nzFaceSide_Back:
|
||||||
|
s_states.backFace.stencilPass = passOperation;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nzFaceSide_Front:
|
||||||
|
s_states.frontFace.stencilPass = passOperation;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nzFaceSide_FrontAndBack:
|
||||||
|
s_states.backFace.stencilPass = passOperation;
|
||||||
|
s_states.frontFace.stencilPass = passOperation;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzRenderer::SetStencilReferenceValue(unsigned int refValue, nzFaceSide faceSide)
|
||||||
|
{
|
||||||
|
#ifdef NAZARA_DEBUG
|
||||||
|
if (faceSide > nzFaceSide_Max)
|
||||||
|
{
|
||||||
|
NazaraError("Face side out of enum");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (faceSide)
|
||||||
|
{
|
||||||
|
case nzFaceSide_Back:
|
||||||
|
s_states.backFace.stencilReference = refValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nzFaceSide_Front:
|
||||||
|
s_states.frontFace.stencilReference = refValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nzFaceSide_FrontAndBack:
|
||||||
|
s_states.backFace.stencilReference = refValue;
|
||||||
|
s_states.frontFace.stencilReference = refValue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzRenderer::SetStencilZFailOperation(nzStencilOperation zfailOperation, nzFaceSide faceSide)
|
||||||
|
{
|
||||||
|
#ifdef NAZARA_DEBUG
|
||||||
|
if (zfailOperation > nzStencilOperation_Max)
|
||||||
|
{
|
||||||
|
NazaraError("Stencil pass operation out of enum");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (faceSide > nzFaceSide_Max)
|
||||||
|
{
|
||||||
|
NazaraError("Face side out of enum");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (faceSide)
|
||||||
|
{
|
||||||
|
case nzFaceSide_Back:
|
||||||
|
s_states.backFace.stencilZFail = zfailOperation;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nzFaceSide_Front:
|
||||||
|
s_states.frontFace.stencilZFail = zfailOperation;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nzFaceSide_FrontAndBack:
|
||||||
|
s_states.backFace.stencilZFail = zfailOperation;
|
||||||
|
s_states.frontFace.stencilZFail = zfailOperation;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NzRenderer::SetTarget(const NzRenderTarget* target)
|
bool NzRenderer::SetTarget(const NzRenderTarget* target)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue