"attribute lowp vec2 aTexCoord0; \n"\
"attribute lowp vec2 aTexCoord1; \n"\
"attribute lowp vec2 aAtlasTransform; \n"\
+"attribute mediump float aFogCoord; \n"\
+" \n"\
+"uniform vec2 FogMinMax; \n"\
" \n"\
"varying lowp float vFactor; \n"\
"varying lowp vec4 vShadeColor; \n"\
"vShadeColor = aColor; \n"\
"vTexCoord0 = aTexCoord0; \n"\
"vTexCoord1 = aTexCoord1; \n"\
+"vFog = (FogMinMax[1] - aFogCoord) / (FogMinMax[1] - FogMinMax[0]); \n"\
" \n"\
+"vFog = clamp(vFog, 0.0, 1.0); \n"\
"} \n"\
" \n";
"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"\
const char *fragmentFooter =
" \n"\
"#ifdef FOG \n"\
-" float z = gl_FragCoord.z * 2.0 - 1.0; \n"\
-" float FogFactor = (FogMinMax[1] - z) / (FogMinMax[1] - FogMinMax[0]); \n"\
-" FogFactor = clamp(FogFactor, 0.0, 1.0); \n"\
-" \n"\
-" gl_FragColor.rgb = mix(FogColor.rgb, comb.rgb, FogFactor ); \n"\
-" gl_FragColor.a = comb.a; \n"\
-"#else \n"\
-" gl_FragColor = comb; \n"\
-"#endif \n"\
-" \n"\
-"#ifdef ALPHA_TEST \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
-"#endif \n"\
+"#endif \n"\
"} \n";
//Fragment shader for InitCycleCopy
if( !COGLColorCombiner::Initialize() )
return false;
- COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
+// COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
// if( pcontext->IsExtensionSupported("GL_fragment_shader") )
// {
m_bShaderIsSupported = true;
m_pDecodedMux = new DecodedMuxForPixelShader;
m_bFragmentProgramIsSupported = true;
m_AlphaRef = 0.0f;
- bAlphaTestState = DISABLE;
- bAlphaTestPreviousState = DISABLE;
- bFogState = DISABLE;
- bFogPreviousState = DISABLE;
+ bAlphaTestState = false;
+ bAlphaTestPreviousState = false;
+ bFogState = false;
+ bFogPreviousState = false;
//Create shaders for fill and copy
GLint success;
if( !COGLColorCombiner4::Initialize() )
return false;
- COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
+// COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
// if( pcontext->IsExtensionSupported("GL_fragment_program") )
// {
m_bFragmentProgramIsSupported = true;
+void COGL_FragmentProgramCombiner::UseProgram(GLuint program)
+{
+ if (program != currentProgram) {
+ glUseProgram(program);
+ currentProgram = program;
+ }
+}
+
void COGL_FragmentProgramCombiner::DisableCombiner(void)
{
//glDisable(GL_FRAGMENT_PROGRAM);
{
m_pOGLRender->DisableMultiTexture();
m_pOGLRender->EnableTexUnit(0,TRUE);
- glUseProgram(copyProgram);
+ UseProgram(copyProgram);
glUniform1f(copyAlphaLocation,m_AlphaRef);
OPENGL_CHECK_ERRORS;
glEnableVertexAttribArray(VS_POSITION);
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 )
{
void COGL_FragmentProgramCombiner::InitCombinerCycleFill(void)
{
- glUseProgram(fillProgram);
+ UseProgram(fillProgram);
glUniform4f(fillColorLocation,((gRDP.fillColor>>16)&0xFF)/255.0f,((gRDP.fillColor>>8)&0xFF)/255.0f,((gRDP.fillColor)&0xFF)/255.0f,((gRDP.fillColor>>24)&0xFF)/255.0f);
OPENGL_CHECK_ERRORS;
}
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;
printf("%s\n",Log);
}
- glUseProgram(res.programID);
+ UseProgram(res.programID);
OPENGL_CHECK_ERRORS;
//Bind texture samplers
{
GLuint ID = m_vCompiledShaders[index].programID;
- glUseProgram(ID);
+ UseProgram(ID);
glEnableVertexAttribArray(VS_POSITION);
OPENGL_CHECK_ERRORS;
glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0]));
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)
{
- OGLShaderCombinerSaveType prog = m_vCompiledShaders[index];
+ OGLShaderCombinerSaveType &prog = m_vCompiledShaders[index];
- glUseProgram(prog.programID);
+ UseProgram(prog.programID);
float *pf;
if(prog.EnvColorLocation != -1)
{
pf = GetEnvColorfv();
- glUniform4fv(prog.EnvColorLocation,1, pf);
- OPENGL_CHECK_ERRORS;
+ if (memcmp(pf, prog.EnvColors, sizeof(prog.EnvColors))) {
+ memcpy(prog.EnvColors, pf, sizeof(prog.EnvColors));
+ glUniform4fv(prog.EnvColorLocation, 1, pf);
+ OPENGL_CHECK_ERRORS;
+ }
}
if(prog.PrimColorLocation != -1)
{
pf = GetPrimitiveColorfv();
- glUniform4fv(prog.PrimColorLocation,1, pf);
- OPENGL_CHECK_ERRORS;
+ if (memcmp(pf, prog.PrimColors, sizeof(prog.PrimColors))) {
+ memcpy(prog.PrimColors, pf, sizeof(prog.PrimColors));
+ glUniform4fv(prog.PrimColorLocation, 1, pf);
+ OPENGL_CHECK_ERRORS;
+ }
}
if(prog.EnvFracLocation != -1)
{
- float frac = gRDP.LODFrac / 255.0f;
- float tempf[4] = {frac,frac,frac,frac};
- glUniform4fv(prog.EnvFracLocation,1, tempf);
- OPENGL_CHECK_ERRORS;
+ // avoid slow float compare..
+ if( *(int *)&gRDP.LODFrac != *(int *)&prog.EnvLODFrac ) {
+ prog.EnvLODFrac = gRDP.LODFrac;
+ float frac = gRDP.LODFrac / 255.0f;
+ float tempf[4] = {frac,frac,frac,frac};
+ glUniform4fv(prog.EnvFracLocation, 1, tempf);
+ OPENGL_CHECK_ERRORS;
+ }
}
if(prog.PrimFracLocation != -1)
{
- float frac2 = gRDP.primLODFrac / 255.0f;
- float tempf2[4] = {frac2,frac2,frac2,frac2};
- glUniform4fv(prog.PrimFracLocation,1, tempf2);
- OPENGL_CHECK_ERRORS;
+ if( *(int *)&gRDP.primLODFrac != *(int *)&prog.PrimLODFrac ) {
+ prog.PrimLODFrac = gRDP.primLODFrac;
+ float frac2 = gRDP.primLODFrac / 255.0f;
+ float tempf2[4] = {frac2,frac2,frac2,frac2};
+ glUniform4fv(prog.PrimFracLocation, 1, tempf2);
+ OPENGL_CHECK_ERRORS;
+ }
}
- if(prog.FogColorLocation != -1)
+ if(prog.FogColorLocation != -1)
{
- glUniform4f(prog.FogColorLocation, gRDP.fvFogColor[0],gRDP.fvFogColor[1],gRDP.fvFogColor[2], gRDP.fvFogColor[3]);
- OPENGL_CHECK_ERRORS;
+ pf = &gRDP.fvFogColor[0];
+ if (memcmp(pf, prog.FogColors, sizeof(prog.FogColors))) {
+ memcpy(prog.FogColors, pf, sizeof(prog.FogColors));
+ glUniform4fv(prog.FogColorLocation, 1, pf);
+ OPENGL_CHECK_ERRORS;
+ }
}
- if(prog.FogMinMaxLocation != -1)
- {
- glUniform2f(prog.FogMinMaxLocation,gRSPfFogMin,gRSPfFogMax);
- OPENGL_CHECK_ERRORS;
+ if(prog.FogMinMaxLocation != -1)
+ {
+ if( gRSPfFogMin != prog.FogMin || gRSPfFogMax != prog.FogMax ) {
+ prog.FogMin = gRSPfFogMin;
+ prog.FogMax = gRSPfFogMax;
+ glUniform2f(prog.FogMinMaxLocation,gRSPfFogMin,gRSPfFogMax);
+ OPENGL_CHECK_ERRORS;
+ }
}
if(prog.AlphaRefLocation != -1)
- {
- glUniform1f(prog.AlphaRefLocation,m_AlphaRef);
- OPENGL_CHECK_ERRORS;
- }
+ {
+ if( m_AlphaRef != prog.AlphaRef ) {
+ prog.AlphaRef = m_AlphaRef;
+ glUniform1f(prog.AlphaRefLocation, m_AlphaRef);
+ OPENGL_CHECK_ERRORS;
+ }
+ }
}
int COGL_FragmentProgramCombiner::FindCompiledMux()