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"
29 GLuint vertexProgram = 9999;
30 const char *vertexShader =
31 "#version " GLSL_VERSION "\n"
32 "attribute mediump vec4 aPosition; \n"\
33 "attribute lowp vec4 aColor; \n"\
34 "attribute lowp vec2 aTexCoord0; \n"\
35 "attribute lowp vec2 aTexCoord1; \n"\
36 "attribute lowp vec2 aAtlasTransform; \n"\
38 "uniform lowp vec2 FogMinMax; \n"\
40 "varying lowp float vFactor; \n"\
41 "varying lowp vec4 vShadeColor; \n"\
42 "varying mediump vec2 vTexCoord0; \n"\
43 "varying lowp vec2 vTexCoord1; \n"\
44 "varying lowp float vFog; \n"\
48 "gl_Position = aPosition; //gl_Position.z = max(0.0,gl_Position.z); \n"\
49 "vShadeColor = aColor; \n"\
50 "vTexCoord0 = aTexCoord0; \n"\
51 "vTexCoord1 = aTexCoord1; \n"\
52 "vFog = clamp((FogMinMax[1] - (gl_Position.z/aPosition.w))/(FogMinMax[1]-FogMinMax[0]),0.0,1.0); \n"\
57 const char *fragmentHeader =
58 "#define saturate(x) clamp( x, 0.0, 1.0 ) \n"\
59 "precision lowp float; \n"\
60 "#ifdef NEED_TEX0 \n"\
61 "uniform sampler2D uTex0; \n"\
64 "#ifdef NEED_TEX1 \n"\
65 "uniform sampler2D uTex1; \n"\
68 "uniform vec4 EnvColor; \n"\
69 "uniform vec4 PrimColor; \n"\
70 "uniform vec4 EnvFrac; \n"\
71 "uniform vec4 PrimFrac; \n"\
72 "uniform float AlphaRef; \n"\
73 "uniform vec4 FogColor; \n"\
75 "varying lowp float vFactor; \n"\
76 "varying lowp vec4 vShadeColor; \n"\
77 "varying mediump vec2 vTexCoord0; \n"\
78 "varying lowp vec2 vTexCoord1; \n"\
79 "varying lowp float vFog; \n"\
83 "vec4 comb,comb2; \n"\
85 "#ifdef NEED_TEX0 \n"\
86 "vec4 t0 = texture2D(uTex0,vTexCoord0); \n"\
89 "#ifdef NEED_TEX1 \n"\
90 "vec4 t1 = texture2D(uTex1,vTexCoord1); \n"\
93 const char *fragmentFooter =
96 "gl_FragColor.rgb = mix(FogColor.rgb,comb.rgb,vFog * step(0.5,1.0-FogColor.a)); \n"\
97 "gl_FragColor.a = comb.a; \n"\
99 "gl_FragColor = comb; \n"\
102 "#ifdef ALPHA_TEST \n"\
111 //Fragment shader for InitCycleCopy
112 const char *fragmentCopy =
113 "#version " GLSL_VERSION "\n"\
114 "precision lowp float; \n"\
115 "uniform sampler2D uTex0; \n"\
116 "uniform float AlphaRef; \n"\
117 "varying lowp vec2 vTexCoord0; \n"\
120 " gl_FragColor = texture2D(uTex0,vTexCoord0).bgra; \n"\
124 GLuint copyProgram,copyAlphaLocation;
126 //Fragment shader for InitCycleFill
127 const char *fragmentFill =
128 "#version " GLSL_VERSION "\n"\
129 "precision lowp float; \n"
130 "uniform vec4 uColor; \n"
133 " gl_FragColor = uColor; \n"
136 GLuint fillProgram,fillColorLocation;
138 COGLFragmentShaderCombiner::COGLFragmentShaderCombiner(CRender *pRender)
139 : COGLColorCombiner(pRender)
141 m_bShaderIsSupported = true;
143 COGLFragmentShaderCombiner::~COGLFragmentShaderCombiner()
147 bool COGLFragmentShaderCombiner::Initialize(void)
149 if( !COGLColorCombiner::Initialize() )
152 COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
153 // if( pcontext->IsExtensionSupported("GL_fragment_shader") )
155 m_bShaderIsSupported = true;
161 void COGLFragmentShaderCombiner::InitCombinerCycle12(void)
164 void COGLFragmentShaderCombiner::DisableCombiner(void)
166 COGLColorCombiner::DisableCombiner();
169 void COGLFragmentShaderCombiner::InitCombinerCycleCopy(void)
171 COGLColorCombiner::InitCombinerCycleCopy();
174 void COGLFragmentShaderCombiner::InitCombinerCycleFill(void)
176 COGLColorCombiner::InitCombinerCycleFill();
178 void COGLFragmentShaderCombiner::InitCombinerBlenderForSimpleTextureDraw(uint32 tile)
180 COGLColorCombiner::InitCombinerBlenderForSimpleTextureDraw(tile);
184 void COGLFragmentShaderCombiner::DisplaySimpleMuxString(void)
186 COGLColorCombiner::DisplaySimpleMuxString();
192 COGL_FragmentProgramCombiner::COGL_FragmentProgramCombiner(CRender *pRender)
193 : COGLColorCombiner4(pRender)
195 delete m_pDecodedMux;
196 m_pDecodedMux = new DecodedMuxForPixelShader;
197 m_bFragmentProgramIsSupported = true;
200 //Create shaders for fill and copy
203 copyProgram = glCreateProgram();
204 vs = glCreateShader(GL_VERTEX_SHADER);
205 glShaderSource(vs,1,&vertexShader,NULL);
208 glGetShaderiv(vs,GL_COMPILE_STATUS,&success);
212 glGetShaderInfoLog(vs,1024,NULL,log);
216 fs = glCreateShader(GL_FRAGMENT_SHADER);
217 glShaderSource(fs,1,&fragmentCopy,NULL);
220 glGetShaderiv(fs,GL_COMPILE_STATUS,&success);
224 glGetShaderInfoLog(fs,1024,NULL,log);
228 glAttachShader(copyProgram,vs);
229 glAttachShader(copyProgram,fs);
231 glBindAttribLocation(copyProgram,VS_TEXCOORD0,"aTexCoord0");
233 glBindAttribLocation(copyProgram,VS_POSITION,"aPosition");
236 glLinkProgram(copyProgram);
237 copyAlphaLocation = glGetUniformLocation(copyProgram,"AlphaRef");
238 glGetProgramiv(copyProgram,GL_LINK_STATUS,&success);
242 glGetProgramInfoLog(copyProgram,1024,NULL,log);
249 fs = glCreateShader(GL_FRAGMENT_SHADER);
250 glShaderSource(fs,1,&fragmentFill,NULL);
253 glGetShaderiv(fs,GL_COMPILE_STATUS,&success);
257 glGetShaderInfoLog(fs,1024,NULL,log);
261 fillProgram = glCreateProgram();
262 glAttachShader(fillProgram,vs);
263 glAttachShader(fillProgram,fs);
265 glBindAttribLocation(fillProgram,VS_POSITION,"aPosition");
268 glLinkProgram(fillProgram);
271 fillColorLocation = glGetUniformLocation(fillProgram,"uColor");
276 COGL_FragmentProgramCombiner::~COGL_FragmentProgramCombiner()
278 int size = m_vCompiledShaders.size();
279 for (int i=0; i<size; i++)
281 GLuint ID = m_vCompiledShaders[i].programID;
285 m_vCompiledShaders[i].programID = 0;
288 m_vCompiledShaders.clear();
291 bool COGL_FragmentProgramCombiner::Initialize(void)
293 if( !COGLColorCombiner4::Initialize() )
296 COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
297 // if( pcontext->IsExtensionSupported("GL_fragment_program") )
299 m_bFragmentProgramIsSupported = true;
307 void COGL_FragmentProgramCombiner::DisableCombiner(void)
309 //glDisable(GL_FRAGMENT_PROGRAM);
310 //OPENGL_CHECK_ERRORS;
311 COGLColorCombiner4::DisableCombiner();
314 void COGL_FragmentProgramCombiner::InitCombinerCycleCopy(void)
316 m_pOGLRender->DisableMultiTexture();
317 m_pOGLRender->EnableTexUnit(0,TRUE);
318 glUseProgram(copyProgram);
319 glUniform1f(copyAlphaLocation,m_AlphaRef);
321 glEnableVertexAttribArray(VS_POSITION);
323 glEnableVertexAttribArray(VS_TEXCOORD0);
325 glDisableVertexAttribArray(VS_COLOR);
327 glDisableVertexAttribArray(VS_TEXCOORD1);
329 COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
332 m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0);
333 m_pOGLRender->SetTexelRepeatFlags(gRSP.curTile);
337 void COGL_FragmentProgramCombiner::InitCombinerCycleFill(void)
339 glUseProgram(fillProgram);
340 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);
345 const char *muxToFP_Maps[][2] = {
347 {"vec3(0.0)", "0.0"}, //MUX_0 = 0,
348 {"vec3(1.0)", "1.0"}, //MUX_1,
349 {"comb.rgb", "comb.a"}, //MUX_COMBINED,
350 {"t0.rgb", "t0.a"}, //MUX_TEXEL0,
351 {"t1.rgb", "t1.a"}, //MUX_TEXEL1,
352 {"PrimColor.rgb", "PrimColor.a"}, //MUX_PRIM,
353 {"vShadeColor.rgb", "vShadeColor.a"}, //MUX_SHADE,
354 {"EnvColor.rgb", "EnvColor.a"}, //MUX_ENV,
355 {"comb.rgb", "comb.a"}, //MUX_COMBALPHA,
356 {"t0.rgb", "t0.a"}, //MUX_T0_ALPHA,
357 {"t1.rgb", "t1.a"}, //MUX_T1_ALPHA,
358 {"PrimColor.rgb", "PrimColor.a"}, //MUX_PRIM_ALPHA,
359 {"vShadeColor.rgb", "vShadeColor.a"}, //MUX_SHADE_ALPHA,
360 {"EnvColor.rgb", "EnvColor.a"}, //MUX_ENV_ALPHA,
361 {"EnvFrac.a", "EnvFrac.a"}, //MUX_LODFRAC,
362 {"PrimFrac.a", "PrimFrac.a"}, //MUX_PRIMLODFRAC,
363 {"vec3(1.0)", "1.0"}, //MUX_K5,
364 {"vec3(1.0)", "1.0"}, //MUX_UNK, // Should not be used
367 const char *muxToFP_Maps[][2] = {
369 {"vec3(0.0)", "0.0"}, //MUX_0 = 0,
370 {"vec3(1.0)", "1.0"}, //MUX_1,
371 {"comb.rgb", "comb.a"}, //MUX_COMBINED,
372 {"t0.bgr", "t0.a"}, //MUX_TEXEL0,
373 {"t1.bgr", "t1.a"}, //MUX_TEXEL1,
374 {"PrimColor.rgb", "PrimColor.a"}, //MUX_PRIM,
375 {"vShadeColor.rgb", "vShadeColor.a"}, //MUX_SHADE,
376 {"EnvColor.rgb", "EnvColor.a"}, //MUX_ENV,
377 {"comb.rgb", "comb.a"}, //MUX_COMBALPHA,
378 {"t0.bgr", "t0.a"}, //MUX_T0_ALPHA,
379 {"t1.bgr", "t1.a"}, //MUX_T1_ALPHA,
380 {"PrimColor.rgb", "PrimColor.a"}, //MUX_PRIM_ALPHA,
381 {"vShadeColor.rgb", "vShadeColor.a"}, //MUX_SHADE_ALPHA,
382 {"EnvColor.rgb", "EnvColor.a"}, //MUX_ENV_ALPHA,
383 {"EnvFrac.a", "EnvFrac.a"}, //MUX_LODFRAC,
384 {"PrimFrac.a", "PrimFrac.a"}, //MUX_PRIMLODFRAC,
385 {"vec3(1.0)", "1.0"}, //MUX_K5,
386 {"vec3(1.0)", "1.0"}, //MUX_UNK, // Should not be used
393 char* MuxToOC(uint8 val)
396 if( val&MUX_ALPHAREPLICATE )
397 return (char*)muxToFP_Maps[val&0x1F][1];
399 return (char*)muxToFP_Maps[val&0x1F][0];
402 char* MuxToOA(uint8 val)
405 return (char*)muxToFP_Maps[val&0x1F][1];
408 static void CheckFpVars(uint8 MuxVar, bool &bNeedT0, bool &bNeedT1)
411 if (MuxVar == MUX_TEXEL0 || MuxVar == MUX_T0_ALPHA)
413 if (MuxVar == MUX_TEXEL1 || MuxVar == MUX_T1_ALPHA)
417 void COGL_FragmentProgramCombiner::GenerateProgramStr()
419 DecodedMuxForPixelShader &mux = *(DecodedMuxForPixelShader*)m_pDecodedMux;
421 mux.splitType[0] = mux.splitType[1] = mux.splitType[2] = mux.splitType[3] = CM_FMT_TYPE_NOT_CHECKED;
422 m_pDecodedMux->Reformat(false);
424 char tempstr[500], newFPBody[4092];
425 bool bNeedT0 = false, bNeedT1 = false, bNeedComb2 = false;
428 for( int cycle=0; cycle<2; cycle++ )
430 for( int channel=0; channel<2; channel++)
432 char* (*func)(uint8) = channel==0?MuxToOC:MuxToOA;
433 char *dst = channel==0?(char*)"rgb":(char*)"a";
434 N64CombinerType &m = mux.m_n64Combiners[cycle*2+channel];
435 switch( mux.splitType[cycle*2+channel] )
437 case CM_FMT_TYPE_NOT_USED:
441 sprintf(tempstr, "comb.%s = %s;\n", dst, func(m.d));
442 CheckFpVars(m.d, bNeedT0, bNeedT1);
444 case CM_FMT_TYPE_A_MOD_C:
445 sprintf(tempstr, "comb.%s = %s * %s;\n", dst, func(m.a), func(m.c));
446 CheckFpVars(m.a, bNeedT0, bNeedT1);
447 CheckFpVars(m.c, bNeedT0, bNeedT1);
449 case CM_FMT_TYPE_A_ADD_D:
450 sprintf(tempstr, "comb.%s = saturate(%s + %s);\n", dst, func(m.a), func(m.d));
451 CheckFpVars(m.a, bNeedT0, bNeedT1);
452 CheckFpVars(m.d, bNeedT0, bNeedT1);
454 case CM_FMT_TYPE_A_SUB_B:
455 sprintf(tempstr, "comb.%s = %s - %s;\n", dst, func(m.a), func(m.b));
456 CheckFpVars(m.a, bNeedT0, bNeedT1);
457 CheckFpVars(m.b, bNeedT0, bNeedT1);
459 case CM_FMT_TYPE_A_MOD_C_ADD_D:
460 sprintf(tempstr, "comb.%s = saturate(%s * %s + %s);\n", dst, func(m.a), func(m.c),func(m.d));
461 CheckFpVars(m.a, bNeedT0, bNeedT1);
462 CheckFpVars(m.c, bNeedT0, bNeedT1);
463 CheckFpVars(m.d, bNeedT0, bNeedT1);
465 case CM_FMT_TYPE_A_LERP_B_C:
466 //ARB ASM LERP and mix have different parameter ordering.
467 //sprintf(tempstr, "comb.%s = saturate(mix(%s, %s, %s));\n", dst,func(m.a),func(m.b), func(m.c));
468 sprintf(tempstr, "comb.%s = (%s - %s) * %s + %s;\n", dst,func(m.a),func(m.b), func(m.c),func(m.b));
469 CheckFpVars(m.a, bNeedT0, bNeedT1);
470 CheckFpVars(m.b, bNeedT0, bNeedT1);
471 CheckFpVars(m.c, bNeedT0, bNeedT1);
472 //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));
475 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));
476 CheckFpVars(m.a, bNeedT0, bNeedT1);
477 CheckFpVars(m.b, bNeedT0, bNeedT1);
478 CheckFpVars(m.c, bNeedT0, bNeedT1);
479 CheckFpVars(m.d, bNeedT0, bNeedT1);
483 strcat(newFPBody, tempstr);
489 strcat(oglNewFP, "#define NEED_TEX0\n");
491 strcat(oglNewFP, "#define NEED_TEX1\n");
492 if(gRDP.bFogEnableInBlender && gRSP.bFogEnabled && options.fogMethod > 0)
493 strcat(oglNewFP,"#define FOG");
494 strcat(oglNewFP, fragmentHeader);
495 strcat(oglNewFP, newFPBody);
496 strcat(oglNewFP, fragmentFooter);
500 int COGL_FragmentProgramCombiner::ParseDecodedMux()
502 if( !m_bFragmentProgramIsSupported )
503 return COGLColorCombiner4::ParseDecodedMux();
505 OGLShaderCombinerSaveType res;
508 if(vertexProgram == 9999)
510 vertexProgram = res.vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
511 glShaderSource(res.vertexShaderID, 1, &vertexShader,NULL);
513 glCompileShader(res.vertexShaderID);
518 res.vertexShaderID = vertexProgram;
522 //Create 2 shaders, with and without alphatest
523 GenerateProgramStr();
525 for(int alphaTest = 0;alphaTest < 2;alphaTest++)
527 res.fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
529 char* tmpShader = (char*)malloc(sizeof(char) * 4096);
530 strcpy(tmpShader,"#version " GLSL_VERSION "\n");
534 strcat(tmpShader,"#define ALPHA_TEST\n");
537 res.alphaTest = alphaTest == 1;
538 strcat(tmpShader,oglNewFP);
540 glShaderSource(res.fragmentShaderID, 1,(const char**) &tmpShader,NULL);
545 glCompileShader(res.fragmentShaderID);
547 glGetShaderiv(res.fragmentShaderID, GL_COMPILE_STATUS, &success);
552 glGetShaderInfoLog(res.fragmentShaderID, 1024, &nLength, Log);
553 printf("Error compiling shader!\n %s",oglNewFP);
557 res.programID = glCreateProgram();
558 glAttachShader(res.programID,res.vertexShaderID);
559 glAttachShader(res.programID,res.fragmentShaderID);
562 glBindAttribLocation(res.programID,VS_COLOR,"aColor");
564 glBindAttribLocation(res.programID,VS_TEXCOORD0,"aTexCoord0");
566 glBindAttribLocation(res.programID,VS_TEXCOORD1,"aTexCoord1");
568 glBindAttribLocation(res.programID,VS_POSITION,"aPosition");
571 glLinkProgram(res.programID);
574 glGetProgramiv(res.programID, GL_LINK_STATUS, &success);
579 glGetShaderInfoLog(res.fragmentShaderID, 1024, &nLength, Log);
580 printf("Error linking program!\n");
584 glUseProgram(res.programID);
587 //Bind texture samplers
588 GLint tex0 = glGetUniformLocation(res.programID,"uTex0");
589 GLint tex1 = glGetUniformLocation(res.programID,"uTex1");
597 res.PrimColorLocation = glGetUniformLocation(res.programID,"PrimColor");
599 res.EnvColorLocation = glGetUniformLocation(res.programID,"EnvColor");
601 res.PrimFracLocation = glGetUniformLocation(res.programID,"PrimFrac");
603 res.EnvFracLocation = glGetUniformLocation(res.programID,"EnvFrac");
605 res.AlphaRefLocation = glGetUniformLocation(res.programID,"AlphaRef");
607 res.FogColorLocation = glGetUniformLocation(res.programID,"FogColor");
609 res.FogMinMaxLocation = glGetUniformLocation(res.programID,"FogMinMax");
612 res.dwMux0 = m_pDecodedMux->m_dwMux0;
613 res.dwMux1 = m_pDecodedMux->m_dwMux1;
614 res.fogIsUsed = gRDP.bFogEnableInBlender && gRSP.bFogEnabled;
616 m_vCompiledShaders.push_back(res);
618 m_lastIndex = m_vCompiledShaders.size()-2;
623 void COGL_FragmentProgramCombiner::GenerateCombinerSetting(int index)
625 GLuint ID = m_vCompiledShaders[index].programID;
628 glEnableVertexAttribArray(VS_POSITION);
630 glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0]));
633 glEnableVertexAttribArray(VS_TEXCOORD0);
635 glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u));
638 glEnableVertexAttribArray(VS_TEXCOORD1);
640 glVertexAttribPointer(VS_TEXCOORD1,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[1].u));
643 glEnableVertexAttribArray(VS_COLOR);
645 glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
649 void COGL_FragmentProgramCombiner::GenerateCombinerSettingConstants(int index)
651 OGLShaderCombinerSaveType prog = m_vCompiledShaders[index];
653 glUseProgram(prog.programID);
655 if(prog.EnvColorLocation != -1)
657 pf = GetEnvColorfv();
658 glUniform4fv(prog.EnvColorLocation,1, pf);
662 if(prog.PrimColorLocation != -1)
664 pf = GetPrimitiveColorfv();
665 glUniform4fv(prog.PrimColorLocation,1, pf);
669 if(prog.EnvFracLocation != -1)
671 float frac = gRDP.LODFrac / 255.0f;
672 float tempf[4] = {frac,frac,frac,frac};
673 glUniform4fv(prog.EnvFracLocation,1, tempf);
677 if(prog.PrimFracLocation != -1)
679 float frac2 = gRDP.primLODFrac / 255.0f;
680 float tempf2[4] = {frac2,frac2,frac2,frac2};
681 glUniform4fv(prog.PrimFracLocation,1, tempf2);
685 //if(prog.FogColorLocation != -1 && prog.FogMinMaxLocation != -1)
687 // //Pass fog colour and distance, use 0 alpha if fog disabled
688 // glUniform4f(prog.FogColorLocation, gRDP.fvFogColor[0],gRDP.fvFogColor[1],gRDP.fvFogColor[2],
689 // gRSP.bFogEnabled ? gRDP.fvFogColor[0] : 0.0f);
690 // glUniform2f(prog.FogMinMaxLocation,gRSPfFogMin,gRSPfFogMax);
693 if(prog.AlphaRefLocation != -1)
694 glUniform1f(prog.AlphaRefLocation,m_AlphaRef);
698 void COGL_FragmentProgramCombiner::UpdateFog(bool bEnable)
700 if(m_lastIndex < 0 || m_lastIndex >= m_vCompiledShaders.size())
702 OGLShaderCombinerSaveType prog = m_vCompiledShaders[m_lastIndex];
705 // DebugMessage(M64MSG_INFO,"Fog Color %x Min %f Max %f",gRDP.fogColor,gRSPfFogMin,gRSPfFogMax);
707 if(prog.FogColorLocation != -1 && prog.FogMinMaxLocation != -1)
709 //Pass fog colour and distance, use 0 alpha if fog disabled
710 glUniform4f(prog.FogColorLocation, gRDP.fvFogColor[0],gRDP.fvFogColor[1],gRDP.fvFogColor[2],
711 bEnable ? gRDP.fvFogColor[0] : 0.0f);
712 //glUniform4f(prog.FogColorLocation, 1.0f,0.3f,0.3f,1.0f);
713 //OPENGL_CHECK_ERRORS;
714 glUniform2f(prog.FogMinMaxLocation,gRSPfFogMin,gRSPfFogMax);
719 int COGL_FragmentProgramCombiner::FindCompiledMux()
722 if( debuggerDropCombiners )
724 m_vCompiledShaders.clear();
725 //m_dwLastMux0 = m_dwLastMux1 = 0;
726 debuggerDropCombiners = false;
729 for( uint32 i=0; i<m_vCompiledShaders.size(); i++ )
731 if( m_vCompiledShaders[i].dwMux0 == m_pDecodedMux->m_dwMux0
732 && m_vCompiledShaders[i].dwMux1 == m_pDecodedMux->m_dwMux1
733 && m_vCompiledShaders[i].fogIsUsed == (gRDP.bFogEnableInBlender && gRSP.bFogEnabled)
734 && m_vCompiledShaders[i].alphaTest == m_AlphaRef > 0.0f)
743 //////////////////////////////////////////////////////////////////////////
744 void COGL_FragmentProgramCombiner::InitCombinerCycle12(void)
746 if( !m_bFragmentProgramIsSupported )
748 COGLColorCombiner4::InitCombinerCycle12();
753 if( debuggerDropCombiners )
755 UpdateCombiner(m_pDecodedMux->m_dwMux0,m_pDecodedMux->m_dwMux1);
756 m_vCompiledShaders.clear();
757 m_dwLastMux0 = m_dwLastMux1 = 0;
758 debuggerDropCombiners = false;
762 m_pOGLRender->EnableMultiTexture();
764 bool combinerIsChanged = false;
766 if( m_pDecodedMux->m_dwMux0 != m_dwLastMux0 || m_pDecodedMux->m_dwMux1 != m_dwLastMux1 || m_lastIndex < 0 )
768 combinerIsChanged = true;
769 m_lastIndex = FindCompiledMux();
770 if( m_lastIndex < 0 ) // Can not found
772 m_lastIndex = ParseDecodedMux();
775 m_dwLastMux0 = m_pDecodedMux->m_dwMux0;
776 m_dwLastMux1 = m_pDecodedMux->m_dwMux1;
780 GenerateCombinerSettingConstants(m_lastIndex);
781 if( m_bCycleChanged || combinerIsChanged || gRDP.texturesAreReloaded || gRDP.colorsAreReloaded )
783 if( m_bCycleChanged || combinerIsChanged )
785 GenerateCombinerSettingConstants(m_lastIndex);
786 GenerateCombinerSetting(m_lastIndex);
788 else if( gRDP.colorsAreReloaded )
790 GenerateCombinerSettingConstants(m_lastIndex);
793 m_pOGLRender->SetAllTexelRepeatFlag();
795 gRDP.colorsAreReloaded = false;
796 gRDP.texturesAreReloaded = false;
800 m_pOGLRender->SetAllTexelRepeatFlag();
805 void COGL_FragmentProgramCombiner::DisplaySimpleMuxString(void)
807 COGLColorCombiner::DisplaySimpleMuxString();
808 DecodedMuxForPixelShader &mux = *(DecodedMuxForPixelShader*)m_pDecodedMux;
810 GenerateProgramStr();
811 //sprintf(oglNewFP, oglFP,
812 // MuxToOC(mux.aRGB0), MuxToOC(mux.bRGB0), MuxToOC(mux.cRGB0), MuxToOC(mux.dRGB0),
813 // MuxToOA(mux.aA0), MuxToOA(mux.bA0), MuxToOA(mux.cA0), MuxToOA(mux.dA0),
814 // MuxToOC(mux.aRGB1), MuxToOC(mux.bRGB1), MuxToOC(mux.cRGB1), MuxToOC(mux.dRGB1),
815 // MuxToOA(mux.aA1), MuxToOA(mux.bA1), MuxToOA(mux.cA1), MuxToOA(mux.dA1)
818 TRACE0("OGL Fragment Program:");