GLES2RICE: Update from upstream
[mupen64plus-pandora.git] / source / gles2rice / src / OGLES2FragmentShaders.cpp
old mode 100644 (file)
new mode 100755 (executable)
index 4c5f06e..d43fcae
@@ -24,7 +24,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #define ALPHA_TEST "    if(gl_FragColor.a < AlphaRef) discard;                        \n"
 //#define ALPHA_TEST
-
+#define ENABLE  true
+#define DISABLE  false
 
 GLuint vertexProgram = 9999;
 const char *vertexShader =
@@ -34,8 +35,7 @@ const char *vertexShader =
 "attribute lowp vec2    aTexCoord0;                         \n"\
 "attribute lowp vec2    aTexCoord1;                         \n"\
 "attribute lowp vec2    aAtlasTransform;                    \n"\
-"                                                           \n"\
-"uniform lowp vec2 FogMinMax;                               \n"\
+"attribute mediump float aFogCoord;                         \n"\
 "                                                           \n"\
 "varying lowp float vFactor;                                \n"\
 "varying lowp vec4  vShadeColor;                            \n"\
@@ -49,7 +49,7 @@ const char *vertexShader =
 "vShadeColor = aColor;                                      \n"\
 "vTexCoord0 = aTexCoord0;                                   \n"\
 "vTexCoord1 = aTexCoord1;                                   \n"\
-"vFog = clamp((FogMinMax[1] - (gl_Position.z/aPosition.w))/(FogMinMax[1]-FogMinMax[0]),0.0,1.0);                                   \n"\
+"vFog = clamp((FogMinMax[1] - aFogCoord)/(FogMinMax[1]-FogMinMax[0]),0.0,1.0);                       \n"\
 "                                                           \n"\
 "}                                                          \n"\
 "                                                           \n";
@@ -71,18 +71,17 @@ const char *fragmentHeader =
 "uniform vec4 PrimFrac;                                     \n"\
 "uniform float AlphaRef;                                    \n"\
 "uniform vec4 FogColor;                                     \n"\
+"uniform vec2  FogMinMax;                                   \n"\
 "                                                           \n"\
-"varying lowp float vFactor;                                \n"\
 "varying lowp vec4  vShadeColor;                            \n"\
 "varying mediump vec2  vTexCoord0;                          \n"\
 "varying lowp vec2  vTexCoord1;                             \n"\
-"varying lowp float vFog;                                   \n"\
 "                                                           \n"\
 "void main()                                                \n"\
 "{                                                          \n"\
 "vec4 comb,comb2;                                           \n"\
 "                                                           \n"\
-"#ifdef NEED_TEX0                                              \n"\
+"#ifdef NEED_TEX0                                           \n"\
 "vec4 t0 = texture2D(uTex0,vTexCoord0);                     \n"\
 "#endif                                                     \n"\
 "                                                           \n"\
@@ -93,19 +92,15 @@ const char *fragmentHeader =
 const char *fragmentFooter =
 "                                                           \n"\
 "#ifdef FOG                                                 \n"\
-"gl_FragColor.rgb = mix(FogColor.rgb,comb.rgb,vFog * step(0.5,1.0-FogColor.a));        \n"\
+"gl_FragColor.rgb = mix(FogColor.rgb,comb.rgb,vFog);        \n"\
 "gl_FragColor.a = comb.a;                                   \n"\
 "#else                                                      \n"\
 "gl_FragColor = comb;                                       \n"\
 "#endif                                                     \n"\
 "                                                           \n"\
 "#ifdef ALPHA_TEST                                          \n"\
-ALPHA_TEST
+   ALPHA_TEST                                                                  
 "#endif                                                     \n"\
-"                                                           \n"\
-"                                                           \n"\
-"                                                           \n"\
-"                                                           \n"\
 "}                                                          \n";
 
 //Fragment shader for InitCycleCopy
@@ -196,6 +191,10 @@ COGL_FragmentProgramCombiner::COGL_FragmentProgramCombiner(CRender *pRender)
     m_pDecodedMux = new DecodedMuxForPixelShader;
     m_bFragmentProgramIsSupported = true;
     m_AlphaRef = 0.0f;
+    bAlphaTestState = false;
+    bAlphaTestPreviousState = false;
+    bFogState = false;
+    bFogPreviousState = false;
 
     //Create shaders for fill and copy
     GLint success;
@@ -326,6 +325,8 @@ void COGL_FragmentProgramCombiner::InitCombinerCycleCopy(void)
     OPENGL_CHECK_ERRORS;
     glDisableVertexAttribArray(VS_TEXCOORD1);
     OPENGL_CHECK_ERRORS;
+       glDisableVertexAttribArray(VS_FOG);
+       OPENGL_CHECK_ERRORS;
     COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
     if( pTexture )
     {
@@ -489,8 +490,6 @@ void COGL_FragmentProgramCombiner::GenerateProgramStr()
         strcat(oglNewFP, "#define NEED_TEX0\n");
     if (bNeedT1)
         strcat(oglNewFP, "#define NEED_TEX1\n");
-    if(gRDP.bFogEnableInBlender && gRSP.bFogEnabled && options.fogMethod > 0)
-        strcat(oglNewFP,"#define FOG");
     strcat(oglNewFP, fragmentHeader);
     strcat(oglNewFP, newFPBody);
     strcat(oglNewFP, fragmentFooter);
@@ -519,103 +518,111 @@ int COGL_FragmentProgramCombiner::ParseDecodedMux()
     }
 
 
-    //Create 2 shaders, with and without alphatest
+    //Create 4 shaders, with and without alphatest + with and without fog
     GenerateProgramStr();
 
     for(int alphaTest = 0;alphaTest < 2;alphaTest++)
     {
-        res.fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
-
-        char* tmpShader = (char*)malloc(sizeof(char) * 4096);
-        strcpy(tmpShader,"#version " GLSL_VERSION "\n");
-
-        if(alphaTest == 1)
-        {
-            strcat(tmpShader,"#define ALPHA_TEST\n");
-        }
-
-        res.alphaTest = alphaTest == 1;
-        strcat(tmpShader,oglNewFP);
-
-        glShaderSource(res.fragmentShaderID, 1,(const char**) &tmpShader,NULL);
-        free(tmpShader);
-
-
-        OPENGL_CHECK_ERRORS;
-        glCompileShader(res.fragmentShaderID);
-
-        glGetShaderiv(res.fragmentShaderID, GL_COMPILE_STATUS, &success);
-        if (!success)
-        {
-            char Log[1024];
-            GLint nLength;
-            glGetShaderInfoLog(res.fragmentShaderID, 1024, &nLength, Log);
-            printf("Error compiling shader!\n %s",oglNewFP);
-            printf("%s", Log);
-        }
-
-        res.programID = glCreateProgram();
-        glAttachShader(res.programID,res.vertexShaderID);
-        glAttachShader(res.programID,res.fragmentShaderID);
-
-        //Bind Attributes
-        glBindAttribLocation(res.programID,VS_COLOR,"aColor");
-        OPENGL_CHECK_ERRORS;
-        glBindAttribLocation(res.programID,VS_TEXCOORD0,"aTexCoord0");
-        OPENGL_CHECK_ERRORS;
-        glBindAttribLocation(res.programID,VS_TEXCOORD1,"aTexCoord1");
-        OPENGL_CHECK_ERRORS;
-        glBindAttribLocation(res.programID,VS_POSITION,"aPosition");
-        OPENGL_CHECK_ERRORS;
-
-        glLinkProgram(res.programID);
-        OPENGL_CHECK_ERRORS;
-
-        glGetProgramiv(res.programID, GL_LINK_STATUS, &success);
-        if (!success)
-        {
-            char Log[1024];
-            GLint nLength;
-            glGetShaderInfoLog(res.fragmentShaderID, 1024, &nLength, Log);
-            printf("Error linking program!\n");
-            printf("%s\n",Log);
-        }
-
-        glUseProgram(res.programID);
-        OPENGL_CHECK_ERRORS;
-
-        //Bind texture samplers
-        GLint tex0 = glGetUniformLocation(res.programID,"uTex0");
-        GLint tex1 = glGetUniformLocation(res.programID,"uTex1");
-
-        if(tex0 != -1)
-            glUniform1i(tex0,0);
-        if(tex1 != -1)
-            glUniform1i(tex1,1);
-
-        //Bind Uniforms
-        res.PrimColorLocation = glGetUniformLocation(res.programID,"PrimColor");
-        OPENGL_CHECK_ERRORS;
-        res.EnvColorLocation = glGetUniformLocation(res.programID,"EnvColor");
-        OPENGL_CHECK_ERRORS;
-        res.PrimFracLocation = glGetUniformLocation(res.programID,"PrimFrac");
-        OPENGL_CHECK_ERRORS;
-        res.EnvFracLocation = glGetUniformLocation(res.programID,"EnvFrac");
-        OPENGL_CHECK_ERRORS;
-        res.AlphaRefLocation = glGetUniformLocation(res.programID,"AlphaRef");
-        OPENGL_CHECK_ERRORS;
-        res.FogColorLocation = glGetUniformLocation(res.programID,"FogColor");
-        OPENGL_CHECK_ERRORS;
-        res.FogMinMaxLocation = glGetUniformLocation(res.programID,"FogMinMax");
-        OPENGL_CHECK_ERRORS;
-
-        res.dwMux0 = m_pDecodedMux->m_dwMux0;
-        res.dwMux1 = m_pDecodedMux->m_dwMux1;
-        res.fogIsUsed = gRDP.bFogEnableInBlender && gRSP.bFogEnabled;
-
-        m_vCompiledShaders.push_back(res);
+               for(int fog = 0;fog < 2;fog++) {
+                       res.fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
+
+                       char* tmpShader = (char*)malloc(sizeof(char) * 4096);
+                       strcpy(tmpShader,"#version " GLSL_VERSION "\n");
+
+                       if(alphaTest == 1)
+                       {
+                               strcat(tmpShader,"#define ALPHA_TEST\n");
+                       }
+                       if(fog == 1)
+                       {
+                               strcat(tmpShader,"#define FOG\n");
+                       }
+
+                       res.fogIsUsed = fog == 1;
+                       res.alphaTest = alphaTest == 1;
+                       strcat(tmpShader,oglNewFP);
+
+                       glShaderSource(res.fragmentShaderID, 1,(const char**) &tmpShader,NULL);
+                       free(tmpShader);
+
+
+                       OPENGL_CHECK_ERRORS;
+                       glCompileShader(res.fragmentShaderID);
+
+                       glGetShaderiv(res.fragmentShaderID, GL_COMPILE_STATUS, &success);
+                       if (!success)
+                       {
+                               char Log[1024];
+                               GLint nLength;
+                               glGetShaderInfoLog(res.fragmentShaderID, 1024, &nLength, Log);
+                               printf("Error compiling shader!\n %s",oglNewFP);
+                               printf("%s", Log);
+                       }
+
+                       res.programID = glCreateProgram();
+                       glAttachShader(res.programID,res.vertexShaderID);
+                       glAttachShader(res.programID,res.fragmentShaderID);
+
+                       //Bind Attributes
+                       glBindAttribLocation(res.programID,VS_COLOR,"aColor");
+                       OPENGL_CHECK_ERRORS;
+                       glBindAttribLocation(res.programID,VS_TEXCOORD0,"aTexCoord0");
+                       OPENGL_CHECK_ERRORS;
+                       glBindAttribLocation(res.programID,VS_TEXCOORD1,"aTexCoord1");
+                       OPENGL_CHECK_ERRORS;
+                       glBindAttribLocation(res.programID,VS_POSITION,"aPosition");
+                       OPENGL_CHECK_ERRORS;
+                       glBindAttribLocation(res.programID,VS_FOG,"aFogCoord");
+                       OPENGL_CHECK_ERRORS;
+
+                       glLinkProgram(res.programID);
+                       OPENGL_CHECK_ERRORS;
+
+                       glGetProgramiv(res.programID, GL_LINK_STATUS, &success);
+                       if (!success)
+                       {
+                               char Log[1024];
+                               GLint nLength;
+                               glGetShaderInfoLog(res.fragmentShaderID, 1024, &nLength, Log);
+                               printf("Error linking program!\n");
+                               printf("%s\n",Log);
+                       }
+
+                       glUseProgram(res.programID);
+                       OPENGL_CHECK_ERRORS;
+
+                       //Bind texture samplers
+                       GLint tex0 = glGetUniformLocation(res.programID,"uTex0");
+                       GLint tex1 = glGetUniformLocation(res.programID,"uTex1");
+
+                       if(tex0 != -1)
+                               glUniform1i(tex0,0);
+                       if(tex1 != -1)
+                               glUniform1i(tex1,1);
+
+                       //Bind Uniforms
+                       res.PrimColorLocation = glGetUniformLocation(res.programID,"PrimColor");
+                       OPENGL_CHECK_ERRORS;
+                       res.EnvColorLocation = glGetUniformLocation(res.programID,"EnvColor");
+                       OPENGL_CHECK_ERRORS;
+                       res.PrimFracLocation = glGetUniformLocation(res.programID,"PrimFrac");
+                       OPENGL_CHECK_ERRORS;
+                       res.EnvFracLocation = glGetUniformLocation(res.programID,"EnvFrac");
+                       OPENGL_CHECK_ERRORS;
+                       res.AlphaRefLocation = glGetUniformLocation(res.programID,"AlphaRef");
+                       OPENGL_CHECK_ERRORS;
+                       res.FogColorLocation = glGetUniformLocation(res.programID,"FogColor");
+                       OPENGL_CHECK_ERRORS;
+                       res.FogMinMaxLocation = glGetUniformLocation(res.programID,"FogMinMax");
+                       OPENGL_CHECK_ERRORS;
+
+                       res.dwMux0 = m_pDecodedMux->m_dwMux0;
+                       res.dwMux1 = m_pDecodedMux->m_dwMux1;
+
+                       m_vCompiledShaders.push_back(res);
+               }
     }
-    m_lastIndex = m_vCompiledShaders.size()-2;
+    m_lastIndex = m_vCompiledShaders.size()-4;
 
     return m_lastIndex;
 }
@@ -644,6 +651,11 @@ void COGL_FragmentProgramCombiner::GenerateCombinerSetting(int index)
     OPENGL_CHECK_ERRORS;
     glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
     OPENGL_CHECK_ERRORS;
+       
+       glEnableVertexAttribArray(VS_FOG);
+       OPENGL_CHECK_ERRORS;
+       glVertexAttribPointer(VS_FOG,1,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][4]));
+       OPENGL_CHECK_ERRORS;
 }
 
 void COGL_FragmentProgramCombiner::GenerateCombinerSettingConstants(int index)
@@ -682,38 +694,23 @@ void COGL_FragmentProgramCombiner::GenerateCombinerSettingConstants(int index)
         OPENGL_CHECK_ERRORS;
     }
 
-    //if(prog.FogColorLocation != -1 && prog.FogMinMaxLocation != -1)
-    //{
-    //    //Pass fog colour and distance, use 0 alpha if fog disabled
-    //    glUniform4f(prog.FogColorLocation, gRDP.fvFogColor[0],gRDP.fvFogColor[1],gRDP.fvFogColor[2],
-    //        gRSP.bFogEnabled ? gRDP.fvFogColor[0] : 0.0f);
-    //    glUniform2f(prog.FogMinMaxLocation,gRSPfFogMin,gRSPfFogMax);
-    //}
-
-    if(prog.AlphaRefLocation != -1)
-        glUniform1f(prog.AlphaRefLocation,m_AlphaRef);
-    OPENGL_CHECK_ERRORS;
-}
-
-void COGL_FragmentProgramCombiner::UpdateFog(bool bEnable)
-{
-    if(m_lastIndex < 0 || m_lastIndex >= m_vCompiledShaders.size())
-        return;
-    OGLShaderCombinerSaveType prog = m_vCompiledShaders[m_lastIndex];
-
-    //if(bEnable)
-    //    DebugMessage(M64MSG_INFO,"Fog Color %x Min %f Max %f",gRDP.fogColor,gRSPfFogMin,gRSPfFogMax);
-
-    if(prog.FogColorLocation != -1 && prog.FogMinMaxLocation != -1)
+       if(prog.FogColorLocation != -1)
     {
-        //Pass fog colour and distance, use 0 alpha if fog disabled
-        glUniform4f(prog.FogColorLocation, gRDP.fvFogColor[0],gRDP.fvFogColor[1],gRDP.fvFogColor[2],
-            bEnable ? gRDP.fvFogColor[0] : 0.0f);
-        //glUniform4f(prog.FogColorLocation, 1.0f,0.3f,0.3f,1.0f);
-        //OPENGL_CHECK_ERRORS;
+        glUniform4f(prog.FogColorLocation, gRDP.fvFogColor[0],gRDP.fvFogColor[1],gRDP.fvFogColor[2], gRDP.fvFogColor[3]);
+        OPENGL_CHECK_ERRORS;
+    }
+       
+       if(prog.FogMinMaxLocation != -1)        
+       {
         glUniform2f(prog.FogMinMaxLocation,gRSPfFogMin,gRSPfFogMax);
         OPENGL_CHECK_ERRORS;
     }
+       
+    if(prog.AlphaRefLocation != -1)
+       {
+        glUniform1f(prog.AlphaRefLocation,m_AlphaRef);
+               OPENGL_CHECK_ERRORS;
+       }
 }
 
 int COGL_FragmentProgramCombiner::FindCompiledMux()
@@ -730,8 +727,8 @@ int COGL_FragmentProgramCombiner::FindCompiledMux()
     {
         if( m_vCompiledShaders[i].dwMux0 == m_pDecodedMux->m_dwMux0 
             && m_vCompiledShaders[i].dwMux1 == m_pDecodedMux->m_dwMux1 
-            && m_vCompiledShaders[i].fogIsUsed == (gRDP.bFogEnableInBlender && gRSP.bFogEnabled)
-            && m_vCompiledShaders[i].alphaTest == m_AlphaRef > 0.0f)
+            && m_vCompiledShaders[i].fogIsUsed == bFogState
+            && m_vCompiledShaders[i].alphaTest == bAlphaTestState)
         {
             return (int)i;
         }
@@ -763,7 +760,8 @@ void COGL_FragmentProgramCombiner::InitCombinerCycle12(void)
 
     bool combinerIsChanged = false;
 
-    if( m_pDecodedMux->m_dwMux0 != m_dwLastMux0 || m_pDecodedMux->m_dwMux1 != m_dwLastMux1 || m_lastIndex < 0 )
+    if( m_pDecodedMux->m_dwMux0 != m_dwLastMux0 || m_pDecodedMux->m_dwMux1 != m_dwLastMux1 
+         || bAlphaTestState != bAlphaTestPreviousState || bFogState != bFogPreviousState || m_lastIndex < 0 )
     {
         combinerIsChanged = true;
         m_lastIndex = FindCompiledMux();
@@ -774,7 +772,10 @@ void COGL_FragmentProgramCombiner::InitCombinerCycle12(void)
 
         m_dwLastMux0 = m_pDecodedMux->m_dwMux0;
         m_dwLastMux1 = m_pDecodedMux->m_dwMux1;
-    }
+        bAlphaTestPreviousState = bAlphaTestState;
+        bFogPreviousState = bFogState;
+        m_AlphaRef = (float)(m_pOGLRender->m_dwAlpha)/255.0f;    
+       }
 
 
     GenerateCombinerSettingConstants(m_lastIndex);