Rice GLES2 (from mupen64plus-ae) plugin. Compile but doesn't works well on the OpenPa...
[mupen64plus-pandora.git] / source / gles2rice / src / OGLExtCombiner.cpp
1 /*
2 Copyright (C) 2003 Rice1964
3
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.
8
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.
13
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.
17 */
18
19 #include <algorithm>
20 #include "osal_opengl.h"
21
22 #if SDL_VIDEO_OPENGL
23 #include "OGLExtensions.h"
24 #endif
25 #include "OGLDebug.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"
32
33 #define GL_MODULATE_ADD_ATI        0x8744
34 #define GL_MODULATE_SUBTRACT_ATI   0x8746
35
36 //========================================================================
37 COGLColorCombiner4::COGLColorCombiner4(CRender *pRender)
38         :COGLColorCombiner(pRender), m_maxTexUnits(0), m_lastIndex(-1),
39         m_dwLastMux0(0), m_dwLastMux1(0)
40 {
41     m_bOGLExtCombinerSupported=false;
42     m_bSupportModAdd_ATI = false;
43     m_bSupportModSub_ATI = false;
44     delete m_pDecodedMux;
45     m_pDecodedMux = new COGLExtDecodedMux;
46 }
47
48 COGLColorCombiner4v2::COGLColorCombiner4v2(CRender *pRender)
49     :COGLColorCombiner4(pRender)
50 {
51     delete m_pDecodedMux;
52     m_pDecodedMux = new DecodedMuxForOGL14V2;
53 }
54
55 COGLColorCombiner2::COGLColorCombiner2(CRender *pRender)
56         :COGLColorCombiner4(pRender)
57 {
58     delete m_pDecodedMux;
59     m_pDecodedMux = new CDirectXDecodedMux;     // Use Mux for DirectX because we support only 1 texture for each stage
60     m_ppGeneralDecodedMux = &m_pDecodedMux;
61 }
62
63 //////////////////////////////////////////////////////////////////////////
64 bool COGLColorCombiner4::Initialize(void)
65 {
66     m_bOGLExtCombinerSupported = false;
67     m_bSupportModAdd_ATI = false;
68     m_bSupportModSub_ATI = false;
69     m_maxTexUnits = 1;
70
71 #if SDL_VIDEO_OPENGL
72     if( COGLColorCombiner::Initialize() )
73     {
74         m_bSupportMultiTexture = true;
75         COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
76
77         if( pcontext->IsExtensionSupported("GL_EXT_texture_env_combine") || pcontext->IsExtensionSupported("GL_ARB_texture_env_combine") )
78         {
79             m_bOGLExtCombinerSupported = true;
80             glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB,&m_maxTexUnits);
81             OPENGL_CHECK_ERRORS;
82             if( m_maxTexUnits > 8 ) m_maxTexUnits = 8;
83
84             TRACE0("Starting Ogl 1.4 multitexture combiner" );
85             TRACE1("m_maxTexUnits = %d", m_maxTexUnits);
86             if( pcontext->IsExtensionSupported("ATI_texture_env_combine3") )
87             {
88                 m_bSupportModAdd_ATI = true;
89                 m_bSupportModSub_ATI = true;
90             }
91         }
92         else
93         {
94             DebugMessage(M64MSG_ERROR, "Your video card does not support OpenGL extension combiner, you can only use the basic OpenGL combiner functions");
95         }
96         m_supportedStages = m_maxTexUnits;
97         return true;
98     }
99     return false;
100
101 #elif SDL_VIDEO_OPENGL_ES2
102     return true;
103 #endif
104 }
105
106 bool COGLColorCombiner2::Initialize(void)
107 {
108     TRACE0("Starting Ogl 1.2/1.3 multitexture combiner" );
109     if( COGLColorCombiner4::Initialize() )
110     {
111         // For general combiner flags
112         m_dwGeneralMaxStages = m_supportedStages;
113
114         m_bTxtOpAdd = m_bSupportAdd;
115         m_bTxtOpSub = m_bSupportSubtract;
116         m_bTxtOpLerp = true;
117
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;
124
125         return true;
126     }
127     else
128     {
129         return false;
130     }
131 }
132 //========================================================================
133 void COGLColorCombiner4::InitCombinerCycleFill(void)
134 {
135     for( int i=0; i<m_supportedStages; i++ )
136     {
137         pglActiveTexture(GL_TEXTURE0_ARB+i);
138         OPENGL_CHECK_ERRORS;
139         m_pOGLRender->EnableTexUnit(i,FALSE);
140     }
141
142     //pglActiveTexture(GL_TEXTURE0_ARB);
143     //m_pOGLRender->EnableTexUnit(0,FALSE);
144     //pglActiveTexture(GL_TEXTURE1_ARB);
145     //m_pOGLRender->EnableTexUnit(1,FALSE);
146 }
147
148 //////////////////////////////////////////////////////////////////////////
149 void COGLColorCombiner4::InitCombinerCycle12(void)
150 {
151     if( !m_bOGLExtCombinerSupported )   
152     {
153         COGLColorCombiner::InitCombinerCycle12();
154         return;
155     }
156
157 #ifdef DEBUGGER
158     if( debuggerDropCombiners )
159     {
160         UpdateCombiner(m_pDecodedMux->m_dwMux0,m_pDecodedMux->m_dwMux1);
161         m_vCompiledSettings.clear();
162         m_dwLastMux0 = m_dwLastMux1 = 0;
163         debuggerDropCombiners = false;
164     }
165 #endif
166
167     m_pOGLRender->EnableMultiTexture();
168
169     bool combinerIsChanged = false;
170
171     if( m_pDecodedMux->m_dwMux0 != m_dwLastMux0 || m_pDecodedMux->m_dwMux1 != m_dwLastMux1 || m_lastIndex < 0 )
172     {
173         combinerIsChanged = true;
174         m_lastIndex = FindCompiledMux();
175         if( m_lastIndex < 0 )       // Can not found
176         {
177             m_lastIndex = ParseDecodedMux();
178 #ifdef DEBUGGER
179             DisplaySimpleMuxString();
180 #endif
181         }
182
183         m_dwLastMux0 = m_pDecodedMux->m_dwMux0;
184         m_dwLastMux1 = m_pDecodedMux->m_dwMux1;
185     }
186     
187
188     if( m_bCycleChanged || combinerIsChanged || gRDP.texturesAreReloaded || gRDP.colorsAreReloaded )
189     {
190         if( m_bCycleChanged || combinerIsChanged )
191         {
192             GenerateCombinerSettingConstants(m_lastIndex);
193             GenerateCombinerSetting(m_lastIndex);
194         }
195         else if( gRDP.colorsAreReloaded )
196         {
197             GenerateCombinerSettingConstants(m_lastIndex);
198         }
199
200         m_pOGLRender->SetAllTexelRepeatFlag();
201
202         gRDP.colorsAreReloaded = false;
203         gRDP.texturesAreReloaded = false;
204     }
205     else
206     {
207         m_pOGLRender->SetAllTexelRepeatFlag();
208     }
209 }
210
211 //////////////////////////////////////////////////////////////////////////
212 int COGLColorCombiner4::ParseDecodedMux()
213 {
214 #define nextUnit()  {unitNo++;}
215 #if SDL_VIDEO_OPENGL
216     if( m_maxTexUnits<3) 
217         return  ParseDecodedMux2Units();
218
219     OGLExtCombinerSaveType res;
220     for( int k=0; k<8; k++ )
221         res.units[k].tex = -1;
222     
223     COGLDecodedMux &mux = *(COGLDecodedMux*)m_pDecodedMux;
224
225     int unitNos[2];
226     for( int rgbalpha = 0; rgbalpha<2; rgbalpha++ )
227     {
228         unitNos[rgbalpha] = 0;
229         for( int cycle = 0; cycle<2; cycle++ )
230         {
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;
237
238             switch( type )
239             {
240             case CM_FMT_TYPE_NOT_USED:
241                 comb.arg0 = MUX_COMBINED;
242                 unit.ops[rgbalpha] = GL_REPLACE;
243                 nextUnit();
244                 break;
245             case CM_FMT_TYPE_D:                 // = A
246                 comb.arg0 = m.d;
247                 unit.ops[rgbalpha] = GL_REPLACE;
248                 nextUnit();
249                 break;
250             case CM_FMT_TYPE_A_ADD_D:           // = A+D
251                 comb.arg0 = m.a;
252                 comb.arg1 = m.d;
253                 unit.ops[rgbalpha] = GL_ADD;
254                 nextUnit();
255                 break;
256             case CM_FMT_TYPE_A_SUB_B:           // = A-B
257                 comb.arg0 = m.a;
258                 comb.arg1 = m.b;
259                 unit.ops[rgbalpha] = GL_SUBTRACT_ARB;
260                 nextUnit();
261                 break;
262             case CM_FMT_TYPE_A_MOD_C:           // = A*C
263                 comb.arg0 = m.a;
264                 comb.arg1 = m.c;
265                 unit.ops[rgbalpha] = GL_MODULATE;
266                 nextUnit();
267                 break;
268             case CM_FMT_TYPE_A_MOD_C_ADD_D:     // = A*C+D
269                 if( m_bSupportModAdd_ATI )
270                 {
271                     comb.arg0 = m.a;
272                     comb.arg2 = m.c;
273                     comb.arg1 = m.d;
274                     unit.ops[rgbalpha] = GL_MODULATE_ADD_ATI;
275                     nextUnit();
276                 }
277                 else
278                 {
279                     if( unitNo < m_maxTexUnits-1 )
280                     {
281                         comb.arg0 = m.a;
282                         comb.arg1 = m.c;
283                         unit.ops[rgbalpha] = GL_MODULATE;
284                         nextUnit();
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;
288                         nextUnit();
289                     }
290                     else
291                     {
292                         comb.arg0 = m.a;
293                         comb.arg1 = m.c;
294                         comb.arg2 = m.d;
295                         unit.ops[rgbalpha] = GL_INTERPOLATE_ARB;
296                         nextUnit();
297                     }
298                 }
299                 break;
300             case CM_FMT_TYPE_A_LERP_B_C:        // = (A-B)*C+B
301                 comb.arg0 = m.a;
302                 comb.arg1 = m.b;
303                 comb.arg2 = m.c;
304                 unit.ops[rgbalpha] = GL_INTERPOLATE_ARB;
305                 nextUnit();
306                 break;
307             case CM_FMT_TYPE_A_SUB_B_ADD_D:     // = A-B+D
308                 if( unitNo < m_maxTexUnits-1 )
309                 {
310                     comb.arg0 = m.a;
311                     comb.arg1 = m.b;
312                     unit.ops[rgbalpha] = GL_SUBTRACT_ARB;
313                     nextUnit();
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;
317                     nextUnit();
318                 }
319                 else
320                 {
321                     comb.arg0 = m.a;
322                     comb.arg1 = m.c;
323                     comb.arg2 = m.d;
324                     unit.ops[rgbalpha] = GL_INTERPOLATE_ARB;
325                     nextUnit();
326                 }
327                 break;
328             case CM_FMT_TYPE_A_SUB_B_MOD_C:     // = (A-B)*C
329                 if( unitNo < m_maxTexUnits-1 )
330                 {
331                     comb.arg0 = m.a;
332                     comb.arg1 = m.b;
333                     unit.ops[rgbalpha] = GL_SUBTRACT_ARB;
334                     nextUnit();
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;
338                     nextUnit();
339                 }
340                 else
341                 {
342                     comb.arg0 = m.a;
343                     comb.arg1 = m.c;
344                     comb.arg2 = m.d;
345                     unit.ops[rgbalpha] = GL_INTERPOLATE_ARB;
346                     nextUnit();
347                 }
348                 break;
349             case CM_FMT_TYPE_A_B_C_D:           // = (A-B)*C+D
350             default:
351                 if( unitNo < m_maxTexUnits-1 )
352                 {
353                     comb.arg0 = m.a;
354                     comb.arg1 = m.b;
355                     unit.ops[rgbalpha] = GL_SUBTRACT_ARB;
356                     nextUnit();
357                     if( m_bSupportModAdd_ATI )
358                     {
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;
363                         nextUnit();
364                     }
365                     else
366                     {
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;
371                         nextUnit();
372                     }
373                 }
374                 else
375                 {
376                     comb.arg0 = m.a;
377                     comb.arg1 = m.c;
378                     comb.arg2 = m.d;
379                     unit.ops[rgbalpha] = GL_INTERPOLATE_ARB;
380                     nextUnit();
381                 }
382                 break;
383             }
384         }
385     }
386         
387     res.numOfUnits = min(m_maxTexUnits, max(unitNos[0],unitNos[1]));
388
389     if( unitNos[0]>m_maxTexUnits || unitNos[1]>m_maxTexUnits ) 
390     {
391         TRACE0("Unit overflows");
392     }
393
394     for( int j=0; j<2; j++ )
395     {
396         if( unitNos[j]<res.numOfUnits )
397         {
398             for( int i=unitNos[j]; i<res.numOfUnits; i++ )
399             {
400                 res.units[i].Combs[j].arg0 = MUX_COMBINED;
401                 res.units[i].ops[j] = GL_REPLACE;
402             }
403         }
404     }
405
406     res.units[0].tex = 0;
407     res.units[1].tex = 1;
408
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);
412
413     return SaveParsedResult(res);
414
415 #elif SDL_VIDEO_OPENGL_ES2
416     return 0;
417 #endif
418 }
419
420 int COGLColorCombiner4::ParseDecodedMux2Units()
421 {
422     OGLExtCombinerSaveType res;
423     for( int k=0; k<8; k++ )
424         res.units[k].tex = -1;
425
426     res.numOfUnits = 2;
427
428     for( int i=0; i<res.numOfUnits*2; i++ ) // Set combiner for each texture unit
429     {
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
432
433         OGLExtCombinerType &unit = res.units[i/2];
434         OGLExt1CombType &comb = unit.Combs[i%2];
435
436         CombinerFormatType type = m_pDecodedMux->splitType[i];
437         N64CombinerType &m = m_pDecodedMux->m_n64Combiners[i];
438
439         comb.arg0 = comb.arg1 = comb.arg2 = MUX_0;
440
441         switch( type )
442         {
443         case CM_FMT_TYPE_NOT_USED:
444             comb.arg0 = MUX_COMBINED;
445             unit.ops[i%2] = GL_REPLACE;
446             break;
447         case CM_FMT_TYPE_D:                 // = A
448             comb.arg0 = m.d;
449             unit.ops[i%2] = GL_REPLACE;
450             break;
451 #if SDL_VIDEO_OPENGL
452         case CM_FMT_TYPE_A_ADD_D:           // = A+D
453             comb.arg0 = m.a;
454             comb.arg1 = m.d;
455             unit.ops[i%2] = GL_ADD;
456             break;
457         case CM_FMT_TYPE_A_SUB_B:           // = A-B
458             comb.arg0 = m.a;
459             comb.arg1 = m.b;
460             unit.ops[i%2] = GL_SUBTRACT_ARB;
461             break;
462         case CM_FMT_TYPE_A_MOD_C:           // = A*C
463             comb.arg0 = m.a;
464             comb.arg1 = m.c;
465             unit.ops[i%2] = GL_MODULATE;
466             break;
467         case CM_FMT_TYPE_A_MOD_C_ADD_D:     // = A*C+D
468             comb.arg0 = m.a;
469             comb.arg1 = m.c;
470             comb.arg2 = m.d;
471             unit.ops[i%2] = GL_INTERPOLATE_ARB;
472             break;
473         case CM_FMT_TYPE_A_LERP_B_C:        // = (A-B)*C+B
474             comb.arg0 = m.a;
475             comb.arg1 = m.b;
476             comb.arg2 = m.c;
477             unit.ops[i%2] = GL_INTERPOLATE_ARB;
478             break;
479         case CM_FMT_TYPE_A_SUB_B_ADD_D:     // = A-B+D
480             // fix me, to use 2 texture units
481             comb.arg0 = m.a;
482             comb.arg1 = m.b;
483             unit.ops[i%2] = GL_SUBTRACT_ARB;
484             break;
485         case CM_FMT_TYPE_A_SUB_B_MOD_C:     // = (A-B)*C
486             // fix me, to use 2 texture units
487             comb.arg0 = m.a;
488             comb.arg1 = m.c;
489             unit.ops[i%2] = GL_MODULATE;
490             break;
491             break;
492         case CM_FMT_TYPE_A_B_C_D:           // = (A-B)*C+D
493 #endif
494         default:
495             comb.arg0 = m.a;
496             comb.arg1 = m.b;
497             comb.arg2 = m.c;
498             unit.ops[i%2] = GL_INTERPOLATE_ARB;
499             break;
500         }
501     }
502
503     if( m_pDecodedMux->splitType[2] == CM_FMT_TYPE_NOT_USED && m_pDecodedMux->splitType[3] == CM_FMT_TYPE_NOT_USED && !m_bTex1Enabled )
504     {
505         res.numOfUnits = 1;
506     }
507
508     res.units[0].tex = 0;
509     res.units[1].tex = 1;
510
511     return SaveParsedResult(res);
512 }
513
514 const char* COGLColorCombiner4::GetOpStr(GLenum op)
515 {
516     switch( op )
517     {
518     case GL_REPLACE:
519         return "REPLACE";
520 #if SDL_VIDEO_OPENGL
521     case GL_MODULATE:
522         return "MOD";
523     case GL_ADD:
524         return "ADD";
525     case GL_ADD_SIGNED_ARB:
526         return "ADD_SIGNED";
527     case GL_INTERPOLATE_ARB:
528         return "INTERPOLATE";
529     case GL_SUBTRACT_ARB:
530         return "SUB";
531 #endif
532     case GL_MODULATE_ADD_ATI:
533         return "MULADD";
534     default:
535         return "SUB";
536     }
537 }
538
539 int COGLColorCombiner4::SaveParsedResult(OGLExtCombinerSaveType &result)
540 {
541     result.dwMux0 = m_pDecodedMux->m_dwMux0;
542     result.dwMux1 = m_pDecodedMux->m_dwMux1;
543
544     for( int n=0; n<result.numOfUnits; n++ )
545     {
546         for( int i=0; i<3; i++ )
547         {
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 )
553             {
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]);
556             }
557             if( result.units[n].alphaComb.args[i] != CM_IGNORE_BYTE )
558             {
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]);
561             }
562         }
563     }
564
565     m_vCompiledSettings.push_back(result);
566     m_lastIndex = m_vCompiledSettings.size()-1;
567
568 #ifdef DEBUGGER
569     if( logCombiners )
570     {
571         DisplaySimpleMuxString();
572     }
573 #endif
574
575     return m_lastIndex;
576 }
577
578 bool isGLtex(GLint val)
579 {
580     if( val >= GL_TEXTURE0_ARB && val <= GL_TEXTURE7_ARB )
581         return true;
582     else
583         return false;
584 }
585
586 int COGLColorCombiner4v2::SaveParsedResult(OGLExtCombinerSaveType &result)
587 {
588     result.dwMux0 = m_pDecodedMux->m_dwMux0;
589     result.dwMux1 = m_pDecodedMux->m_dwMux1;
590
591     int n;
592
593     for( n=0; n<result.numOfUnits; n++ )
594     {
595         for( int i=0; i<3; i++ )
596         {
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 )
602             {
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;
606
607                 result.units[n].glRGBFlags[i] = MapRGBArgFlags(result.units[n].rgbComb.args[i]);
608             }
609             if( result.units[n].alphaComb.args[i] != CM_IGNORE_BYTE )
610             {
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;
614
615                 result.units[n].glAlphaFlags[i] = MapAlphaArgFlags(result.units[n].alphaComb.args[i]);
616             }
617         }
618
619         if( isGLtex(result.units[n].glRGBArgs[0]) && isGLtex(result.units[n].glRGBArgs[1]) && isGLtex(result.units[n].glRGBArgs[2]) )
620         {
621             result.units[n].glRGBArgs[2] = GL_CONSTANT_ARB;
622         }
623         if( isGLtex(result.units[n].glAlphaArgs[0]) && isGLtex(result.units[n].glAlphaArgs[1]) && isGLtex(result.units[n].glAlphaArgs[2]) )
624         {
625             result.units[n].glRGBArgs[2] = GL_CONSTANT_ARB;
626         }
627     }
628
629     int extraUnit = 0;
630     if( result.envIsUsed )  extraUnit++;
631     if( result.lodFracIsUsed ) extraUnit++;
632     for( n=result.numOfUnits; n<result.numOfUnits+extraUnit; n++ )
633     {
634         for( int i=0; i<3; i++ )
635         {
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;
642         }
643         
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;
656     }
657
658     result.numOfUnits += extraUnit;
659
660     m_vCompiledSettings.push_back(result);
661     m_lastIndex = m_vCompiledSettings.size()-1;
662
663 #ifdef DEBUGGER
664     if( logCombiners )
665     {
666         DisplaySimpleMuxString();
667     }
668 #endif
669
670     return m_lastIndex;
671 }
672
673
674 #ifdef DEBUGGER
675 extern const char *translatedCombTypes[];
676 void COGLColorCombiner4::DisplaySimpleMuxString(void)
677 {
678     char buf0[30], buf1[30], buf2[30];
679     OGLExtCombinerSaveType &result = m_vCompiledSettings[m_lastIndex];
680
681     COGLColorCombiner::DisplaySimpleMuxString();
682     DebuggerAppendMsg("OpenGL 1.2: %d Stages", result.numOfUnits);      
683     for( int i=0; i<result.numOfUnits; i++ )
684     {
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));       
687     }
688     TRACE0("\n\n");
689 }
690 void COGLColorCombiner2::DisplaySimpleMuxString(void)
691 {
692     char buf0[30], buf1[30], buf2[30];
693     OGLExtCombinerSaveType &result = m_vCompiledSettings[m_lastIndex];
694
695     COGLColorCombiner::DisplaySimpleMuxString();
696     int generalCombinerIndex = CGeneralCombiner::FindCompiledMux();
697     if( generalCombinerIndex < 0 )      // Can not found
698     {
699         generalCombinerIndex = CGeneralCombiner::ParseDecodedMux();
700     }
701     DebuggerAppendMsg("Generated general combiners:");
702     GeneralCombinerInfo &generalRes = m_vCompiledCombinerStages[generalCombinerIndex];
703     General_DisplayBlendingStageInfo(generalRes);
704
705     DebuggerAppendMsg("OpenGL 1.2: %d Stages", result.numOfUnits);      
706     for( int i=0; i<result.numOfUnits; i++ )
707     {
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));       
710     }
711     TRACE0("\n\n");
712 }
713 #endif
714
715
716 //////////////////////////////////////////////////////////////////////////
717 int COGLColorCombiner4::FindCompiledMux()
718 {
719 #ifdef DEBUGGER
720     if( debuggerDropCombiners )
721     {
722         m_vCompiledSettings.clear();
723         //m_dwLastMux0 = m_dwLastMux1 = 0;
724         debuggerDropCombiners = false;
725     }
726 #endif
727     for( uint32 i=0; i<m_vCompiledSettings.size(); i++ )
728     {
729         if( m_vCompiledSettings[i].dwMux0 == m_pDecodedMux->m_dwMux0 && m_vCompiledSettings[i].dwMux1 == m_pDecodedMux->m_dwMux1 )
730             return (int)i;
731     }
732
733     return -1;
734 }
735
736 //========================================================================
737
738 GLint COGLColorCombiner4::RGBArgsMap4[] =
739 {
740 #if SDL_VIDEO_OPENGL
741     GL_PRIMARY_COLOR_ARB,           //MUX_0
742     GL_PRIMARY_COLOR_ARB,           //MUX_1
743     GL_PREVIOUS_ARB,                //MUX_COMBINED,
744 #endif
745     GL_TEXTURE0_ARB,                //MUX_TEXEL0,
746 #if SDL_VIDEO_OPENGL
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,
752 #endif
753     GL_TEXTURE0_ARB,                //MUX_T0_ALPHA,
754 #if SDL_VIDEO_OPENGL
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
763 #endif
764 };
765
766 GLint COGLColorCombiner4v2::RGBArgsMap4v2[] =
767 {
768 #if SDL_VIDEO_OPENGL
769     GL_PRIMARY_COLOR_ARB,           //MUX_0
770     GL_PRIMARY_COLOR_ARB,           //MUX_1
771     GL_PREVIOUS_ARB,                //MUX_COMBINED,
772 #endif
773     GL_TEXTURE0_ARB,                //MUX_TEXEL0,
774 #if SDL_VIDEO_OPENGL
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
793 #endif
794 };
795
796 GLint COGLColorCombiner2::RGBArgsMap2[] =
797 {
798 #if SDL_VIDEO_OPENGL
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,
804 #endif
805     GL_TEXTURE0_ARB,                //MUX_TEXEL0,
806 #if SDL_VIDEO_OPENGL
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
823 #endif
824 };
825
826 //========================================================================
827
828 GLint COGLColorCombiner4::MapRGBArgs(uint8 arg)
829 {
830     return RGBArgsMap4[arg&MUX_MASK];
831 }
832
833 GLint COGLColorCombiner4v2::MapRGBArgs(uint8 arg)
834 {
835     return RGBArgsMap4v2[arg&MUX_MASK];
836 }
837
838 GLint COGLColorCombiner2::MapRGBArgs(uint8 arg)
839 {
840     return RGBArgsMap2[arg&MUX_MASK];
841 }
842
843 GLint COGLColorCombiner4::MapRGBArgFlags(uint8 arg)
844 {
845     if( (arg & MUX_ALPHAREPLICATE) && (arg & MUX_COMPLEMENT) )
846     {
847         return GL_ONE_MINUS_SRC_ALPHA;
848     }
849     else if( (arg & MUX_ALPHAREPLICATE) )
850     {
851         return GL_SRC_ALPHA;
852     }
853     else if(arg & MUX_COMPLEMENT) 
854     {
855         return GL_ONE_MINUS_SRC_COLOR;
856     }
857     else
858         return GL_SRC_COLOR;
859 }
860
861 GLint COGLColorCombiner4::MapAlphaArgs(uint8 arg)
862 {
863     return RGBArgsMap4[arg&MUX_MASK];
864 }
865
866 GLint COGLColorCombiner4v2::MapAlphaArgs(uint8 arg)
867 {
868     return RGBArgsMap4v2[arg&MUX_MASK];
869 }
870
871 GLint COGLColorCombiner2::MapAlphaArgs(uint8 arg)
872 {
873     return RGBArgsMap2[arg&MUX_MASK];
874 }
875
876 GLint COGLColorCombiner4::MapAlphaArgFlags(uint8 arg)
877 {
878     if(arg & MUX_COMPLEMENT) 
879     {
880         return GL_ONE_MINUS_SRC_ALPHA;
881     }
882     else
883         return GL_SRC_ALPHA;
884 }
885
886 //========================================================================
887
888 void ApplyFor1Unit(OGLExtCombinerType &unit)
889 {
890 #if SDL_VIDEO_OPENGL
891     glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, unit.rgbOp);
892     OPENGL_CHECK_ERRORS;
893
894     if( unit.rgbArg0 != CM_IGNORE_BYTE )
895     {
896         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, (unit.rgbArg0gl));
897         OPENGL_CHECK_ERRORS;
898         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, (unit.rgbFlag0gl));
899         OPENGL_CHECK_ERRORS;
900     }
901
902     if( unit.rgbArg1 != CM_IGNORE_BYTE )
903     {
904         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, (unit.rgbArg1gl));
905         OPENGL_CHECK_ERRORS;
906         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, (unit.rgbFlag1gl));
907         OPENGL_CHECK_ERRORS;
908     }
909
910     if( unit.rgbArg2 != CM_IGNORE_BYTE )
911     {
912         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, (unit.rgbArg2gl));
913         OPENGL_CHECK_ERRORS;
914         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, (unit.rgbFlag2gl));
915         OPENGL_CHECK_ERRORS;
916     }
917
918     if( unit.alphaArg0 != CM_IGNORE_BYTE )
919     {
920         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, (unit.alphaArg0gl));
921         OPENGL_CHECK_ERRORS;
922         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, (unit.alphaFlag0gl));
923         OPENGL_CHECK_ERRORS;
924     }
925
926     if( unit.alphaArg1 != CM_IGNORE_BYTE )
927     {
928         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, (unit.alphaArg1gl));
929         OPENGL_CHECK_ERRORS;
930         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, (unit.alphaFlag1gl));
931         OPENGL_CHECK_ERRORS;
932     }
933
934     if( unit.alphaArg2 != CM_IGNORE_BYTE )
935     {
936         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, (unit.alphaArg2gl));
937         OPENGL_CHECK_ERRORS;
938         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, (unit.alphaFlag2gl));
939         OPENGL_CHECK_ERRORS;
940     }
941 #endif
942 }
943
944 //////////////////////////////////////////////////////////////////////////
945
946 void COGLColorCombiner4::GenerateCombinerSetting(int index)
947 {
948     OGLExtCombinerSaveType &res = m_vCompiledSettings[index];
949
950     // Texture unit 0
951     COGLTexture* pTexture = NULL;
952     COGLTexture* pTexture1 = NULL;
953
954     if( m_bTex0Enabled || m_bTex1Enabled || gRDP.otherMode.cycle_type  == CYCLE_TYPE_COPY )
955     {
956         if( m_bTex0Enabled || gRDP.otherMode.cycle_type  == CYCLE_TYPE_COPY )
957         {
958             pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
959             if( pTexture )  m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0);
960         }
961         if( m_bTex1Enabled )
962         {
963             pTexture1 = g_textures[(gRSP.curTile+1)&7].m_pCOGLTexture;
964             if( pTexture1 ) m_pOGLRender->BindTexture(pTexture1->m_dwTextureName, 1);
965         }
966     }
967
968
969
970     for( int i=0; i<res.numOfUnits; i++ )
971     {
972         pglActiveTexture(GL_TEXTURE0_ARB+i);
973         OPENGL_CHECK_ERRORS;
974         m_pOGLRender->EnableTexUnit(i,TRUE);
975         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
976         OPENGL_CHECK_ERRORS;
977         ApplyFor1Unit(res.units[i]);
978     }
979
980     if( res.numOfUnits < m_maxTexUnits )
981     {
982         for( int i=res.numOfUnits; i<m_maxTexUnits; i++ )
983         {
984             pglActiveTexture(GL_TEXTURE0_ARB+i);
985             OPENGL_CHECK_ERRORS;
986             m_pOGLRender->DisBindTexture(0, i);
987             m_pOGLRender->EnableTexUnit(i,FALSE);
988         }
989     }
990 }
991
992
993 void COGLColorCombiner4::GenerateCombinerSettingConstants(int index)
994 {
995     OGLExtCombinerSaveType &res = m_vCompiledSettings[index];
996
997     float *fv;
998     float tempf[4];
999
1000     bool isused = true;
1001
1002     if( res.primIsUsed )
1003     {
1004         fv = GetPrimitiveColorfv(); // CONSTANT COLOR
1005     }
1006     else if( res.envIsUsed )
1007     {
1008         fv = GetEnvColorfv();   // CONSTANT COLOR
1009     }
1010     else if( res.lodFracIsUsed )
1011     {
1012         float frac = gRDP.LODFrac / 255.0f;
1013         tempf[0] = tempf[1] = tempf[2] = tempf[3] = frac;
1014         fv = &tempf[0];
1015     }
1016     else
1017     {
1018         isused = false;
1019     }
1020
1021     if( isused )
1022     {
1023         for( int i=0; i<res.numOfUnits; i++ )
1024         {
1025             pglActiveTexture(GL_TEXTURE0_ARB+i);
1026             OPENGL_CHECK_ERRORS;
1027             glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,fv);
1028             OPENGL_CHECK_ERRORS;
1029         }
1030     }
1031 }
1032
1033
1034 void COGLColorCombiner4v2::GenerateCombinerSettingConstants(int index)
1035 {
1036     //COGLColorCombiner4::GenerateCombinerSettingConstants(index);
1037     //return;
1038
1039     OGLExtCombinerSaveType &res = m_vCompiledSettings[index];
1040     COGLExtRender *prender = (COGLExtRender *)m_pRender;
1041
1042     if( res.primIsUsed )
1043     {
1044         float *fv = GetPrimitiveColorfv();  // CONSTANT COLOR
1045         for( int i=0; i<res.numOfUnits; i++ )
1046         {
1047             pglActiveTexture(GL_TEXTURE0_ARB+i);
1048             OPENGL_CHECK_ERRORS;
1049             glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,fv);
1050             OPENGL_CHECK_ERRORS;
1051         }
1052     }
1053
1054     if( res.envIsUsed )
1055     {
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);
1063     }
1064
1065     if( res.lodFracIsUsed)
1066     {
1067         int unit = 3;
1068         if( !res.envIsUsed )
1069             unit = 2;
1070
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);
1078     }
1079     else
1080     {
1081         int unit = 3;
1082         if( !res.envIsUsed )
1083             unit = 2;
1084
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);
1090     }
1091 }
1092
1093
1094 GLenum GeneralToGLMaps[]=
1095 {
1096     GL_REPLACE,             //CM_REPLACE,
1097 #if SDL_VIDEO_OPENGL
1098     GL_MODULATE,            //CM_MODULATE,
1099     GL_ADD,                 //CM_ADD,
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
1107 #endif
1108     GL_MODULATE_ADD_ATI,    //CM_MULTIPLYADD,       
1109 };
1110
1111
1112 //////////////////////////////////////////////////////////////////////////
1113 int COGLColorCombiner2::ParseDecodedMux()
1114 {
1115     //return COGLColorCombiner4::ParseDecodedMux();
1116
1117     int generalCombinerIndex = CGeneralCombiner::FindCompiledMux();
1118     if( generalCombinerIndex < 0 )      // Can not found
1119     {
1120         generalCombinerIndex = CGeneralCombiner::ParseDecodedMux();
1121     }
1122
1123     GeneralCombinerInfo &generalRes = m_vCompiledCombinerStages[generalCombinerIndex];
1124     OGLExtCombinerSaveType res;
1125
1126     // Convert generalRes to OGLExtCombinerSaveType
1127     for( int unitNo=0; unitNo<generalRes.nStages; unitNo++ )
1128     {
1129         OGLExtCombinerType &unit = res.units[unitNo];
1130         //OGLExt1CombType &colorComb = unit.Combs[0];
1131         //OGLExt1CombType &alphaComb = unit.Combs[1];
1132
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;
1139
1140         unit.rgbOp = GeneralToGLMaps[generalRes.stages[unitNo].colorOp.op];
1141         if( unit.rgbOp == GL_MODULATE_ADD_ATI && !m_bTxtOpMulAdd )
1142         {
1143             if( (unit.rgbArg0&MUX_MASK) == (unit.rgbArg2&MUX_MASK) && (unit.rgbArg0&MUX_COMPLEMENT) )
1144             {
1145                 unit.rgbOp = GL_ADD;
1146                 unit.rgbArg0 &= ~MUX_COMPLEMENT;
1147             }
1148             else
1149             {
1150                 unit.rgbOp = GL_MODULATE;
1151             }
1152         }
1153         unit.alphaOp = GeneralToGLMaps[generalRes.stages[unitNo].alphaOp.op];
1154         if( unit.alphaOp == GL_MODULATE_ADD_ATI && !m_bTxtOpMulAdd )    
1155         {
1156             if( (unit.alphaArg0&MUX_MASK) == (unit.alphaArg2&MUX_MASK) && (unit.alphaArg0&MUX_COMPLEMENT) )
1157             {
1158                 unit.alphaOp = GL_ADD;
1159                 unit.alphaArg0 &= ~MUX_COMPLEMENT;
1160             }
1161             else
1162             {
1163                 unit.alphaOp = GL_MODULATE;
1164             }
1165         }
1166
1167         unit.tex = generalRes.stages[unitNo].dwTexture;
1168         unit.textureIsUsed = generalRes.stages[unitNo].bTextureUsed;
1169     }
1170
1171     res.numOfUnits = generalRes.nStages;
1172     res.constantColor = generalRes.TFactor;
1173     return SaveParsedResult(res);
1174 }
1175
1176
1177 void COGLColorCombiner2::GenerateCombinerSettingConstants(int index)
1178 {
1179     OGLExtCombinerSaveType &res = m_vCompiledSettings[index];
1180
1181     bool isused = true;
1182
1183     float *fv;
1184     float tempf[4];
1185
1186     if( res.primIsUsed )
1187     {
1188         fv = GetPrimitiveColorfv(); // CONSTANT COLOR
1189     }
1190     else if( res.envIsUsed )
1191     {
1192         fv = GetEnvColorfv();   // CONSTANT COLOR
1193     }
1194     else if( res.lodFracIsUsed )
1195     {
1196         float frac = gRDP.LODFrac / 255.0f;
1197         tempf[0] = tempf[1] = tempf[2] = tempf[3] = frac;
1198         fv = &tempf[0];
1199     }
1200     else
1201     {
1202         isused = false;
1203     }
1204
1205     if( isused )
1206     {
1207         for( int i=0; i<res.numOfUnits; i++ )
1208         {
1209             pglActiveTextureARB(GL_TEXTURE0_ARB+i);
1210             OPENGL_CHECK_ERRORS;
1211             glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,fv);
1212             OPENGL_CHECK_ERRORS;
1213         }
1214     }
1215 }
1216 void COGLColorCombiner2::GenerateCombinerSetting(int index)
1217 {
1218     OGLExtCombinerSaveType &res = m_vCompiledSettings[index];
1219     COGLExtRender *prender = (COGLExtRender *)m_pRender;
1220
1221     for( int i=0; i<res.numOfUnits; i++ )
1222     {
1223         pglActiveTextureARB(GL_TEXTURE0_ARB+i);
1224         OPENGL_CHECK_ERRORS;
1225         //if(res.units[i].textureIsUsed)
1226         {
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);
1231         }
1232         /*
1233         else
1234         {
1235             m_pOGLRender->EnableTexUnit(i,TRUE);
1236             prender->SetTextureToTextureUnitMap(-1,i);
1237             //m_pOGLRender->EnableTexUnit(i,FALSE);
1238             //m_pOGLRender->DisBindTexture(0, i);
1239         }
1240         */
1241
1242         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
1243         OPENGL_CHECK_ERRORS;
1244         ApplyFor1Unit(res.units[i]);
1245     }
1246
1247     if( res.numOfUnits < m_maxTexUnits )
1248     {
1249         for( int i=res.numOfUnits; i<m_maxTexUnits; i++ )
1250         {
1251             pglActiveTextureARB(GL_TEXTURE0_ARB+i);
1252             OPENGL_CHECK_ERRORS;
1253             m_pOGLRender->EnableTexUnit(i,FALSE);
1254             prender->SetTextureToTextureUnitMap(-1,i);
1255         }
1256     }
1257 }
1258