diff --git a/GLSLCombiner.cpp b/GLSLCombiner.cpp index 1b069cb7..ef1fe4b3 100644 --- a/GLSLCombiner.cpp +++ b/GLSLCombiner.cpp @@ -421,7 +421,9 @@ ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCo strFragmentShader.append(fragment_shader_color_dither); strFragmentShader.append(fragment_shader_alpha_dither); - strFragmentShader.append(" gl_FragColor = vec4(color2, alpha2); \n"); + strFragmentShader.append(" if (uFogUsage == 3) gl_FragColor = uFogColor; \n"); + strFragmentShader.append(" else if (uFogUsage == 2) gl_FragColor = vec4(color2, uFogColor.a); \n"); + strFragmentShader.append(" else gl_FragColor = vec4(color2, alpha2); \n"); strFragmentShader.append(" if (!alpha_test(gl_FragColor.a)) discard; \n"); if (video().getRender().isImageTexturesSupported()) { @@ -434,7 +436,7 @@ ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCo #ifdef USE_TOONIFY strFragmentShader.append(" toonify(intensity); \n"); #endif - strFragmentShader.append(" if (uEnableFog != 0) \n"); + strFragmentShader.append(" if (uFogUsage == 1) \n"); strFragmentShader.append(" gl_FragColor = vec4(mix(gl_FragColor.rgb, uFogColor.rgb, vFogFragCoord), gl_FragColor.a); \n"); strFragmentShader.append(fragment_shader_end); @@ -493,7 +495,8 @@ void ShaderCombiner::_locateUniforms() { LocateUniform(uTlutImage); LocateUniform(uZlutImage); LocateUniform(uDepthImage); - LocateUniform(uEnableFog); + LocateUniform(uFogMode); + LocateUniform(uFogUsage); LocateUniform(uAlphaCompareMode); LocateUniform(uAlphaDitherMode); LocateUniform(uColorDitherMode); @@ -596,13 +599,44 @@ void ShaderCombiner::updateLight(bool _bForce) { } } -void ShaderCombiner::updateColors(bool _bForce) { +void ShaderCombiner::updateColors(bool _bForce) +{ _setV4Uniform(m_uniforms.uEnvColor, &gDP.envColor.r, _bForce); _setV4Uniform(m_uniforms.uPrimColor, &gDP.primColor.r, _bForce); _setV4Uniform(m_uniforms.uCenterColor, &gDP.key.center.r, _bForce); _setV4Uniform(m_uniforms.uScaleColor, &gDP.key.scale.r, _bForce); - _setIUniform(m_uniforms.uEnableFog, (config.enableFog != 0 && (gSP.geometryMode & G_FOG) != 0) ? 1 : 0, _bForce); - if (m_uniforms.uEnableFog.val != 0) { + const u32 blender = (gDP.otherMode.l >> 16); + int nFogUsage; + switch (blender) { + case 0x0150: + case 0x0D18: + case 0xC912: + nFogUsage = 2; + break; + case 0xF550: + nFogUsage = 3; + break; + default: + nFogUsage = (config.enableFog != 0 && (gSP.geometryMode & G_FOG) != 0) ? 1 : 0; + } + int nFogMode = 0; // Normal + if (nFogUsage == 0) { + switch (blender) { + case 0xC410: + case 0xC411: + case 0xF500: + nFogMode = 1; // fog blend + nFogUsage = 1; + break; + case 0x04D1: + nFogMode = 2; // inverse fog blend + nFogUsage = 1; + break; + } + } + _setIUniform(m_uniforms.uFogUsage, nFogUsage, _bForce); + _setIUniform(m_uniforms.uFogMode, nFogMode, _bForce); + if (nFogUsage + nFogMode != 0) { _setFUniform(m_uniforms.uFogMultiplier, (float)gSP.fog.multiplier / 256.0f, _bForce); _setFUniform(m_uniforms.uFogOffset, (float)gSP.fog.offset / 256.0f, _bForce); _setV4Uniform(m_uniforms.uFogColor, &gDP.fogColor.r, _bForce); diff --git a/GLSLCombiner.h b/GLSLCombiner.h index d24c5dd6..45e66f6a 100644 --- a/GLSLCombiner.h +++ b/GLSLCombiner.h @@ -35,7 +35,7 @@ private: struct UniformLocation { iUniform uTex0, uTex1, uTlutImage, uZlutImage, uDepthImage, - uEnableFog, uEnableLod, uEnableAlphaTest, + uFogMode, uFogUsage, uEnableLod, uEnableAlphaTest, uEnableDepth, uEnableDepthCompare, uEnableDepthUpdate, uDepthMode, uFb8Bit, uFbFixedAlpha, uRenderState, uMaxTile, uTextureDetail, uTexturePersp, diff --git a/OpenGL.cpp b/OpenGL.cpp index 041222b9..cc846e54 100644 --- a/OpenGL.cpp +++ b/OpenGL.cpp @@ -452,6 +452,16 @@ void OGLRender::_setBlendMode() const glBlendFunc( GL_ZERO, GL_ONE ); break; + case 0xF550: //clr_fog * a_fog + clr_mem * (1-a) + case 0x0150: // spiderman + case 0x0D18: //clr_in * a_fog + clr_mem * (1-a) + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + break; + + case 0xC912: //40 winks, clr_in * a_fog + clr_mem * 1 + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + break; + default: LOG(LOG_VERBOSE, "Unhandled blend mode=%x", gDP.otherMode.l >> 16); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); diff --git a/Shaders.h b/Shaders.h index 5d74e584..caec0c2b 100644 --- a/Shaders.h +++ b/Shaders.h @@ -9,8 +9,10 @@ static const char* vertex_shader = " \n" "uniform int uRenderState; \n" "uniform int uTexturePersp; \n" +"uniform int uFogMode; \n" +"uniform vec4 uFogColor; \n" "uniform lowp float uNoiseTime; \n" -"uniform mediump float uFogMultiplier, uFogOffset; \n" +"uniform mediump float uFogMultiplier, uFogOffset; \n" "uniform mediump float uScreenWidth, uScreenHeight; \n" " \n" "uniform mediump vec2 uTexScale; \n" @@ -26,7 +28,7 @@ static const char* vertex_shader = "varying mediump vec2 vTexCoord1; \n" "varying mediump vec2 vLodTexCoord; \n" "varying mediump vec2 vNoiseCoord2D; \n" -"varying lowp float vNumLights; \n" +"varying lowp float vNumLights; \n" "varying mediump float vFogFragCoord; \n" #else "attribute vec4 aPosition; \n" @@ -39,6 +41,9 @@ static const char* vertex_shader = "uniform int uRenderState; \n" "uniform int uTexturePersp; \n" "uniform float uNoiseTime; \n" +" \n" +"uniform int uFogMode; \n" +"uniform vec4 uFogColor; \n" "uniform float uFogMultiplier, uFogOffset; \n" "uniform float uScreenWidth, uScreenHeight; \n" " \n" @@ -94,12 +99,22 @@ static const char* vertex_shader = " vNumLights = 0.0; \n" " } \n" " vNoiseCoord2D = vec2(gl_Position.x*uScreenWidth, gl_Position.y*uScreenHeight + uNoiseTime);\n" -" if (aPosition.z < -aPosition.w) \n" -" vFogFragCoord = -uFogMultiplier + uFogOffset; \n" -" else \n" -" vFogFragCoord = aPosition.z/aPosition.w * uFogMultiplier \n" +" switch (uFogMode) { \n" +" case 0: \n" +" if (aPosition.z < -aPosition.w) \n" +" vFogFragCoord = -uFogMultiplier + uFogOffset; \n" +" else \n" +" vFogFragCoord = aPosition.z/aPosition.w*uFogMultiplier \n" " + uFogOffset; \n" -" vFogFragCoord = clamp(vFogFragCoord, 0.0, 1.0); \n" +" break; \n" +" case 1: \n" +" vFogFragCoord = uFogColor.a; \n" +" break; \n" +" case 2: \n" +" vFogFragCoord = 1.0 - uFogColor.a; \n" +" break; \n" +" } \n" +" vFogFragCoord = clamp(vFogFragCoord, 0.0, 1.0); \n" "} \n" ; @@ -118,7 +133,7 @@ static const char* fragment_shader_header_common_variables = "uniform lowp int uAlphaCompareMode; \n" "uniform lowp int uAlphaDitherMode; \n" "uniform lowp int uColorDitherMode; \n" -"uniform lowp int uEnableFog; \n" +"uniform lowp int uFogUsage; \n" "uniform lowp int uFb8Bit; \n" "uniform lowp int uFbFixedAlpha;\n" "varying lowp vec4 vShadeColor; \n" @@ -143,7 +158,7 @@ static const char* fragment_shader_header_common_variables = "uniform int uAlphaCompareMode; \n" "uniform int uAlphaDitherMode; \n" "uniform int uColorDitherMode; \n" -"uniform int uEnableFog; \n" +"uniform int uFogUsage; \n" "uniform int uFb8Bit; \n" "uniform int uFbFixedAlpha; \n" "varying vec4 vShadeColor; \n"