OpenGL Renderer:

- Fix some more graphical bugs with fog and translucent fragments.
- Do some small optimizations to the fragment shaders.
This commit is contained in:
rogerman 2015-04-27 21:18:48 +00:00
parent ecc22fb24d
commit e89544aa7b
6 changed files with 80 additions and 71 deletions

View File

@ -278,11 +278,11 @@ static const char *fragmentShader_100 = {"\
uniform bool stateEnableAlphaTest; \n\
uniform bool stateEnableAntialiasing;\n\
uniform bool stateEnableEdgeMarking;\n\
uniform bool stateEnableFogAlphaOnly;\n\
uniform bool stateUseWDepth; \n\
uniform float stateAlphaTestRef; \n\
\n\
uniform int polyMode; \n\
uniform bool polyEnableDepthWrite;\n\
uniform bool polySetNewDepthForTranslucent;\n\
uniform int polyID; \n\
\n\
@ -328,9 +328,9 @@ static const char *fragmentShader_100 = {"\
float newFragDepth = (stateUseWDepth) ? vtxPosition.w/4096.0 : clamp((vtxPosition.z/vertW) * 0.5 + 0.5, 0.0, 1.0); \n\
\n\
gl_FragData[0] = newFragColor;\n\
gl_FragData[3] = vec4( float(polyEnableFog), float(stateEnableFogAlphaOnly), 0.0, 1.0);\n\
if (newFragColor.a > 0.999) gl_FragData[2] = vec4(float(polyID)/63.0, float(stateEnableAntialiasing), 0.0, 1.0);\n\
if (polyEnableDepthWrite && (newFragColor.a > 0.999 || polySetNewDepthForTranslucent)) gl_FragData[1] = vec4( packVec3FromFloat(newFragDepth), 1.0);\n\
gl_FragData[1] = vec4( packVec3FromFloat(newFragDepth), float(polyEnableDepthWrite && (newFragColor.a > 0.999 || polySetNewDepthForTranslucent)));\n\
gl_FragData[2] = vec4(float(polyID)/63.0, float(stateEnableAntialiasing), 0.0, float(newFragColor.a > 0.999));\n\
gl_FragData[3] = vec4( float(polyEnableFog), 0.0, 0.0, float(newFragColor.a > 0.999 || !polyEnableFog));\n\
gl_FragDepth = newFragDepth;\n\
} \n\
"};
@ -419,7 +419,7 @@ static const char *EdgeMarkFragShader_100 = {"\
}\n\
}\n\
\n\
gl_FragData[0] = (doEdgeMark) ? ((doAntialias) ? mix(edgeColor, inFragColor, 0.4) : edgeColor) : inFragColor;\n\
gl_FragData[0] = mix(inFragColor, edgeColor, (doEdgeMark) ? ((doAntialias) ? (16.0/31.0) : 1.0) : 0.0);\n\
}\n\
"};
@ -443,6 +443,7 @@ static const char *FogFragShader_100 = {"\
uniform sampler2D texInFragColor;\n\
uniform sampler2D texInFragDepth;\n\
uniform sampler2D texInFogAttributes;\n\
uniform bool stateEnableFogAlphaOnly;\n\
uniform vec4 stateFogColor;\n\
uniform float stateFogDensity[32];\n\
uniform float stateFogOffset;\n\
@ -457,13 +458,15 @@ static const char *FogFragShader_100 = {"\
void main()\n\
{\n\
vec4 inFragColor = texture2D(texInFragColor, texCoord);\n\
float inFragDepth = unpackFloatFromVec3(texture2D(texInFragDepth, texCoord).rgb);\n\
vec4 inFogAttributes = texture2D(texInFogAttributes, texCoord);\n\
\n\
bool polyEnableFog = bool(inFogAttributes.r);\n\
bool stateEnableFogAlphaOnly = bool(inFogAttributes.g) ;\n\
vec4 newFoggedColor = inFragColor;\n\
\n\
if (polyEnableFog)\n\
{\n\
float inFragDepth = unpackFloatFromVec3(texture2D(texInFragDepth, texCoord).rgb);\n\
float fogMixWeight = 0.0;\n\
\n\
if (inFragDepth <= min(stateFogOffset + stateFogStep, 1.0))\n\
{\n\
fogMixWeight = stateFogDensity[0];\n\
@ -486,8 +489,10 @@ static const char *FogFragShader_100 = {"\
}\n\
}\n\
\n\
vec4 newFoggedColor = mix(inFragColor, stateFogColor, fogMixWeight);\n\
gl_FragData[0] = (polyEnableFog) ? ((stateEnableFogAlphaOnly) ? vec4(inFragColor.rgb, newFoggedColor.a) : newFoggedColor) : inFragColor;\n\
newFoggedColor = mix(inFragColor, (stateEnableFogAlphaOnly) ? vec4(inFragColor.rgb, stateFogColor.a) : stateFogColor, fogMixWeight);\n\
}\n\
\n\
gl_FragData[0] = newFoggedColor;\n\
}\n\
"};
@ -1283,7 +1288,6 @@ Render3DError OpenGLRenderer_1_2::InitGeometryProgram(const std::string &vertexS
OGLRef.uniformStateEnableAlphaTest = glGetUniformLocation(OGLRef.programGeometryID, "stateEnableAlphaTest");
OGLRef.uniformStateEnableAntialiasing = glGetUniformLocation(OGLRef.programGeometryID, "stateEnableAntialiasing");
OGLRef.uniformStateEnableEdgeMarking = glGetUniformLocation(OGLRef.programGeometryID, "stateEnableEdgeMarking");
OGLRef.uniformStateEnableFogAlphaOnly = glGetUniformLocation(OGLRef.programGeometryID, "stateEnableFogAlphaOnly");
OGLRef.uniformStateUseWDepth = glGetUniformLocation(OGLRef.programGeometryID, "stateUseWDepth");
OGLRef.uniformStateAlphaTestRef = glGetUniformLocation(OGLRef.programGeometryID, "stateAlphaTestRef");
@ -2089,7 +2093,6 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D_State *renderState)
glUniform1i(OGLRef.uniformStateEnableAlphaTest, (renderState->enableAlphaTest) ? GL_TRUE : GL_FALSE);
glUniform1i(OGLRef.uniformStateEnableAntialiasing, (renderState->enableAntialiasing) ? GL_TRUE : GL_FALSE);
glUniform1i(OGLRef.uniformStateEnableEdgeMarking, (renderState->enableEdgeMarking) ? GL_TRUE : GL_FALSE);
glUniform1i(OGLRef.uniformStateEnableFogAlphaOnly, (renderState->enableFogAlphaOnly) ? GL_TRUE : GL_FALSE);
glUniform1i(OGLRef.uniformStateUseWDepth, (renderState->wbuffer) ? GL_TRUE : GL_FALSE);
glUniform1f(OGLRef.uniformStateAlphaTestRef, divide5bitBy31_LUT[renderState->alphaTestRef]);
glUniform1i(OGLRef.uniformTexRenderObject, 0);
@ -2552,7 +2555,6 @@ Render3DError OpenGLRenderer_1_2::Reset()
glUniform1i(OGLRef.uniformStateEnableAlphaTest, GL_TRUE);
glUniform1i(OGLRef.uniformStateEnableAntialiasing, GL_FALSE);
glUniform1i(OGLRef.uniformStateEnableEdgeMarking, GL_TRUE);
glUniform1i(OGLRef.uniformStateEnableFogAlphaOnly, GL_FALSE);
glUniform1i(OGLRef.uniformStateUseWDepth, GL_FALSE);
glUniform1f(OGLRef.uniformStateAlphaTestRef, 0.0f);
@ -3255,6 +3257,7 @@ Render3DError OpenGLRenderer_2_0::InitPostprocessingPrograms(const std::string &
OGLRef.uniformTexGDepth_Fog = glGetUniformLocation(OGLRef.programFogID, "texInFragDepth");
OGLRef.uniformTexGFog_Fog = glGetUniformLocation(OGLRef.programFogID, "texInFogAttributes");
OGLRef.uniformStateEnableFogAlphaOnly = glGetUniformLocation(OGLRef.programFogID, "stateEnableFogAlphaOnly");
OGLRef.uniformStateFogColor = glGetUniformLocation(OGLRef.programFogID, "stateFogColor");
OGLRef.uniformStateFogDensity = glGetUniformLocation(OGLRef.programFogID, "stateFogDensity");
OGLRef.uniformStateFogOffset = glGetUniformLocation(OGLRef.programFogID, "stateFogOffset");
@ -3398,7 +3401,6 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D_State *renderState)
glUniform1i(OGLRef.uniformStateEnableAlphaTest, (renderState->enableAlphaTest) ? GL_TRUE : GL_FALSE);
glUniform1i(OGLRef.uniformStateEnableAntialiasing, (renderState->enableAntialiasing) ? GL_TRUE : GL_FALSE);
glUniform1i(OGLRef.uniformStateEnableEdgeMarking, (renderState->enableEdgeMarking) ? GL_TRUE : GL_FALSE);
glUniform1i(OGLRef.uniformStateEnableFogAlphaOnly, (renderState->enableFogAlphaOnly) ? GL_TRUE : GL_FALSE);
glUniform1i(OGLRef.uniformStateUseWDepth, (renderState->wbuffer) ? GL_TRUE : GL_FALSE);
glUniform1f(OGLRef.uniformStateAlphaTestRef, divide5bitBy31_LUT[renderState->alphaTestRef]);
glUniform1i(OGLRef.uniformTexRenderObject, 0);
@ -3515,7 +3517,7 @@ Render3DError OpenGLRenderer_2_0::RenderEdgeMarking(const u16 *colorTable)
return RENDER3DERROR_NOERR;
}
Render3DError OpenGLRenderer_2_0::RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift)
Render3DError OpenGLRenderer_2_0::RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift, const bool alphaOnly)
{
OGLRenderRef &OGLRef = *this->ref;
static GLfloat oglDensityTable[32];
@ -3545,6 +3547,7 @@ Render3DError OpenGLRenderer_2_0::RenderFog(const u8 *densityTable, const u32 co
glUniform1i(OGLRef.uniformTexGColor_Fog, OGLTextureUnitID_GColor);
glUniform1i(OGLRef.uniformTexGDepth_Fog, OGLTextureUnitID_GDepth);
glUniform1i(OGLRef.uniformTexGFog_Fog, OGLTextureUnitID_FogAttr);
glUniform1i(OGLRef.uniformStateEnableFogAlphaOnly, (alphaOnly) ? GL_TRUE : GL_FALSE);
glUniform4f(OGLRef.uniformStateFogColor, oglColor[0], oglColor[1], oglColor[2], oglColor[3]);
glUniform1f(OGLRef.uniformStateFogOffset, oglOffset);
glUniform1f(OGLRef.uniformStateFogStep, oglFogStep);

View File

@ -282,7 +282,8 @@ enum OGLTextureUnitID
OGLTextureUnitID_GColor,
OGLTextureUnitID_GDepth,
OGLTextureUnitID_GPolyID,
OGLTextureUnitID_FogAttr
OGLTextureUnitID_FogAttr,
OGLTextureUnitID_TranslucentFogAttr
};
enum OGLErrorCode
@ -634,7 +635,7 @@ protected:
virtual Render3DError BeginRender(const GFX3D_State *renderState);
virtual Render3DError RenderEdgeMarking(const u16 *colorTable);
virtual Render3DError RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift);
virtual Render3DError RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift, const bool alphaOnly);
virtual Render3DError SetupPolygon(const POLY *thePoly);
virtual Render3DError SetupTexture(const POLY *thePoly, bool enableTexturing);

View File

@ -115,7 +115,6 @@ static const char *GeometryFragShader_150 = {"\
uniform bool stateEnableAlphaTest; \n\
uniform bool stateEnableAntialiasing;\n\
uniform bool stateEnableEdgeMarking;\n\
uniform bool stateEnableFogAlphaOnly;\n\
uniform bool stateUseWDepth; \n\
uniform float stateAlphaTestRef; \n\
\n\
@ -171,9 +170,9 @@ static const char *GeometryFragShader_150 = {"\
float newFragDepth = (stateUseWDepth) ? vtxPosition.w/4096.0 : clamp((vtxPosition.z/vertW) * 0.5 + 0.5, 0.0, 1.0); \n\
\n\
outFragColor = newFragColor;\n\
outFogAttributes = vec4( float(polyEnableFog), float(stateEnableFogAlphaOnly), 0.0, 1.0);\n\
if (newFragColor.a > 0.999) outPolyID = vec4(float(polyID)/63.0, float(stateEnableAntialiasing), 0.0, 1.0);\n\
if (polyEnableDepthWrite && (newFragColor.a > 0.999 || polySetNewDepthForTranslucent)) outFragDepth = vec4( packVec3FromFloat(newFragDepth), 1.0);\n\
outFragDepth = vec4( packVec3FromFloat(newFragDepth), float(polyEnableDepthWrite && (newFragColor.a > 0.999 || polySetNewDepthForTranslucent)));\n\
outPolyID = vec4(float(polyID)/63.0, float(stateEnableAntialiasing), 0.0, float(newFragColor.a > 0.999));\n\
outFogAttributes = vec4( float(polyEnableFog), 0.0, 0.0, float(newFragColor.a > 0.999 || !polyEnableFog));\n\
gl_FragDepth = newFragDepth;\n\
} \n\
"};
@ -268,7 +267,7 @@ static const char *EdgeMarkFragShader_150 = {"\
}\n\
}\n\
\n\
outFragColor = (doEdgeMark) ? ((doAntialias) ? mix(edgeColor, inFragColor, 0.4) : edgeColor) : inFragColor;\n\
outFragColor = mix(inFragColor, edgeColor, (doEdgeMark) ? ((doAntialias) ? (16.0/31.0) : 1.0) : 0.0);\n\
}\n\
"};
@ -296,6 +295,7 @@ static const char *FogFragShader_150 = {"\
uniform sampler2D texInFragColor;\n\
uniform sampler2D texInFragDepth;\n\
uniform sampler2D texInFogAttributes;\n\
uniform bool stateEnableFogAlphaOnly;\n\
uniform vec4 stateFogColor;\n\
uniform float stateFogDensity[32];\n\
uniform float stateFogOffset;\n\
@ -312,13 +312,15 @@ static const char *FogFragShader_150 = {"\
void main()\n\
{\n\
vec4 inFragColor = texture(texInFragColor, texCoord);\n\
float inFragDepth = unpackFloatFromVec3(texture(texInFragDepth, texCoord).rgb);\n\
vec4 inFogAttributes = texture(texInFogAttributes, texCoord);\n\
\n\
bool polyEnableFog = bool(inFogAttributes.r);\n\
bool stateEnableFogAlphaOnly = bool(inFogAttributes.g) ;\n\
vec4 newFoggedColor = inFragColor;\n\
\n\
if (polyEnableFog)\n\
{\n\
float inFragDepth = unpackFloatFromVec3(texture(texInFragDepth, texCoord).rgb);\n\
float fogMixWeight = 0.0;\n\
\n\
if (inFragDepth <= min(stateFogOffset + stateFogStep, 1.0))\n\
{\n\
fogMixWeight = stateFogDensity[0];\n\
@ -341,8 +343,10 @@ static const char *FogFragShader_150 = {"\
}\n\
}\n\
\n\
vec4 newFoggedColor = mix(inFragColor, stateFogColor, fogMixWeight);\n\
outFragColor = (polyEnableFog) ? ((stateEnableFogAlphaOnly) ? vec4(inFragColor.rgb, newFoggedColor.a) : newFoggedColor) : inFragColor;\n\
newFoggedColor = mix(inFragColor, (stateEnableFogAlphaOnly) ? vec4(inFragColor.rgb, stateFogColor.a) : stateFogColor, fogMixWeight);\n\
}\n\
\n\
outFragColor = newFoggedColor;\n\
}\n\
"};
@ -950,7 +954,7 @@ Render3DError OpenGLRenderer_3_2::RenderEdgeMarking(const u16 *colorTable)
return RENDER3DERROR_NOERR;
}
Render3DError OpenGLRenderer_3_2::RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift)
Render3DError OpenGLRenderer_3_2::RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift, const bool alphaOnly)
{
OGLRenderRef &OGLRef = *this->ref;
static GLfloat oglDensityTable[32];
@ -975,6 +979,7 @@ Render3DError OpenGLRenderer_3_2::RenderFog(const u8 *densityTable, const u32 co
glUniform1i(OGLRef.uniformTexGColor_Fog, OGLTextureUnitID_GColor);
glUniform1i(OGLRef.uniformTexGDepth_Fog, OGLTextureUnitID_GDepth);
glUniform1i(OGLRef.uniformTexGFog_Fog, OGLTextureUnitID_FogAttr);
glUniform1i(OGLRef.uniformStateEnableFogAlphaOnly, (alphaOnly) ? GL_TRUE : GL_FALSE);
glUniform4f(OGLRef.uniformStateFogColor, oglColor[0], oglColor[1], oglColor[2], oglColor[3]);
glUniform1f(OGLRef.uniformStateFogOffset, oglOffset);
glUniform1f(OGLRef.uniformStateFogStep, oglFogStep);

View File

@ -79,7 +79,7 @@ protected:
virtual Render3DError SelectRenderingFramebuffer();
virtual Render3DError DownsampleFBO();
virtual Render3DError RenderEdgeMarking(const u16 *colorTable);
virtual Render3DError RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift);
virtual Render3DError RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift, const bool alphaOnly);
virtual Render3DError ClearUsingImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthStencilBuffer, const bool *__restrict fogBuffer);

View File

@ -131,7 +131,7 @@ Render3DError Render3D::RenderEdgeMarking(const u16 *colorTable)
return RENDER3DERROR_NOERR;
}
Render3DError Render3D::RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift)
Render3DError Render3D::RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift, const bool alphaOnly)
{
return RENDER3DERROR_NOERR;
}
@ -264,7 +264,7 @@ Render3DError Render3D::Render(const GFX3D_State *renderState, const VERTLIST *v
if (renderState->enableFog)
{
this->RenderFog(MMU.MMU_MEM[ARMCPU_ARM9][0x40]+0x0360, renderState->fogColor, renderState->fogOffset, renderState->fogShift);
this->RenderFog(MMU.MMU_MEM[ARMCPU_ARM9][0x40]+0x0360, renderState->fogColor, renderState->fogOffset, renderState->fogShift, renderState->enableFogAlphaOnly);
}
this->EndRender(frameCount);

View File

@ -91,7 +91,7 @@ protected:
virtual Render3DError BeginRender(const GFX3D_State *renderState);
virtual Render3DError RenderGeometry(const GFX3D_State *renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList);
virtual Render3DError RenderEdgeMarking(const u16 *colorTable);
virtual Render3DError RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift);
virtual Render3DError RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift, const bool alphaOnly);
virtual Render3DError EndRender(const u64 frameCount);
virtual Render3DError UpdateToonTable(const u16 *toonTableBuffer);