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 "osal_opengl.h"
23 #include "OGLExtensions.h"
26 #include "OGLExtCombiner.h"
27 #include "OGLExtRender.h"
28 #include "OGLDecodedMux.h"
29 #include "OGLGraphicsContext.h"
30 #include "OGLTexture.h"
31 #include "DirectXDecodedMux.h"
33 #define GL_MODULATE_ADD_ATI 0x8744
34 #define GL_MODULATE_SUBTRACT_ATI 0x8746
36 //========================================================================
37 COGLColorCombiner4::COGLColorCombiner4(CRender *pRender)
38 :COGLColorCombiner(pRender), m_maxTexUnits(0), m_lastIndex(-1),
39 m_dwLastMux0(0), m_dwLastMux1(0)
41 m_bOGLExtCombinerSupported=false;
42 m_bSupportModAdd_ATI = false;
43 m_bSupportModSub_ATI = false;
45 m_pDecodedMux = new COGLExtDecodedMux;
48 COGLColorCombiner4v2::COGLColorCombiner4v2(CRender *pRender)
49 :COGLColorCombiner4(pRender)
52 m_pDecodedMux = new DecodedMuxForOGL14V2;
55 COGLColorCombiner2::COGLColorCombiner2(CRender *pRender)
56 :COGLColorCombiner4(pRender)
59 m_pDecodedMux = new CDirectXDecodedMux; // Use Mux for DirectX because we support only 1 texture for each stage
60 m_ppGeneralDecodedMux = &m_pDecodedMux;
63 //////////////////////////////////////////////////////////////////////////
64 bool COGLColorCombiner4::Initialize(void)
66 m_bOGLExtCombinerSupported = false;
67 m_bSupportModAdd_ATI = false;
68 m_bSupportModSub_ATI = false;
72 if( COGLColorCombiner::Initialize() )
74 m_bSupportMultiTexture = true;
75 COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
77 if( pcontext->IsExtensionSupported("GL_EXT_texture_env_combine") || pcontext->IsExtensionSupported("GL_ARB_texture_env_combine") )
79 m_bOGLExtCombinerSupported = true;
80 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB,&m_maxTexUnits);
82 if( m_maxTexUnits > 8 ) m_maxTexUnits = 8;
84 TRACE0("Starting Ogl 1.4 multitexture combiner" );
85 TRACE1("m_maxTexUnits = %d", m_maxTexUnits);
86 if( pcontext->IsExtensionSupported("ATI_texture_env_combine3") )
88 m_bSupportModAdd_ATI = true;
89 m_bSupportModSub_ATI = true;
94 DebugMessage(M64MSG_ERROR, "Your video card does not support OpenGL extension combiner, you can only use the basic OpenGL combiner functions");
96 m_supportedStages = m_maxTexUnits;
101 #elif SDL_VIDEO_OPENGL_ES2
106 bool COGLColorCombiner2::Initialize(void)
108 TRACE0("Starting Ogl 1.2/1.3 multitexture combiner" );
109 if( COGLColorCombiner4::Initialize() )
111 // For general combiner flags
112 m_dwGeneralMaxStages = m_supportedStages;
114 m_bTxtOpAdd = m_bSupportAdd;
115 m_bTxtOpSub = m_bSupportSubtract;
118 m_bTxtOpAddSmooth = true;
119 m_bTxtOpBlendCurAlpha = true;
120 m_bTxtOpBlendDifAlpha = true;
121 m_bTxtOpBlendFacAlpha = true;
122 m_bTxtOpBlendTxtAlpha = true;
123 m_bTxtOpMulAdd = m_bSupportModAdd_ATI;
132 //========================================================================
133 void COGLColorCombiner4::InitCombinerCycleFill(void)
135 for( int i=0; i<m_supportedStages; i++ )
137 pglActiveTexture(GL_TEXTURE0_ARB+i);
139 m_pOGLRender->EnableTexUnit(i,FALSE);
142 //pglActiveTexture(GL_TEXTURE0_ARB);
143 //m_pOGLRender->EnableTexUnit(0,FALSE);
144 //pglActiveTexture(GL_TEXTURE1_ARB);
145 //m_pOGLRender->EnableTexUnit(1,FALSE);
148 //////////////////////////////////////////////////////////////////////////
149 void COGLColorCombiner4::InitCombinerCycle12(void)
151 if( !m_bOGLExtCombinerSupported )
153 COGLColorCombiner::InitCombinerCycle12();
158 if( debuggerDropCombiners )
160 UpdateCombiner(m_pDecodedMux->m_dwMux0,m_pDecodedMux->m_dwMux1);
161 m_vCompiledSettings.clear();
162 m_dwLastMux0 = m_dwLastMux1 = 0;
163 debuggerDropCombiners = false;
167 m_pOGLRender->EnableMultiTexture();
169 bool combinerIsChanged = false;
171 if( m_pDecodedMux->m_dwMux0 != m_dwLastMux0 || m_pDecodedMux->m_dwMux1 != m_dwLastMux1 || m_lastIndex < 0 )
173 combinerIsChanged = true;
174 m_lastIndex = FindCompiledMux();
175 if( m_lastIndex < 0 ) // Can not found
177 m_lastIndex = ParseDecodedMux();
179 DisplaySimpleMuxString();
183 m_dwLastMux0 = m_pDecodedMux->m_dwMux0;
184 m_dwLastMux1 = m_pDecodedMux->m_dwMux1;
188 if( m_bCycleChanged || combinerIsChanged || gRDP.texturesAreReloaded || gRDP.colorsAreReloaded )
190 if( m_bCycleChanged || combinerIsChanged )
192 GenerateCombinerSettingConstants(m_lastIndex);
193 GenerateCombinerSetting(m_lastIndex);
195 else if( gRDP.colorsAreReloaded )
197 GenerateCombinerSettingConstants(m_lastIndex);
200 m_pOGLRender->SetAllTexelRepeatFlag();
202 gRDP.colorsAreReloaded = false;
203 gRDP.texturesAreReloaded = false;
207 m_pOGLRender->SetAllTexelRepeatFlag();
211 //////////////////////////////////////////////////////////////////////////
212 int COGLColorCombiner4::ParseDecodedMux()
214 #define nextUnit() {unitNo++;}
217 return ParseDecodedMux2Units();
219 OGLExtCombinerSaveType res;
220 for( int k=0; k<8; k++ )
221 res.units[k].tex = -1;
223 COGLDecodedMux &mux = *(COGLDecodedMux*)m_pDecodedMux;
226 for( int rgbalpha = 0; rgbalpha<2; rgbalpha++ )
228 unitNos[rgbalpha] = 0;
229 for( int cycle = 0; cycle<2; cycle++ )
231 int &unitNo = unitNos[rgbalpha];
232 OGLExtCombinerType &unit = res.units[unitNo];
233 OGLExt1CombType &comb = unit.Combs[rgbalpha];
234 CombinerFormatType type = m_pDecodedMux->splitType[cycle*2+rgbalpha];
235 N64CombinerType &m = m_pDecodedMux->m_n64Combiners[cycle*2+rgbalpha];
236 comb.arg0 = comb.arg1 = comb.arg2 = CM_IGNORE_BYTE;
240 case CM_FMT_TYPE_NOT_USED:
241 comb.arg0 = MUX_COMBINED;
242 unit.ops[rgbalpha] = GL_REPLACE;
245 case CM_FMT_TYPE_D: // = A
247 unit.ops[rgbalpha] = GL_REPLACE;
250 case CM_FMT_TYPE_A_ADD_D: // = A+D
253 unit.ops[rgbalpha] = GL_ADD;
256 case CM_FMT_TYPE_A_SUB_B: // = A-B
259 unit.ops[rgbalpha] = GL_SUBTRACT_ARB;
262 case CM_FMT_TYPE_A_MOD_C: // = A*C
265 unit.ops[rgbalpha] = GL_MODULATE;
268 case CM_FMT_TYPE_A_MOD_C_ADD_D: // = A*C+D
269 if( m_bSupportModAdd_ATI )
274 unit.ops[rgbalpha] = GL_MODULATE_ADD_ATI;
279 if( unitNo < m_maxTexUnits-1 )
283 unit.ops[rgbalpha] = GL_MODULATE;
285 res.units[unitNo].Combs[rgbalpha].arg0 = MUX_COMBINED;
286 res.units[unitNo].Combs[rgbalpha].arg1 = m.d;
287 res.units[unitNo].ops[rgbalpha] = GL_ADD;
295 unit.ops[rgbalpha] = GL_INTERPOLATE_ARB;
300 case CM_FMT_TYPE_A_LERP_B_C: // = (A-B)*C+B
304 unit.ops[rgbalpha] = GL_INTERPOLATE_ARB;
307 case CM_FMT_TYPE_A_SUB_B_ADD_D: // = A-B+D
308 if( unitNo < m_maxTexUnits-1 )
312 unit.ops[rgbalpha] = GL_SUBTRACT_ARB;
314 res.units[unitNo].Combs[rgbalpha].arg0 = MUX_COMBINED;
315 res.units[unitNo].Combs[rgbalpha].arg1 = m.d;
316 res.units[unitNo].ops[rgbalpha] = GL_ADD;
324 unit.ops[rgbalpha] = GL_INTERPOLATE_ARB;
328 case CM_FMT_TYPE_A_SUB_B_MOD_C: // = (A-B)*C
329 if( unitNo < m_maxTexUnits-1 )
333 unit.ops[rgbalpha] = GL_SUBTRACT_ARB;
335 res.units[unitNo].Combs[rgbalpha].arg0 = MUX_COMBINED;
336 res.units[unitNo].Combs[rgbalpha].arg1 = m.c;
337 res.units[unitNo].ops[rgbalpha] = GL_MODULATE;
345 unit.ops[rgbalpha] = GL_INTERPOLATE_ARB;
349 case CM_FMT_TYPE_A_B_C_D: // = (A-B)*C+D
351 if( unitNo < m_maxTexUnits-1 )
355 unit.ops[rgbalpha] = GL_SUBTRACT_ARB;
357 if( m_bSupportModAdd_ATI )
359 res.units[unitNo].Combs[rgbalpha].arg0 = MUX_COMBINED;
360 res.units[unitNo].Combs[rgbalpha].arg2 = m.c;
361 res.units[unitNo].Combs[rgbalpha].arg1 = m.d;
362 res.units[unitNo].ops[rgbalpha] = GL_MODULATE_ADD_ATI;
367 res.units[unitNo].Combs[rgbalpha].arg0 = m.a;
368 res.units[unitNo].Combs[rgbalpha].arg1 = m.b;
369 res.units[unitNo].Combs[rgbalpha].arg2 = m.c;
370 res.units[unitNo].ops[rgbalpha] = GL_INTERPOLATE_ARB;
379 unit.ops[rgbalpha] = GL_INTERPOLATE_ARB;
387 res.numOfUnits = min(m_maxTexUnits, max(unitNos[0],unitNos[1]));
389 if( unitNos[0]>m_maxTexUnits || unitNos[1]>m_maxTexUnits )
391 TRACE0("Unit overflows");
394 for( int j=0; j<2; j++ )
396 if( unitNos[j]<res.numOfUnits )
398 for( int i=unitNos[j]; i<res.numOfUnits; i++ )
400 res.units[i].Combs[j].arg0 = MUX_COMBINED;
401 res.units[i].ops[j] = GL_REPLACE;
406 res.units[0].tex = 0;
407 res.units[1].tex = 1;
409 res.primIsUsed = mux.isUsed(MUX_PRIM);
410 res.envIsUsed = mux.isUsed(MUX_ENV);
411 res.lodFracIsUsed = mux.isUsed(MUX_LODFRAC) || mux.isUsed(MUX_PRIMLODFRAC);
413 return SaveParsedResult(res);
415 #elif SDL_VIDEO_OPENGL_ES2
420 int COGLColorCombiner4::ParseDecodedMux2Units()
422 OGLExtCombinerSaveType res;
423 for( int k=0; k<8; k++ )
424 res.units[k].tex = -1;
428 for( int i=0; i<res.numOfUnits*2; i++ ) // Set combiner for each texture unit
430 // For each texture unit, set both RGB and Alpha channel
431 // Keep in mind that the m_pDecodeMux has been reformated and simplified very well
433 OGLExtCombinerType &unit = res.units[i/2];
434 OGLExt1CombType &comb = unit.Combs[i%2];
436 CombinerFormatType type = m_pDecodedMux->splitType[i];
437 N64CombinerType &m = m_pDecodedMux->m_n64Combiners[i];
439 comb.arg0 = comb.arg1 = comb.arg2 = MUX_0;
443 case CM_FMT_TYPE_NOT_USED:
444 comb.arg0 = MUX_COMBINED;
445 unit.ops[i%2] = GL_REPLACE;
447 case CM_FMT_TYPE_D: // = A
449 unit.ops[i%2] = GL_REPLACE;
452 case CM_FMT_TYPE_A_ADD_D: // = A+D
455 unit.ops[i%2] = GL_ADD;
457 case CM_FMT_TYPE_A_SUB_B: // = A-B
460 unit.ops[i%2] = GL_SUBTRACT_ARB;
462 case CM_FMT_TYPE_A_MOD_C: // = A*C
465 unit.ops[i%2] = GL_MODULATE;
467 case CM_FMT_TYPE_A_MOD_C_ADD_D: // = A*C+D
471 unit.ops[i%2] = GL_INTERPOLATE_ARB;
473 case CM_FMT_TYPE_A_LERP_B_C: // = (A-B)*C+B
477 unit.ops[i%2] = GL_INTERPOLATE_ARB;
479 case CM_FMT_TYPE_A_SUB_B_ADD_D: // = A-B+D
480 // fix me, to use 2 texture units
483 unit.ops[i%2] = GL_SUBTRACT_ARB;
485 case CM_FMT_TYPE_A_SUB_B_MOD_C: // = (A-B)*C
486 // fix me, to use 2 texture units
489 unit.ops[i%2] = GL_MODULATE;
492 case CM_FMT_TYPE_A_B_C_D: // = (A-B)*C+D
498 unit.ops[i%2] = GL_INTERPOLATE_ARB;
503 if( m_pDecodedMux->splitType[2] == CM_FMT_TYPE_NOT_USED && m_pDecodedMux->splitType[3] == CM_FMT_TYPE_NOT_USED && !m_bTex1Enabled )
508 res.units[0].tex = 0;
509 res.units[1].tex = 1;
511 return SaveParsedResult(res);
514 const char* COGLColorCombiner4::GetOpStr(GLenum op)
525 case GL_ADD_SIGNED_ARB:
527 case GL_INTERPOLATE_ARB:
528 return "INTERPOLATE";
529 case GL_SUBTRACT_ARB:
532 case GL_MODULATE_ADD_ATI:
539 int COGLColorCombiner4::SaveParsedResult(OGLExtCombinerSaveType &result)
541 result.dwMux0 = m_pDecodedMux->m_dwMux0;
542 result.dwMux1 = m_pDecodedMux->m_dwMux1;
544 for( int n=0; n<result.numOfUnits; n++ )
546 for( int i=0; i<3; i++ )
548 result.units[n].glRGBArgs[i] = 0;
549 result.units[n].glRGBFlags[i] = 0;
550 result.units[n].glAlphaArgs[i] = 0;
551 result.units[n].glAlphaFlags[i] = 0;
552 if( result.units[n].rgbComb.args[i] != CM_IGNORE_BYTE )
554 result.units[n].glRGBArgs[i] = MapRGBArgs(result.units[n].rgbComb.args[i]);
555 result.units[n].glRGBFlags[i] = MapRGBArgFlags(result.units[n].rgbComb.args[i]);
557 if( result.units[n].alphaComb.args[i] != CM_IGNORE_BYTE )
559 result.units[n].glAlphaArgs[i] = MapAlphaArgs(result.units[n].alphaComb.args[i]);
560 result.units[n].glAlphaFlags[i] = MapAlphaArgFlags(result.units[n].alphaComb.args[i]);
565 m_vCompiledSettings.push_back(result);
566 m_lastIndex = m_vCompiledSettings.size()-1;
571 DisplaySimpleMuxString();
578 bool isGLtex(GLint val)
580 if( val >= GL_TEXTURE0_ARB && val <= GL_TEXTURE7_ARB )
586 int COGLColorCombiner4v2::SaveParsedResult(OGLExtCombinerSaveType &result)
588 result.dwMux0 = m_pDecodedMux->m_dwMux0;
589 result.dwMux1 = m_pDecodedMux->m_dwMux1;
593 for( n=0; n<result.numOfUnits; n++ )
595 for( int i=0; i<3; i++ )
597 result.units[n].glRGBArgs[i] = 0;
598 result.units[n].glRGBFlags[i] = 0;
599 result.units[n].glAlphaArgs[i] = 0;
600 result.units[n].glAlphaFlags[i] = 0;
601 if( result.units[n].rgbComb.args[i] != CM_IGNORE_BYTE )
603 result.units[n].glRGBArgs[i] = MapRGBArgs(result.units[n].rgbComb.args[i]);
604 if( result.units[n].glRGBArgs[i] == GL_TEXTURE3_ARB && !result.envIsUsed )
605 result.units[n].glRGBArgs[i] = GL_TEXTURE2_ARB;
607 result.units[n].glRGBFlags[i] = MapRGBArgFlags(result.units[n].rgbComb.args[i]);
609 if( result.units[n].alphaComb.args[i] != CM_IGNORE_BYTE )
611 result.units[n].glAlphaArgs[i] = MapAlphaArgs(result.units[n].alphaComb.args[i]);
612 if( result.units[n].glAlphaArgs[i] == GL_TEXTURE3_ARB && !result.envIsUsed )
613 result.units[n].glAlphaArgs[i] = GL_TEXTURE2_ARB;
615 result.units[n].glAlphaFlags[i] = MapAlphaArgFlags(result.units[n].alphaComb.args[i]);
619 if( isGLtex(result.units[n].glRGBArgs[0]) && isGLtex(result.units[n].glRGBArgs[1]) && isGLtex(result.units[n].glRGBArgs[2]) )
621 result.units[n].glRGBArgs[2] = GL_CONSTANT_ARB;
623 if( isGLtex(result.units[n].glAlphaArgs[0]) && isGLtex(result.units[n].glAlphaArgs[1]) && isGLtex(result.units[n].glAlphaArgs[2]) )
625 result.units[n].glRGBArgs[2] = GL_CONSTANT_ARB;
630 if( result.envIsUsed ) extraUnit++;
631 if( result.lodFracIsUsed ) extraUnit++;
632 for( n=result.numOfUnits; n<result.numOfUnits+extraUnit; n++ )
634 for( int i=0; i<3; i++ )
636 result.units[n].rgbComb.args[i]=CM_IGNORE_BYTE;
637 result.units[n].alphaComb.args[i]=CM_IGNORE_BYTE;
638 result.units[n].glRGBArgs[i] = 0;
639 result.units[n].glRGBFlags[i] = 0;
640 result.units[n].glAlphaArgs[i] = 0;
641 result.units[n].glAlphaFlags[i] = 0;
644 result.units[n].rgbComb.args[0]=MUX_COMBINED;
645 result.units[n].alphaComb.args[0]=MUX_COMBINED;
646 result.units[n].rgbOp = GL_REPLACE;
647 result.units[n].alphaOp = GL_REPLACE;
648 result.units[n].glRGBArgs[0] = GL_PREVIOUS_ARB;
649 result.units[n].glRGBArgs[1] = GL_PREVIOUS_ARB;
650 result.units[n].rgbFlag0gl = GL_SRC_COLOR;
651 result.units[n].rgbFlag1gl = GL_SRC_COLOR;
652 result.units[n].glAlphaArgs[0] = GL_PREVIOUS_ARB;
653 result.units[n].glAlphaArgs[1] = GL_PREVIOUS_ARB;
654 result.units[n].alphaFlag0gl = GL_SRC_ALPHA;
655 result.units[n].alphaFlag1gl = GL_SRC_ALPHA;
658 result.numOfUnits += extraUnit;
660 m_vCompiledSettings.push_back(result);
661 m_lastIndex = m_vCompiledSettings.size()-1;
666 DisplaySimpleMuxString();
675 extern const char *translatedCombTypes[];
676 void COGLColorCombiner4::DisplaySimpleMuxString(void)
678 char buf0[30], buf1[30], buf2[30];
679 OGLExtCombinerSaveType &result = m_vCompiledSettings[m_lastIndex];
681 COGLColorCombiner::DisplaySimpleMuxString();
682 DebuggerAppendMsg("OpenGL 1.2: %d Stages", result.numOfUnits);
683 for( int i=0; i<result.numOfUnits; i++ )
685 DebuggerAppendMsg("//aRGB%d:\t%s: %s, %s, %s\n", i,GetOpStr(result.units[i].rgbOp), DecodedMux::FormatStr(result.units[i].rgbArg0,buf0), DecodedMux::FormatStr(result.units[i].rgbArg1,buf1), DecodedMux::FormatStr(result.units[i].rgbArg2,buf2));
686 DebuggerAppendMsg("//aAlpha%d:\t%s: %s, %s, %s\n", i,GetOpStr(result.units[i].alphaOp), DecodedMux::FormatStr(result.units[i].alphaArg0,buf0), DecodedMux::FormatStr(result.units[i].alphaArg1,buf1), DecodedMux::FormatStr(result.units[i].alphaArg2,buf2));
690 void COGLColorCombiner2::DisplaySimpleMuxString(void)
692 char buf0[30], buf1[30], buf2[30];
693 OGLExtCombinerSaveType &result = m_vCompiledSettings[m_lastIndex];
695 COGLColorCombiner::DisplaySimpleMuxString();
696 int generalCombinerIndex = CGeneralCombiner::FindCompiledMux();
697 if( generalCombinerIndex < 0 ) // Can not found
699 generalCombinerIndex = CGeneralCombiner::ParseDecodedMux();
701 DebuggerAppendMsg("Generated general combiners:");
702 GeneralCombinerInfo &generalRes = m_vCompiledCombinerStages[generalCombinerIndex];
703 General_DisplayBlendingStageInfo(generalRes);
705 DebuggerAppendMsg("OpenGL 1.2: %d Stages", result.numOfUnits);
706 for( int i=0; i<result.numOfUnits; i++ )
708 DebuggerAppendMsg("//aRGB%d:\t%s: %s, %s, %s\n", i,GetOpStr(result.units[i].rgbOp), DecodedMux::FormatStr(result.units[i].rgbArg0,buf0), DecodedMux::FormatStr(result.units[i].rgbArg1,buf1), DecodedMux::FormatStr(result.units[i].rgbArg2,buf2));
709 DebuggerAppendMsg("//aAlpha%d:\t%s: %s, %s, %s\n", i,GetOpStr(result.units[i].alphaOp), DecodedMux::FormatStr(result.units[i].alphaArg0,buf0), DecodedMux::FormatStr(result.units[i].alphaArg1,buf1), DecodedMux::FormatStr(result.units[i].alphaArg2,buf2));
716 //////////////////////////////////////////////////////////////////////////
717 int COGLColorCombiner4::FindCompiledMux()
720 if( debuggerDropCombiners )
722 m_vCompiledSettings.clear();
723 //m_dwLastMux0 = m_dwLastMux1 = 0;
724 debuggerDropCombiners = false;
727 for( uint32 i=0; i<m_vCompiledSettings.size(); i++ )
729 if( m_vCompiledSettings[i].dwMux0 == m_pDecodedMux->m_dwMux0 && m_vCompiledSettings[i].dwMux1 == m_pDecodedMux->m_dwMux1 )
736 //========================================================================
738 GLint COGLColorCombiner4::RGBArgsMap4[] =
741 GL_PRIMARY_COLOR_ARB, //MUX_0
742 GL_PRIMARY_COLOR_ARB, //MUX_1
743 GL_PREVIOUS_ARB, //MUX_COMBINED,
745 GL_TEXTURE0_ARB, //MUX_TEXEL0,
747 GL_TEXTURE1_ARB, //MUX_TEXEL1,
748 GL_CONSTANT_ARB, //MUX_PRIM,
749 GL_PRIMARY_COLOR_ARB, //MUX_SHADE,
750 GL_CONSTANT_ARB, //MUX_ENV,
751 GL_PREVIOUS_ARB, //MUX_COMBALPHA,
753 GL_TEXTURE0_ARB, //MUX_T0_ALPHA,
755 GL_TEXTURE1_ARB, //MUX_T1_ALPHA,
756 GL_CONSTANT_ARB, //MUX_PRIM_ALPHA,
757 GL_PRIMARY_COLOR_ARB, //MUX_SHADE_ALPHA,
758 GL_CONSTANT_ARB, //MUX_ENV_ALPHA,
759 GL_CONSTANT_ARB, //MUX_LODFRAC,
760 GL_CONSTANT_ARB, //MUX_PRIMLODFRAC,
761 GL_PRIMARY_COLOR_ARB, //MUX_K5
762 GL_PRIMARY_COLOR_ARB //MUX_UNK
766 GLint COGLColorCombiner4v2::RGBArgsMap4v2[] =
769 GL_PRIMARY_COLOR_ARB, //MUX_0
770 GL_PRIMARY_COLOR_ARB, //MUX_1
771 GL_PREVIOUS_ARB, //MUX_COMBINED,
773 GL_TEXTURE0_ARB, //MUX_TEXEL0,
775 GL_TEXTURE1_ARB, //MUX_TEXEL1,
776 GL_CONSTANT_ARB, //MUX_PRIM,
777 GL_PRIMARY_COLOR_ARB, //MUX_SHADE,
778 GL_TEXTURE2_ARB, //MUX_ENV,
779 //{GL_TEXTURE1_ARB, }, //MUX_ENV,
780 GL_PREVIOUS_ARB, //MUX_COMBALPHA,
781 GL_TEXTURE0_ARB, //MUX_T0_ALPHA,
782 GL_TEXTURE1_ARB, //MUX_T1_ALPHA,
783 GL_CONSTANT_ARB, //MUX_PRIM_ALPHA,
784 GL_PRIMARY_COLOR_ARB, //MUX_SHADE_ALPHA,
785 GL_TEXTURE2_ARB, //MUX_ENV_ALPHA,
786 //{GL_TEXTURE1_ARB, }, //MUX_ENV_ALPHA,
787 //{GL_TEXTURE3_ARB, }, //MUX_LODFRAC,
788 //{GL_TEXTURE3_ARB, }, //MUX_PRIMLODFRAC,
789 GL_TEXTURE1_ARB, //MUX_LODFRAC,
790 GL_TEXTURE1_ARB, //MUX_PRIMLODFRAC,
791 GL_PRIMARY_COLOR_ARB, //MUX_K5
792 GL_PRIMARY_COLOR_ARB //MUX_UNK
796 GLint COGLColorCombiner2::RGBArgsMap2[] =
799 GL_PRIMARY_COLOR_ARB, //MUX_0
800 GL_PRIMARY_COLOR_ARB, //MUX_1
801 GL_PREVIOUS_ARB, //MUX_COMBINED,
802 //{GL_TEXTURE, }, //MUX_TEXEL0,
803 //{GL_TEXTURE, }, //MUX_TEXEL1,
805 GL_TEXTURE0_ARB, //MUX_TEXEL0,
807 GL_TEXTURE1_ARB, //MUX_TEXEL1,
808 GL_CONSTANT_ARB, //MUX_PRIM,
809 GL_PRIMARY_COLOR_ARB, //MUX_SHADE,
810 GL_CONSTANT_ARB, //MUX_ENV,
811 GL_PREVIOUS_ARB, //MUX_COMBALPHA,
812 //{GL_TEXTURE, }, //MUX_T0_ALPHA,
813 //{GL_TEXTURE, }, //MUX_T1_ALPHA,
814 GL_TEXTURE0_ARB, //MUX_TEXEL0,
815 GL_TEXTURE1_ARB, //MUX_TEXEL1,
816 GL_CONSTANT_ARB, //MUX_PRIM_ALPHA,
817 GL_PRIMARY_COLOR_ARB, //MUX_SHADE_ALPHA,
818 GL_CONSTANT_ARB, //MUX_ENV_ALPHA,
819 GL_CONSTANT_ARB, //MUX_LODFRAC,
820 GL_CONSTANT_ARB, //MUX_PRIMLODFRAC,
821 GL_PRIMARY_COLOR_ARB, //MUX_K5
822 GL_PRIMARY_COLOR_ARB //MUX_UNK
826 //========================================================================
828 GLint COGLColorCombiner4::MapRGBArgs(uint8 arg)
830 return RGBArgsMap4[arg&MUX_MASK];
833 GLint COGLColorCombiner4v2::MapRGBArgs(uint8 arg)
835 return RGBArgsMap4v2[arg&MUX_MASK];
838 GLint COGLColorCombiner2::MapRGBArgs(uint8 arg)
840 return RGBArgsMap2[arg&MUX_MASK];
843 GLint COGLColorCombiner4::MapRGBArgFlags(uint8 arg)
845 if( (arg & MUX_ALPHAREPLICATE) && (arg & MUX_COMPLEMENT) )
847 return GL_ONE_MINUS_SRC_ALPHA;
849 else if( (arg & MUX_ALPHAREPLICATE) )
853 else if(arg & MUX_COMPLEMENT)
855 return GL_ONE_MINUS_SRC_COLOR;
861 GLint COGLColorCombiner4::MapAlphaArgs(uint8 arg)
863 return RGBArgsMap4[arg&MUX_MASK];
866 GLint COGLColorCombiner4v2::MapAlphaArgs(uint8 arg)
868 return RGBArgsMap4v2[arg&MUX_MASK];
871 GLint COGLColorCombiner2::MapAlphaArgs(uint8 arg)
873 return RGBArgsMap2[arg&MUX_MASK];
876 GLint COGLColorCombiner4::MapAlphaArgFlags(uint8 arg)
878 if(arg & MUX_COMPLEMENT)
880 return GL_ONE_MINUS_SRC_ALPHA;
886 //========================================================================
888 void ApplyFor1Unit(OGLExtCombinerType &unit)
891 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, unit.rgbOp);
894 if( unit.rgbArg0 != CM_IGNORE_BYTE )
896 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, (unit.rgbArg0gl));
898 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, (unit.rgbFlag0gl));
902 if( unit.rgbArg1 != CM_IGNORE_BYTE )
904 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, (unit.rgbArg1gl));
906 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, (unit.rgbFlag1gl));
910 if( unit.rgbArg2 != CM_IGNORE_BYTE )
912 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, (unit.rgbArg2gl));
914 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, (unit.rgbFlag2gl));
918 if( unit.alphaArg0 != CM_IGNORE_BYTE )
920 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, (unit.alphaArg0gl));
922 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, (unit.alphaFlag0gl));
926 if( unit.alphaArg1 != CM_IGNORE_BYTE )
928 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, (unit.alphaArg1gl));
930 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, (unit.alphaFlag1gl));
934 if( unit.alphaArg2 != CM_IGNORE_BYTE )
936 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, (unit.alphaArg2gl));
938 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, (unit.alphaFlag2gl));
944 //////////////////////////////////////////////////////////////////////////
946 void COGLColorCombiner4::GenerateCombinerSetting(int index)
948 OGLExtCombinerSaveType &res = m_vCompiledSettings[index];
951 COGLTexture* pTexture = NULL;
952 COGLTexture* pTexture1 = NULL;
954 if( m_bTex0Enabled || m_bTex1Enabled || gRDP.otherMode.cycle_type == CYCLE_TYPE_COPY )
956 if( m_bTex0Enabled || gRDP.otherMode.cycle_type == CYCLE_TYPE_COPY )
958 pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
959 if( pTexture ) m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0);
963 pTexture1 = g_textures[(gRSP.curTile+1)&7].m_pCOGLTexture;
964 if( pTexture1 ) m_pOGLRender->BindTexture(pTexture1->m_dwTextureName, 1);
970 for( int i=0; i<res.numOfUnits; i++ )
972 pglActiveTexture(GL_TEXTURE0_ARB+i);
974 m_pOGLRender->EnableTexUnit(i,TRUE);
975 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
977 ApplyFor1Unit(res.units[i]);
980 if( res.numOfUnits < m_maxTexUnits )
982 for( int i=res.numOfUnits; i<m_maxTexUnits; i++ )
984 pglActiveTexture(GL_TEXTURE0_ARB+i);
986 m_pOGLRender->DisBindTexture(0, i);
987 m_pOGLRender->EnableTexUnit(i,FALSE);
993 void COGLColorCombiner4::GenerateCombinerSettingConstants(int index)
995 OGLExtCombinerSaveType &res = m_vCompiledSettings[index];
1002 if( res.primIsUsed )
1004 fv = GetPrimitiveColorfv(); // CONSTANT COLOR
1006 else if( res.envIsUsed )
1008 fv = GetEnvColorfv(); // CONSTANT COLOR
1010 else if( res.lodFracIsUsed )
1012 float frac = gRDP.LODFrac / 255.0f;
1013 tempf[0] = tempf[1] = tempf[2] = tempf[3] = frac;
1023 for( int i=0; i<res.numOfUnits; i++ )
1025 pglActiveTexture(GL_TEXTURE0_ARB+i);
1026 OPENGL_CHECK_ERRORS;
1027 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,fv);
1028 OPENGL_CHECK_ERRORS;
1034 void COGLColorCombiner4v2::GenerateCombinerSettingConstants(int index)
1036 //COGLColorCombiner4::GenerateCombinerSettingConstants(index);
1039 OGLExtCombinerSaveType &res = m_vCompiledSettings[index];
1040 COGLExtRender *prender = (COGLExtRender *)m_pRender;
1042 if( res.primIsUsed )
1044 float *fv = GetPrimitiveColorfv(); // CONSTANT COLOR
1045 for( int i=0; i<res.numOfUnits; i++ )
1047 pglActiveTexture(GL_TEXTURE0_ARB+i);
1048 OPENGL_CHECK_ERRORS;
1049 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,fv);
1050 OPENGL_CHECK_ERRORS;
1056 // Set Texture unit 2 to ENV
1057 pglActiveTexture(GL_TEXTURE2_ARB);
1058 OPENGL_CHECK_ERRORS;
1059 prender->EnableTexUnit(2,TRUE);
1060 TxtrCacheEntry *pEntry = gTextureManager.GetConstantColorTexture(MUX_ENV);
1061 prender->SetCurrentTexture( (gRSP.curTile+2)%7, pEntry->pTexture, 4, 4, pEntry);
1062 prender->SetTexelRepeatFlags((gRSP.curTile+2)%7);
1065 if( res.lodFracIsUsed)
1068 if( !res.envIsUsed )
1071 // Set Texture unit 3 to LODFRAC
1072 pglActiveTexture(GL_TEXTURE0_ARB+unit);
1073 OPENGL_CHECK_ERRORS;
1074 prender->EnableTexUnit(unit,TRUE);
1075 TxtrCacheEntry *pEntry = gTextureManager.GetConstantColorTexture(MUX_LODFRAC);
1076 prender->SetCurrentTexture( (gRSP.curTile+unit)%7, pEntry->pTexture, 4, 4, pEntry);
1077 prender->SetTexelRepeatFlags((gRSP.curTile+unit)%7);
1082 if( !res.envIsUsed )
1085 // Disable texture unit 3
1086 pglActiveTexture(GL_TEXTURE0_ARB+unit);
1087 OPENGL_CHECK_ERRORS;
1088 prender->EnableTexUnit(unit,FALSE);
1089 prender->SetTextureToTextureUnitMap(-1,unit);
1094 GLenum GeneralToGLMaps[]=
1096 GL_REPLACE, //CM_REPLACE,
1097 #if SDL_VIDEO_OPENGL
1098 GL_MODULATE, //CM_MODULATE,
1100 GL_SUBTRACT_ARB, //CM_SUBTRACT,
1101 GL_INTERPOLATE_ARB, //CM_INTERPOLATE,
1102 GL_INTERPOLATE_ARB, //CM_ADDSMOOTH,
1103 GL_INTERPOLATE_ARB, //CM_BLENDCURRENTALPHA
1104 GL_INTERPOLATE_ARB, //CM_BLENDDIFFUSEALPHA
1105 GL_INTERPOLATE_ARB, //CM_BLENDFACTORALPHA,
1106 GL_INTERPOLATE_ARB, //CM_BLENDTEXTUREALPHA
1108 GL_MODULATE_ADD_ATI, //CM_MULTIPLYADD,
1112 //////////////////////////////////////////////////////////////////////////
1113 int COGLColorCombiner2::ParseDecodedMux()
1115 //return COGLColorCombiner4::ParseDecodedMux();
1117 int generalCombinerIndex = CGeneralCombiner::FindCompiledMux();
1118 if( generalCombinerIndex < 0 ) // Can not found
1120 generalCombinerIndex = CGeneralCombiner::ParseDecodedMux();
1123 GeneralCombinerInfo &generalRes = m_vCompiledCombinerStages[generalCombinerIndex];
1124 OGLExtCombinerSaveType res;
1126 // Convert generalRes to OGLExtCombinerSaveType
1127 for( int unitNo=0; unitNo<generalRes.nStages; unitNo++ )
1129 OGLExtCombinerType &unit = res.units[unitNo];
1130 //OGLExt1CombType &colorComb = unit.Combs[0];
1131 //OGLExt1CombType &alphaComb = unit.Combs[1];
1133 unit.rgbArg0 = (uint8)generalRes.stages[unitNo].colorOp.Arg1;
1134 unit.rgbArg1 = (uint8)generalRes.stages[unitNo].colorOp.Arg2;
1135 unit.rgbArg2 = (uint8)generalRes.stages[unitNo].colorOp.Arg0;
1136 unit.alphaArg0 = (uint8)generalRes.stages[unitNo].alphaOp.Arg1;
1137 unit.alphaArg1 = (uint8)generalRes.stages[unitNo].alphaOp.Arg2;
1138 unit.alphaArg2 = (uint8)generalRes.stages[unitNo].alphaOp.Arg0;
1140 unit.rgbOp = GeneralToGLMaps[generalRes.stages[unitNo].colorOp.op];
1141 if( unit.rgbOp == GL_MODULATE_ADD_ATI && !m_bTxtOpMulAdd )
1143 if( (unit.rgbArg0&MUX_MASK) == (unit.rgbArg2&MUX_MASK) && (unit.rgbArg0&MUX_COMPLEMENT) )
1145 unit.rgbOp = GL_ADD;
1146 unit.rgbArg0 &= ~MUX_COMPLEMENT;
1150 unit.rgbOp = GL_MODULATE;
1153 unit.alphaOp = GeneralToGLMaps[generalRes.stages[unitNo].alphaOp.op];
1154 if( unit.alphaOp == GL_MODULATE_ADD_ATI && !m_bTxtOpMulAdd )
1156 if( (unit.alphaArg0&MUX_MASK) == (unit.alphaArg2&MUX_MASK) && (unit.alphaArg0&MUX_COMPLEMENT) )
1158 unit.alphaOp = GL_ADD;
1159 unit.alphaArg0 &= ~MUX_COMPLEMENT;
1163 unit.alphaOp = GL_MODULATE;
1167 unit.tex = generalRes.stages[unitNo].dwTexture;
1168 unit.textureIsUsed = generalRes.stages[unitNo].bTextureUsed;
1171 res.numOfUnits = generalRes.nStages;
1172 res.constantColor = generalRes.TFactor;
1173 return SaveParsedResult(res);
1177 void COGLColorCombiner2::GenerateCombinerSettingConstants(int index)
1179 OGLExtCombinerSaveType &res = m_vCompiledSettings[index];
1186 if( res.primIsUsed )
1188 fv = GetPrimitiveColorfv(); // CONSTANT COLOR
1190 else if( res.envIsUsed )
1192 fv = GetEnvColorfv(); // CONSTANT COLOR
1194 else if( res.lodFracIsUsed )
1196 float frac = gRDP.LODFrac / 255.0f;
1197 tempf[0] = tempf[1] = tempf[2] = tempf[3] = frac;
1207 for( int i=0; i<res.numOfUnits; i++ )
1209 pglActiveTextureARB(GL_TEXTURE0_ARB+i);
1210 OPENGL_CHECK_ERRORS;
1211 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,fv);
1212 OPENGL_CHECK_ERRORS;
1216 void COGLColorCombiner2::GenerateCombinerSetting(int index)
1218 OGLExtCombinerSaveType &res = m_vCompiledSettings[index];
1219 COGLExtRender *prender = (COGLExtRender *)m_pRender;
1221 for( int i=0; i<res.numOfUnits; i++ )
1223 pglActiveTextureARB(GL_TEXTURE0_ARB+i);
1224 OPENGL_CHECK_ERRORS;
1225 //if(res.units[i].textureIsUsed)
1227 prender->SetTextureToTextureUnitMap(res.units[i].tex,i);
1228 m_pOGLRender->EnableTexUnit(i,TRUE);
1229 COGLTexture* pTexture = g_textures[(gRSP.curTile+res.units[i].tex)&7].m_pCOGLTexture;
1230 if( pTexture ) m_pOGLRender->BindTexture(pTexture->m_dwTextureName, i);
1235 m_pOGLRender->EnableTexUnit(i,TRUE);
1236 prender->SetTextureToTextureUnitMap(-1,i);
1237 //m_pOGLRender->EnableTexUnit(i,FALSE);
1238 //m_pOGLRender->DisBindTexture(0, i);
1242 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
1243 OPENGL_CHECK_ERRORS;
1244 ApplyFor1Unit(res.units[i]);
1247 if( res.numOfUnits < m_maxTexUnits )
1249 for( int i=res.numOfUnits; i<m_maxTexUnits; i++ )
1251 pglActiveTextureARB(GL_TEXTURE0_ARB+i);
1252 OPENGL_CHECK_ERRORS;
1253 m_pOGLRender->EnableTexUnit(i,FALSE);
1254 prender->SetTextureToTextureUnitMap(-1,i);