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") )
80 m_bOGLExtCombinerSupported = true;
81 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB,&m_maxTexUnits);
83 if( m_maxTexUnits > 8 ) m_maxTexUnits = 8;
85 TRACE0("Starting Ogl 1.4 multitexture combiner" );
86 TRACE1("m_maxTexUnits = %d", m_maxTexUnits);
88 if( pcontext->IsExtensionSupported("ATI_texture_env_combine3") )
90 m_bSupportModAdd_ATI = true;
91 m_bSupportModSub_ATI = true;
98 DebugMessage(M64MSG_ERROR, "Your video card does not support OpenGL extension combiner, you can only use the basic OpenGL combiner functions");
101 m_supportedStages = m_maxTexUnits;
106 #elif SDL_VIDEO_OPENGL_ES2
111 bool COGLColorCombiner2::Initialize(void)
113 TRACE0("Starting Ogl 1.2/1.3 multitexture combiner" );
114 if( COGLColorCombiner4::Initialize() )
116 // For general combiner flags
117 m_dwGeneralMaxStages = m_supportedStages;
119 m_bTxtOpAdd = m_bSupportAdd;
120 m_bTxtOpSub = m_bSupportSubtract;
123 m_bTxtOpAddSmooth = true;
124 m_bTxtOpBlendCurAlpha = true;
125 m_bTxtOpBlendDifAlpha = true;
126 m_bTxtOpBlendFacAlpha = true;
127 m_bTxtOpBlendTxtAlpha = true;
128 m_bTxtOpMulAdd = m_bSupportModAdd_ATI;
137 //========================================================================
138 void COGLColorCombiner4::InitCombinerCycleFill(void)
140 for( int i=0; i<m_supportedStages; i++ )
142 pglActiveTexture(GL_TEXTURE0_ARB+i);
144 m_pOGLRender->EnableTexUnit(i,FALSE);
147 //pglActiveTexture(GL_TEXTURE0_ARB);
148 //m_pOGLRender->EnableTexUnit(0,FALSE);
149 //pglActiveTexture(GL_TEXTURE1_ARB);
150 //m_pOGLRender->EnableTexUnit(1,FALSE);
153 //////////////////////////////////////////////////////////////////////////
154 void COGLColorCombiner4::InitCombinerCycle12(void)
156 if( !m_bOGLExtCombinerSupported )
158 COGLColorCombiner::InitCombinerCycle12();
163 if( debuggerDropCombiners )
165 UpdateCombiner(m_pDecodedMux->m_dwMux0,m_pDecodedMux->m_dwMux1);
166 m_vCompiledSettings.clear();
167 m_dwLastMux0 = m_dwLastMux1 = 0;
168 debuggerDropCombiners = false;
172 m_pOGLRender->EnableMultiTexture();
174 bool combinerIsChanged = false;
176 if( m_pDecodedMux->m_dwMux0 != m_dwLastMux0 || m_pDecodedMux->m_dwMux1 != m_dwLastMux1 || m_lastIndex < 0 )
178 combinerIsChanged = true;
179 m_lastIndex = FindCompiledMux();
180 if( m_lastIndex < 0 ) // Can not found
182 m_lastIndex = ParseDecodedMux();
184 DisplaySimpleMuxString();
188 m_dwLastMux0 = m_pDecodedMux->m_dwMux0;
189 m_dwLastMux1 = m_pDecodedMux->m_dwMux1;
193 if( m_bCycleChanged || combinerIsChanged || gRDP.texturesAreReloaded || gRDP.colorsAreReloaded )
195 if( m_bCycleChanged || combinerIsChanged )
197 GenerateCombinerSettingConstants(m_lastIndex);
198 GenerateCombinerSetting(m_lastIndex);
200 else if( gRDP.colorsAreReloaded )
202 GenerateCombinerSettingConstants(m_lastIndex);
205 m_pOGLRender->SetAllTexelRepeatFlag();
207 gRDP.colorsAreReloaded = false;
208 gRDP.texturesAreReloaded = false;
212 m_pOGLRender->SetAllTexelRepeatFlag();
216 //////////////////////////////////////////////////////////////////////////
217 int COGLColorCombiner4::ParseDecodedMux()
219 #define nextUnit() {unitNo++;}
222 return ParseDecodedMux2Units();
224 OGLExtCombinerSaveType res;
225 for( int k=0; k<8; k++ )
226 res.units[k].tex = -1;
228 COGLDecodedMux &mux = *(COGLDecodedMux*)m_pDecodedMux;
231 for( int rgbalpha = 0; rgbalpha<2; rgbalpha++ )
233 unitNos[rgbalpha] = 0;
234 for( int cycle = 0; cycle<2; cycle++ )
236 int &unitNo = unitNos[rgbalpha];
237 OGLExtCombinerType &unit = res.units[unitNo];
238 OGLExt1CombType &comb = unit.Combs[rgbalpha];
239 CombinerFormatType type = m_pDecodedMux->splitType[cycle*2+rgbalpha];
240 N64CombinerType &m = m_pDecodedMux->m_n64Combiners[cycle*2+rgbalpha];
241 comb.arg0 = comb.arg1 = comb.arg2 = CM_IGNORE_BYTE;
245 case CM_FMT_TYPE_NOT_USED:
246 comb.arg0 = MUX_COMBINED;
247 unit.ops[rgbalpha] = GL_REPLACE;
250 case CM_FMT_TYPE_D: // = A
252 unit.ops[rgbalpha] = GL_REPLACE;
255 case CM_FMT_TYPE_A_ADD_D: // = A+D
258 unit.ops[rgbalpha] = GL_ADD;
261 case CM_FMT_TYPE_A_SUB_B: // = A-B
264 unit.ops[rgbalpha] = GL_SUBTRACT_ARB;
267 case CM_FMT_TYPE_A_MOD_C: // = A*C
270 unit.ops[rgbalpha] = GL_MODULATE;
273 case CM_FMT_TYPE_A_MOD_C_ADD_D: // = A*C+D
274 if( m_bSupportModAdd_ATI )
279 unit.ops[rgbalpha] = GL_MODULATE_ADD_ATI;
284 if( unitNo < m_maxTexUnits-1 )
288 unit.ops[rgbalpha] = GL_MODULATE;
290 res.units[unitNo].Combs[rgbalpha].arg0 = MUX_COMBINED;
291 res.units[unitNo].Combs[rgbalpha].arg1 = m.d;
292 res.units[unitNo].ops[rgbalpha] = GL_ADD;
300 unit.ops[rgbalpha] = GL_INTERPOLATE_ARB;
305 case CM_FMT_TYPE_A_LERP_B_C: // = (A-B)*C+B
309 unit.ops[rgbalpha] = GL_INTERPOLATE_ARB;
312 case CM_FMT_TYPE_A_SUB_B_ADD_D: // = A-B+D
313 if( unitNo < m_maxTexUnits-1 )
317 unit.ops[rgbalpha] = GL_SUBTRACT_ARB;
319 res.units[unitNo].Combs[rgbalpha].arg0 = MUX_COMBINED;
320 res.units[unitNo].Combs[rgbalpha].arg1 = m.d;
321 res.units[unitNo].ops[rgbalpha] = GL_ADD;
329 unit.ops[rgbalpha] = GL_INTERPOLATE_ARB;
333 case CM_FMT_TYPE_A_SUB_B_MOD_C: // = (A-B)*C
334 if( unitNo < m_maxTexUnits-1 )
338 unit.ops[rgbalpha] = GL_SUBTRACT_ARB;
340 res.units[unitNo].Combs[rgbalpha].arg0 = MUX_COMBINED;
341 res.units[unitNo].Combs[rgbalpha].arg1 = m.c;
342 res.units[unitNo].ops[rgbalpha] = GL_MODULATE;
350 unit.ops[rgbalpha] = GL_INTERPOLATE_ARB;
354 case CM_FMT_TYPE_A_B_C_D: // = (A-B)*C+D
356 if( unitNo < m_maxTexUnits-1 )
360 unit.ops[rgbalpha] = GL_SUBTRACT_ARB;
362 if( m_bSupportModAdd_ATI )
364 res.units[unitNo].Combs[rgbalpha].arg0 = MUX_COMBINED;
365 res.units[unitNo].Combs[rgbalpha].arg2 = m.c;
366 res.units[unitNo].Combs[rgbalpha].arg1 = m.d;
367 res.units[unitNo].ops[rgbalpha] = GL_MODULATE_ADD_ATI;
372 res.units[unitNo].Combs[rgbalpha].arg0 = m.a;
373 res.units[unitNo].Combs[rgbalpha].arg1 = m.b;
374 res.units[unitNo].Combs[rgbalpha].arg2 = m.c;
375 res.units[unitNo].ops[rgbalpha] = GL_INTERPOLATE_ARB;
384 unit.ops[rgbalpha] = GL_INTERPOLATE_ARB;
392 res.numOfUnits = min(m_maxTexUnits, max(unitNos[0],unitNos[1]));
394 if( unitNos[0]>m_maxTexUnits || unitNos[1]>m_maxTexUnits )
396 TRACE0("Unit overflows");
399 for( int j=0; j<2; j++ )
401 if( unitNos[j]<res.numOfUnits )
403 for( int i=unitNos[j]; i<res.numOfUnits; i++ )
405 res.units[i].Combs[j].arg0 = MUX_COMBINED;
406 res.units[i].ops[j] = GL_REPLACE;
411 res.units[0].tex = 0;
412 res.units[1].tex = 1;
414 res.primIsUsed = mux.isUsed(MUX_PRIM);
415 res.envIsUsed = mux.isUsed(MUX_ENV);
416 res.lodFracIsUsed = mux.isUsed(MUX_LODFRAC) || mux.isUsed(MUX_PRIMLODFRAC);
418 return SaveParsedResult(res);
420 #elif SDL_VIDEO_OPENGL_ES2
425 int COGLColorCombiner4::ParseDecodedMux2Units()
427 OGLExtCombinerSaveType res;
428 for( int k=0; k<8; k++ )
429 res.units[k].tex = -1;
433 for( int i=0; i<res.numOfUnits*2; i++ ) // Set combiner for each texture unit
435 // For each texture unit, set both RGB and Alpha channel
436 // Keep in mind that the m_pDecodeMux has been reformated and simplified very well
438 OGLExtCombinerType &unit = res.units[i/2];
439 OGLExt1CombType &comb = unit.Combs[i%2];
441 CombinerFormatType type = m_pDecodedMux->splitType[i];
442 N64CombinerType &m = m_pDecodedMux->m_n64Combiners[i];
444 comb.arg0 = comb.arg1 = comb.arg2 = MUX_0;
448 case CM_FMT_TYPE_NOT_USED:
449 comb.arg0 = MUX_COMBINED;
450 unit.ops[i%2] = GL_REPLACE;
452 case CM_FMT_TYPE_D: // = A
454 unit.ops[i%2] = GL_REPLACE;
457 case CM_FMT_TYPE_A_ADD_D: // = A+D
460 unit.ops[i%2] = GL_ADD;
462 case CM_FMT_TYPE_A_SUB_B: // = A-B
465 unit.ops[i%2] = GL_SUBTRACT_ARB;
467 case CM_FMT_TYPE_A_MOD_C: // = A*C
470 unit.ops[i%2] = GL_MODULATE;
472 case CM_FMT_TYPE_A_MOD_C_ADD_D: // = A*C+D
476 unit.ops[i%2] = GL_INTERPOLATE_ARB;
478 case CM_FMT_TYPE_A_LERP_B_C: // = (A-B)*C+B
482 unit.ops[i%2] = GL_INTERPOLATE_ARB;
484 case CM_FMT_TYPE_A_SUB_B_ADD_D: // = A-B+D
485 // fix me, to use 2 texture units
488 unit.ops[i%2] = GL_SUBTRACT_ARB;
490 case CM_FMT_TYPE_A_SUB_B_MOD_C: // = (A-B)*C
491 // fix me, to use 2 texture units
494 unit.ops[i%2] = GL_MODULATE;
497 case CM_FMT_TYPE_A_B_C_D: // = (A-B)*C+D
503 unit.ops[i%2] = GL_INTERPOLATE_ARB;
508 if( m_pDecodedMux->splitType[2] == CM_FMT_TYPE_NOT_USED && m_pDecodedMux->splitType[3] == CM_FMT_TYPE_NOT_USED && !m_bTex1Enabled )
513 res.units[0].tex = 0;
514 res.units[1].tex = 1;
516 return SaveParsedResult(res);
519 const char* COGLColorCombiner4::GetOpStr(GLenum op)
530 case GL_ADD_SIGNED_ARB:
532 case GL_INTERPOLATE_ARB:
533 return "INTERPOLATE";
534 case GL_SUBTRACT_ARB:
537 case GL_MODULATE_ADD_ATI:
544 int COGLColorCombiner4::SaveParsedResult(OGLExtCombinerSaveType &result)
546 result.dwMux0 = m_pDecodedMux->m_dwMux0;
547 result.dwMux1 = m_pDecodedMux->m_dwMux1;
549 for( int n=0; n<result.numOfUnits; n++ )
551 for( int i=0; i<3; i++ )
553 result.units[n].glRGBArgs[i] = 0;
554 result.units[n].glRGBFlags[i] = 0;
555 result.units[n].glAlphaArgs[i] = 0;
556 result.units[n].glAlphaFlags[i] = 0;
557 if( result.units[n].rgbComb.args[i] != CM_IGNORE_BYTE )
559 result.units[n].glRGBArgs[i] = MapRGBArgs(result.units[n].rgbComb.args[i]);
560 result.units[n].glRGBFlags[i] = MapRGBArgFlags(result.units[n].rgbComb.args[i]);
562 if( result.units[n].alphaComb.args[i] != CM_IGNORE_BYTE )
564 result.units[n].glAlphaArgs[i] = MapAlphaArgs(result.units[n].alphaComb.args[i]);
565 result.units[n].glAlphaFlags[i] = MapAlphaArgFlags(result.units[n].alphaComb.args[i]);
570 m_vCompiledSettings.push_back(result);
571 m_lastIndex = m_vCompiledSettings.size()-1;
576 DisplaySimpleMuxString();
583 bool isGLtex(GLint val)
585 if( val >= GL_TEXTURE0_ARB && val <= GL_TEXTURE7_ARB )
591 int COGLColorCombiner4v2::SaveParsedResult(OGLExtCombinerSaveType &result)
593 result.dwMux0 = m_pDecodedMux->m_dwMux0;
594 result.dwMux1 = m_pDecodedMux->m_dwMux1;
598 for( n=0; n<result.numOfUnits; n++ )
600 for( int i=0; i<3; i++ )
602 result.units[n].glRGBArgs[i] = 0;
603 result.units[n].glRGBFlags[i] = 0;
604 result.units[n].glAlphaArgs[i] = 0;
605 result.units[n].glAlphaFlags[i] = 0;
606 if( result.units[n].rgbComb.args[i] != CM_IGNORE_BYTE )
608 result.units[n].glRGBArgs[i] = MapRGBArgs(result.units[n].rgbComb.args[i]);
609 if( result.units[n].glRGBArgs[i] == GL_TEXTURE3_ARB && !result.envIsUsed )
610 result.units[n].glRGBArgs[i] = GL_TEXTURE2_ARB;
612 result.units[n].glRGBFlags[i] = MapRGBArgFlags(result.units[n].rgbComb.args[i]);
614 if( result.units[n].alphaComb.args[i] != CM_IGNORE_BYTE )
616 result.units[n].glAlphaArgs[i] = MapAlphaArgs(result.units[n].alphaComb.args[i]);
617 if( result.units[n].glAlphaArgs[i] == GL_TEXTURE3_ARB && !result.envIsUsed )
618 result.units[n].glAlphaArgs[i] = GL_TEXTURE2_ARB;
620 result.units[n].glAlphaFlags[i] = MapAlphaArgFlags(result.units[n].alphaComb.args[i]);
624 if( isGLtex(result.units[n].glRGBArgs[0]) && isGLtex(result.units[n].glRGBArgs[1]) && isGLtex(result.units[n].glRGBArgs[2]) )
626 result.units[n].glRGBArgs[2] = GL_CONSTANT_ARB;
628 if( isGLtex(result.units[n].glAlphaArgs[0]) && isGLtex(result.units[n].glAlphaArgs[1]) && isGLtex(result.units[n].glAlphaArgs[2]) )
630 result.units[n].glRGBArgs[2] = GL_CONSTANT_ARB;
635 if( result.envIsUsed ) extraUnit++;
636 if( result.lodFracIsUsed ) extraUnit++;
637 for( n=result.numOfUnits; n<result.numOfUnits+extraUnit; n++ )
639 for( int i=0; i<3; i++ )
641 result.units[n].rgbComb.args[i]=CM_IGNORE_BYTE;
642 result.units[n].alphaComb.args[i]=CM_IGNORE_BYTE;
643 result.units[n].glRGBArgs[i] = 0;
644 result.units[n].glRGBFlags[i] = 0;
645 result.units[n].glAlphaArgs[i] = 0;
646 result.units[n].glAlphaFlags[i] = 0;
649 result.units[n].rgbComb.args[0]=MUX_COMBINED;
650 result.units[n].alphaComb.args[0]=MUX_COMBINED;
651 result.units[n].rgbOp = GL_REPLACE;
652 result.units[n].alphaOp = GL_REPLACE;
653 result.units[n].glRGBArgs[0] = GL_PREVIOUS_ARB;
654 result.units[n].glRGBArgs[1] = GL_PREVIOUS_ARB;
655 result.units[n].rgbFlag0gl = GL_SRC_COLOR;
656 result.units[n].rgbFlag1gl = GL_SRC_COLOR;
657 result.units[n].glAlphaArgs[0] = GL_PREVIOUS_ARB;
658 result.units[n].glAlphaArgs[1] = GL_PREVIOUS_ARB;
659 result.units[n].alphaFlag0gl = GL_SRC_ALPHA;
660 result.units[n].alphaFlag1gl = GL_SRC_ALPHA;
663 result.numOfUnits += extraUnit;
665 m_vCompiledSettings.push_back(result);
666 m_lastIndex = m_vCompiledSettings.size()-1;
671 DisplaySimpleMuxString();
680 extern const char *translatedCombTypes[];
681 void COGLColorCombiner4::DisplaySimpleMuxString(void)
683 char buf0[30], buf1[30], buf2[30];
684 OGLExtCombinerSaveType &result = m_vCompiledSettings[m_lastIndex];
686 COGLColorCombiner::DisplaySimpleMuxString();
687 DebuggerAppendMsg("OpenGL 1.2: %d Stages", result.numOfUnits);
688 for( int i=0; i<result.numOfUnits; i++ )
690 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));
691 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));
695 void COGLColorCombiner2::DisplaySimpleMuxString(void)
697 char buf0[30], buf1[30], buf2[30];
698 OGLExtCombinerSaveType &result = m_vCompiledSettings[m_lastIndex];
700 COGLColorCombiner::DisplaySimpleMuxString();
701 int generalCombinerIndex = CGeneralCombiner::FindCompiledMux();
702 if( generalCombinerIndex < 0 ) // Can not found
704 generalCombinerIndex = CGeneralCombiner::ParseDecodedMux();
706 DebuggerAppendMsg("Generated general combiners:");
707 GeneralCombinerInfo &generalRes = m_vCompiledCombinerStages[generalCombinerIndex];
708 General_DisplayBlendingStageInfo(generalRes);
710 DebuggerAppendMsg("OpenGL 1.2: %d Stages", result.numOfUnits);
711 for( int i=0; i<result.numOfUnits; i++ )
713 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));
714 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));
721 //////////////////////////////////////////////////////////////////////////
722 int COGLColorCombiner4::FindCompiledMux()
725 if( debuggerDropCombiners )
727 m_vCompiledSettings.clear();
728 //m_dwLastMux0 = m_dwLastMux1 = 0;
729 debuggerDropCombiners = false;
732 for( uint32 i=0; i<m_vCompiledSettings.size(); i++ )
734 if( m_vCompiledSettings[i].dwMux0 == m_pDecodedMux->m_dwMux0 && m_vCompiledSettings[i].dwMux1 == m_pDecodedMux->m_dwMux1 )
741 //========================================================================
743 GLint COGLColorCombiner4::RGBArgsMap4[] =
746 GL_PRIMARY_COLOR_ARB, //MUX_0
747 GL_PRIMARY_COLOR_ARB, //MUX_1
748 GL_PREVIOUS_ARB, //MUX_COMBINED,
750 GL_TEXTURE0_ARB, //MUX_TEXEL0,
752 GL_TEXTURE1_ARB, //MUX_TEXEL1,
753 GL_CONSTANT_ARB, //MUX_PRIM,
754 GL_PRIMARY_COLOR_ARB, //MUX_SHADE,
755 GL_CONSTANT_ARB, //MUX_ENV,
756 GL_PREVIOUS_ARB, //MUX_COMBALPHA,
758 GL_TEXTURE0_ARB, //MUX_T0_ALPHA,
760 GL_TEXTURE1_ARB, //MUX_T1_ALPHA,
761 GL_CONSTANT_ARB, //MUX_PRIM_ALPHA,
762 GL_PRIMARY_COLOR_ARB, //MUX_SHADE_ALPHA,
763 GL_CONSTANT_ARB, //MUX_ENV_ALPHA,
764 GL_CONSTANT_ARB, //MUX_LODFRAC,
765 GL_CONSTANT_ARB, //MUX_PRIMLODFRAC,
766 GL_PRIMARY_COLOR_ARB, //MUX_K5
767 GL_PRIMARY_COLOR_ARB //MUX_UNK
771 GLint COGLColorCombiner4v2::RGBArgsMap4v2[] =
774 GL_PRIMARY_COLOR_ARB, //MUX_0
775 GL_PRIMARY_COLOR_ARB, //MUX_1
776 GL_PREVIOUS_ARB, //MUX_COMBINED,
778 GL_TEXTURE0_ARB, //MUX_TEXEL0,
780 GL_TEXTURE1_ARB, //MUX_TEXEL1,
781 GL_CONSTANT_ARB, //MUX_PRIM,
782 GL_PRIMARY_COLOR_ARB, //MUX_SHADE,
783 GL_TEXTURE2_ARB, //MUX_ENV,
784 //{GL_TEXTURE1_ARB, }, //MUX_ENV,
785 GL_PREVIOUS_ARB, //MUX_COMBALPHA,
786 GL_TEXTURE0_ARB, //MUX_T0_ALPHA,
787 GL_TEXTURE1_ARB, //MUX_T1_ALPHA,
788 GL_CONSTANT_ARB, //MUX_PRIM_ALPHA,
789 GL_PRIMARY_COLOR_ARB, //MUX_SHADE_ALPHA,
790 GL_TEXTURE2_ARB, //MUX_ENV_ALPHA,
791 //{GL_TEXTURE1_ARB, }, //MUX_ENV_ALPHA,
792 //{GL_TEXTURE3_ARB, }, //MUX_LODFRAC,
793 //{GL_TEXTURE3_ARB, }, //MUX_PRIMLODFRAC,
794 GL_TEXTURE1_ARB, //MUX_LODFRAC,
795 GL_TEXTURE1_ARB, //MUX_PRIMLODFRAC,
796 GL_PRIMARY_COLOR_ARB, //MUX_K5
797 GL_PRIMARY_COLOR_ARB //MUX_UNK
801 GLint COGLColorCombiner2::RGBArgsMap2[] =
804 GL_PRIMARY_COLOR_ARB, //MUX_0
805 GL_PRIMARY_COLOR_ARB, //MUX_1
806 GL_PREVIOUS_ARB, //MUX_COMBINED,
807 //{GL_TEXTURE, }, //MUX_TEXEL0,
808 //{GL_TEXTURE, }, //MUX_TEXEL1,
810 GL_TEXTURE0_ARB, //MUX_TEXEL0,
812 GL_TEXTURE1_ARB, //MUX_TEXEL1,
813 GL_CONSTANT_ARB, //MUX_PRIM,
814 GL_PRIMARY_COLOR_ARB, //MUX_SHADE,
815 GL_CONSTANT_ARB, //MUX_ENV,
816 GL_PREVIOUS_ARB, //MUX_COMBALPHA,
817 //{GL_TEXTURE, }, //MUX_T0_ALPHA,
818 //{GL_TEXTURE, }, //MUX_T1_ALPHA,
819 GL_TEXTURE0_ARB, //MUX_TEXEL0,
820 GL_TEXTURE1_ARB, //MUX_TEXEL1,
821 GL_CONSTANT_ARB, //MUX_PRIM_ALPHA,
822 GL_PRIMARY_COLOR_ARB, //MUX_SHADE_ALPHA,
823 GL_CONSTANT_ARB, //MUX_ENV_ALPHA,
824 GL_CONSTANT_ARB, //MUX_LODFRAC,
825 GL_CONSTANT_ARB, //MUX_PRIMLODFRAC,
826 GL_PRIMARY_COLOR_ARB, //MUX_K5
827 GL_PRIMARY_COLOR_ARB //MUX_UNK
831 //========================================================================
833 GLint COGLColorCombiner4::MapRGBArgs(uint8 arg)
835 return RGBArgsMap4[arg&MUX_MASK];
838 GLint COGLColorCombiner4v2::MapRGBArgs(uint8 arg)
840 return RGBArgsMap4v2[arg&MUX_MASK];
843 GLint COGLColorCombiner2::MapRGBArgs(uint8 arg)
845 return RGBArgsMap2[arg&MUX_MASK];
848 GLint COGLColorCombiner4::MapRGBArgFlags(uint8 arg)
850 if( (arg & MUX_ALPHAREPLICATE) && (arg & MUX_COMPLEMENT) )
852 return GL_ONE_MINUS_SRC_ALPHA;
854 else if( (arg & MUX_ALPHAREPLICATE) )
858 else if(arg & MUX_COMPLEMENT)
860 return GL_ONE_MINUS_SRC_COLOR;
866 GLint COGLColorCombiner4::MapAlphaArgs(uint8 arg)
868 return RGBArgsMap4[arg&MUX_MASK];
871 GLint COGLColorCombiner4v2::MapAlphaArgs(uint8 arg)
873 return RGBArgsMap4v2[arg&MUX_MASK];
876 GLint COGLColorCombiner2::MapAlphaArgs(uint8 arg)
878 return RGBArgsMap2[arg&MUX_MASK];
881 GLint COGLColorCombiner4::MapAlphaArgFlags(uint8 arg)
883 if(arg & MUX_COMPLEMENT)
885 return GL_ONE_MINUS_SRC_ALPHA;
891 //========================================================================
893 void ApplyFor1Unit(OGLExtCombinerType &unit)
896 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, unit.rgbOp);
899 if( unit.rgbArg0 != CM_IGNORE_BYTE )
901 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, (unit.rgbArg0gl));
903 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, (unit.rgbFlag0gl));
907 if( unit.rgbArg1 != CM_IGNORE_BYTE )
909 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, (unit.rgbArg1gl));
911 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, (unit.rgbFlag1gl));
915 if( unit.rgbArg2 != CM_IGNORE_BYTE )
917 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, (unit.rgbArg2gl));
919 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, (unit.rgbFlag2gl));
923 if( unit.alphaArg0 != CM_IGNORE_BYTE )
925 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, (unit.alphaArg0gl));
927 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, (unit.alphaFlag0gl));
931 if( unit.alphaArg1 != CM_IGNORE_BYTE )
933 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, (unit.alphaArg1gl));
935 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, (unit.alphaFlag1gl));
939 if( unit.alphaArg2 != CM_IGNORE_BYTE )
941 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, (unit.alphaArg2gl));
943 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, (unit.alphaFlag2gl));
949 //////////////////////////////////////////////////////////////////////////
951 void COGLColorCombiner4::GenerateCombinerSetting(int index)
953 OGLExtCombinerSaveType &res = m_vCompiledSettings[index];
956 COGLTexture* pTexture = NULL;
957 COGLTexture* pTexture1 = NULL;
959 if( m_bTex0Enabled || m_bTex1Enabled || gRDP.otherMode.cycle_type == CYCLE_TYPE_COPY )
961 if( m_bTex0Enabled || gRDP.otherMode.cycle_type == CYCLE_TYPE_COPY )
963 pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
964 if( pTexture ) m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0);
968 pTexture1 = g_textures[(gRSP.curTile+1)&7].m_pCOGLTexture;
969 if( pTexture1 ) m_pOGLRender->BindTexture(pTexture1->m_dwTextureName, 1);
975 for( int i=0; i<res.numOfUnits; i++ )
977 pglActiveTexture(GL_TEXTURE0_ARB+i);
979 m_pOGLRender->EnableTexUnit(i,TRUE);
980 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
982 ApplyFor1Unit(res.units[i]);
985 if( res.numOfUnits < m_maxTexUnits )
987 for( int i=res.numOfUnits; i<m_maxTexUnits; i++ )
989 pglActiveTexture(GL_TEXTURE0_ARB+i);
991 m_pOGLRender->DisBindTexture(0, i);
992 m_pOGLRender->EnableTexUnit(i,FALSE);
998 void COGLColorCombiner4::GenerateCombinerSettingConstants(int index)
1000 OGLExtCombinerSaveType &res = m_vCompiledSettings[index];
1007 if( res.primIsUsed )
1009 fv = GetPrimitiveColorfv(); // CONSTANT COLOR
1011 else if( res.envIsUsed )
1013 fv = GetEnvColorfv(); // CONSTANT COLOR
1015 else if( res.lodFracIsUsed )
1017 float frac = gRDP.LODFrac / 255.0f;
1018 tempf[0] = tempf[1] = tempf[2] = tempf[3] = frac;
1028 for( int i=0; i<res.numOfUnits; i++ )
1030 pglActiveTexture(GL_TEXTURE0_ARB+i);
1031 OPENGL_CHECK_ERRORS;
1032 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,fv);
1033 OPENGL_CHECK_ERRORS;
1039 void COGLColorCombiner4v2::GenerateCombinerSettingConstants(int index)
1041 //COGLColorCombiner4::GenerateCombinerSettingConstants(index);
1044 OGLExtCombinerSaveType &res = m_vCompiledSettings[index];
1045 COGLExtRender *prender = (COGLExtRender *)m_pRender;
1047 if( res.primIsUsed )
1049 float *fv = GetPrimitiveColorfv(); // CONSTANT COLOR
1050 for( int i=0; i<res.numOfUnits; i++ )
1052 pglActiveTexture(GL_TEXTURE0_ARB+i);
1053 OPENGL_CHECK_ERRORS;
1054 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,fv);
1055 OPENGL_CHECK_ERRORS;
1061 // Set Texture unit 2 to ENV
1062 pglActiveTexture(GL_TEXTURE2_ARB);
1063 OPENGL_CHECK_ERRORS;
1064 prender->EnableTexUnit(2,TRUE);
1065 TxtrCacheEntry *pEntry = gTextureManager.GetConstantColorTexture(MUX_ENV);
1066 prender->SetCurrentTexture( (gRSP.curTile+2)%7, pEntry->pTexture, 4, 4, pEntry);
1067 prender->SetTexelRepeatFlags((gRSP.curTile+2)%7);
1070 if( res.lodFracIsUsed)
1073 if( !res.envIsUsed )
1076 // Set Texture unit 3 to LODFRAC
1077 pglActiveTexture(GL_TEXTURE0_ARB+unit);
1078 OPENGL_CHECK_ERRORS;
1079 prender->EnableTexUnit(unit,TRUE);
1080 TxtrCacheEntry *pEntry = gTextureManager.GetConstantColorTexture(MUX_LODFRAC);
1081 prender->SetCurrentTexture( (gRSP.curTile+unit)%7, pEntry->pTexture, 4, 4, pEntry);
1082 prender->SetTexelRepeatFlags((gRSP.curTile+unit)%7);
1087 if( !res.envIsUsed )
1090 // Disable texture unit 3
1091 pglActiveTexture(GL_TEXTURE0_ARB+unit);
1092 OPENGL_CHECK_ERRORS;
1093 prender->EnableTexUnit(unit,FALSE);
1094 prender->SetTextureToTextureUnitMap(-1,unit);
1099 GLenum GeneralToGLMaps[]=
1101 GL_REPLACE, //CM_REPLACE,
1102 #if SDL_VIDEO_OPENGL
1103 GL_MODULATE, //CM_MODULATE,
1105 GL_SUBTRACT_ARB, //CM_SUBTRACT,
1106 GL_INTERPOLATE_ARB, //CM_INTERPOLATE,
1107 GL_INTERPOLATE_ARB, //CM_ADDSMOOTH,
1108 GL_INTERPOLATE_ARB, //CM_BLENDCURRENTALPHA
1109 GL_INTERPOLATE_ARB, //CM_BLENDDIFFUSEALPHA
1110 GL_INTERPOLATE_ARB, //CM_BLENDFACTORALPHA,
1111 GL_INTERPOLATE_ARB, //CM_BLENDTEXTUREALPHA
1113 GL_MODULATE_ADD_ATI, //CM_MULTIPLYADD,
1117 //////////////////////////////////////////////////////////////////////////
1118 int COGLColorCombiner2::ParseDecodedMux()
1120 //return COGLColorCombiner4::ParseDecodedMux();
1122 int generalCombinerIndex = CGeneralCombiner::FindCompiledMux();
1123 if( generalCombinerIndex < 0 ) // Can not found
1125 generalCombinerIndex = CGeneralCombiner::ParseDecodedMux();
1128 GeneralCombinerInfo &generalRes = m_vCompiledCombinerStages[generalCombinerIndex];
1129 OGLExtCombinerSaveType res;
1131 // Convert generalRes to OGLExtCombinerSaveType
1132 for( int unitNo=0; unitNo<generalRes.nStages; unitNo++ )
1134 OGLExtCombinerType &unit = res.units[unitNo];
1135 //OGLExt1CombType &colorComb = unit.Combs[0];
1136 //OGLExt1CombType &alphaComb = unit.Combs[1];
1138 unit.rgbArg0 = (uint8)generalRes.stages[unitNo].colorOp.Arg1;
1139 unit.rgbArg1 = (uint8)generalRes.stages[unitNo].colorOp.Arg2;
1140 unit.rgbArg2 = (uint8)generalRes.stages[unitNo].colorOp.Arg0;
1141 unit.alphaArg0 = (uint8)generalRes.stages[unitNo].alphaOp.Arg1;
1142 unit.alphaArg1 = (uint8)generalRes.stages[unitNo].alphaOp.Arg2;
1143 unit.alphaArg2 = (uint8)generalRes.stages[unitNo].alphaOp.Arg0;
1145 unit.rgbOp = GeneralToGLMaps[generalRes.stages[unitNo].colorOp.op];
1146 if( unit.rgbOp == GL_MODULATE_ADD_ATI && !m_bTxtOpMulAdd )
1148 if( (unit.rgbArg0&MUX_MASK) == (unit.rgbArg2&MUX_MASK) && (unit.rgbArg0&MUX_COMPLEMENT) )
1150 unit.rgbOp = GL_ADD;
1151 unit.rgbArg0 &= ~MUX_COMPLEMENT;
1155 unit.rgbOp = GL_MODULATE;
1158 unit.alphaOp = GeneralToGLMaps[generalRes.stages[unitNo].alphaOp.op];
1159 if( unit.alphaOp == GL_MODULATE_ADD_ATI && !m_bTxtOpMulAdd )
1161 if( (unit.alphaArg0&MUX_MASK) == (unit.alphaArg2&MUX_MASK) && (unit.alphaArg0&MUX_COMPLEMENT) )
1163 unit.alphaOp = GL_ADD;
1164 unit.alphaArg0 &= ~MUX_COMPLEMENT;
1168 unit.alphaOp = GL_MODULATE;
1172 unit.tex = generalRes.stages[unitNo].dwTexture;
1173 unit.textureIsUsed = generalRes.stages[unitNo].bTextureUsed;
1176 res.numOfUnits = generalRes.nStages;
1177 res.constantColor = generalRes.TFactor;
1178 return SaveParsedResult(res);
1182 void COGLColorCombiner2::GenerateCombinerSettingConstants(int index)
1184 OGLExtCombinerSaveType &res = m_vCompiledSettings[index];
1191 if( res.primIsUsed )
1193 fv = GetPrimitiveColorfv(); // CONSTANT COLOR
1195 else if( res.envIsUsed )
1197 fv = GetEnvColorfv(); // CONSTANT COLOR
1199 else if( res.lodFracIsUsed )
1201 float frac = gRDP.LODFrac / 255.0f;
1202 tempf[0] = tempf[1] = tempf[2] = tempf[3] = frac;
1212 for( int i=0; i<res.numOfUnits; i++ )
1214 pglActiveTextureARB(GL_TEXTURE0_ARB+i);
1215 OPENGL_CHECK_ERRORS;
1216 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,fv);
1217 OPENGL_CHECK_ERRORS;
1221 void COGLColorCombiner2::GenerateCombinerSetting(int index)
1223 OGLExtCombinerSaveType &res = m_vCompiledSettings[index];
1224 COGLExtRender *prender = (COGLExtRender *)m_pRender;
1226 for( int i=0; i<res.numOfUnits; i++ )
1228 pglActiveTextureARB(GL_TEXTURE0_ARB+i);
1229 OPENGL_CHECK_ERRORS;
1230 //if(res.units[i].textureIsUsed)
1232 prender->SetTextureToTextureUnitMap(res.units[i].tex,i);
1233 m_pOGLRender->EnableTexUnit(i,TRUE);
1234 COGLTexture* pTexture = g_textures[(gRSP.curTile+res.units[i].tex)&7].m_pCOGLTexture;
1235 if( pTexture ) m_pOGLRender->BindTexture(pTexture->m_dwTextureName, i);
1240 m_pOGLRender->EnableTexUnit(i,TRUE);
1241 prender->SetTextureToTextureUnitMap(-1,i);
1242 //m_pOGLRender->EnableTexUnit(i,FALSE);
1243 //m_pOGLRender->DisBindTexture(0, i);
1247 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
1248 OPENGL_CHECK_ERRORS;
1249 ApplyFor1Unit(res.units[i]);
1252 if( res.numOfUnits < m_maxTexUnits )
1254 for( int i=res.numOfUnits; i<m_maxTexUnits; i++ )
1256 pglActiveTextureARB(GL_TEXTURE0_ARB+i);
1257 OPENGL_CHECK_ERRORS;
1258 m_pOGLRender->EnableTexUnit(i,FALSE);
1259 prender->SetTextureToTextureUnitMap(-1,i);