2 Copyright (C) 2003 Rice1964
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 #include "OGLES2FragmentShaders.h"
21 #include "OGLRender.h"
22 #include "OGLGraphicsContext.h"
23 #include "OGLTexture.h"
25 #define ALPHA_TEST " if(gl_FragColor.a < AlphaRef) discard; \n"
30 GLuint vertexProgram = 9999;
31 const char *vertexShader =
32 "#version " GLSL_VERSION "\n"
33 "attribute mediump vec4 aPosition; \n"\
34 "attribute lowp vec4 aColor; \n"\
35 "attribute lowp vec2 aTexCoord0; \n"\
36 "attribute lowp vec2 aTexCoord1; \n"\
37 "attribute lowp vec2 aAtlasTransform; \n"\
38 "attribute mediump float aFogCoord; \n"\
40 "uniform vec2 FogMinMax; \n"\
42 "varying lowp float vFactor; \n"\
43 "varying lowp vec4 vShadeColor; \n"\
44 "varying mediump vec2 vTexCoord0; \n"\
45 "varying lowp vec2 vTexCoord1; \n"\
46 "varying lowp float vFog; \n"\
50 "gl_Position = aPosition; //gl_Position.z = max(0.0,gl_Position.z); \n"\
51 "vShadeColor = aColor; \n"\
52 "vTexCoord0 = aTexCoord0; \n"\
53 "vTexCoord1 = aTexCoord1; \n"\
54 "vFog = (FogMinMax[1] - aFogCoord) / (FogMinMax[1] - FogMinMax[0]); \n"\
56 "vFog = clamp(vFog, 0.0, 1.0); \n"\
60 const char *fragmentHeader =
61 "#define saturate(x) clamp( x, 0.0, 1.0 ) \n"\
62 "precision lowp float; \n"\
63 "#ifdef NEED_TEX0 \n"\
64 "uniform sampler2D uTex0; \n"\
67 "#ifdef NEED_TEX1 \n"\
68 "uniform sampler2D uTex1; \n"\
71 "uniform vec4 EnvColor; \n"\
72 "uniform vec4 PrimColor; \n"\
73 "uniform vec4 EnvFrac; \n"\
74 "uniform vec4 PrimFrac; \n"\
75 "uniform float AlphaRef; \n"\
76 "uniform vec4 FogColor; \n"\
78 "varying lowp vec4 vShadeColor; \n"\
79 "varying mediump vec2 vTexCoord0; \n"\
80 "varying lowp vec2 vTexCoord1; \n"\
81 "varying lowp float vFog; \n"\
85 "vec4 comb,comb2; \n"\
87 "#ifdef NEED_TEX0 \n"\
88 "vec4 t0 = texture2D(uTex0,vTexCoord0); \n"\
91 "#ifdef NEED_TEX1 \n"\
92 "vec4 t1 = texture2D(uTex1,vTexCoord1); \n"\
95 const char *fragmentFooter =
98 "gl_FragColor.rgb = mix(FogColor.rgb,comb.rgb,vFog); \n"\
99 "gl_FragColor.a = comb.a; \n"\
101 "gl_FragColor = comb; \n"\
104 "#ifdef ALPHA_TEST \n"\
109 //Fragment shader for InitCycleCopy
110 const char *fragmentCopy =
111 "#version " GLSL_VERSION "\n"\
112 "precision lowp float; \n"\
113 "uniform sampler2D uTex0; \n"\
114 "uniform float AlphaRef; \n"\
115 "varying lowp vec2 vTexCoord0; \n"\
118 " gl_FragColor = texture2D(uTex0,vTexCoord0).bgra; \n"\
122 GLuint copyProgram,copyAlphaLocation;
124 //Fragment shader for InitCycleFill
125 const char *fragmentFill =
126 "#version " GLSL_VERSION "\n"\
127 "precision lowp float; \n"
128 "uniform vec4 uColor; \n"
131 " gl_FragColor = uColor; \n"
134 GLuint fillProgram,fillColorLocation;
136 COGLFragmentShaderCombiner::COGLFragmentShaderCombiner(CRender *pRender)
137 : COGLColorCombiner(pRender)
139 m_bShaderIsSupported = true;
141 COGLFragmentShaderCombiner::~COGLFragmentShaderCombiner()
145 bool COGLFragmentShaderCombiner::Initialize(void)
147 if( !COGLColorCombiner::Initialize() )
150 // COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
151 // if( pcontext->IsExtensionSupported("GL_fragment_shader") )
153 m_bShaderIsSupported = true;
159 void COGLFragmentShaderCombiner::InitCombinerCycle12(void)
162 void COGLFragmentShaderCombiner::DisableCombiner(void)
164 COGLColorCombiner::DisableCombiner();
167 void COGLFragmentShaderCombiner::InitCombinerCycleCopy(void)
169 COGLColorCombiner::InitCombinerCycleCopy();
172 void COGLFragmentShaderCombiner::InitCombinerCycleFill(void)
174 COGLColorCombiner::InitCombinerCycleFill();
176 void COGLFragmentShaderCombiner::InitCombinerBlenderForSimpleTextureDraw(uint32 tile)
178 COGLColorCombiner::InitCombinerBlenderForSimpleTextureDraw(tile);
182 void COGLFragmentShaderCombiner::DisplaySimpleMuxString(void)
184 COGLColorCombiner::DisplaySimpleMuxString();
190 COGL_FragmentProgramCombiner::COGL_FragmentProgramCombiner(CRender *pRender)
191 : COGLColorCombiner4(pRender)
193 delete m_pDecodedMux;
194 m_pDecodedMux = new DecodedMuxForPixelShader;
195 m_bFragmentProgramIsSupported = true;
197 bAlphaTestState = false;
198 bAlphaTestPreviousState = false;
200 bFogPreviousState = false;
202 //Create shaders for fill and copy
205 copyProgram = glCreateProgram();
206 vs = glCreateShader(GL_VERTEX_SHADER);
207 glShaderSource(vs,1,&vertexShader,NULL);
210 glGetShaderiv(vs,GL_COMPILE_STATUS,&success);
214 glGetShaderInfoLog(vs,1024,NULL,log);
218 fs = glCreateShader(GL_FRAGMENT_SHADER);
219 glShaderSource(fs,1,&fragmentCopy,NULL);
222 glGetShaderiv(fs,GL_COMPILE_STATUS,&success);
226 glGetShaderInfoLog(fs,1024,NULL,log);
230 glAttachShader(copyProgram,vs);
231 glAttachShader(copyProgram,fs);
233 glBindAttribLocation(copyProgram,VS_TEXCOORD0,"aTexCoord0");
235 glBindAttribLocation(copyProgram,VS_POSITION,"aPosition");
238 glLinkProgram(copyProgram);
239 copyAlphaLocation = glGetUniformLocation(copyProgram,"AlphaRef");
240 glGetProgramiv(copyProgram,GL_LINK_STATUS,&success);
244 glGetProgramInfoLog(copyProgram,1024,NULL,log);
251 fs = glCreateShader(GL_FRAGMENT_SHADER);
252 glShaderSource(fs,1,&fragmentFill,NULL);
255 glGetShaderiv(fs,GL_COMPILE_STATUS,&success);
259 glGetShaderInfoLog(fs,1024,NULL,log);
263 fillProgram = glCreateProgram();
264 glAttachShader(fillProgram,vs);
265 glAttachShader(fillProgram,fs);
267 glBindAttribLocation(fillProgram,VS_POSITION,"aPosition");
270 glLinkProgram(fillProgram);
273 fillColorLocation = glGetUniformLocation(fillProgram,"uColor");
278 COGL_FragmentProgramCombiner::~COGL_FragmentProgramCombiner()
280 int size = m_vCompiledShaders.size();
281 for (int i=0; i<size; i++)
283 GLuint ID = m_vCompiledShaders[i].programID;
287 m_vCompiledShaders[i].programID = 0;
290 m_vCompiledShaders.clear();
293 bool COGL_FragmentProgramCombiner::Initialize(void)
295 if( !COGLColorCombiner4::Initialize() )
298 // COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
299 // if( pcontext->IsExtensionSupported("GL_fragment_program") )
301 m_bFragmentProgramIsSupported = true;
309 void COGL_FragmentProgramCombiner::UseProgram(GLuint program)
311 if (program != currentProgram) {
312 glUseProgram(program);
313 currentProgram = program;
317 void COGL_FragmentProgramCombiner::DisableCombiner(void)
319 //glDisable(GL_FRAGMENT_PROGRAM);
320 //OPENGL_CHECK_ERRORS;
321 COGLColorCombiner4::DisableCombiner();
324 void COGL_FragmentProgramCombiner::InitCombinerCycleCopy(void)
326 m_pOGLRender->DisableMultiTexture();
327 m_pOGLRender->EnableTexUnit(0,TRUE);
328 UseProgram(copyProgram);
329 glUniform1f(copyAlphaLocation,m_AlphaRef);
331 glEnableVertexAttribArray(VS_POSITION);
333 glEnableVertexAttribArray(VS_TEXCOORD0);
335 glDisableVertexAttribArray(VS_COLOR);
337 glDisableVertexAttribArray(VS_TEXCOORD1);
339 glDisableVertexAttribArray(VS_FOG);
341 COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
344 m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0);
345 m_pOGLRender->SetTexelRepeatFlags(gRSP.curTile);
349 void COGL_FragmentProgramCombiner::InitCombinerCycleFill(void)
351 UseProgram(fillProgram);
352 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);
357 const char *muxToFP_Maps[][2] = {
359 {"vec3(0.0)", "0.0"}, //MUX_0 = 0,
360 {"vec3(1.0)", "1.0"}, //MUX_1,
361 {"comb.rgb", "comb.a"}, //MUX_COMBINED,
362 {"t0.rgb", "t0.a"}, //MUX_TEXEL0,
363 {"t1.rgb", "t1.a"}, //MUX_TEXEL1,
364 {"PrimColor.rgb", "PrimColor.a"}, //MUX_PRIM,
365 {"vShadeColor.rgb", "vShadeColor.a"}, //MUX_SHADE,
366 {"EnvColor.rgb", "EnvColor.a"}, //MUX_ENV,
367 {"comb.rgb", "comb.a"}, //MUX_COMBALPHA,
368 {"t0.rgb", "t0.a"}, //MUX_T0_ALPHA,
369 {"t1.rgb", "t1.a"}, //MUX_T1_ALPHA,
370 {"PrimColor.rgb", "PrimColor.a"}, //MUX_PRIM_ALPHA,
371 {"vShadeColor.rgb", "vShadeColor.a"}, //MUX_SHADE_ALPHA,
372 {"EnvColor.rgb", "EnvColor.a"}, //MUX_ENV_ALPHA,
373 {"EnvFrac.a", "EnvFrac.a"}, //MUX_LODFRAC,
374 {"PrimFrac.a", "PrimFrac.a"}, //MUX_PRIMLODFRAC,
375 {"vec3(1.0)", "1.0"}, //MUX_K5,
376 {"vec3(1.0)", "1.0"}, //MUX_UNK, // Should not be used
379 const char *muxToFP_Maps[][2] = {
381 {"vec3(0.0)", "0.0"}, //MUX_0 = 0,
382 {"vec3(1.0)", "1.0"}, //MUX_1,
383 {"comb.rgb", "comb.a"}, //MUX_COMBINED,
384 {"t0.bgr", "t0.a"}, //MUX_TEXEL0,
385 {"t1.bgr", "t1.a"}, //MUX_TEXEL1,
386 {"PrimColor.rgb", "PrimColor.a"}, //MUX_PRIM,
387 {"vShadeColor.rgb", "vShadeColor.a"}, //MUX_SHADE,
388 {"EnvColor.rgb", "EnvColor.a"}, //MUX_ENV,
389 {"comb.rgb", "comb.a"}, //MUX_COMBALPHA,
390 {"t0.bgr", "t0.a"}, //MUX_T0_ALPHA,
391 {"t1.bgr", "t1.a"}, //MUX_T1_ALPHA,
392 {"PrimColor.rgb", "PrimColor.a"}, //MUX_PRIM_ALPHA,
393 {"vShadeColor.rgb", "vShadeColor.a"}, //MUX_SHADE_ALPHA,
394 {"EnvColor.rgb", "EnvColor.a"}, //MUX_ENV_ALPHA,
395 {"EnvFrac.a", "EnvFrac.a"}, //MUX_LODFRAC,
396 {"PrimFrac.a", "PrimFrac.a"}, //MUX_PRIMLODFRAC,
397 {"vec3(1.0)", "1.0"}, //MUX_K5,
398 {"vec3(1.0)", "1.0"}, //MUX_UNK, // Should not be used
405 char* MuxToOC(uint8 val)
408 if( val&MUX_ALPHAREPLICATE )
409 return (char*)muxToFP_Maps[val&0x1F][1];
411 return (char*)muxToFP_Maps[val&0x1F][0];
414 char* MuxToOA(uint8 val)
417 return (char*)muxToFP_Maps[val&0x1F][1];
420 static void CheckFpVars(uint8 MuxVar, bool &bNeedT0, bool &bNeedT1)
423 if (MuxVar == MUX_TEXEL0 || MuxVar == MUX_T0_ALPHA)
425 if (MuxVar == MUX_TEXEL1 || MuxVar == MUX_T1_ALPHA)
429 void COGL_FragmentProgramCombiner::GenerateProgramStr()
431 DecodedMuxForPixelShader &mux = *(DecodedMuxForPixelShader*)m_pDecodedMux;
433 mux.splitType[0] = mux.splitType[1] = mux.splitType[2] = mux.splitType[3] = CM_FMT_TYPE_NOT_CHECKED;
434 m_pDecodedMux->Reformat(false);
436 char tempstr[500], newFPBody[4092];
437 bool bNeedT0 = false, bNeedT1 = false, bNeedComb2 = false;
440 for( int cycle=0; cycle<2; cycle++ )
442 for( int channel=0; channel<2; channel++)
444 char* (*func)(uint8) = channel==0?MuxToOC:MuxToOA;
445 char *dst = channel==0?(char*)"rgb":(char*)"a";
446 N64CombinerType &m = mux.m_n64Combiners[cycle*2+channel];
447 switch( mux.splitType[cycle*2+channel] )
449 case CM_FMT_TYPE_NOT_USED:
453 sprintf(tempstr, "comb.%s = %s;\n", dst, func(m.d));
454 CheckFpVars(m.d, bNeedT0, bNeedT1);
456 case CM_FMT_TYPE_A_MOD_C:
457 sprintf(tempstr, "comb.%s = %s * %s;\n", dst, func(m.a), func(m.c));
458 CheckFpVars(m.a, bNeedT0, bNeedT1);
459 CheckFpVars(m.c, bNeedT0, bNeedT1);
461 case CM_FMT_TYPE_A_ADD_D:
462 sprintf(tempstr, "comb.%s = saturate(%s + %s);\n", dst, func(m.a), func(m.d));
463 CheckFpVars(m.a, bNeedT0, bNeedT1);
464 CheckFpVars(m.d, bNeedT0, bNeedT1);
466 case CM_FMT_TYPE_A_SUB_B:
467 sprintf(tempstr, "comb.%s = %s - %s;\n", dst, func(m.a), func(m.b));
468 CheckFpVars(m.a, bNeedT0, bNeedT1);
469 CheckFpVars(m.b, bNeedT0, bNeedT1);
471 case CM_FMT_TYPE_A_MOD_C_ADD_D:
472 sprintf(tempstr, "comb.%s = saturate(%s * %s + %s);\n", dst, func(m.a), func(m.c),func(m.d));
473 CheckFpVars(m.a, bNeedT0, bNeedT1);
474 CheckFpVars(m.c, bNeedT0, bNeedT1);
475 CheckFpVars(m.d, bNeedT0, bNeedT1);
477 case CM_FMT_TYPE_A_LERP_B_C:
478 //ARB ASM LERP and mix have different parameter ordering.
479 //sprintf(tempstr, "comb.%s = saturate(mix(%s, %s, %s));\n", dst,func(m.a),func(m.b), func(m.c));
480 sprintf(tempstr, "comb.%s = (%s - %s) * %s + %s;\n", dst,func(m.a),func(m.b), func(m.c),func(m.b));
481 CheckFpVars(m.a, bNeedT0, bNeedT1);
482 CheckFpVars(m.b, bNeedT0, bNeedT1);
483 CheckFpVars(m.c, bNeedT0, bNeedT1);
484 //sprintf(tempstr, "SUB comb.%s, %s, %s;\nMAD_SAT comb.%s, comb, %s, %s;\n", dst, func(m.a), func(m.b), dst, func(m.c), func(m.b));
487 sprintf(tempstr, "comb2.%s = %s - %s;\ncomb.%s = saturate(comb2.%s * %s + %s);\n", dst, func(m.a), func(m.b), dst,dst, func(m.c),func(m.d));
488 CheckFpVars(m.a, bNeedT0, bNeedT1);
489 CheckFpVars(m.b, bNeedT0, bNeedT1);
490 CheckFpVars(m.c, bNeedT0, bNeedT1);
491 CheckFpVars(m.d, bNeedT0, bNeedT1);
495 strcat(newFPBody, tempstr);
501 strcat(oglNewFP, "#define NEED_TEX0\n");
503 strcat(oglNewFP, "#define NEED_TEX1\n");
504 strcat(oglNewFP, fragmentHeader);
505 strcat(oglNewFP, newFPBody);
506 strcat(oglNewFP, fragmentFooter);
510 int COGL_FragmentProgramCombiner::ParseDecodedMux()
512 if( !m_bFragmentProgramIsSupported )
513 return COGLColorCombiner4::ParseDecodedMux();
515 OGLShaderCombinerSaveType res;
518 if(vertexProgram == 9999)
520 vertexProgram = res.vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
521 glShaderSource(res.vertexShaderID, 1, &vertexShader,NULL);
523 glCompileShader(res.vertexShaderID);
528 res.vertexShaderID = vertexProgram;
532 //Create 4 shaders, with and without alphatest + with and without fog
533 GenerateProgramStr();
535 for(int alphaTest = 0;alphaTest < 2;alphaTest++)
537 for(int fog = 0;fog < 2;fog++) {
538 res.fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
540 char* tmpShader = (char*)malloc(sizeof(char) * 4096);
541 strcpy(tmpShader,"#version " GLSL_VERSION "\n");
545 strcat(tmpShader,"#define ALPHA_TEST\n");
549 strcat(tmpShader,"#define FOG\n");
552 res.fogIsUsed = fog == 1;
553 res.alphaTest = alphaTest == 1;
554 strcat(tmpShader,oglNewFP);
556 glShaderSource(res.fragmentShaderID, 1,(const char**) &tmpShader,NULL);
561 glCompileShader(res.fragmentShaderID);
563 glGetShaderiv(res.fragmentShaderID, GL_COMPILE_STATUS, &success);
568 glGetShaderInfoLog(res.fragmentShaderID, 1024, &nLength, Log);
569 printf("Error compiling shader!\n %s",oglNewFP);
573 res.programID = glCreateProgram();
574 glAttachShader(res.programID,res.vertexShaderID);
575 glAttachShader(res.programID,res.fragmentShaderID);
578 glBindAttribLocation(res.programID,VS_COLOR,"aColor");
580 glBindAttribLocation(res.programID,VS_TEXCOORD0,"aTexCoord0");
582 glBindAttribLocation(res.programID,VS_TEXCOORD1,"aTexCoord1");
584 glBindAttribLocation(res.programID,VS_POSITION,"aPosition");
586 glBindAttribLocation(res.programID,VS_FOG,"aFogCoord");
589 glLinkProgram(res.programID);
592 glGetProgramiv(res.programID, GL_LINK_STATUS, &success);
597 glGetShaderInfoLog(res.fragmentShaderID, 1024, &nLength, Log);
598 printf("Error linking program!\n");
602 UseProgram(res.programID);
605 //Bind texture samplers
606 GLint tex0 = glGetUniformLocation(res.programID,"uTex0");
607 GLint tex1 = glGetUniformLocation(res.programID,"uTex1");
615 res.PrimColorLocation = glGetUniformLocation(res.programID,"PrimColor");
617 res.EnvColorLocation = glGetUniformLocation(res.programID,"EnvColor");
619 res.PrimFracLocation = glGetUniformLocation(res.programID,"PrimFrac");
621 res.EnvFracLocation = glGetUniformLocation(res.programID,"EnvFrac");
623 res.AlphaRefLocation = glGetUniformLocation(res.programID,"AlphaRef");
625 res.FogColorLocation = glGetUniformLocation(res.programID,"FogColor");
627 res.FogMinMaxLocation = glGetUniformLocation(res.programID,"FogMinMax");
630 res.dwMux0 = m_pDecodedMux->m_dwMux0;
631 res.dwMux1 = m_pDecodedMux->m_dwMux1;
633 m_vCompiledShaders.push_back(res);
636 m_lastIndex = m_vCompiledShaders.size()-4;
641 void COGL_FragmentProgramCombiner::GenerateCombinerSetting(int index)
643 GLuint ID = m_vCompiledShaders[index].programID;
646 glEnableVertexAttribArray(VS_POSITION);
648 glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0]));
651 glEnableVertexAttribArray(VS_TEXCOORD0);
653 glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u));
656 glEnableVertexAttribArray(VS_TEXCOORD1);
658 glVertexAttribPointer(VS_TEXCOORD1,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[1].u));
661 glEnableVertexAttribArray(VS_COLOR);
663 glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
666 glEnableVertexAttribArray(VS_FOG);
668 glVertexAttribPointer(VS_FOG,1,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][4]));
672 void COGL_FragmentProgramCombiner::GenerateCombinerSettingConstants(int index)
674 OGLShaderCombinerSaveType &prog = m_vCompiledShaders[index];
676 UseProgram(prog.programID);
678 if(prog.EnvColorLocation != -1)
680 pf = GetEnvColorfv();
681 if (memcmp(pf, prog.EnvColors, sizeof(prog.EnvColors))) {
682 memcpy(prog.EnvColors, pf, sizeof(prog.EnvColors));
683 glUniform4fv(prog.EnvColorLocation, 1, pf);
688 if(prog.PrimColorLocation != -1)
690 pf = GetPrimitiveColorfv();
691 if (memcmp(pf, prog.PrimColors, sizeof(prog.PrimColors))) {
692 memcpy(prog.PrimColors, pf, sizeof(prog.PrimColors));
693 glUniform4fv(prog.PrimColorLocation, 1, pf);
698 if(prog.EnvFracLocation != -1)
700 // avoid slow float compare..
701 if( *(int *)&gRDP.LODFrac != *(int *)&prog.EnvLODFrac ) {
702 prog.EnvLODFrac = gRDP.LODFrac;
703 float frac = gRDP.LODFrac / 255.0f;
704 float tempf[4] = {frac,frac,frac,frac};
705 glUniform4fv(prog.EnvFracLocation, 1, tempf);
710 if(prog.PrimFracLocation != -1)
712 if( *(int *)&gRDP.primLODFrac != *(int *)&prog.PrimLODFrac ) {
713 prog.PrimLODFrac = gRDP.primLODFrac;
714 float frac2 = gRDP.primLODFrac / 255.0f;
715 float tempf2[4] = {frac2,frac2,frac2,frac2};
716 glUniform4fv(prog.PrimFracLocation, 1, tempf2);
721 if(prog.FogColorLocation != -1)
723 pf = &gRDP.fvFogColor[0];
724 if (memcmp(pf, prog.FogColors, sizeof(prog.FogColors))) {
725 memcpy(prog.FogColors, pf, sizeof(prog.FogColors));
726 glUniform4fv(prog.FogColorLocation, 1, pf);
731 if(prog.FogMinMaxLocation != -1)
733 if( gRSPfFogMin != prog.FogMin || gRSPfFogMax != prog.FogMax ) {
734 prog.FogMin = gRSPfFogMin;
735 prog.FogMax = gRSPfFogMax;
736 glUniform2f(prog.FogMinMaxLocation,gRSPfFogMin,gRSPfFogMax);
741 if(prog.AlphaRefLocation != -1)
743 if( m_AlphaRef != prog.AlphaRef ) {
744 prog.AlphaRef = m_AlphaRef;
745 glUniform1f(prog.AlphaRefLocation, m_AlphaRef);
751 int COGL_FragmentProgramCombiner::FindCompiledMux()
754 if( debuggerDropCombiners )
756 m_vCompiledShaders.clear();
757 //m_dwLastMux0 = m_dwLastMux1 = 0;
758 debuggerDropCombiners = false;
761 for( uint32 i=0; i<m_vCompiledShaders.size(); i++ )
763 if( m_vCompiledShaders[i].dwMux0 == m_pDecodedMux->m_dwMux0
764 && m_vCompiledShaders[i].dwMux1 == m_pDecodedMux->m_dwMux1
765 && m_vCompiledShaders[i].fogIsUsed == bFogState
766 && m_vCompiledShaders[i].alphaTest == bAlphaTestState)
775 //////////////////////////////////////////////////////////////////////////
776 void COGL_FragmentProgramCombiner::InitCombinerCycle12(void)
778 if( !m_bFragmentProgramIsSupported )
780 COGLColorCombiner4::InitCombinerCycle12();
785 if( debuggerDropCombiners )
787 UpdateCombiner(m_pDecodedMux->m_dwMux0,m_pDecodedMux->m_dwMux1);
788 m_vCompiledShaders.clear();
789 m_dwLastMux0 = m_dwLastMux1 = 0;
790 debuggerDropCombiners = false;
794 m_pOGLRender->EnableMultiTexture();
796 bool combinerIsChanged = false;
798 if( m_pDecodedMux->m_dwMux0 != m_dwLastMux0 || m_pDecodedMux->m_dwMux1 != m_dwLastMux1
799 || bAlphaTestState != bAlphaTestPreviousState || bFogState != bFogPreviousState || m_lastIndex < 0 )
801 combinerIsChanged = true;
802 m_lastIndex = FindCompiledMux();
803 if( m_lastIndex < 0 ) // Can not found
805 m_lastIndex = ParseDecodedMux();
808 m_dwLastMux0 = m_pDecodedMux->m_dwMux0;
809 m_dwLastMux1 = m_pDecodedMux->m_dwMux1;
810 bAlphaTestPreviousState = bAlphaTestState;
811 bFogPreviousState = bFogState;
812 m_AlphaRef = (float)(m_pOGLRender->m_dwAlpha)/255.0f;
816 GenerateCombinerSettingConstants(m_lastIndex);
817 if( m_bCycleChanged || combinerIsChanged || gRDP.texturesAreReloaded || gRDP.colorsAreReloaded )
819 if( m_bCycleChanged || combinerIsChanged )
821 GenerateCombinerSettingConstants(m_lastIndex);
822 GenerateCombinerSetting(m_lastIndex);
824 else if( gRDP.colorsAreReloaded )
826 GenerateCombinerSettingConstants(m_lastIndex);
829 m_pOGLRender->SetAllTexelRepeatFlag();
831 gRDP.colorsAreReloaded = false;
832 gRDP.texturesAreReloaded = false;
836 m_pOGLRender->SetAllTexelRepeatFlag();
841 void COGL_FragmentProgramCombiner::DisplaySimpleMuxString(void)
843 COGLColorCombiner::DisplaySimpleMuxString();
844 DecodedMuxForPixelShader &mux = *(DecodedMuxForPixelShader*)m_pDecodedMux;
846 GenerateProgramStr();
847 //sprintf(oglNewFP, oglFP,
848 // MuxToOC(mux.aRGB0), MuxToOC(mux.bRGB0), MuxToOC(mux.cRGB0), MuxToOC(mux.dRGB0),
849 // MuxToOA(mux.aA0), MuxToOA(mux.bA0), MuxToOA(mux.cA0), MuxToOA(mux.dA0),
850 // MuxToOC(mux.aRGB1), MuxToOC(mux.bRGB1), MuxToOC(mux.cRGB1), MuxToOC(mux.dRGB1),
851 // MuxToOA(mux.aA1), MuxToOA(mux.bA1), MuxToOA(mux.cA1), MuxToOA(mux.dA1)
854 TRACE0("OGL Fragment Program:");