1 /******************************************************************************
2 * Arachnoid Graphics Plugin for Mupen64Plus
3 * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
5 * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *****************************************************************************/
24 #include "AdvancedTexEnvCombiner.h"
25 #include "CombinerStructs.h"
26 #include "MultiTexturingExt.h" //glActiveTextureARB
27 #include "ExtensionChecker.h"
29 #ifndef GL_ATI_texture_env_combine3
30 #define GL_ATI_texture_env_combine3
31 #define GL_ATI_texture_env_combine3
32 #define GL_MODULATE_ADD_ATI 0x8744
33 #define GL_MODULATE_SIGNED_ADD_ATI 0x8745
34 #define GL_MODULATE_SUBTRACT_ATI 0x8746
35 #endif //GL_ATI_texture_env_combine3
37 #ifndef GL_ATIX_texture_env_route
38 #define GL_ATIX_texture_env_route 1
39 #define GL_SECONDARY_COLOR_ATIX 0x8747
40 #define GL_TEXTURE_OUTPUT_RGB_ATIX 0x8748
41 #define GL_TEXTURE_OUTPUT_ALPHA_ATIX 0x8749
42 #endif // GL_ATIX_texture_env_route
44 static TexEnvCombinerArg TexEnvArgs[] =
47 { GL_PREVIOUS_ARB, GL_SRC_COLOR },
49 { GL_TEXTURE, GL_SRC_COLOR },
51 { GL_TEXTURE, GL_SRC_COLOR },
53 { GL_CONSTANT_ARB, GL_SRC_COLOR },
55 { GL_PRIMARY_COLOR_ARB, GL_SRC_COLOR },
57 { GL_CONSTANT_ARB, GL_SRC_COLOR },
59 { GL_CONSTANT_ARB, GL_SRC_COLOR },
61 { GL_CONSTANT_ARB, GL_SRC_COLOR },
63 { GL_PREVIOUS_ARB, GL_SRC_ALPHA },
65 { GL_TEXTURE, GL_SRC_ALPHA },
67 { GL_TEXTURE, GL_SRC_ALPHA },
69 { GL_CONSTANT_ARB, GL_SRC_ALPHA },
71 { GL_PRIMARY_COLOR_ARB, GL_SRC_ALPHA },
73 { GL_CONSTANT_ARB, GL_SRC_COLOR },
75 { GL_CONSTANT_ARB, GL_SRC_COLOR },
77 { GL_CONSTANT_ARB, GL_SRC_COLOR },
79 { GL_TEXTURE, GL_SRC_COLOR },
81 { GL_CONSTANT_ARB, GL_SRC_COLOR },
83 { GL_CONSTANT_ARB, GL_SRC_COLOR },
85 { GL_CONSTANT_ARB, GL_SRC_COLOR },
87 { GL_CONSTANT_ARB, GL_SRC_COLOR }
90 //-----------------------------------------------------------------------------
92 //-----------------------------------------------------------------------------
93 AdvancedTexEnvCombiner::AdvancedTexEnvCombiner()
97 //-----------------------------------------------------------------------------
99 //-----------------------------------------------------------------------------
100 AdvancedTexEnvCombiner::~AdvancedTexEnvCombiner()
104 //-----------------------------------------------------------------------------
106 //! Checks if extensions are supported
107 //-----------------------------------------------------------------------------
108 void AdvancedTexEnvCombiner::initialize()
111 ARB_texture_env_combine = true;
112 ARB_texture_env_crossbar = true;
114 ARB_texture_env_combine = isExtensionSupported( "GL_ARB_texture_env_combine" );
115 ARB_texture_env_crossbar = isExtensionSupported( "GL_ARB_texture_env_crossbar" );
117 ATI_texture_env_combine3 = isExtensionSupported( "GL_ATI_texture_env_combine3" );
118 ATIX_texture_env_route = isExtensionSupported( "GL_ATIX_texture_env_route" );
119 NV_texture_env_combine4 = isExtensionSupported( "GL_NV_texture_env_combine4" );;
121 if ( ARB_texture_env_crossbar || NV_texture_env_combine4 || ATIX_texture_env_route )
123 TexEnvArgs[TEXEL0].source = GL_TEXTURE0_ARB;
124 TexEnvArgs[TEXEL0_ALPHA].source = GL_TEXTURE0_ARB;
125 TexEnvArgs[TEXEL1].source = GL_TEXTURE1_ARB;
126 TexEnvArgs[TEXEL1_ALPHA].source = GL_TEXTURE1_ARB;
129 if ( ATI_texture_env_combine3 )
131 TexEnvArgs[ONE].source = GL_ONE;
132 TexEnvArgs[ZERO].source = GL_ZERO;
136 //-----------------------------------------------------------------------------
137 //* Begin Texture Update
138 //! Disables all textures
139 //-----------------------------------------------------------------------------
140 void AdvancedTexEnvCombiner::beginTextureUpdate()
142 const int openGLMaxTextureUnits = 8;
144 //Disable all texture channels
145 for (int i = 0; i <openGLMaxTextureUnits; i++)
147 glActiveTextureARB(GL_TEXTURE0_ARB + i);
148 glDisable(GL_TEXTURE_2D );
153 //-----------------------------------------------------------------------------
154 //* End Texture Update
155 //! Enables selected textures in a texture environment
156 //! @param texEnv Texture environment with textures to be enabled
157 //-----------------------------------------------------------------------------
158 void AdvancedTexEnvCombiner::endTextureUpdate(TexEnvCombiner* texEnv)
161 for (int i = 0; i <texEnv->usedUnits; i++)
163 glActiveTextureARB( GL_TEXTURE0_ARB + i );
164 glEnable( GL_TEXTURE_2D );
168 //-----------------------------------------------------------------------------
169 //* Set Texture Enviroment Colors
170 //! Sets texture enviorment colors for all active textures
171 //! @param texEnv Texture environment with textures that will be assigned colors
172 //-----------------------------------------------------------------------------
173 void AdvancedTexEnvCombiner::setTextureEnviromentColors(TexEnvCombiner* texEnv)
177 int openGLMaxTextureUnits = 8;
179 for (int i = 0; i < openGLMaxTextureUnits; i++)
181 this->getCombinerColor( color, texEnv->color[i].constant, texEnv->alpha[i].constant );
183 glActiveTextureARB(GL_TEXTURE0_ARB + i);
184 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &color[0]);
188 //-----------------------------------------------------------------------------
189 //* Set Texture Enviroment
190 //! Sets texture environment for all active textures
191 //! @param texEnv Texture environment with input data which will be
192 //! sent to OpenGL using function "glTexEnvi" using ARB extensions
193 //-----------------------------------------------------------------------------
194 void AdvancedTexEnvCombiner::setTextureEnviroment(TexEnvCombiner* texEnv)
196 const int openGLMaxTextureUnits = 8;
198 for (int i=0; i<openGLMaxTextureUnits; ++i)
200 glActiveTextureARB(GL_TEXTURE0_ARB + i);
202 if ( (i < texEnv->usedUnits ) || (i < 2 && texEnv->usesT1) )
204 glEnable( GL_TEXTURE_2D );
205 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
206 glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, texEnv->color[i].combine );
207 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, texEnv->color[i].arg0.source );
208 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, texEnv->color[i].arg0.operand );
209 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, texEnv->color[i].arg1.source );
210 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, texEnv->color[i].arg1.operand );
211 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, texEnv->color[i].arg2.source );
212 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, texEnv->color[i].arg2.operand );
213 glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, texEnv->alpha[i].combine );
214 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, texEnv->alpha[i].arg0.source );
215 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, texEnv->alpha[i].arg0.operand );
216 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, texEnv->alpha[i].arg1.source );
217 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, texEnv->alpha[i].arg1.operand );
218 glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, texEnv->alpha[i].arg2.source );
219 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, texEnv->alpha[i].arg2.operand );
223 glDisable(GL_TEXTURE_2D);
228 //-----------------------------------------------------------------------------
229 //* Create New Texture Enviornment
230 //! Allocates a new texture enviroment
231 //! @param[in] colorCombiner How to combine and get a color
232 //! @param[in] alphaCombiner How to combine and get an alpha value
233 //! @return The texture enviroment that was created
234 //-----------------------------------------------------------------------------
235 TexEnvCombiner* AdvancedTexEnvCombiner::createNewTextureEnviroment(Combiner* colorCombiner, Combiner *alphaCombiner)
237 TexEnvCombiner* envCombiner = new TexEnvCombiner();
241 const int openGLMaxTextureUnits = 8;
243 //For each texture unit
244 for (int i = 0; i < openGLMaxTextureUnits; i++)
246 envCombiner->color[i].combine = GL_REPLACE;
247 envCombiner->alpha[i].combine = GL_REPLACE;
249 SetColorCombinerValues( i, arg0, GL_PREVIOUS_ARB, GL_SRC_COLOR );
250 SetColorCombinerValues( i, arg1, GL_PREVIOUS_ARB, GL_SRC_COLOR );
251 SetColorCombinerValues( i, arg2, GL_PREVIOUS_ARB, GL_SRC_COLOR );
252 envCombiner->color[i].constant = COMBINED;
253 envCombiner->color[i].outputTexture = GL_TEXTURE0_ARB + i;
255 SetAlphaCombinerValues( i, arg0, GL_PREVIOUS_ARB, GL_SRC_ALPHA );
256 SetAlphaCombinerValues( i, arg1, GL_PREVIOUS_ARB, GL_SRC_ALPHA );
257 SetAlphaCombinerValues( i, arg2, GL_PREVIOUS_ARB, GL_SRC_ALPHA );
258 envCombiner->alpha[i].constant = COMBINED;
259 envCombiner->alpha[i].outputTexture = GL_TEXTURE0_ARB + i;
262 envCombiner->usesT0 = false;
263 envCombiner->usesT1 = false;
265 envCombiner->vertex.color = COMBINED;
266 envCombiner->vertex.secondaryColor = COMBINED;
267 envCombiner->vertex.alpha = COMBINED;
271 for (int i=0; i<alphaCombiner->numStages; i++)
273 for (int j = 0; j < alphaCombiner->stage[i].numOps; j++)
277 if (alphaCombiner->stage[i].op[j].param1 == PRIMITIVE_ALPHA)
279 else if (alphaCombiner->stage[i].op[j].param1 == ENV_ALPHA)
281 else if (alphaCombiner->stage[i].op[j].param1 == ONE)
284 if (((alphaCombiner->stage[i].numOps - j) >= 3) &&
285 (alphaCombiner->stage[i].op[j].op == SUB) &&
286 (alphaCombiner->stage[i].op[j+1].op == MUL) &&
287 (alphaCombiner->stage[i].op[j+2].op == ADD) &&
289 (ARB_texture_env_combine))
291 envCombiner->usesT0 |= alphaCombiner->stage[i].op[j].param1 == TEXEL0_ALPHA;
292 envCombiner->usesT1 |= alphaCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA;
294 if (alphaCombiner->stage[i].op[j].param1 == ONE)
296 SetAlphaCombinerValues( curUnit, arg0, envCombiner->alpha[curUnit].arg0.source, GL_ONE_MINUS_SRC_ALPHA );
300 envCombiner->alpha[curUnit].combine = GL_SUBTRACT_ARB;
301 SetAlphaCombinerValues( curUnit, arg1, envCombiner->alpha[curUnit].arg0.source, GL_SRC_ALPHA );
302 SetAlphaCombinerArg( curUnit, arg0, alphaCombiner->stage[i].op[j].param1 );
309 envCombiner->usesT0 |= alphaCombiner->stage[i].op[j].param1 == TEXEL0_ALPHA;
310 envCombiner->usesT1 |= alphaCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA;
312 envCombiner->alpha[curUnit].combine = GL_MODULATE;
313 SetAlphaCombinerArg( curUnit, arg1, alphaCombiner->stage[i].op[j].param1 );
318 envCombiner->usesT0 |= alphaCombiner->stage[i].op[j].param1 == TEXEL0_ALPHA;
319 envCombiner->usesT1 |= alphaCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA;
321 envCombiner->alpha[curUnit].combine = GL_SUBTRACT_ARB;
322 SetAlphaCombinerArg( curUnit, arg0, alphaCombiner->stage[i].op[j].param1 );
328 envCombiner->usesT0 |= alphaCombiner->stage[i].op[j].param1 == TEXEL0_ALPHA;
329 envCombiner->usesT1 |= alphaCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA;
331 switch (alphaCombiner->stage[i].op[j].op)
334 if (!(ARB_texture_env_crossbar || NV_texture_env_combine4) &&
335 (alphaCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA) && (curUnit == 0))
338 envCombiner->alpha[curUnit].combine = GL_REPLACE;
340 SetAlphaCombinerArg( curUnit, arg0, alphaCombiner->stage[i].op[j].param1 );
343 if (!ARB_texture_env_combine)
346 if (!(ARB_texture_env_crossbar || NV_texture_env_combine4) &&
347 (alphaCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA) && (curUnit == 0))
350 if ((j > 0) && (alphaCombiner->stage[i].op[j-1].op == LOAD) && (alphaCombiner->stage[i].op[j-1].param1 == ONE))
352 SetAlphaCombinerArg( curUnit, arg0, alphaCombiner->stage[i].op[j].param1 );
353 envCombiner->alpha[curUnit].arg0.operand = GL_ONE_MINUS_SRC_ALPHA;
355 else if ((ATI_texture_env_combine3) && (curUnit > 0) && (envCombiner->alpha[curUnit - 1].combine == GL_MODULATE))
358 SetAlphaCombinerValues( curUnit, arg2, envCombiner->alpha[curUnit].arg1.source, envCombiner->alpha[curUnit].arg1.operand );
359 envCombiner->alpha[curUnit].combine = GL_MODULATE_SUBTRACT_ATI;
360 SetAlphaCombinerArg( curUnit, arg1, alphaCombiner->stage[i].op[j].param1 );
365 envCombiner->alpha[curUnit].combine = GL_SUBTRACT_ARB;
366 SetAlphaCombinerArg( curUnit, arg1, alphaCombiner->stage[i].op[j].param1 );
371 if (!( ARB_texture_env_crossbar || NV_texture_env_combine4) &&
372 (alphaCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA) && (curUnit == 0))
375 envCombiner->alpha[curUnit].combine = GL_MODULATE;
377 SetAlphaCombinerArg( curUnit, arg1, alphaCombiner->stage[i].op[j].param1 );
381 if (!(ARB_texture_env_crossbar || NV_texture_env_combine4) &&
382 (alphaCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA) && (curUnit == 0))
385 if ((ATI_texture_env_combine3) && (curUnit > 0) && (envCombiner->alpha[curUnit - 1].combine == GL_MODULATE))
388 SetAlphaCombinerValues( curUnit, arg2, envCombiner->alpha[curUnit].arg1.source, envCombiner->alpha[curUnit].arg1.operand );
389 envCombiner->alpha[curUnit].combine = GL_MODULATE_ADD_ATI;
390 SetAlphaCombinerArg( curUnit, arg1, alphaCombiner->stage[i].op[j].param1 );
394 envCombiner->alpha[curUnit].combine = GL_ADD;
395 SetAlphaCombinerArg( curUnit, arg1, alphaCombiner->stage[i].op[j].param1 );
400 envCombiner->usesT0 |= (alphaCombiner->stage[i].op[j].param2 == TEXEL0_ALPHA) || (alphaCombiner->stage[i].op[j].param3 == TEXEL0_ALPHA);
401 envCombiner->usesT1 |= (alphaCombiner->stage[i].op[j].param2 == TEXEL1_ALPHA) || (alphaCombiner->stage[i].op[j].param3 == TEXEL1_ALPHA);
403 envCombiner->alpha[curUnit].combine = GL_INTERPOLATE_ARB;
405 SetAlphaCombinerArg( curUnit, arg0, alphaCombiner->stage[i].op[j].param1 );
406 SetAlphaCombinerArg( curUnit, arg1, alphaCombiner->stage[i].op[j].param2 );
407 SetAlphaCombinerArg( curUnit, arg2, alphaCombiner->stage[i].op[j].param3 );
416 envCombiner->usedUnits = max( curUnit, 1 );
419 for (int i = 0; i < colorCombiner->numStages; i++)
421 for (int j = 0; j < colorCombiner->stage[i].numOps; j++)
425 if (colorCombiner->stage[i].op[j].param1 == PRIMITIVE)
426 sb = (m_primColor[0] + m_primColor[2] + m_primColor[1]) / 3.0f;
427 else if (colorCombiner->stage[i].op[j].param1 == ENVIRONMENT)
428 sb = (m_envColor[0] + m_envColor[2] + m_envColor[1]) / 3.0f;
430 // This helps with problems caused by not using signed values between texture units
431 if (((colorCombiner->stage[i].numOps - j) >= 3) &&
432 (colorCombiner->stage[i].op[j].op == SUB) &&
433 (colorCombiner->stage[i].op[j+1].op == MUL) &&
434 (colorCombiner->stage[i].op[j+2].op == ADD) &&
436 (ARB_texture_env_combine))
438 envCombiner->usesT0 |= ((colorCombiner->stage[i].op[j].param1 == TEXEL0) || (colorCombiner->stage[i].op[j].param1 == TEXEL0_ALPHA));
439 envCombiner->usesT1 |= ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA));
441 envCombiner->color[curUnit].combine = GL_SUBTRACT_ARB;
442 SetColorCombinerValues( curUnit, arg1, envCombiner->color[curUnit].arg0.source, envCombiner->color[curUnit].arg0.operand );
443 SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param1 );
448 envCombiner->usesT0 |= ((colorCombiner->stage[i].op[j].param1 == TEXEL0) || (colorCombiner->stage[i].op[j].param1 == TEXEL0_ALPHA));
449 envCombiner->usesT1 |= ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA));
451 envCombiner->color[curUnit].combine = GL_MODULATE;
452 SetColorCombinerArg( curUnit, arg1, colorCombiner->stage[i].op[j].param1 );
457 envCombiner->usesT0 |= ((colorCombiner->stage[i].op[j].param1 == TEXEL0) || (colorCombiner->stage[i].op[j].param1 == TEXEL0_ALPHA));
458 envCombiner->usesT1 |= ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA));
460 envCombiner->color[curUnit].combine = GL_SUBTRACT_ARB;
461 SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param1 );
467 envCombiner->usesT0 |= ((colorCombiner->stage[i].op[j].param1 == TEXEL0) || (colorCombiner->stage[i].op[j].param1 == TEXEL0_ALPHA));
468 envCombiner->usesT1 |= ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA));
470 switch (colorCombiner->stage[i].op[j].op)
473 if (!( ARB_texture_env_crossbar || NV_texture_env_combine4) &&
474 ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA)) && (curUnit == 0))
477 envCombiner->color[curUnit].combine = GL_REPLACE;
479 SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param1 );
482 if (!ARB_texture_env_combine)
485 if (!(ARB_texture_env_crossbar || NV_texture_env_combine4) &&
486 ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA)) && (curUnit == 0))
489 if ((j > 0) && (colorCombiner->stage[i].op[j-1].op == LOAD) && (colorCombiner->stage[i].op[j-1].param1 == ONE))
491 SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param1 );
492 envCombiner->color[curUnit].arg0.operand = GL_ONE_MINUS_SRC_COLOR;
494 else if (( ATI_texture_env_combine3) && (curUnit > 0) && (envCombiner->color[curUnit - 1].combine == GL_MODULATE))
497 SetColorCombinerValues( curUnit, arg2, envCombiner->color[curUnit].arg1.source, envCombiner->color[curUnit].arg1.operand );
498 envCombiner->color[curUnit].combine = GL_MODULATE_SUBTRACT_ATI;
499 SetColorCombinerArg( curUnit, arg1, colorCombiner->stage[i].op[j].param1 );
504 envCombiner->color[curUnit].combine = GL_SUBTRACT_ARB;
505 SetColorCombinerArg( curUnit, arg1, colorCombiner->stage[i].op[j].param1 );
510 if (!( ARB_texture_env_crossbar || NV_texture_env_combine4) &&
511 ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA)) && (curUnit == 0))
514 envCombiner->color[curUnit].combine = GL_MODULATE;
516 SetColorCombinerArg( curUnit, arg1, colorCombiner->stage[i].op[j].param1 );
520 if (!( ARB_texture_env_crossbar || NV_texture_env_combine4) &&
521 ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA)) && (curUnit == 0))
524 // ATI_texture_env_combine3 adds GL_MODULATE_ADD_ATI; saves texture units
525 if (( ATI_texture_env_combine3) && (curUnit > 0) && (envCombiner->color[curUnit - 1].combine == GL_MODULATE))
528 SetColorCombinerValues( curUnit, arg2, envCombiner->color[curUnit].arg1.source, envCombiner->color[curUnit].arg1.operand );
529 envCombiner->color[curUnit].combine = GL_MODULATE_ADD_ATI;
530 SetColorCombinerArg( curUnit, arg1, colorCombiner->stage[i].op[j].param1 );
534 envCombiner->color[curUnit].combine = GL_ADD;
535 SetColorCombinerArg( curUnit, arg1, colorCombiner->stage[i].op[j].param1 );
540 envCombiner->usesT0 |= (colorCombiner->stage[i].op[j].param2 == TEXEL0) || (colorCombiner->stage[i].op[j].param3 == TEXEL0) || (colorCombiner->stage[i].op[j].param3 == TEXEL0_ALPHA);
541 envCombiner->usesT1 |= (colorCombiner->stage[i].op[j].param2 == TEXEL1) || (colorCombiner->stage[i].op[j].param3 == TEXEL1) || (colorCombiner->stage[i].op[j].param3 == TEXEL1_ALPHA);
543 if (!( ARB_texture_env_crossbar || NV_texture_env_combine4) &&
544 ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param2 == TEXEL1) || (colorCombiner->stage[i].op[j].param3 == TEXEL1) || (colorCombiner->stage[i].op[j].param3 == TEXEL1_ALPHA)) && (curUnit == 0))
546 if (colorCombiner->stage[i].op[j].param1 == TEXEL0)
548 envCombiner->color[curUnit].combine = GL_REPLACE;
549 SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param1 );
550 colorCombiner->stage[i].op[j].param1 = COMBINED;
552 if (colorCombiner->stage[i].op[j].param2 == TEXEL0)
554 envCombiner->color[curUnit].combine = GL_REPLACE;
555 SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param2 )
557 colorCombiner->stage[i].op[j].param2 = COMBINED;
559 if (colorCombiner->stage[i].op[j].param3 == TEXEL0)
561 envCombiner->color[curUnit].combine = GL_REPLACE;
562 SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param3 );
563 colorCombiner->stage[i].op[j].param3 = COMBINED;
565 if (colorCombiner->stage[i].op[j].param3 == TEXEL0_ALPHA)
567 envCombiner->color[curUnit].combine = GL_REPLACE;
568 SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param3 );
569 colorCombiner->stage[i].op[j].param3 = COMBINED_ALPHA;
575 envCombiner->color[curUnit].combine = GL_INTERPOLATE_ARB;
577 SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param1 );
578 SetColorCombinerArg( curUnit, arg1, colorCombiner->stage[i].op[j].param2 );
579 SetColorCombinerArg( curUnit, arg2, colorCombiner->stage[i].op[j].param3 );
588 envCombiner->usedUnits = max( (unsigned short)curUnit, envCombiner->usedUnits );