Added missing launcher
[mupen64plus-pandora.git] / source / rice_gles / 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 #ifndef HAVE_GLES
77         if( pcontext->IsExtensionSupported("GL_EXT_texture_env_combine") || pcontext->IsExtensionSupported("GL_ARB_texture_env_combine") )
78 #endif
79         {
80             m_bOGLExtCombinerSupported = true;
81             glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB,&m_maxTexUnits);
82             OPENGL_CHECK_ERRORS;
83             if( m_maxTexUnits > 8 ) m_maxTexUnits = 8;
84
85             TRACE0("Starting Ogl 1.4 multitexture combiner" );
86             TRACE1("m_maxTexUnits = %d", m_maxTexUnits);
87 #ifndef HAVE_GLES
88             if( pcontext->IsExtensionSupported("ATI_texture_env_combine3") )
89             {
90                 m_bSupportModAdd_ATI = true;
91                 m_bSupportModSub_ATI = true;
92             }
93 #endif
94         }
95 #ifndef HAVE_GLES
96         else
97         {
98             DebugMessage(M64MSG_ERROR, "Your video card does not support OpenGL extension combiner, you can only use the basic OpenGL combiner functions");
99         }
100 #endif
101         m_supportedStages = m_maxTexUnits;
102         return true;
103     }
104     return false;
105
106 #elif SDL_VIDEO_OPENGL_ES2
107     return true;
108 #endif
109 }
110
111 bool COGLColorCombiner2::Initialize(void)
112 {
113     TRACE0("Starting Ogl 1.2/1.3 multitexture combiner" );
114     if( COGLColorCombiner4::Initialize() )
115     {
116         // For general combiner flags
117         m_dwGeneralMaxStages = m_supportedStages;
118
119         m_bTxtOpAdd = m_bSupportAdd;
120         m_bTxtOpSub = m_bSupportSubtract;
121         m_bTxtOpLerp = true;
122
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;
129
130         return true;
131     }
132     else
133     {
134         return false;
135     }
136 }
137 //========================================================================
138 void COGLColorCombiner4::InitCombinerCycleFill(void)
139 {
140     for( int i=0; i<m_supportedStages; i++ )
141     {
142         pglActiveTexture(GL_TEXTURE0_ARB+i);
143         OPENGL_CHECK_ERRORS;
144         m_pOGLRender->EnableTexUnit(i,FALSE);
145     }
146
147     //pglActiveTexture(GL_TEXTURE0_ARB);
148     //m_pOGLRender->EnableTexUnit(0,FALSE);
149     //pglActiveTexture(GL_TEXTURE1_ARB);
150     //m_pOGLRender->EnableTexUnit(1,FALSE);
151 }
152
153 //////////////////////////////////////////////////////////////////////////
154 void COGLColorCombiner4::InitCombinerCycle12(void)
155 {
156     if( !m_bOGLExtCombinerSupported )   
157     {
158         COGLColorCombiner::InitCombinerCycle12();
159         return;
160     }
161
162 #ifdef DEBUGGER
163     if( debuggerDropCombiners )
164     {
165         UpdateCombiner(m_pDecodedMux->m_dwMux0,m_pDecodedMux->m_dwMux1);
166         m_vCompiledSettings.clear();
167         m_dwLastMux0 = m_dwLastMux1 = 0;
168         debuggerDropCombiners = false;
169     }
170 #endif
171
172     m_pOGLRender->EnableMultiTexture();
173
174     bool combinerIsChanged = false;
175
176     if( m_pDecodedMux->m_dwMux0 != m_dwLastMux0 || m_pDecodedMux->m_dwMux1 != m_dwLastMux1 || m_lastIndex < 0 )
177     {
178         combinerIsChanged = true;
179         m_lastIndex = FindCompiledMux();
180         if( m_lastIndex < 0 )       // Can not found
181         {
182             m_lastIndex = ParseDecodedMux();
183 #ifdef DEBUGGER
184             DisplaySimpleMuxString();
185 #endif
186         }
187
188         m_dwLastMux0 = m_pDecodedMux->m_dwMux0;
189         m_dwLastMux1 = m_pDecodedMux->m_dwMux1;
190     }
191     
192
193     if( m_bCycleChanged || combinerIsChanged || gRDP.texturesAreReloaded || gRDP.colorsAreReloaded )
194     {
195         if( m_bCycleChanged || combinerIsChanged )
196         {
197             GenerateCombinerSettingConstants(m_lastIndex);
198             GenerateCombinerSetting(m_lastIndex);
199         }
200         else if( gRDP.colorsAreReloaded )
201         {
202             GenerateCombinerSettingConstants(m_lastIndex);
203         }
204
205         m_pOGLRender->SetAllTexelRepeatFlag();
206
207         gRDP.colorsAreReloaded = false;
208         gRDP.texturesAreReloaded = false;
209     }
210     else
211     {
212         m_pOGLRender->SetAllTexelRepeatFlag();
213     }
214 }
215
216 //////////////////////////////////////////////////////////////////////////
217 int COGLColorCombiner4::ParseDecodedMux()
218 {
219 #define nextUnit()  {unitNo++;}
220 #if SDL_VIDEO_OPENGL
221     if( m_maxTexUnits<3) 
222         return  ParseDecodedMux2Units();
223
224     OGLExtCombinerSaveType res;
225     for( int k=0; k<8; k++ )
226         res.units[k].tex = -1;
227     
228     COGLDecodedMux &mux = *(COGLDecodedMux*)m_pDecodedMux;
229
230     int unitNos[2];
231     for( int rgbalpha = 0; rgbalpha<2; rgbalpha++ )
232     {
233         unitNos[rgbalpha] = 0;
234         for( int cycle = 0; cycle<2; cycle++ )
235         {
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;
242
243             switch( type )
244             {
245             case CM_FMT_TYPE_NOT_USED:
246                 comb.arg0 = MUX_COMBINED;
247                 unit.ops[rgbalpha] = GL_REPLACE;
248                 nextUnit();
249                 break;
250             case CM_FMT_TYPE_D:                 // = A
251                 comb.arg0 = m.d;
252                 unit.ops[rgbalpha] = GL_REPLACE;
253                 nextUnit();
254                 break;
255             case CM_FMT_TYPE_A_ADD_D:           // = A+D
256                 comb.arg0 = m.a;
257                 comb.arg1 = m.d;
258                 unit.ops[rgbalpha] = GL_ADD;
259                 nextUnit();
260                 break;
261             case CM_FMT_TYPE_A_SUB_B:           // = A-B
262                 comb.arg0 = m.a;
263                 comb.arg1 = m.b;
264                 unit.ops[rgbalpha] = GL_SUBTRACT_ARB;
265                 nextUnit();
266                 break;
267             case CM_FMT_TYPE_A_MOD_C:           // = A*C
268                 comb.arg0 = m.a;
269                 comb.arg1 = m.c;
270                 unit.ops[rgbalpha] = GL_MODULATE;
271                 nextUnit();
272                 break;
273             case CM_FMT_TYPE_A_MOD_C_ADD_D:     // = A*C+D
274                 if( m_bSupportModAdd_ATI )
275                 {
276                     comb.arg0 = m.a;
277                     comb.arg2 = m.c;
278                     comb.arg1 = m.d;
279                     unit.ops[rgbalpha] = GL_MODULATE_ADD_ATI;
280                     nextUnit();
281                 }
282                 else
283                 {
284                     if( unitNo < m_maxTexUnits-1 )
285                     {
286                         comb.arg0 = m.a;
287                         comb.arg1 = m.c;
288                         unit.ops[rgbalpha] = GL_MODULATE;
289                         nextUnit();
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;
293                         nextUnit();
294                     }
295                     else
296                     {
297                         comb.arg0 = m.a;
298                         comb.arg1 = m.c;
299                         comb.arg2 = m.d;
300                         unit.ops[rgbalpha] = GL_INTERPOLATE_ARB;
301                         nextUnit();
302                     }
303                 }
304                 break;
305             case CM_FMT_TYPE_A_LERP_B_C:        // = (A-B)*C+B
306                 comb.arg0 = m.a;
307                 comb.arg1 = m.b;
308                 comb.arg2 = m.c;
309                 unit.ops[rgbalpha] = GL_INTERPOLATE_ARB;
310                 nextUnit();
311                 break;
312             case CM_FMT_TYPE_A_SUB_B_ADD_D:     // = A-B+D
313                 if( unitNo < m_maxTexUnits-1 )
314                 {
315                     comb.arg0 = m.a;
316                     comb.arg1 = m.b;
317                     unit.ops[rgbalpha] = GL_SUBTRACT_ARB;
318                     nextUnit();
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;
322                     nextUnit();
323                 }
324                 else
325                 {
326                     comb.arg0 = m.a;
327                     comb.arg1 = m.c;
328                     comb.arg2 = m.d;
329                     unit.ops[rgbalpha] = GL_INTERPOLATE_ARB;
330                     nextUnit();
331                 }
332                 break;
333             case CM_FMT_TYPE_A_SUB_B_MOD_C:     // = (A-B)*C
334                 if( unitNo < m_maxTexUnits-1 )
335                 {
336                     comb.arg0 = m.a;
337                     comb.arg1 = m.b;
338                     unit.ops[rgbalpha] = GL_SUBTRACT_ARB;
339                     nextUnit();
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;
343                     nextUnit();
344                 }
345                 else
346                 {
347                     comb.arg0 = m.a;
348                     comb.arg1 = m.c;
349                     comb.arg2 = m.d;
350                     unit.ops[rgbalpha] = GL_INTERPOLATE_ARB;
351                     nextUnit();
352                 }
353                 break;
354             case CM_FMT_TYPE_A_B_C_D:           // = (A-B)*C+D
355             default:
356                 if( unitNo < m_maxTexUnits-1 )
357                 {
358                     comb.arg0 = m.a;
359                     comb.arg1 = m.b;
360                     unit.ops[rgbalpha] = GL_SUBTRACT_ARB;
361                     nextUnit();
362                     if( m_bSupportModAdd_ATI )
363                     {
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;
368                         nextUnit();
369                     }
370                     else
371                     {
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;
376                         nextUnit();
377                     }
378                 }
379                 else
380                 {
381                     comb.arg0 = m.a;
382                     comb.arg1 = m.c;
383                     comb.arg2 = m.d;
384                     unit.ops[rgbalpha] = GL_INTERPOLATE_ARB;
385                     nextUnit();
386                 }
387                 break;
388             }
389         }
390     }
391         
392     res.numOfUnits = min(m_maxTexUnits, max(unitNos[0],unitNos[1]));
393
394     if( unitNos[0]>m_maxTexUnits || unitNos[1]>m_maxTexUnits ) 
395     {
396         TRACE0("Unit overflows");
397     }
398
399     for( int j=0; j<2; j++ )
400     {
401         if( unitNos[j]<res.numOfUnits )
402         {
403             for( int i=unitNos[j]; i<res.numOfUnits; i++ )
404             {
405                 res.units[i].Combs[j].arg0 = MUX_COMBINED;
406                 res.units[i].ops[j] = GL_REPLACE;
407             }
408         }
409     }
410
411     res.units[0].tex = 0;
412     res.units[1].tex = 1;
413
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);
417
418     return SaveParsedResult(res);
419
420 #elif SDL_VIDEO_OPENGL_ES2
421     return 0;
422 #endif
423 }
424
425 int COGLColorCombiner4::ParseDecodedMux2Units()
426 {
427     OGLExtCombinerSaveType res;
428     for( int k=0; k<8; k++ )
429         res.units[k].tex = -1;
430
431     res.numOfUnits = 2;
432
433     for( int i=0; i<res.numOfUnits*2; i++ ) // Set combiner for each texture unit
434     {
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
437
438         OGLExtCombinerType &unit = res.units[i/2];
439         OGLExt1CombType &comb = unit.Combs[i%2];
440
441         CombinerFormatType type = m_pDecodedMux->splitType[i];
442         N64CombinerType &m = m_pDecodedMux->m_n64Combiners[i];
443
444         comb.arg0 = comb.arg1 = comb.arg2 = MUX_0;
445
446         switch( type )
447         {
448         case CM_FMT_TYPE_NOT_USED:
449             comb.arg0 = MUX_COMBINED;
450             unit.ops[i%2] = GL_REPLACE;
451             break;
452         case CM_FMT_TYPE_D:                 // = A
453             comb.arg0 = m.d;
454             unit.ops[i%2] = GL_REPLACE;
455             break;
456 #if SDL_VIDEO_OPENGL
457         case CM_FMT_TYPE_A_ADD_D:           // = A+D
458             comb.arg0 = m.a;
459             comb.arg1 = m.d;
460             unit.ops[i%2] = GL_ADD;
461             break;
462         case CM_FMT_TYPE_A_SUB_B:           // = A-B
463             comb.arg0 = m.a;
464             comb.arg1 = m.b;
465             unit.ops[i%2] = GL_SUBTRACT_ARB;
466             break;
467         case CM_FMT_TYPE_A_MOD_C:           // = A*C
468             comb.arg0 = m.a;
469             comb.arg1 = m.c;
470             unit.ops[i%2] = GL_MODULATE;
471             break;
472         case CM_FMT_TYPE_A_MOD_C_ADD_D:     // = A*C+D
473             comb.arg0 = m.a;
474             comb.arg1 = m.c;
475             comb.arg2 = m.d;
476             unit.ops[i%2] = GL_INTERPOLATE_ARB;
477             break;
478         case CM_FMT_TYPE_A_LERP_B_C:        // = (A-B)*C+B
479             comb.arg0 = m.a;
480             comb.arg1 = m.b;
481             comb.arg2 = m.c;
482             unit.ops[i%2] = GL_INTERPOLATE_ARB;
483             break;
484         case CM_FMT_TYPE_A_SUB_B_ADD_D:     // = A-B+D
485             // fix me, to use 2 texture units
486             comb.arg0 = m.a;
487             comb.arg1 = m.b;
488             unit.ops[i%2] = GL_SUBTRACT_ARB;
489             break;
490         case CM_FMT_TYPE_A_SUB_B_MOD_C:     // = (A-B)*C
491             // fix me, to use 2 texture units
492             comb.arg0 = m.a;
493             comb.arg1 = m.c;
494             unit.ops[i%2] = GL_MODULATE;
495             break;
496             break;
497         case CM_FMT_TYPE_A_B_C_D:           // = (A-B)*C+D
498 #endif
499         default:
500             comb.arg0 = m.a;
501             comb.arg1 = m.b;
502             comb.arg2 = m.c;
503             unit.ops[i%2] = GL_INTERPOLATE_ARB;
504             break;
505         }
506     }
507
508     if( m_pDecodedMux->splitType[2] == CM_FMT_TYPE_NOT_USED && m_pDecodedMux->splitType[3] == CM_FMT_TYPE_NOT_USED && !m_bTex1Enabled )
509     {
510         res.numOfUnits = 1;
511     }
512
513     res.units[0].tex = 0;
514     res.units[1].tex = 1;
515
516     return SaveParsedResult(res);
517 }
518
519 const char* COGLColorCombiner4::GetOpStr(GLenum op)
520 {
521     switch( op )
522     {
523     case GL_REPLACE:
524         return "REPLACE";
525 #if SDL_VIDEO_OPENGL
526     case GL_MODULATE:
527         return "MOD";
528     case GL_ADD:
529         return "ADD";
530     case GL_ADD_SIGNED_ARB:
531         return "ADD_SIGNED";
532     case GL_INTERPOLATE_ARB:
533         return "INTERPOLATE";
534     case GL_SUBTRACT_ARB:
535         return "SUB";
536 #endif
537     case GL_MODULATE_ADD_ATI:
538         return "MULADD";
539     default:
540         return "SUB";
541     }
542 }
543
544 int COGLColorCombiner4::SaveParsedResult(OGLExtCombinerSaveType &result)
545 {
546     result.dwMux0 = m_pDecodedMux->m_dwMux0;
547     result.dwMux1 = m_pDecodedMux->m_dwMux1;
548
549     for( int n=0; n<result.numOfUnits; n++ )
550     {
551         for( int i=0; i<3; i++ )
552         {
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 )
558             {
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]);
561             }
562             if( result.units[n].alphaComb.args[i] != CM_IGNORE_BYTE )
563             {
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]);
566             }
567         }
568     }
569
570     m_vCompiledSettings.push_back(result);
571     m_lastIndex = m_vCompiledSettings.size()-1;
572
573 #ifdef DEBUGGER
574     if( logCombiners )
575     {
576         DisplaySimpleMuxString();
577     }
578 #endif
579
580     return m_lastIndex;
581 }
582
583 bool isGLtex(GLint val)
584 {
585     if( val >= GL_TEXTURE0_ARB && val <= GL_TEXTURE7_ARB )
586         return true;
587     else
588         return false;
589 }
590
591 int COGLColorCombiner4v2::SaveParsedResult(OGLExtCombinerSaveType &result)
592 {
593     result.dwMux0 = m_pDecodedMux->m_dwMux0;
594     result.dwMux1 = m_pDecodedMux->m_dwMux1;
595
596     int n;
597
598     for( n=0; n<result.numOfUnits; n++ )
599     {
600         for( int i=0; i<3; i++ )
601         {
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 )
607             {
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;
611
612                 result.units[n].glRGBFlags[i] = MapRGBArgFlags(result.units[n].rgbComb.args[i]);
613             }
614             if( result.units[n].alphaComb.args[i] != CM_IGNORE_BYTE )
615             {
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;
619
620                 result.units[n].glAlphaFlags[i] = MapAlphaArgFlags(result.units[n].alphaComb.args[i]);
621             }
622         }
623
624         if( isGLtex(result.units[n].glRGBArgs[0]) && isGLtex(result.units[n].glRGBArgs[1]) && isGLtex(result.units[n].glRGBArgs[2]) )
625         {
626             result.units[n].glRGBArgs[2] = GL_CONSTANT_ARB;
627         }
628         if( isGLtex(result.units[n].glAlphaArgs[0]) && isGLtex(result.units[n].glAlphaArgs[1]) && isGLtex(result.units[n].glAlphaArgs[2]) )
629         {
630             result.units[n].glRGBArgs[2] = GL_CONSTANT_ARB;
631         }
632     }
633
634     int extraUnit = 0;
635     if( result.envIsUsed )  extraUnit++;
636     if( result.lodFracIsUsed ) extraUnit++;
637     for( n=result.numOfUnits; n<result.numOfUnits+extraUnit; n++ )
638     {
639         for( int i=0; i<3; i++ )
640         {
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;
647         }
648         
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;
661     }
662
663     result.numOfUnits += extraUnit;
664
665     m_vCompiledSettings.push_back(result);
666     m_lastIndex = m_vCompiledSettings.size()-1;
667
668 #ifdef DEBUGGER
669     if( logCombiners )
670     {
671         DisplaySimpleMuxString();
672     }
673 #endif
674
675     return m_lastIndex;
676 }
677
678
679 #ifdef DEBUGGER
680 extern const char *translatedCombTypes[];
681 void COGLColorCombiner4::DisplaySimpleMuxString(void)
682 {
683     char buf0[30], buf1[30], buf2[30];
684     OGLExtCombinerSaveType &result = m_vCompiledSettings[m_lastIndex];
685
686     COGLColorCombiner::DisplaySimpleMuxString();
687     DebuggerAppendMsg("OpenGL 1.2: %d Stages", result.numOfUnits);      
688     for( int i=0; i<result.numOfUnits; i++ )
689     {
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));       
692     }
693     TRACE0("\n\n");
694 }
695 void COGLColorCombiner2::DisplaySimpleMuxString(void)
696 {
697     char buf0[30], buf1[30], buf2[30];
698     OGLExtCombinerSaveType &result = m_vCompiledSettings[m_lastIndex];
699
700     COGLColorCombiner::DisplaySimpleMuxString();
701     int generalCombinerIndex = CGeneralCombiner::FindCompiledMux();
702     if( generalCombinerIndex < 0 )      // Can not found
703     {
704         generalCombinerIndex = CGeneralCombiner::ParseDecodedMux();
705     }
706     DebuggerAppendMsg("Generated general combiners:");
707     GeneralCombinerInfo &generalRes = m_vCompiledCombinerStages[generalCombinerIndex];
708     General_DisplayBlendingStageInfo(generalRes);
709
710     DebuggerAppendMsg("OpenGL 1.2: %d Stages", result.numOfUnits);      
711     for( int i=0; i<result.numOfUnits; i++ )
712     {
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));       
715     }
716     TRACE0("\n\n");
717 }
718 #endif
719
720
721 //////////////////////////////////////////////////////////////////////////
722 int COGLColorCombiner4::FindCompiledMux()
723 {
724 #ifdef DEBUGGER
725     if( debuggerDropCombiners )
726     {
727         m_vCompiledSettings.clear();
728         //m_dwLastMux0 = m_dwLastMux1 = 0;
729         debuggerDropCombiners = false;
730     }
731 #endif
732     for( uint32 i=0; i<m_vCompiledSettings.size(); i++ )
733     {
734         if( m_vCompiledSettings[i].dwMux0 == m_pDecodedMux->m_dwMux0 && m_vCompiledSettings[i].dwMux1 == m_pDecodedMux->m_dwMux1 )
735             return (int)i;
736     }
737
738     return -1;
739 }
740
741 //========================================================================
742
743 GLint COGLColorCombiner4::RGBArgsMap4[] =
744 {
745 #if SDL_VIDEO_OPENGL
746     GL_PRIMARY_COLOR_ARB,           //MUX_0
747     GL_PRIMARY_COLOR_ARB,           //MUX_1
748     GL_PREVIOUS_ARB,                //MUX_COMBINED,
749 #endif
750     GL_TEXTURE0_ARB,                //MUX_TEXEL0,
751 #if SDL_VIDEO_OPENGL
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,
757 #endif
758     GL_TEXTURE0_ARB,                //MUX_T0_ALPHA,
759 #if SDL_VIDEO_OPENGL
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
768 #endif
769 };
770
771 GLint COGLColorCombiner4v2::RGBArgsMap4v2[] =
772 {
773 #if SDL_VIDEO_OPENGL
774     GL_PRIMARY_COLOR_ARB,           //MUX_0
775     GL_PRIMARY_COLOR_ARB,           //MUX_1
776     GL_PREVIOUS_ARB,                //MUX_COMBINED,
777 #endif
778     GL_TEXTURE0_ARB,                //MUX_TEXEL0,
779 #if SDL_VIDEO_OPENGL
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
798 #endif
799 };
800
801 GLint COGLColorCombiner2::RGBArgsMap2[] =
802 {
803 #if SDL_VIDEO_OPENGL
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,
809 #endif
810     GL_TEXTURE0_ARB,                //MUX_TEXEL0,
811 #if SDL_VIDEO_OPENGL
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
828 #endif
829 };
830
831 //========================================================================
832
833 GLint COGLColorCombiner4::MapRGBArgs(uint8 arg)
834 {
835     return RGBArgsMap4[arg&MUX_MASK];
836 }
837
838 GLint COGLColorCombiner4v2::MapRGBArgs(uint8 arg)
839 {
840     return RGBArgsMap4v2[arg&MUX_MASK];
841 }
842
843 GLint COGLColorCombiner2::MapRGBArgs(uint8 arg)
844 {
845     return RGBArgsMap2[arg&MUX_MASK];
846 }
847
848 GLint COGLColorCombiner4::MapRGBArgFlags(uint8 arg)
849 {
850     if( (arg & MUX_ALPHAREPLICATE) && (arg & MUX_COMPLEMENT) )
851     {
852         return GL_ONE_MINUS_SRC_ALPHA;
853     }
854     else if( (arg & MUX_ALPHAREPLICATE) )
855     {
856         return GL_SRC_ALPHA;
857     }
858     else if(arg & MUX_COMPLEMENT) 
859     {
860         return GL_ONE_MINUS_SRC_COLOR;
861     }
862     else
863         return GL_SRC_COLOR;
864 }
865
866 GLint COGLColorCombiner4::MapAlphaArgs(uint8 arg)
867 {
868     return RGBArgsMap4[arg&MUX_MASK];
869 }
870
871 GLint COGLColorCombiner4v2::MapAlphaArgs(uint8 arg)
872 {
873     return RGBArgsMap4v2[arg&MUX_MASK];
874 }
875
876 GLint COGLColorCombiner2::MapAlphaArgs(uint8 arg)
877 {
878     return RGBArgsMap2[arg&MUX_MASK];
879 }
880
881 GLint COGLColorCombiner4::MapAlphaArgFlags(uint8 arg)
882 {
883     if(arg & MUX_COMPLEMENT) 
884     {
885         return GL_ONE_MINUS_SRC_ALPHA;
886     }
887     else
888         return GL_SRC_ALPHA;
889 }
890
891 //========================================================================
892
893 void ApplyFor1Unit(OGLExtCombinerType &unit)
894 {
895 #if SDL_VIDEO_OPENGL
896     glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, unit.rgbOp);
897     OPENGL_CHECK_ERRORS;
898
899     if( unit.rgbArg0 != CM_IGNORE_BYTE )
900     {
901         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, (unit.rgbArg0gl));
902         OPENGL_CHECK_ERRORS;
903         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, (unit.rgbFlag0gl));
904         OPENGL_CHECK_ERRORS;
905     }
906
907     if( unit.rgbArg1 != CM_IGNORE_BYTE )
908     {
909         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, (unit.rgbArg1gl));
910         OPENGL_CHECK_ERRORS;
911         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, (unit.rgbFlag1gl));
912         OPENGL_CHECK_ERRORS;
913     }
914
915     if( unit.rgbArg2 != CM_IGNORE_BYTE )
916     {
917         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, (unit.rgbArg2gl));
918         OPENGL_CHECK_ERRORS;
919         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, (unit.rgbFlag2gl));
920         OPENGL_CHECK_ERRORS;
921     }
922
923     if( unit.alphaArg0 != CM_IGNORE_BYTE )
924     {
925         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, (unit.alphaArg0gl));
926         OPENGL_CHECK_ERRORS;
927         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, (unit.alphaFlag0gl));
928         OPENGL_CHECK_ERRORS;
929     }
930
931     if( unit.alphaArg1 != CM_IGNORE_BYTE )
932     {
933         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, (unit.alphaArg1gl));
934         OPENGL_CHECK_ERRORS;
935         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, (unit.alphaFlag1gl));
936         OPENGL_CHECK_ERRORS;
937     }
938
939     if( unit.alphaArg2 != CM_IGNORE_BYTE )
940     {
941         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, (unit.alphaArg2gl));
942         OPENGL_CHECK_ERRORS;
943         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, (unit.alphaFlag2gl));
944         OPENGL_CHECK_ERRORS;
945     }
946 #endif
947 }
948
949 //////////////////////////////////////////////////////////////////////////
950
951 void COGLColorCombiner4::GenerateCombinerSetting(int index)
952 {
953     OGLExtCombinerSaveType &res = m_vCompiledSettings[index];
954
955     // Texture unit 0
956     COGLTexture* pTexture = NULL;
957     COGLTexture* pTexture1 = NULL;
958
959     if( m_bTex0Enabled || m_bTex1Enabled || gRDP.otherMode.cycle_type  == CYCLE_TYPE_COPY )
960     {
961         if( m_bTex0Enabled || gRDP.otherMode.cycle_type  == CYCLE_TYPE_COPY )
962         {
963             pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
964             if( pTexture )  m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0);
965         }
966         if( m_bTex1Enabled )
967         {
968             pTexture1 = g_textures[(gRSP.curTile+1)&7].m_pCOGLTexture;
969             if( pTexture1 ) m_pOGLRender->BindTexture(pTexture1->m_dwTextureName, 1);
970         }
971     }
972
973
974
975     for( int i=0; i<res.numOfUnits; i++ )
976     {
977         pglActiveTexture(GL_TEXTURE0_ARB+i);
978         OPENGL_CHECK_ERRORS;
979         m_pOGLRender->EnableTexUnit(i,TRUE);
980         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
981         OPENGL_CHECK_ERRORS;
982         ApplyFor1Unit(res.units[i]);
983     }
984
985     if( res.numOfUnits < m_maxTexUnits )
986     {
987         for( int i=res.numOfUnits; i<m_maxTexUnits; i++ )
988         {
989             pglActiveTexture(GL_TEXTURE0_ARB+i);
990             OPENGL_CHECK_ERRORS;
991             m_pOGLRender->DisBindTexture(0, i);
992             m_pOGLRender->EnableTexUnit(i,FALSE);
993         }
994     }
995 }
996
997
998 void COGLColorCombiner4::GenerateCombinerSettingConstants(int index)
999 {
1000     OGLExtCombinerSaveType &res = m_vCompiledSettings[index];
1001
1002     float *fv;
1003     float tempf[4];
1004
1005     bool isused = true;
1006
1007     if( res.primIsUsed )
1008     {
1009         fv = GetPrimitiveColorfv(); // CONSTANT COLOR
1010     }
1011     else if( res.envIsUsed )
1012     {
1013         fv = GetEnvColorfv();   // CONSTANT COLOR
1014     }
1015     else if( res.lodFracIsUsed )
1016     {
1017         float frac = gRDP.LODFrac / 255.0f;
1018         tempf[0] = tempf[1] = tempf[2] = tempf[3] = frac;
1019         fv = &tempf[0];
1020     }
1021     else
1022     {
1023         isused = false;
1024     }
1025
1026     if( isused )
1027     {
1028         for( int i=0; i<res.numOfUnits; i++ )
1029         {
1030             pglActiveTexture(GL_TEXTURE0_ARB+i);
1031             OPENGL_CHECK_ERRORS;
1032             glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,fv);
1033             OPENGL_CHECK_ERRORS;
1034         }
1035     }
1036 }
1037
1038
1039 void COGLColorCombiner4v2::GenerateCombinerSettingConstants(int index)
1040 {
1041     //COGLColorCombiner4::GenerateCombinerSettingConstants(index);
1042     //return;
1043
1044     OGLExtCombinerSaveType &res = m_vCompiledSettings[index];
1045     COGLExtRender *prender = (COGLExtRender *)m_pRender;
1046
1047     if( res.primIsUsed )
1048     {
1049         float *fv = GetPrimitiveColorfv();  // CONSTANT COLOR
1050         for( int i=0; i<res.numOfUnits; i++ )
1051         {
1052             pglActiveTexture(GL_TEXTURE0_ARB+i);
1053             OPENGL_CHECK_ERRORS;
1054             glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,fv);
1055             OPENGL_CHECK_ERRORS;
1056         }
1057     }
1058
1059     if( res.envIsUsed )
1060     {
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);
1068     }
1069
1070     if( res.lodFracIsUsed)
1071     {
1072         int unit = 3;
1073         if( !res.envIsUsed )
1074             unit = 2;
1075
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);
1083     }
1084     else
1085     {
1086         int unit = 3;
1087         if( !res.envIsUsed )
1088             unit = 2;
1089
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);
1095     }
1096 }
1097
1098
1099 GLenum GeneralToGLMaps[]=
1100 {
1101     GL_REPLACE,             //CM_REPLACE,
1102 #if SDL_VIDEO_OPENGL
1103     GL_MODULATE,            //CM_MODULATE,
1104     GL_ADD,                 //CM_ADD,
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
1112 #endif
1113     GL_MODULATE_ADD_ATI,    //CM_MULTIPLYADD,       
1114 };
1115
1116
1117 //////////////////////////////////////////////////////////////////////////
1118 int COGLColorCombiner2::ParseDecodedMux()
1119 {
1120     //return COGLColorCombiner4::ParseDecodedMux();
1121
1122     int generalCombinerIndex = CGeneralCombiner::FindCompiledMux();
1123     if( generalCombinerIndex < 0 )      // Can not found
1124     {
1125         generalCombinerIndex = CGeneralCombiner::ParseDecodedMux();
1126     }
1127
1128     GeneralCombinerInfo &generalRes = m_vCompiledCombinerStages[generalCombinerIndex];
1129     OGLExtCombinerSaveType res;
1130
1131     // Convert generalRes to OGLExtCombinerSaveType
1132     for( int unitNo=0; unitNo<generalRes.nStages; unitNo++ )
1133     {
1134         OGLExtCombinerType &unit = res.units[unitNo];
1135         //OGLExt1CombType &colorComb = unit.Combs[0];
1136         //OGLExt1CombType &alphaComb = unit.Combs[1];
1137
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;
1144
1145         unit.rgbOp = GeneralToGLMaps[generalRes.stages[unitNo].colorOp.op];
1146         if( unit.rgbOp == GL_MODULATE_ADD_ATI && !m_bTxtOpMulAdd )
1147         {
1148             if( (unit.rgbArg0&MUX_MASK) == (unit.rgbArg2&MUX_MASK) && (unit.rgbArg0&MUX_COMPLEMENT) )
1149             {
1150                 unit.rgbOp = GL_ADD;
1151                 unit.rgbArg0 &= ~MUX_COMPLEMENT;
1152             }
1153             else
1154             {
1155                 unit.rgbOp = GL_MODULATE;
1156             }
1157         }
1158         unit.alphaOp = GeneralToGLMaps[generalRes.stages[unitNo].alphaOp.op];
1159         if( unit.alphaOp == GL_MODULATE_ADD_ATI && !m_bTxtOpMulAdd )    
1160         {
1161             if( (unit.alphaArg0&MUX_MASK) == (unit.alphaArg2&MUX_MASK) && (unit.alphaArg0&MUX_COMPLEMENT) )
1162             {
1163                 unit.alphaOp = GL_ADD;
1164                 unit.alphaArg0 &= ~MUX_COMPLEMENT;
1165             }
1166             else
1167             {
1168                 unit.alphaOp = GL_MODULATE;
1169             }
1170         }
1171
1172         unit.tex = generalRes.stages[unitNo].dwTexture;
1173         unit.textureIsUsed = generalRes.stages[unitNo].bTextureUsed;
1174     }
1175
1176     res.numOfUnits = generalRes.nStages;
1177     res.constantColor = generalRes.TFactor;
1178     return SaveParsedResult(res);
1179 }
1180
1181
1182 void COGLColorCombiner2::GenerateCombinerSettingConstants(int index)
1183 {
1184     OGLExtCombinerSaveType &res = m_vCompiledSettings[index];
1185
1186     bool isused = true;
1187
1188     float *fv;
1189     float tempf[4];
1190
1191     if( res.primIsUsed )
1192     {
1193         fv = GetPrimitiveColorfv(); // CONSTANT COLOR
1194     }
1195     else if( res.envIsUsed )
1196     {
1197         fv = GetEnvColorfv();   // CONSTANT COLOR
1198     }
1199     else if( res.lodFracIsUsed )
1200     {
1201         float frac = gRDP.LODFrac / 255.0f;
1202         tempf[0] = tempf[1] = tempf[2] = tempf[3] = frac;
1203         fv = &tempf[0];
1204     }
1205     else
1206     {
1207         isused = false;
1208     }
1209
1210     if( isused )
1211     {
1212         for( int i=0; i<res.numOfUnits; i++ )
1213         {
1214             pglActiveTextureARB(GL_TEXTURE0_ARB+i);
1215             OPENGL_CHECK_ERRORS;
1216             glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,fv);
1217             OPENGL_CHECK_ERRORS;
1218         }
1219     }
1220 }
1221 void COGLColorCombiner2::GenerateCombinerSetting(int index)
1222 {
1223     OGLExtCombinerSaveType &res = m_vCompiledSettings[index];
1224     COGLExtRender *prender = (COGLExtRender *)m_pRender;
1225
1226     for( int i=0; i<res.numOfUnits; i++ )
1227     {
1228         pglActiveTextureARB(GL_TEXTURE0_ARB+i);
1229         OPENGL_CHECK_ERRORS;
1230         //if(res.units[i].textureIsUsed)
1231         {
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);
1236         }
1237         /*
1238         else
1239         {
1240             m_pOGLRender->EnableTexUnit(i,TRUE);
1241             prender->SetTextureToTextureUnitMap(-1,i);
1242             //m_pOGLRender->EnableTexUnit(i,FALSE);
1243             //m_pOGLRender->DisBindTexture(0, i);
1244         }
1245         */
1246
1247         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
1248         OPENGL_CHECK_ERRORS;
1249         ApplyFor1Unit(res.units[i]);
1250     }
1251
1252     if( res.numOfUnits < m_maxTexUnits )
1253     {
1254         for( int i=res.numOfUnits; i<m_maxTexUnits; i++ )
1255         {
1256             pglActiveTextureARB(GL_TEXTURE0_ARB+i);
1257             OPENGL_CHECK_ERRORS;
1258             m_pOGLRender->EnableTexUnit(i,FALSE);
1259             prender->SetTextureToTextureUnitMap(-1,i);
1260         }
1261     }
1262 }
1263