From e92e919926e86d3c656a0bc74419be58b069c62f Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Fri, 23 Nov 2012 01:26:12 +0100 Subject: [PATCH] Fix problems with additive blending, fix color doubling. Greatly improves MotoGP among others. --- GPU/GLES/DisplayListInterpreter.cpp | 9 +++--- GPU/GLES/FragmentShaderGenerator.cpp | 42 +++++++++++++++------------- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/GPU/GLES/DisplayListInterpreter.cpp b/GPU/GLES/DisplayListInterpreter.cpp index bc697405a..4d3567048 100644 --- a/GPU/GLES/DisplayListInterpreter.cpp +++ b/GPU/GLES/DisplayListInterpreter.cpp @@ -131,7 +131,7 @@ void GLES_GPU::CopyDisplayToOutput() DEBUG_LOG(HLE, "Found no FBO! displayFBPtr = %08x", displayFramebufPtr_); // No framebuffer to display! Clear to black. glClearColor(0,0,0,1); - glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); return; } @@ -367,7 +367,7 @@ void SetBlendModePSP(u32 data) GL_ONE_MINUS_SRC_ALPHA, // should be 2x GL_DST_ALPHA, // should be 2x GL_ONE_MINUS_DST_ALPHA, // should be 2x - and COLOR? - GL_SRC_ALPHA, // should be FIXA + GL_ONE, // should be FIXA }; const GLint bLookup[] = { GL_SRC_COLOR, @@ -380,7 +380,7 @@ void SetBlendModePSP(u32 data) GL_ONE_MINUS_SRC_ALPHA, // should be 2x GL_DST_ALPHA, // should be 2x GL_ONE_MINUS_DST_ALPHA, // should be 2x - GL_SRC_ALPHA, // should be FIXB + GL_ONE, // should be FIXB }; const GLint eqLookup[] = { GL_FUNC_ADD, @@ -389,11 +389,12 @@ void SetBlendModePSP(u32 data) #if defined(ANDROID) || defined(BLACKBERRY) GL_FUNC_ADD, GL_FUNC_ADD, + GL_FUNC_ADD, // should be abs(diff) #else GL_MIN, GL_MAX, + GL_MAX, // should be abs(diff) #endif - GL_FUNC_ADD, // should be abs(diff) }; int a = data & 0xF; int b = (data >> 4) & 0xF; diff --git a/GPU/GLES/FragmentShaderGenerator.cpp b/GPU/GLES/FragmentShaderGenerator.cpp index 8b1e0b257..f5a3dee05 100644 --- a/GPU/GLES/FragmentShaderGenerator.cpp +++ b/GPU/GLES/FragmentShaderGenerator.cpp @@ -86,19 +86,21 @@ char *GenerateFragmentShader() WRITE(p, "varying vec2 v_texcoord;\n"); WRITE(p, "void main() {"); + WRITE(p, " vec4 v;\n"); if (gstate.clearmode & 1) { - WRITE(p, "gl_FragColor = v_color0;\n"); + WRITE(p, "v = v_color0;\n"); } else { const char *secondary = ""; + // Secondary color for specular on top of texture if (lmode) { - WRITE(p, "vec4 s = v_color1;"); + WRITE(p, " vec4 s = vec4(v_color1.xyz, 0.0);"); secondary = " + s"; } else { - WRITE(p, " vec4 s = vec4(0.0, 0.0, 0.0, 0.0);\n"); // Secondary color, TODO + WRITE(p, " vec4 s = vec4(0.0, 0.0, 0.0, 0.0);\n"); secondary = ""; } @@ -112,39 +114,41 @@ char *GenerateFragmentShader() WRITE(p, " vec4 p = clamp(v_color0, 0.0, 1.0);\n"); // , secondary); } - // Color doubling - if (gstate.texfunc & 0x10000) { - WRITE(p, " t.rgb *= 2.0;\n"); - WRITE(p, " p.rgb *= 2.0;\n"); - } - if (gstate.texfunc & 0x100) { // texfmt == RGBA switch (gstate.texfunc & 0x7) { case GE_TEXFUNC_MODULATE: - WRITE(p, " gl_FragColor = t * p%s;\n", secondary); break; + WRITE(p, " v = t * p%s;\n", secondary); break; case GE_TEXFUNC_DECAL: - WRITE(p, " gl_FragColor = vec4(1.0 - t.a * p.rgb + t.a * u_texenv.rgb, p.a)%s;\n", secondary); break; + WRITE(p, " v = vec4(1.0 - t.a * p.rgb + t.a * u_texenv.rgb, p.a)%s;\n", secondary); break; case GE_TEXFUNC_BLEND: - WRITE(p, " gl_FragColor = vec4((1.0 - t.rgb) * p.rgb + t.rgb * u_texenv.rgb, p.a * t.a)%s;\n", secondary); break; + WRITE(p, " v = vec4((1.0 - t.rgb) * p.rgb + t.rgb * u_texenv.rgb, p.a * t.a)%s;\n", secondary); break; case GE_TEXFUNC_REPLACE: - WRITE(p, " gl_FragColor = t%s;\n", secondary); break; + WRITE(p, " v = t%s;\n", secondary); break; case GE_TEXFUNC_ADD: - WRITE(p, " gl_FragColor = vec4(t.rgb + p.rgb, p.a * t.a)%s;\n", secondary); break; + WRITE(p, " v = vec4(t.rgb + p.rgb, p.a * t.a)%s;\n", secondary); break; } } else { // texfmt == RGB switch (gstate.texfunc & 0x7) { case GE_TEXFUNC_MODULATE: - WRITE(p, " gl_FragColor = vec4(t.rgb * p.rgb, p.a)%s;\n", secondary); break; + WRITE(p, " v = vec4(t.rgb * p.rgb, p.a)%s;\n", secondary); break; case GE_TEXFUNC_DECAL: - WRITE(p, " gl_FragColor = vec4(t.rgb, p.a)%s;\n", secondary); break; + WRITE(p, " v = vec4(t.rgb, p.a)%s;\n", secondary); break; case GE_TEXFUNC_BLEND: - WRITE(p, " gl_FragColor = vec4(1.0 - t.rgb) * p.rgb + t.rgb * u_texenv.rgb, p.a)%s;\n", secondary); break; + WRITE(p, " v = vec4(1.0 - t.rgb) * p.rgb + t.rgb * u_texenv.rgb, p.a)%s;\n", secondary); break; case GE_TEXFUNC_REPLACE: - WRITE(p, " gl_FragColor = vec4(t.rgb, p.a)%s;\n", secondary); break; + WRITE(p, " v = vec4(t.rgb, p.a)%s;\n", secondary); break; case GE_TEXFUNC_ADD: - WRITE(p, " gl_FragColor = vec4(t.rgb + p.rgb, p.a)%s;\n", secondary); break; + WRITE(p, " v = vec4(t.rgb + p.rgb, p.a)%s;\n", secondary); break; } } + + // Color doubling + if (gstate.texfunc & 0x10000) { + WRITE(p, " gl_FragColor = v * vec4(2.0, 2.0, 2.0, 1.0);"); + } else { + WRITE(p, " gl_FragColor = v;\n"); + } + /* if (gstate.alphaTestEnable & 1) { int alphaTestFunc = gstate.alphatest & 7;