OpenGL Renderer: Minor rework on handling shadow polygons.
- Determining the depth write state is now handled purely within the fragment shader. - Color and depth write states are now handled more consistently across fixed-function and fragment shader. - Force backface culling when drawing shadow polygons.
This commit is contained in:
parent
49309fb053
commit
8fab80596b
|
@ -292,22 +292,22 @@ static const char *vertexShader_100 = {"\
|
||||||
|
|
||||||
// Fragment Shader GLSL 1.00
|
// Fragment Shader GLSL 1.00
|
||||||
static const char *fragmentShader_100 = {"\
|
static const char *fragmentShader_100 = {"\
|
||||||
varying vec4 vtxPosition; \n\
|
varying vec4 vtxPosition;\n\
|
||||||
varying vec2 vtxTexCoord; \n\
|
varying vec2 vtxTexCoord;\n\
|
||||||
varying vec4 vtxColor; \n\
|
varying vec4 vtxColor;\n\
|
||||||
\n\
|
\n\
|
||||||
uniform sampler2D texRenderObject; \n\
|
uniform sampler2D texRenderObject;\n\
|
||||||
uniform sampler1D texToonTable; \n\
|
uniform sampler1D texToonTable;\n\
|
||||||
\n\
|
\n\
|
||||||
uniform int stateToonShadingMode; \n\
|
uniform int stateToonShadingMode;\n\
|
||||||
uniform bool stateEnableAlphaTest; \n\
|
uniform bool stateEnableAlphaTest;\n\
|
||||||
uniform bool stateEnableAntialiasing;\n\
|
uniform bool stateEnableAntialiasing;\n\
|
||||||
uniform bool stateEnableEdgeMarking;\n\
|
uniform bool stateEnableEdgeMarking;\n\
|
||||||
uniform bool stateUseWDepth; \n\
|
uniform bool stateUseWDepth;\n\
|
||||||
uniform float stateAlphaTestRef; \n\
|
uniform float stateAlphaTestRef;\n\
|
||||||
\n\
|
\n\
|
||||||
uniform int polyMode; \n\
|
uniform int polyMode;\n\
|
||||||
uniform bool polyEnableDepthWrite;\n\
|
uniform bool polySetupShadow;\n\
|
||||||
uniform bool polySetNewDepthForTranslucent;\n\
|
uniform bool polySetNewDepthForTranslucent;\n\
|
||||||
uniform int polyID;\n\
|
uniform int polyID;\n\
|
||||||
\n\
|
\n\
|
||||||
|
@ -322,9 +322,20 @@ static const char *fragmentShader_100 = {"\
|
||||||
return packedValue;\n\
|
return packedValue;\n\
|
||||||
}\n\
|
}\n\
|
||||||
\n\
|
\n\
|
||||||
void main() \n\
|
void main()\n\
|
||||||
{ \n\
|
{\n\
|
||||||
vec4 mainTexColor = (polyEnableTexture) ? texture2D(texRenderObject, vtxTexCoord) : vec4(1.0, 1.0, 1.0, 1.0); \n\
|
vec4 newFragColor = vec4(0.0, 0.0, 0.0, 0.0);\n\
|
||||||
|
vec4 newPolyID = vec4(0.0, 0.0, 0.0, 0.0);\n\
|
||||||
|
vec4 newFogAttributes = vec4(0.0, 0.0, 0.0, 0.0);\n\
|
||||||
|
vec4 newFragDepth = vec4(0.0, 0.0, 0.0, 0.0);\n\
|
||||||
|
\n\
|
||||||
|
float vertW = (vtxPosition.w == 0.0) ? 0.00000001 : vtxPosition.w;\n\
|
||||||
|
// hack: when using z-depth, drop some LSBs so that the overworld map in Dragon Quest IV shows up correctly\n\
|
||||||
|
float newFragDepth = (stateUseWDepth) ? vtxPosition.w/4096.0 : clamp( (floor((((vtxPosition.z/vertW) * 0.5 + 0.5) * 16777215.0) / 4.0) * 4.0) / 16777215.0, 0.0, 1.0);\n\
|
||||||
|
\n\
|
||||||
|
if (!bool(polySetupShadow))\n\
|
||||||
|
{\n\
|
||||||
|
vec4 mainTexColor = (polyEnableTexture) ? texture2D(texRenderObject, vtxTexCoord) : vec4(1.0, 1.0, 1.0, 1.0);\n\
|
||||||
\n\
|
\n\
|
||||||
if (texSingleBitAlpha)\n\
|
if (texSingleBitAlpha)\n\
|
||||||
{\n\
|
{\n\
|
||||||
|
@ -339,41 +350,39 @@ static const char *fragmentShader_100 = {"\
|
||||||
}\n\
|
}\n\
|
||||||
}\n\
|
}\n\
|
||||||
\n\
|
\n\
|
||||||
vec4 newFragColor = mainTexColor * vtxColor; \n\
|
vec4 newFragColor = mainTexColor * vtxColor;\n\
|
||||||
\n\
|
\n\
|
||||||
if(polyMode == 1) \n\
|
if(polyMode == 1)\n\
|
||||||
{ \n\
|
{\n\
|
||||||
newFragColor.rgb = (polyEnableTexture) ? mix(vtxColor.rgb, mainTexColor.rgb, mainTexColor.a) : vtxColor.rgb; \n\
|
newFragColor.rgb = (polyEnableTexture) ? mix(vtxColor.rgb, mainTexColor.rgb, mainTexColor.a) : vtxColor.rgb;\n\
|
||||||
newFragColor.a = vtxColor.a; \n\
|
newFragColor.a = vtxColor.a;\n\
|
||||||
} \n\
|
}\n\
|
||||||
else if(polyMode == 2) \n\
|
else if(polyMode == 2)\n\
|
||||||
{ \n\
|
{\n\
|
||||||
vec3 toonColor = vec3(texture1D(texToonTable, vtxColor.r).rgb); \n\
|
vec3 toonColor = vec3(texture1D(texToonTable, vtxColor.r).rgb);\n\
|
||||||
newFragColor.rgb = (stateToonShadingMode == 0) ? mainTexColor.rgb * toonColor.rgb : min((mainTexColor.rgb * vtxColor.r) + toonColor.rgb, 1.0); \n\
|
newFragColor.rgb = (stateToonShadingMode == 0) ? mainTexColor.rgb * toonColor.rgb : min((mainTexColor.rgb * vtxColor.r) + toonColor.rgb, 1.0);\n\
|
||||||
} \n\
|
}\n\
|
||||||
else if(polyMode == 3) \n\
|
else if(polyMode == 3)\n\
|
||||||
{ \n\
|
{\n\
|
||||||
if (polyID != 0) \n\
|
newFragColor = vtxColor;\n\
|
||||||
{ \n\
|
}\n\
|
||||||
newFragColor = vtxColor; \n\
|
|
||||||
} \n\
|
|
||||||
} \n\
|
|
||||||
\n\
|
\n\
|
||||||
if (newFragColor.a < 0.001 || (stateEnableAlphaTest && newFragColor.a < stateAlphaTestRef)) \n\
|
if (newFragColor.a < 0.001 || (stateEnableAlphaTest && newFragColor.a < stateAlphaTestRef))\n\
|
||||||
{ \n\
|
{\n\
|
||||||
discard; \n\
|
discard;\n\
|
||||||
} \n\
|
}\n\
|
||||||
\n\
|
\n\
|
||||||
float vertW = (vtxPosition.w == 0.0) ? 0.00000001 : vtxPosition.w; \n\
|
newFragDepth = vec4( packVec3FromFloat(newFragDepth), float(polyEnableDepthWrite && (newFragColor.a > 0.999 || polySetNewDepthForTranslucent)));\n\
|
||||||
// hack: when using z-depth, drop some LSBs so that the overworld map in Dragon Quest IV shows up correctly\n\
|
newPolyID = vec4(float(polyID)/63.0, 0.0, 0.0, float(newFragColor.a > 0.999));\n\
|
||||||
float newFragDepth = (stateUseWDepth) ? vtxPosition.w/4096.0 : clamp( (floor((((vtxPosition.z/vertW) * 0.5 + 0.5) * 16777215.0) / 4.0) * 4.0) / 16777215.0, 0.0, 1.0); \n\
|
newFogAttributes = vec4(float(polyEnableFog), 0.0, 0.0, float((newFragColor.a > 0.999) ? 1.0 : 0.5));\n\
|
||||||
|
}\n\
|
||||||
\n\
|
\n\
|
||||||
gl_FragData[0] = newFragColor;\n\
|
gl_FragData[0] = newFragColor;\n\
|
||||||
gl_FragData[1] = vec4( packVec3FromFloat(newFragDepth), float(polyEnableDepthWrite && (newFragColor.a > 0.999 || polySetNewDepthForTranslucent)));\n\
|
gl_FragData[1] = newFragDepth;\n\
|
||||||
gl_FragData[2] = vec4(float(polyID)/63.0, 0.0, 0.0, float(newFragColor.a > 0.999));\n\
|
gl_FragData[2] = newPolyID;\n\
|
||||||
gl_FragData[3] = vec4(float(polyEnableFog), 0.0, 0.0, float((newFragColor.a > 0.999) ? 1.0 : 0.5));\n\
|
gl_FragData[3] = newFogAttributes;\n\
|
||||||
gl_FragDepth = newFragDepth;\n\
|
gl_FragDepth = newFragDepth;\n\
|
||||||
} \n\
|
}\n\
|
||||||
"};
|
"};
|
||||||
|
|
||||||
// Vertex shader for applying edge marking, GLSL 1.00
|
// Vertex shader for applying edge marking, GLSL 1.00
|
||||||
|
@ -1623,7 +1632,7 @@ Render3DError OpenGLRenderer_1_2::InitGeometryProgramShaderLocations()
|
||||||
|
|
||||||
OGLRef.uniformPolyTexScale = glGetUniformLocation(OGLRef.programGeometryID, "polyTexScale");
|
OGLRef.uniformPolyTexScale = glGetUniformLocation(OGLRef.programGeometryID, "polyTexScale");
|
||||||
OGLRef.uniformPolyMode = glGetUniformLocation(OGLRef.programGeometryID, "polyMode");
|
OGLRef.uniformPolyMode = glGetUniformLocation(OGLRef.programGeometryID, "polyMode");
|
||||||
OGLRef.uniformPolyEnableDepthWrite = glGetUniformLocation(OGLRef.programGeometryID, "polyEnableDepthWrite");
|
OGLRef.uniformPolySetupShadow = glGetUniformLocation(OGLRef.programGeometryID, "polySetupShadow");
|
||||||
OGLRef.uniformPolySetNewDepthForTranslucent = glGetUniformLocation(OGLRef.programGeometryID, "polySetNewDepthForTranslucent");
|
OGLRef.uniformPolySetNewDepthForTranslucent = glGetUniformLocation(OGLRef.programGeometryID, "polySetNewDepthForTranslucent");
|
||||||
OGLRef.uniformPolyAlpha = glGetUniformLocation(OGLRef.programGeometryID, "polyAlpha");
|
OGLRef.uniformPolyAlpha = glGetUniformLocation(OGLRef.programGeometryID, "polyAlpha");
|
||||||
OGLRef.uniformPolyID = glGetUniformLocation(OGLRef.programGeometryID, "polyID");
|
OGLRef.uniformPolyID = glGetUniformLocation(OGLRef.programGeometryID, "polyID");
|
||||||
|
@ -2980,6 +2989,13 @@ Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly)
|
||||||
glDepthFunc(oglDepthFunc[attr.enableDepthEqualTest]);
|
glDepthFunc(oglDepthFunc[attr.enableDepthEqualTest]);
|
||||||
|
|
||||||
// Set up culling mode
|
// Set up culling mode
|
||||||
|
if ( (attr.polygonMode == POLYGON_MODE_SHADOW) && (attr.polygonID != 0) )
|
||||||
|
{
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
glCullFace(GL_BACK);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
static const GLenum oglCullingMode[4] = {GL_FRONT_AND_BACK, GL_FRONT, GL_BACK, 0};
|
static const GLenum oglCullingMode[4] = {GL_FRONT_AND_BACK, GL_FRONT, GL_BACK, 0};
|
||||||
GLenum cullingMode = oglCullingMode[attr.surfaceCullingMode];
|
GLenum cullingMode = oglCullingMode[attr.surfaceCullingMode];
|
||||||
|
|
||||||
|
@ -2992,12 +3008,21 @@ Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly)
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
glCullFace(cullingMode);
|
glCullFace(cullingMode);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set up depth write
|
// Set up color and depth write
|
||||||
GLboolean enableDepthWrite = GL_TRUE;
|
if ( (attr.polygonMode == POLYGON_MODE_SHADOW) && (attr.polygonID == 0) )
|
||||||
|
{
|
||||||
|
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||||
|
glDepthMask(GL_FALSE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
|
glDepthMask(GL_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
// Handle shadow polys. Do this after checking for depth write, since shadow polys
|
// Set up stencil testing
|
||||||
// can change this too.
|
|
||||||
if (attr.polygonMode == POLYGON_MODE_SHADOW)
|
if (attr.polygonMode == POLYGON_MODE_SHADOW)
|
||||||
{
|
{
|
||||||
glEnable(GL_STENCIL_TEST);
|
glEnable(GL_STENCIL_TEST);
|
||||||
|
@ -3009,8 +3034,6 @@ Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly)
|
||||||
//do not write color or depth information.
|
//do not write color or depth information.
|
||||||
glStencilFunc(GL_NOTEQUAL, 0x80, 0xFF);
|
glStencilFunc(GL_NOTEQUAL, 0x80, 0xFF);
|
||||||
glStencilOp(GL_KEEP, GL_ZERO, GL_KEEP);
|
glStencilOp(GL_KEEP, GL_ZERO, GL_KEEP);
|
||||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
|
||||||
enableDepthWrite = GL_FALSE;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3018,27 +3041,19 @@ Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly)
|
||||||
//only draw the shadow poly where the stencilbuf==1.
|
//only draw the shadow poly where the stencilbuf==1.
|
||||||
glStencilFunc(GL_EQUAL, 0, 0xFF);
|
glStencilFunc(GL_EQUAL, 0, 0xFF);
|
||||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
|
||||||
enableDepthWrite = GL_TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( attr.isTranslucent || (std::find(this->_shadowPolyID.begin(), this->_shadowPolyID.end(), attr.polygonID) == this->_shadowPolyID.end()) )
|
else if ( attr.isTranslucent || (std::find(this->_shadowPolyID.begin(), this->_shadowPolyID.end(), attr.polygonID) == this->_shadowPolyID.end()) )
|
||||||
{
|
{
|
||||||
glDisable(GL_STENCIL_TEST);
|
glDisable(GL_STENCIL_TEST);
|
||||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
|
||||||
enableDepthWrite = (!attr.isTranslucent || attr.isOpaque || attr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glEnable(GL_STENCIL_TEST);
|
glEnable(GL_STENCIL_TEST);
|
||||||
glStencilFunc(GL_ALWAYS, 0x80, 0xFF);
|
glStencilFunc(GL_ALWAYS, 0x80, 0xFF);
|
||||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
|
||||||
enableDepthWrite = GL_TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glDepthMask(enableDepthWrite);
|
|
||||||
|
|
||||||
// Set up polygon attributes
|
// Set up polygon attributes
|
||||||
if (this->isShaderSupported)
|
if (this->isShaderSupported)
|
||||||
{
|
{
|
||||||
|
@ -3047,7 +3062,7 @@ Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly)
|
||||||
glUniform1i(OGLRef.uniformPolyEnableFog, (attr.enableRenderFog && !(attr.polygonMode == POLYGON_MODE_SHADOW && attr.polygonID == 0)) ? GL_TRUE : GL_FALSE);
|
glUniform1i(OGLRef.uniformPolyEnableFog, (attr.enableRenderFog && !(attr.polygonMode == POLYGON_MODE_SHADOW && attr.polygonID == 0)) ? GL_TRUE : GL_FALSE);
|
||||||
glUniform1f(OGLRef.uniformPolyAlpha, (!attr.isWireframe && attr.isTranslucent) ? divide5bitBy31_LUT[attr.alpha] : 1.0f);
|
glUniform1f(OGLRef.uniformPolyAlpha, (!attr.isWireframe && attr.isTranslucent) ? divide5bitBy31_LUT[attr.alpha] : 1.0f);
|
||||||
glUniform1i(OGLRef.uniformPolyID, attr.polygonID);
|
glUniform1i(OGLRef.uniformPolyID, attr.polygonID);
|
||||||
glUniform1i(OGLRef.uniformPolyEnableDepthWrite, (!(attr.polygonMode == POLYGON_MODE_SHADOW && attr.polygonID == 0)) ? GL_TRUE : GL_FALSE);
|
glUniform1i(OGLRef.uniformPolySetupShadow, ( (attr.polygonMode == POLYGON_MODE_SHADOW) && (attr.polygonID == 0) ) ? GL_TRUE : GL_FALSE);
|
||||||
glUniform1i(OGLRef.uniformPolySetNewDepthForTranslucent, (attr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE);
|
glUniform1i(OGLRef.uniformPolySetNewDepthForTranslucent, (attr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4582,6 +4597,13 @@ Render3DError OpenGLRenderer_2_0::SetupPolygon(const POLY &thePoly)
|
||||||
glDepthFunc(oglDepthFunc[attr.enableDepthEqualTest]);
|
glDepthFunc(oglDepthFunc[attr.enableDepthEqualTest]);
|
||||||
|
|
||||||
// Set up culling mode
|
// Set up culling mode
|
||||||
|
if ( (attr.polygonMode == POLYGON_MODE_SHADOW) && (attr.polygonID != 0) )
|
||||||
|
{
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
glCullFace(GL_BACK);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
static const GLenum oglCullingMode[4] = {GL_FRONT_AND_BACK, GL_FRONT, GL_BACK, 0};
|
static const GLenum oglCullingMode[4] = {GL_FRONT_AND_BACK, GL_FRONT, GL_BACK, 0};
|
||||||
GLenum cullingMode = oglCullingMode[attr.surfaceCullingMode];
|
GLenum cullingMode = oglCullingMode[attr.surfaceCullingMode];
|
||||||
|
|
||||||
|
@ -4594,12 +4616,21 @@ Render3DError OpenGLRenderer_2_0::SetupPolygon(const POLY &thePoly)
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
glCullFace(cullingMode);
|
glCullFace(cullingMode);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set up depth write
|
// Set up color and depth write
|
||||||
GLboolean enableDepthWrite = GL_TRUE;
|
if ( (attr.polygonMode == POLYGON_MODE_SHADOW) && (attr.polygonID == 0) )
|
||||||
|
{
|
||||||
|
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||||
|
glDepthMask(GL_FALSE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
|
glDepthMask(GL_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
// Handle shadow polys. Do this after checking for depth write, since shadow polys
|
// Set up stencil testing
|
||||||
// can change this too.
|
|
||||||
if (attr.polygonMode == POLYGON_MODE_SHADOW)
|
if (attr.polygonMode == POLYGON_MODE_SHADOW)
|
||||||
{
|
{
|
||||||
glEnable(GL_STENCIL_TEST);
|
glEnable(GL_STENCIL_TEST);
|
||||||
|
@ -4611,8 +4642,6 @@ Render3DError OpenGLRenderer_2_0::SetupPolygon(const POLY &thePoly)
|
||||||
//do not write color or depth information.
|
//do not write color or depth information.
|
||||||
glStencilFunc(GL_NOTEQUAL, 0x80, 0xFF);
|
glStencilFunc(GL_NOTEQUAL, 0x80, 0xFF);
|
||||||
glStencilOp(GL_KEEP, GL_ZERO, GL_KEEP);
|
glStencilOp(GL_KEEP, GL_ZERO, GL_KEEP);
|
||||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
|
||||||
enableDepthWrite = GL_FALSE;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -4620,34 +4649,26 @@ Render3DError OpenGLRenderer_2_0::SetupPolygon(const POLY &thePoly)
|
||||||
//only draw the shadow poly where the stencilbuf==1.
|
//only draw the shadow poly where the stencilbuf==1.
|
||||||
glStencilFunc(GL_EQUAL, 0, 0xFF);
|
glStencilFunc(GL_EQUAL, 0, 0xFF);
|
||||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
|
||||||
enableDepthWrite = GL_TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( attr.isTranslucent || (std::find(this->_shadowPolyID.begin(), this->_shadowPolyID.end(), attr.polygonID) == this->_shadowPolyID.end()) )
|
else if ( attr.isTranslucent || (std::find(this->_shadowPolyID.begin(), this->_shadowPolyID.end(), attr.polygonID) == this->_shadowPolyID.end()) )
|
||||||
{
|
{
|
||||||
glDisable(GL_STENCIL_TEST);
|
glDisable(GL_STENCIL_TEST);
|
||||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
|
||||||
enableDepthWrite = (!attr.isTranslucent || attr.isOpaque || attr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glEnable(GL_STENCIL_TEST);
|
glEnable(GL_STENCIL_TEST);
|
||||||
glStencilFunc(GL_ALWAYS, 0x80, 0xFF);
|
glStencilFunc(GL_ALWAYS, 0x80, 0xFF);
|
||||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
|
||||||
enableDepthWrite = GL_TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glDepthMask(enableDepthWrite);
|
|
||||||
|
|
||||||
// Set up polygon attributes
|
// Set up polygon attributes
|
||||||
OGLRenderRef &OGLRef = *this->ref;
|
OGLRenderRef &OGLRef = *this->ref;
|
||||||
glUniform1i(OGLRef.uniformPolyMode, attr.polygonMode);
|
glUniform1i(OGLRef.uniformPolyMode, attr.polygonMode);
|
||||||
glUniform1i(OGLRef.uniformPolyEnableFog, (attr.enableRenderFog && !(attr.polygonMode == POLYGON_MODE_SHADOW && attr.polygonID == 0)) ? GL_TRUE : GL_FALSE);
|
glUniform1i(OGLRef.uniformPolyEnableFog, (attr.enableRenderFog && !(attr.polygonMode == POLYGON_MODE_SHADOW && attr.polygonID == 0)) ? GL_TRUE : GL_FALSE);
|
||||||
glUniform1f(OGLRef.uniformPolyAlpha, (!attr.isWireframe && attr.isTranslucent) ? divide5bitBy31_LUT[attr.alpha] : 1.0f);
|
glUniform1f(OGLRef.uniformPolyAlpha, (!attr.isWireframe && attr.isTranslucent) ? divide5bitBy31_LUT[attr.alpha] : 1.0f);
|
||||||
glUniform1i(OGLRef.uniformPolyID, attr.polygonID);
|
glUniform1i(OGLRef.uniformPolyID, attr.polygonID);
|
||||||
glUniform1i(OGLRef.uniformPolyEnableDepthWrite, (!(attr.polygonMode == POLYGON_MODE_SHADOW && attr.polygonID == 0)) ? GL_TRUE : GL_FALSE);
|
glUniform1i(OGLRef.uniformPolySetupShadow, ( (attr.polygonMode == POLYGON_MODE_SHADOW) && (attr.polygonID == 0) ) ? GL_TRUE : GL_FALSE);
|
||||||
glUniform1i(OGLRef.uniformPolySetNewDepthForTranslucent, (attr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE);
|
glUniform1i(OGLRef.uniformPolySetNewDepthForTranslucent, (attr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE);
|
||||||
|
|
||||||
return OGLERROR_NOERR;
|
return OGLERROR_NOERR;
|
||||||
|
|
|
@ -377,7 +377,7 @@ struct OGLPolyStates
|
||||||
{
|
{
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
struct { GLubyte enableTexture, enableFog, enableDepthWrite, setNewDepthForTranslucent; };
|
struct { GLubyte enableTexture, enableFog, setupShadowPoly, setNewDepthForTranslucent; };
|
||||||
GLubyte flags[4];
|
GLubyte flags[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -474,7 +474,7 @@ struct OGLRenderRef
|
||||||
|
|
||||||
GLint uniformPolyTexScale;
|
GLint uniformPolyTexScale;
|
||||||
GLint uniformPolyMode;
|
GLint uniformPolyMode;
|
||||||
GLint uniformPolyEnableDepthWrite;
|
GLint uniformPolySetupShadow;
|
||||||
GLint uniformPolySetNewDepthForTranslucent;
|
GLint uniformPolySetNewDepthForTranslucent;
|
||||||
GLint uniformPolyAlpha;
|
GLint uniformPolyAlpha;
|
||||||
GLint uniformPolyID;
|
GLint uniformPolyID;
|
||||||
|
|
|
@ -116,7 +116,7 @@ static const char *GeometryVtxShader_150 = {"\
|
||||||
out vec4 vtxColor; \n\
|
out vec4 vtxColor; \n\
|
||||||
flat out uint polyEnableTexture;\n\
|
flat out uint polyEnableTexture;\n\
|
||||||
flat out uint polyEnableFog;\n\
|
flat out uint polyEnableFog;\n\
|
||||||
flat out uint polyEnableDepthWrite;\n\
|
flat out uint polySetupShadow;\n\
|
||||||
flat out uint polySetNewDepthForTranslucent;\n\
|
flat out uint polySetNewDepthForTranslucent;\n\
|
||||||
flat out uint polyMode;\n\
|
flat out uint polyMode;\n\
|
||||||
flat out uint polyID;\n\
|
flat out uint polyID;\n\
|
||||||
|
@ -133,7 +133,7 @@ static const char *GeometryVtxShader_150 = {"\
|
||||||
\n\
|
\n\
|
||||||
polyEnableTexture = polyStateFlags[0];\n\
|
polyEnableTexture = polyStateFlags[0];\n\
|
||||||
polyEnableFog = polyStateFlags[1];\n\
|
polyEnableFog = polyStateFlags[1];\n\
|
||||||
polyEnableDepthWrite = polyStateFlags[2];\n\
|
polySetupShadow = polyStateFlags[2];\n\
|
||||||
polySetNewDepthForTranslucent = polyStateFlags[3];\n\
|
polySetNewDepthForTranslucent = polyStateFlags[3];\n\
|
||||||
polyMode = polyStateValues[1];\n\
|
polyMode = polyStateValues[1];\n\
|
||||||
polyID = polyStateValues[2];\n\
|
polyID = polyStateValues[2];\n\
|
||||||
|
@ -154,12 +154,12 @@ static const char *GeometryVtxShader_150 = {"\
|
||||||
static const char *GeometryFragShader_150 = {"\
|
static const char *GeometryFragShader_150 = {"\
|
||||||
#version 150 \n\
|
#version 150 \n\
|
||||||
\n\
|
\n\
|
||||||
in vec4 vtxPosition; \n\
|
in vec4 vtxPosition;\n\
|
||||||
in vec2 vtxTexCoord; \n\
|
in vec2 vtxTexCoord;\n\
|
||||||
in vec4 vtxColor; \n\
|
in vec4 vtxColor;\n\
|
||||||
flat in uint polyEnableTexture;\n\
|
flat in uint polyEnableTexture;\n\
|
||||||
flat in uint polyEnableFog;\n\
|
flat in uint polyEnableFog;\n\
|
||||||
flat in uint polyEnableDepthWrite;\n\
|
flat in uint polySetupShadow;\n\
|
||||||
flat in uint polySetNewDepthForTranslucent;\n\
|
flat in uint polySetNewDepthForTranslucent;\n\
|
||||||
flat in uint polyMode;\n\
|
flat in uint polyMode;\n\
|
||||||
flat in uint polyID;\n\
|
flat in uint polyID;\n\
|
||||||
|
@ -184,7 +184,7 @@ static const char *GeometryFragShader_150 = {"\
|
||||||
vec4 toonColor[32];\n\
|
vec4 toonColor[32];\n\
|
||||||
} state;\n\
|
} state;\n\
|
||||||
\n\
|
\n\
|
||||||
uniform sampler2D texRenderObject; \n\
|
uniform sampler2D texRenderObject;\n\
|
||||||
uniform usamplerBuffer PolyStates;\n\
|
uniform usamplerBuffer PolyStates;\n\
|
||||||
uniform int polyIndex;\n\
|
uniform int polyIndex;\n\
|
||||||
\n\
|
\n\
|
||||||
|
@ -200,8 +200,19 @@ static const char *GeometryFragShader_150 = {"\
|
||||||
return packedValue;\n\
|
return packedValue;\n\
|
||||||
}\n\
|
}\n\
|
||||||
\n\
|
\n\
|
||||||
void main() \n\
|
void main()\n\
|
||||||
{ \n\
|
{\n\
|
||||||
|
vec4 newFragColor = vec4(0.0, 0.0, 0.0, 0.0);\n\
|
||||||
|
vec4 newPolyID = vec4(0.0, 0.0, 0.0, 0.0);\n\
|
||||||
|
vec4 newFogAttributes = vec4(0.0, 0.0, 0.0, 0.0);\n\
|
||||||
|
vec4 newFragDepth = vec4(0.0, 0.0, 0.0, 0.0);\n\
|
||||||
|
\n\
|
||||||
|
float vertW = (vtxPosition.w == 0.0) ? 0.00000001 : vtxPosition.w;\n\
|
||||||
|
// hack: when using z-depth, drop some LSBs so that the overworld map in Dragon Quest IV shows up correctly\n\
|
||||||
|
float newFragDepthValue = (state.useWDepth) ? vtxPosition.w/4096.0 : clamp( (floor((((vtxPosition.z/vertW) * 0.5 + 0.5) * 16777215.0) / 4.0) * 4.0) / 16777215.0, 0.0, 1.0);\n\
|
||||||
|
\n\
|
||||||
|
if (!bool(polySetupShadow))\n\
|
||||||
|
{\n\
|
||||||
vec4 mainTexColor = bool(polyEnableTexture) ? texture(texRenderObject, vtxTexCoord) : vec4(1.0, 1.0, 1.0, 1.0);\n\
|
vec4 mainTexColor = bool(polyEnableTexture) ? texture(texRenderObject, vtxTexCoord) : vec4(1.0, 1.0, 1.0, 1.0);\n\
|
||||||
\n\
|
\n\
|
||||||
if (bool(texSingleBitAlpha))\n\
|
if (bool(texSingleBitAlpha))\n\
|
||||||
|
@ -217,41 +228,39 @@ static const char *GeometryFragShader_150 = {"\
|
||||||
}\n\
|
}\n\
|
||||||
}\n\
|
}\n\
|
||||||
\n\
|
\n\
|
||||||
vec4 newFragColor = mainTexColor * vtxColor; \n\
|
newFragColor = mainTexColor * vtxColor;\n\
|
||||||
\n\
|
\n\
|
||||||
if (polyMode == 1u) \n\
|
if (polyMode == 1u)\n\
|
||||||
{ \n\
|
{\n\
|
||||||
newFragColor.rgb = bool(polyEnableTexture) ? mix(vtxColor.rgb, mainTexColor.rgb, mainTexColor.a) : vtxColor.rgb;\n\
|
newFragColor.rgb = bool(polyEnableTexture) ? mix(vtxColor.rgb, mainTexColor.rgb, mainTexColor.a) : vtxColor.rgb;\n\
|
||||||
newFragColor.a = vtxColor.a; \n\
|
newFragColor.a = vtxColor.a;\n\
|
||||||
} \n\
|
}\n\
|
||||||
else if (polyMode == 2u) \n\
|
else if (polyMode == 2u)\n\
|
||||||
{ \n\
|
{\n\
|
||||||
vec3 newToonColor = state.toonColor[int((vtxColor.r * 31.0) + 0.5)].rgb;\n\
|
vec3 newToonColor = state.toonColor[int((vtxColor.r * 31.0) + 0.5)].rgb;\n\
|
||||||
newFragColor.rgb = (state.toonShadingMode == 0) ? mainTexColor.rgb * newToonColor.rgb : min((mainTexColor.rgb * vtxColor.r) + newToonColor.rgb, 1.0); \n\
|
newFragColor.rgb = (state.toonShadingMode == 0) ? mainTexColor.rgb * newToonColor.rgb : min((mainTexColor.rgb * vtxColor.r) + newToonColor.rgb, 1.0);\n\
|
||||||
} \n\
|
}\n\
|
||||||
else if (polyMode == 3u) \n\
|
else if (polyMode == 3u)\n\
|
||||||
{ \n\
|
{\n\
|
||||||
if (polyID != 0u) \n\
|
newFragColor = vtxColor;\n\
|
||||||
{ \n\
|
}\n\
|
||||||
newFragColor = vtxColor; \n\
|
|
||||||
} \n\
|
|
||||||
} \n\
|
|
||||||
\n\
|
\n\
|
||||||
if (newFragColor.a < 0.001 || (state.enableAlphaTest && newFragColor.a < state.alphaTestRef))\n\
|
if (newFragColor.a < 0.001 || (state.enableAlphaTest && newFragColor.a < state.alphaTestRef))\n\
|
||||||
{\n\
|
{\n\
|
||||||
discard;\n\
|
discard;\n\
|
||||||
}\n\
|
}\n\
|
||||||
\n\
|
\n\
|
||||||
float vertW = (vtxPosition.w == 0.0) ? 0.00000001 : vtxPosition.w; \n\
|
newFragDepth = vec4( packVec3FromFloat(newFragDepthValue), float((newFragColor.a > 0.999) || bool(polySetNewDepthForTranslucent)) );\n\
|
||||||
// hack: when using z-depth, drop some LSBs so that the overworld map in Dragon Quest IV shows up correctly\n\
|
newPolyID = vec4(float(polyID)/63.0, 0.0, 0.0, float(newFragColor.a > 0.999));\n\
|
||||||
float newFragDepth = (state.useWDepth) ? vtxPosition.w/4096.0 : clamp( (floor((((vtxPosition.z/vertW) * 0.5 + 0.5) * 16777215.0) / 4.0) * 4.0) / 16777215.0, 0.0, 1.0); \n\
|
newFogAttributes = vec4(float(polyEnableFog), 0.0, 0.0, float((newFragColor.a > 0.999) ? 1.0 : 0.5));\n\
|
||||||
|
}\n\
|
||||||
\n\
|
\n\
|
||||||
outFragColor = newFragColor;\n\
|
outFragColor = newFragColor;\n\
|
||||||
outFragDepth = vec4( packVec3FromFloat(newFragDepth), float(bool(polyEnableDepthWrite) && (newFragColor.a > 0.999 || bool(polySetNewDepthForTranslucent))));\n\
|
outFragDepth = newFragDepth;\n\
|
||||||
outPolyID = vec4(float(polyID)/63.0, 0.0, 0.0, float(newFragColor.a > 0.999));\n\
|
outPolyID = newPolyID;\n\
|
||||||
outFogAttributes = vec4(float(polyEnableFog), 0.0, 0.0, float((newFragColor.a > 0.999) ? 1.0 : 0.5));\n\
|
outFogAttributes = newFogAttributes;\n\
|
||||||
gl_FragDepth = newFragDepth;\n\
|
gl_FragDepth = newFragDepthValue;\n\
|
||||||
} \n\
|
}\n\
|
||||||
"};
|
"};
|
||||||
|
|
||||||
// Vertex shader for applying edge marking, GLSL 1.50
|
// Vertex shader for applying edge marking, GLSL 1.50
|
||||||
|
@ -1431,7 +1440,7 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine)
|
||||||
|
|
||||||
polyStates[i].enableTexture = (this->_textureList[i]->IsSamplingEnabled()) ? GL_TRUE : GL_FALSE;
|
polyStates[i].enableTexture = (this->_textureList[i]->IsSamplingEnabled()) ? GL_TRUE : GL_FALSE;
|
||||||
polyStates[i].enableFog = (polyAttr.enableRenderFog && !(polyAttr.polygonMode == POLYGON_MODE_SHADOW && polyAttr.polygonID == 0)) ? GL_TRUE : GL_FALSE;
|
polyStates[i].enableFog = (polyAttr.enableRenderFog && !(polyAttr.polygonMode == POLYGON_MODE_SHADOW && polyAttr.polygonID == 0)) ? GL_TRUE : GL_FALSE;
|
||||||
polyStates[i].enableDepthWrite = !(polyAttr.polygonMode == POLYGON_MODE_SHADOW && polyAttr.polygonID == 0) ? GL_TRUE : GL_FALSE;
|
polyStates[i].setupShadowPoly = (polyAttr.polygonMode == POLYGON_MODE_SHADOW && polyAttr.polygonID == 0) ? GL_TRUE : GL_FALSE;
|
||||||
polyStates[i].setNewDepthForTranslucent = (polyAttr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE;
|
polyStates[i].setNewDepthForTranslucent = (polyAttr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE;
|
||||||
polyStates[i].polyAlpha = (!polyAttr.isWireframe && polyAttr.isTranslucent) ? polyAttr.alpha : 0x1F;
|
polyStates[i].polyAlpha = (!polyAttr.isWireframe && polyAttr.isTranslucent) ? polyAttr.alpha : 0x1F;
|
||||||
polyStates[i].polyMode = polyAttr.polygonMode;
|
polyStates[i].polyMode = polyAttr.polygonMode;
|
||||||
|
@ -1623,6 +1632,13 @@ Render3DError OpenGLRenderer_3_2::SetupPolygon(const POLY &thePoly)
|
||||||
glDepthFunc(oglDepthFunc[attr.enableDepthEqualTest]);
|
glDepthFunc(oglDepthFunc[attr.enableDepthEqualTest]);
|
||||||
|
|
||||||
// Set up culling mode
|
// Set up culling mode
|
||||||
|
if ( (attr.polygonMode == POLYGON_MODE_SHADOW) && (attr.polygonID != 0) )
|
||||||
|
{
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
glCullFace(GL_BACK);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
static const GLenum oglCullingMode[4] = {GL_FRONT_AND_BACK, GL_FRONT, GL_BACK, 0};
|
static const GLenum oglCullingMode[4] = {GL_FRONT_AND_BACK, GL_FRONT, GL_BACK, 0};
|
||||||
GLenum cullingMode = oglCullingMode[attr.surfaceCullingMode];
|
GLenum cullingMode = oglCullingMode[attr.surfaceCullingMode];
|
||||||
|
|
||||||
|
@ -1635,12 +1651,21 @@ Render3DError OpenGLRenderer_3_2::SetupPolygon(const POLY &thePoly)
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
glCullFace(cullingMode);
|
glCullFace(cullingMode);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set up depth write
|
// Set up color and depth write
|
||||||
GLboolean enableDepthWrite = GL_TRUE;
|
if ( (attr.polygonMode == POLYGON_MODE_SHADOW) && (attr.polygonID == 0) )
|
||||||
|
{
|
||||||
|
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||||
|
glDepthMask(GL_FALSE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
|
glDepthMask(GL_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
// Handle shadow polys. Do this after checking for depth write, since shadow polys
|
// Set up stencil testing
|
||||||
// can change this too.
|
|
||||||
if (attr.polygonMode == POLYGON_MODE_SHADOW)
|
if (attr.polygonMode == POLYGON_MODE_SHADOW)
|
||||||
{
|
{
|
||||||
glEnable(GL_STENCIL_TEST);
|
glEnable(GL_STENCIL_TEST);
|
||||||
|
@ -1652,8 +1677,6 @@ Render3DError OpenGLRenderer_3_2::SetupPolygon(const POLY &thePoly)
|
||||||
//do not write color or depth information.
|
//do not write color or depth information.
|
||||||
glStencilFunc(GL_NOTEQUAL, 0x80, 0xFF);
|
glStencilFunc(GL_NOTEQUAL, 0x80, 0xFF);
|
||||||
glStencilOp(GL_KEEP, GL_ZERO, GL_KEEP);
|
glStencilOp(GL_KEEP, GL_ZERO, GL_KEEP);
|
||||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
|
||||||
enableDepthWrite = GL_FALSE;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1661,27 +1684,19 @@ Render3DError OpenGLRenderer_3_2::SetupPolygon(const POLY &thePoly)
|
||||||
//only draw the shadow poly where the stencilbuf==1.
|
//only draw the shadow poly where the stencilbuf==1.
|
||||||
glStencilFunc(GL_EQUAL, 0, 0xFF);
|
glStencilFunc(GL_EQUAL, 0, 0xFF);
|
||||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
|
||||||
enableDepthWrite = GL_TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( attr.isTranslucent || (std::find(this->_shadowPolyID.begin(), this->_shadowPolyID.end(), attr.polygonID) == this->_shadowPolyID.end()) )
|
else if ( attr.isTranslucent || (std::find(this->_shadowPolyID.begin(), this->_shadowPolyID.end(), attr.polygonID) == this->_shadowPolyID.end()) )
|
||||||
{
|
{
|
||||||
glDisable(GL_STENCIL_TEST);
|
glDisable(GL_STENCIL_TEST);
|
||||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
|
||||||
enableDepthWrite = (!attr.isTranslucent || attr.isOpaque || attr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glEnable(GL_STENCIL_TEST);
|
glEnable(GL_STENCIL_TEST);
|
||||||
glStencilFunc(GL_ALWAYS, 0x80, 0xFF);
|
glStencilFunc(GL_ALWAYS, 0x80, 0xFF);
|
||||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
|
||||||
enableDepthWrite = GL_TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glDepthMask(enableDepthWrite);
|
|
||||||
|
|
||||||
return OGLERROR_NOERR;
|
return OGLERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue