PANDORA: Make GLES context compatible with latest driver (FB only, no X11)
[mupen64plus-pandora.git] / source / rice_gles / src / OGLExtCombiner.cpp
CommitLineData
d07c171f 1/*
2Copyright (C) 2003 Rice1964
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, 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//========================================================================
37COGLColorCombiner4::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
48COGLColorCombiner4v2::COGLColorCombiner4v2(CRender *pRender)
49 :COGLColorCombiner4(pRender)
50{
51 delete m_pDecodedMux;
52 m_pDecodedMux = new DecodedMuxForOGL14V2;
53}
54
55COGLColorCombiner2::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//////////////////////////////////////////////////////////////////////////
64bool 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
111bool 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//========================================================================
138void 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//////////////////////////////////////////////////////////////////////////
154void 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//////////////////////////////////////////////////////////////////////////
217int 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
425int 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
519const 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
544int 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
583bool isGLtex(GLint val)
584{
585 if( val >= GL_TEXTURE0_ARB && val <= GL_TEXTURE7_ARB )
586 return true;
587 else
588 return false;
589}
590
591int 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
680extern const char *translatedCombTypes[];
681void 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}
695void 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//////////////////////////////////////////////////////////////////////////
722int 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
743GLint 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
771GLint 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
801GLint 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
833GLint COGLColorCombiner4::MapRGBArgs(uint8 arg)
834{
835 return RGBArgsMap4[arg&MUX_MASK];
836}
837
838GLint COGLColorCombiner4v2::MapRGBArgs(uint8 arg)
839{
840 return RGBArgsMap4v2[arg&MUX_MASK];
841}
842
843GLint COGLColorCombiner2::MapRGBArgs(uint8 arg)
844{
845 return RGBArgsMap2[arg&MUX_MASK];
846}
847
848GLint 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
866GLint COGLColorCombiner4::MapAlphaArgs(uint8 arg)
867{
868 return RGBArgsMap4[arg&MUX_MASK];
869}
870
871GLint COGLColorCombiner4v2::MapAlphaArgs(uint8 arg)
872{
873 return RGBArgsMap4v2[arg&MUX_MASK];
874}
875
876GLint COGLColorCombiner2::MapAlphaArgs(uint8 arg)
877{
878 return RGBArgsMap2[arg&MUX_MASK];
879}
880
881GLint 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
893void 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
951void 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
998void 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
1039void 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
1099GLenum 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//////////////////////////////////////////////////////////////////////////
1118int 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
1182void 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}
1221void 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