Commit bea36566 authored by nadro's avatar nadro

- Added support for Color Mask in OpenGL call bridge.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@4980 dfc29bdd-3216-0410-991c-e03cc46cb475
parent d8ed51f1
...@@ -893,8 +893,7 @@ void COpenGLDriver::clearBuffers(bool backBuffer, bool zBuffer, bool stencilBuff ...@@ -893,8 +893,7 @@ void COpenGLDriver::clearBuffers(bool backBuffer, bool zBuffer, bool stencilBuff
GLbitfield mask = 0; GLbitfield mask = 0;
if (backBuffer) if (backBuffer)
{ {
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); BridgeCalls->setColorMask(true, true, true, true);
Material.ColorMask = ECP_ALL;
const f32 inv = 1.0f / 255.0f; const f32 inv = 1.0f / 255.0f;
glClearColor(color.getRed() * inv, color.getGreen() * inv, glClearColor(color.getRed() * inv, color.getGreen() * inv,
...@@ -906,8 +905,6 @@ void COpenGLDriver::clearBuffers(bool backBuffer, bool zBuffer, bool stencilBuff ...@@ -906,8 +905,6 @@ void COpenGLDriver::clearBuffers(bool backBuffer, bool zBuffer, bool stencilBuff
if (zBuffer) if (zBuffer)
{ {
BridgeCalls->setDepthMask(true); BridgeCalls->setDepthMask(true);
Material.ZWriteEnable = true;
mask |= GL_DEPTH_BUFFER_BIT; mask |= GL_DEPTH_BUFFER_BIT;
} }
...@@ -3004,94 +3001,86 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater ...@@ -3004,94 +3001,86 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater
if (resetAllRenderStates || (lastmaterial.Wireframe != material.Wireframe) || (lastmaterial.PointCloud != material.PointCloud)) if (resetAllRenderStates || (lastmaterial.Wireframe != material.Wireframe) || (lastmaterial.PointCloud != material.PointCloud))
glPolygonMode(GL_FRONT_AND_BACK, material.Wireframe ? GL_LINE : material.PointCloud? GL_POINT : GL_FILL); glPolygonMode(GL_FRONT_AND_BACK, material.Wireframe ? GL_LINE : material.PointCloud? GL_POINT : GL_FILL);
// zbuffer // ZBuffer
if (resetAllRenderStates || lastmaterial.ZBuffer != material.ZBuffer) switch (material.ZBuffer)
{ {
switch (material.ZBuffer) case ECFN_DISABLED:
{ BridgeCalls->setDepthTest(false);
case ECFN_DISABLED: break;
BridgeCalls->setDepthTest(false); case ECFN_LESSEQUAL:
break; BridgeCalls->setDepthTest(true);
case ECFN_LESSEQUAL: BridgeCalls->setDepthFunc(GL_LEQUAL);
BridgeCalls->setDepthTest(true); break;
BridgeCalls->setDepthFunc(GL_LEQUAL); case ECFN_EQUAL:
break; BridgeCalls->setDepthTest(true);
case ECFN_EQUAL: BridgeCalls->setDepthFunc(GL_EQUAL);
BridgeCalls->setDepthTest(true); break;
BridgeCalls->setDepthFunc(GL_EQUAL); case ECFN_LESS:
break; BridgeCalls->setDepthTest(true);
case ECFN_LESS: BridgeCalls->setDepthFunc(GL_LESS);
BridgeCalls->setDepthTest(true); break;
BridgeCalls->setDepthFunc(GL_LESS); case ECFN_NOTEQUAL:
break; BridgeCalls->setDepthTest(true);
case ECFN_NOTEQUAL: BridgeCalls->setDepthFunc(GL_NOTEQUAL);
BridgeCalls->setDepthTest(true); break;
BridgeCalls->setDepthFunc(GL_NOTEQUAL); case ECFN_GREATEREQUAL:
break; BridgeCalls->setDepthTest(true);
case ECFN_GREATEREQUAL: BridgeCalls->setDepthFunc(GL_GEQUAL);
BridgeCalls->setDepthTest(true); break;
BridgeCalls->setDepthFunc(GL_GEQUAL); case ECFN_GREATER:
break; BridgeCalls->setDepthTest(true);
case ECFN_GREATER: BridgeCalls->setDepthFunc(GL_GREATER);
BridgeCalls->setDepthTest(true); break;
BridgeCalls->setDepthFunc(GL_GREATER); case ECFN_ALWAYS:
break; BridgeCalls->setDepthTest(true);
case ECFN_ALWAYS: BridgeCalls->setDepthFunc(GL_ALWAYS);
BridgeCalls->setDepthTest(true); break;
BridgeCalls->setDepthFunc(GL_ALWAYS); case ECFN_NEVER:
break; BridgeCalls->setDepthTest(true);
case ECFN_NEVER: BridgeCalls->setDepthFunc(GL_NEVER);
BridgeCalls->setDepthTest(true); break;
BridgeCalls->setDepthFunc(GL_NEVER); default:
break; break;
}
} }
// zwrite // ZWrite
// if (resetAllRenderStates || lastmaterial.ZWriteEnable != material.ZWriteEnable) if (material.ZWriteEnable && (AllowZWriteOnTransparent || (material.BlendOperation == EBO_NONE &&
!MaterialRenderers[material.MaterialType].Renderer->isTransparent())))
{ {
if (material.ZWriteEnable && (AllowZWriteOnTransparent || (!material.isTransparent() && BridgeCalls->setDepthMask(true);
!MaterialRenderers[material.MaterialType].Renderer->isTransparent())))
{
BridgeCalls->setDepthMask(true);
}
else
BridgeCalls->setDepthMask(false);
} }
else
// back face culling
if (resetAllRenderStates || (lastmaterial.FrontfaceCulling != material.FrontfaceCulling) || (lastmaterial.BackfaceCulling != material.BackfaceCulling))
{ {
if ((material.FrontfaceCulling) && (material.BackfaceCulling)) BridgeCalls->setDepthMask(false);
{
BridgeCalls->setCullFaceFunc(GL_FRONT_AND_BACK);
BridgeCalls->setCullFace(true);
}
else
if (material.BackfaceCulling)
{
BridgeCalls->setCullFaceFunc(GL_BACK);
BridgeCalls->setCullFace(true);
}
else
if (material.FrontfaceCulling)
{
BridgeCalls->setCullFaceFunc(GL_FRONT);
BridgeCalls->setCullFace(true);
}
else
BridgeCalls->setCullFace(false);
} }
// Color Mask // Back face culling
if (resetAllRenderStates || lastmaterial.ColorMask != material.ColorMask) if ((material.FrontfaceCulling) && (material.BackfaceCulling))
{
BridgeCalls->setCullFaceFunc(GL_FRONT_AND_BACK);
BridgeCalls->setCullFace(true);
}
else if (material.BackfaceCulling)
{
BridgeCalls->setCullFaceFunc(GL_BACK);
BridgeCalls->setCullFace(true);
}
else if (material.FrontfaceCulling)
{ {
glColorMask( BridgeCalls->setCullFaceFunc(GL_FRONT);
(material.ColorMask & ECP_RED)?GL_TRUE:GL_FALSE, BridgeCalls->setCullFace(true);
(material.ColorMask & ECP_GREEN)?GL_TRUE:GL_FALSE,
(material.ColorMask & ECP_BLUE)?GL_TRUE:GL_FALSE,
(material.ColorMask & ECP_ALPHA)?GL_TRUE:GL_FALSE);
} }
else
{
BridgeCalls->setCullFace(false);
}
// Color Mask
BridgeCalls->setColorMask(
(material.ColorMask & ECP_RED)?GL_TRUE:GL_FALSE,
(material.ColorMask & ECP_GREEN)?GL_TRUE:GL_FALSE,
(material.ColorMask & ECP_BLUE)?GL_TRUE:GL_FALSE,
(material.ColorMask & ECP_ALPHA)?GL_TRUE:GL_FALSE);
// Blend Equation // Blend Equation
if (material.BlendOperation == EBO_NONE) if (material.BlendOperation == EBO_NONE)
...@@ -3291,6 +3280,7 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater ...@@ -3291,6 +3280,7 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater
} }
} }
// Texture parameters
setTextureRenderStates(material, resetAllRenderStates); setTextureRenderStates(material, resetAllRenderStates);
// set current fixed pipeline state // set current fixed pipeline state
...@@ -4023,7 +4013,8 @@ void COpenGLDriver::drawStencilShadow(bool clearStencilBuffer, video::SColor lef ...@@ -4023,7 +4013,8 @@ void COpenGLDriver::drawStencilShadow(bool clearStencilBuffer, video::SColor lef
glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, Quad2DIndices); glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, Quad2DIndices);
clearBuffers(false, false, clearStencilBuffer, 0x0); if (clearStencilBuffer)
glClear(GL_STENCIL_BUFFER_BIT);
// restore settings // restore settings
glPopMatrix(); glPopMatrix();
...@@ -4564,11 +4555,12 @@ bool COpenGLDriver::setRenderTarget(const core::array<video::IRenderTarget>& tar ...@@ -4564,11 +4555,12 @@ bool COpenGLDriver::setRenderTarget(const core::array<video::IRenderTarget>& tar
{ {
if (FeatureAvailable[IRR_EXT_draw_buffers2]) if (FeatureAvailable[IRR_EXT_draw_buffers2])
{ {
extGlColorMaskIndexed(i, BridgeCalls->setColorMaskIndexed(i,
(targets[i].ColorMask & ECP_RED)?GL_TRUE:GL_FALSE, (targets[i].ColorMask & ECP_RED)?GL_TRUE:GL_FALSE,
(targets[i].ColorMask & ECP_GREEN)?GL_TRUE:GL_FALSE, (targets[i].ColorMask & ECP_GREEN)?GL_TRUE:GL_FALSE,
(targets[i].ColorMask & ECP_BLUE)?GL_TRUE:GL_FALSE, (targets[i].ColorMask & ECP_BLUE)?GL_TRUE:GL_FALSE,
(targets[i].ColorMask & ECP_ALPHA)?GL_TRUE:GL_FALSE); (targets[i].ColorMask & ECP_ALPHA)?GL_TRUE:GL_FALSE);
if (targets[i].BlendOp==EBO_NONE) if (targets[i].BlendOp==EBO_NONE)
BridgeCalls->setBlendIndexed(i, false); BridgeCalls->setBlendIndexed(i, false);
else else
...@@ -5055,16 +5047,18 @@ COpenGLCallBridge::COpenGLCallBridge(COpenGLDriver* driver) : Driver(driver), ...@@ -5055,16 +5047,18 @@ COpenGLCallBridge::COpenGLCallBridge(COpenGLDriver* driver) : Driver(driver),
DepthFunc(GL_LESS), DepthMask(true), DepthTest(false), MatrixMode(GL_MODELVIEW), DepthFunc(GL_LESS), DepthMask(true), DepthTest(false), MatrixMode(GL_MODELVIEW),
ActiveTexture(GL_TEXTURE0_ARB), ClientActiveTexture(GL_TEXTURE0_ARB), ViewportX(0), ViewportY(0) ActiveTexture(GL_TEXTURE0_ARB), ClientActiveTexture(GL_TEXTURE0_ARB), ViewportX(0), ViewportY(0)
{ {
BlendIndexCount = core::max_(static_cast<GLuint>(1), static_cast<GLuint>(Driver->MaxMultipleRenderTargets)); FrameBufferCount = core::max_(static_cast<GLuint>(1), static_cast<GLuint>(Driver->MaxMultipleRenderTargets));
BlendEquation = new GLenum[BlendIndexCount]; BlendEquation = new GLenum[FrameBufferCount];
BlendSourceRGB = new GLenum[BlendIndexCount]; BlendSourceRGB = new GLenum[FrameBufferCount];
BlendDestinationRGB = new GLenum[BlendIndexCount]; BlendDestinationRGB = new GLenum[FrameBufferCount];
BlendSourceAlpha = new GLenum[BlendIndexCount]; BlendSourceAlpha = new GLenum[FrameBufferCount];
BlendDestinationAlpha = new GLenum[BlendIndexCount]; BlendDestinationAlpha = new GLenum[FrameBufferCount];
Blend = new bool[BlendIndexCount]; Blend = new bool[FrameBufferCount];
for (u32 i = 0; i < BlendIndexCount; ++i) ColorMask = new bool[FrameBufferCount][4];
for (u32 i = 0; i < FrameBufferCount; ++i)
{ {
#if defined(GL_VERSION_1_4) #if defined(GL_VERSION_1_4)
BlendEquation[i] = GL_FUNC_ADD; BlendEquation[i] = GL_FUNC_ADD;
...@@ -5078,6 +5072,9 @@ COpenGLCallBridge::COpenGLCallBridge(COpenGLDriver* driver) : Driver(driver), ...@@ -5078,6 +5072,9 @@ COpenGLCallBridge::COpenGLCallBridge(COpenGLDriver* driver) : Driver(driver),
BlendDestinationAlpha[i] = GL_ZERO; BlendDestinationAlpha[i] = GL_ZERO;
Blend[i] = false; Blend[i] = false;
for (u32 j = 0; j < 4; ++j)
ColorMask[i][j] = true;
} }
for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i) for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i)
...@@ -5103,6 +5100,8 @@ COpenGLCallBridge::COpenGLCallBridge(COpenGLDriver* driver) : Driver(driver), ...@@ -5103,6 +5100,8 @@ COpenGLCallBridge::COpenGLCallBridge(COpenGLDriver* driver) : Driver(driver),
glBlendFunc(GL_ONE, GL_ZERO); glBlendFunc(GL_ONE, GL_ZERO);
glDisable(GL_BLEND); glDisable(GL_BLEND);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glCullFace(GL_BACK); glCullFace(GL_BACK);
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
glDepthFunc(GL_LESS); glDepthFunc(GL_LESS);
...@@ -5138,6 +5137,8 @@ COpenGLCallBridge::~COpenGLCallBridge() ...@@ -5138,6 +5137,8 @@ COpenGLCallBridge::~COpenGLCallBridge()
delete[] BlendSourceAlpha; delete[] BlendSourceAlpha;
delete[] BlendDestinationAlpha; delete[] BlendDestinationAlpha;
delete[] Blend; delete[] Blend;
delete[] ColorMask;
} }
void COpenGLCallBridge::setAlphaFunc(GLenum mode, GLclampf ref) void COpenGLCallBridge::setAlphaFunc(GLenum mode, GLclampf ref)
...@@ -5169,14 +5170,14 @@ void COpenGLCallBridge::setBlendEquation(GLenum mode) ...@@ -5169,14 +5170,14 @@ void COpenGLCallBridge::setBlendEquation(GLenum mode)
{ {
Driver->extGlBlendEquation(mode); Driver->extGlBlendEquation(mode);
for (GLuint i = 0; i < BlendIndexCount; ++i) for (GLuint i = 0; i < FrameBufferCount; ++i)
BlendEquation[i] = mode; BlendEquation[i] = mode;
} }
} }
void COpenGLCallBridge::setBlendEquationIndexed(GLuint index, GLenum mode) void COpenGLCallBridge::setBlendEquationIndexed(GLuint index, GLenum mode)
{ {
if (index < BlendIndexCount && BlendEquation[index] != mode) if (index < FrameBufferCount && BlendEquation[index] != mode)
{ {
Driver->extGlBlendEquationIndexed(index, mode); Driver->extGlBlendEquationIndexed(index, mode);
...@@ -5191,7 +5192,7 @@ void COpenGLCallBridge::setBlendFunc(GLenum source, GLenum destination) ...@@ -5191,7 +5192,7 @@ void COpenGLCallBridge::setBlendFunc(GLenum source, GLenum destination)
{ {
glBlendFunc(source, destination); glBlendFunc(source, destination);
for (GLuint i = 0; i < BlendIndexCount; ++i) for (GLuint i = 0; i < FrameBufferCount; ++i)
{ {
BlendSourceRGB[i] = source; BlendSourceRGB[i] = source;
BlendDestinationRGB[i] = destination; BlendDestinationRGB[i] = destination;
...@@ -5210,7 +5211,7 @@ void COpenGLCallBridge::setBlendFuncSeparate(GLenum sourceRGB, GLenum destinatio ...@@ -5210,7 +5211,7 @@ void COpenGLCallBridge::setBlendFuncSeparate(GLenum sourceRGB, GLenum destinatio
{ {
Driver->extGlBlendFuncSeparate(sourceRGB, destinationRGB, sourceAlpha, destinationAlpha); Driver->extGlBlendFuncSeparate(sourceRGB, destinationRGB, sourceAlpha, destinationAlpha);
for (GLuint i = 0; i < BlendIndexCount; ++i) for (GLuint i = 0; i < FrameBufferCount; ++i)
{ {
BlendSourceRGB[i] = sourceRGB; BlendSourceRGB[i] = sourceRGB;
BlendDestinationRGB[i] = destinationRGB; BlendDestinationRGB[i] = destinationRGB;
...@@ -5227,7 +5228,7 @@ void COpenGLCallBridge::setBlendFuncSeparate(GLenum sourceRGB, GLenum destinatio ...@@ -5227,7 +5228,7 @@ void COpenGLCallBridge::setBlendFuncSeparate(GLenum sourceRGB, GLenum destinatio
void COpenGLCallBridge::setBlendFuncIndexed(GLuint index, GLenum source, GLenum destination) void COpenGLCallBridge::setBlendFuncIndexed(GLuint index, GLenum source, GLenum destination)
{ {
if (index < BlendIndexCount && (BlendSourceRGB[index] != source || BlendDestinationRGB[index] != destination || if (index < FrameBufferCount && (BlendSourceRGB[index] != source || BlendDestinationRGB[index] != destination ||
BlendSourceAlpha[index] != source || BlendDestinationAlpha[index] != destination)) BlendSourceAlpha[index] != source || BlendDestinationAlpha[index] != destination))
{ {
Driver->extGlBlendFuncIndexed(index, source, destination); Driver->extGlBlendFuncIndexed(index, source, destination);
...@@ -5243,7 +5244,7 @@ void COpenGLCallBridge::setBlendFuncSeparateIndexed(GLuint index, GLenum sourceR ...@@ -5243,7 +5244,7 @@ void COpenGLCallBridge::setBlendFuncSeparateIndexed(GLuint index, GLenum sourceR
{ {
if (sourceRGB != sourceAlpha || destinationRGB != destinationAlpha) if (sourceRGB != sourceAlpha || destinationRGB != destinationAlpha)
{ {
if (index < BlendIndexCount && (BlendSourceRGB[index] != sourceRGB || BlendDestinationRGB[index] != destinationRGB || if (index < FrameBufferCount && (BlendSourceRGB[index] != sourceRGB || BlendDestinationRGB[index] != destinationRGB ||
BlendSourceAlpha[index] != sourceAlpha || BlendDestinationAlpha[index] != destinationAlpha)) BlendSourceAlpha[index] != sourceAlpha || BlendDestinationAlpha[index] != destinationAlpha))
{ {
Driver->extGlBlendFuncSeparateIndexed(index, sourceRGB, destinationRGB, sourceAlpha, destinationAlpha); Driver->extGlBlendFuncSeparateIndexed(index, sourceRGB, destinationRGB, sourceAlpha, destinationAlpha);
...@@ -5269,14 +5270,14 @@ void COpenGLCallBridge::setBlend(bool enable) ...@@ -5269,14 +5270,14 @@ void COpenGLCallBridge::setBlend(bool enable)
else else
glDisable(GL_BLEND); glDisable(GL_BLEND);
for (GLuint i = 0; i < BlendIndexCount; ++i) for (GLuint i = 0; i < FrameBufferCount; ++i)
Blend[i] = enable; Blend[i] = enable;
} }
} }
void COpenGLCallBridge::setBlendIndexed(GLuint index, bool enable) void COpenGLCallBridge::setBlendIndexed(GLuint index, bool enable)
{ {
if (index < BlendIndexCount && Blend[index] != enable) if (index < FrameBufferCount && Blend[index] != enable)
{ {
if (enable) if (enable)
Driver->extGlEnableIndexed(GL_BLEND, index); Driver->extGlEnableIndexed(GL_BLEND, index);
...@@ -5287,6 +5288,35 @@ void COpenGLCallBridge::setBlendIndexed(GLuint index, bool enable) ...@@ -5287,6 +5288,35 @@ void COpenGLCallBridge::setBlendIndexed(GLuint index, bool enable)
} }
} }
void COpenGLCallBridge::setColorMask(bool red, bool green, bool blue, bool alpha)
{
if (ColorMask[0][0] != red || ColorMask[0][1] != green || ColorMask[0][2] != blue || ColorMask[0][3] != alpha)
{
glColorMask(red, green, blue, alpha);
for (GLuint i = 0; i < FrameBufferCount; ++i)
{
ColorMask[i][0] = red;
ColorMask[i][1] = green;
ColorMask[i][2] = blue;
ColorMask[i][3] = alpha;
}
}
}
void COpenGLCallBridge::setColorMaskIndexed(GLuint index, bool red, bool green, bool blue, bool alpha)
{
if (index < FrameBufferCount && (ColorMask[index][0] != red || ColorMask[index][1] != green || ColorMask[index][2] != blue || ColorMask[index][3] != alpha))
{
Driver->extGlColorMaskIndexed(index, red, green, blue, alpha);
ColorMask[index][0] = red;
ColorMask[index][1] = green;
ColorMask[index][2] = blue;
ColorMask[index][3] = alpha;
}
}
void COpenGLCallBridge::setClientState(bool vertex, bool normal, bool color, bool texCoord0) void COpenGLCallBridge::setClientState(bool vertex, bool normal, bool color, bool texCoord0)
{ {
if(ClientStateVertex != vertex) if(ClientStateVertex != vertex)
......
...@@ -675,6 +675,12 @@ namespace video ...@@ -675,6 +675,12 @@ namespace video
void setClientState(bool vertex, bool normal, bool color, bool texCoord0); void setClientState(bool vertex, bool normal, bool color, bool texCoord0);
// Color Mask.
void setColorMask(bool red, bool green, bool blue, bool alpha);
void setColorMaskIndexed(GLuint index, bool red, bool green, bool blue, bool alpha);
// Cull face calls. // Cull face calls.
void setCullFaceFunc(GLenum mode); void setCullFaceFunc(GLenum mode);
...@@ -710,6 +716,8 @@ namespace video ...@@ -710,6 +716,8 @@ namespace video
private: private:
COpenGLDriver* Driver; COpenGLDriver* Driver;
GLuint FrameBufferCount;
GLenum AlphaMode; GLenum AlphaMode;
GLclampf AlphaRef; GLclampf AlphaRef;
bool AlphaTest; bool AlphaTest;
...@@ -720,13 +728,14 @@ namespace video ...@@ -720,13 +728,14 @@ namespace video
GLenum* BlendSourceAlpha; GLenum* BlendSourceAlpha;
GLenum* BlendDestinationAlpha; GLenum* BlendDestinationAlpha;
bool* Blend; bool* Blend;
GLuint BlendIndexCount;
bool ClientStateVertex; bool ClientStateVertex;
bool ClientStateNormal; bool ClientStateNormal;
bool ClientStateColor; bool ClientStateColor;
bool ClientStateTexCoord0; bool ClientStateTexCoord0;
bool (*ColorMask)[4];
GLenum CullFaceMode; GLenum CullFaceMode;
bool CullFace; bool CullFace;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment