Some attempts to speedup Rice when using FB
[mupen64plus-pandora.git] / source / gles2rice / src / OGLExtCombiner.cpp
CommitLineData
292f9317 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
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
106bool 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//========================================================================
133void 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//////////////////////////////////////////////////////////////////////////
149void 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//////////////////////////////////////////////////////////////////////////
212int 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
420int 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
514const 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
539int 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
578bool isGLtex(GLint val)
579{
580 if( val >= GL_TEXTURE0_ARB && val <= GL_TEXTURE7_ARB )
581 return true;
582 else
583 return false;
584}
585
586int 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
675extern const char *translatedCombTypes[];
676void 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}
690void 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//////////////////////////////////////////////////////////////////////////
717int 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
738GLint 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
766GLint 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
796GLint 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
828GLint COGLColorCombiner4::MapRGBArgs(uint8 arg)
829{
830 return RGBArgsMap4[arg&MUX_MASK];
831}
832
833GLint COGLColorCombiner4v2::MapRGBArgs(uint8 arg)
834{
835 return RGBArgsMap4v2[arg&MUX_MASK];
836}
837
838GLint COGLColorCombiner2::MapRGBArgs(uint8 arg)
839{
840 return RGBArgsMap2[arg&MUX_MASK];
841}
842
843GLint 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
861GLint COGLColorCombiner4::MapAlphaArgs(uint8 arg)
862{
863 return RGBArgsMap4[arg&MUX_MASK];
864}
865
866GLint COGLColorCombiner4v2::MapAlphaArgs(uint8 arg)
867{
868 return RGBArgsMap4v2[arg&MUX_MASK];
869}
870
871GLint COGLColorCombiner2::MapAlphaArgs(uint8 arg)
872{
873 return RGBArgsMap2[arg&MUX_MASK];
874}
875
876GLint 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
888void 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
946void 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
993void 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
1034void 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
1094GLenum 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//////////////////////////////////////////////////////////////////////////
1113int 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
1177void 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}
1216void 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