1593 lines
51 KiB
C++
1593 lines
51 KiB
C++
//**************************************************************
|
|
//* OpenGLide for Macintosh - Glide to OpenGL Wrapper
|
|
//* http://macglide.sourceforge.net/
|
|
//*
|
|
//* update the GL state before rendering vertices
|
|
//*
|
|
//* OpenGLide is OpenSource under LGPL license
|
|
//* Mac version and additional features by Jens-Olaf Hemprich
|
|
//**************************************************************
|
|
|
|
#include "GlideSettings.h"
|
|
#include "GLColorAlphaCombineEnvTables.h"
|
|
#include "GLRender.h"
|
|
#include "GLRenderUpdateState.h"
|
|
|
|
struct
|
|
{
|
|
GrChromakeyMode_t ChromaKeyMode;
|
|
} OldGlideState =
|
|
{
|
|
GR_CHROMAKEY_DISABLE,
|
|
};
|
|
|
|
bool s_bUpdateTextureState = false;
|
|
bool s_bUpdateFogModeState = false;
|
|
bool s_bUpdateFogColorState = false;
|
|
bool s_bUpdateBlendState = false;
|
|
bool s_bUpdateChromaKeyAndAlphaState = false;
|
|
bool s_bUpdateColorCombineState = false;
|
|
bool s_bUpdateAlphaCombineState = false;
|
|
bool s_bUpdateColorInvertState = false;
|
|
bool s_bUpdateAlphaInvertState = false;
|
|
bool s_bUpdateConstantColorValueState = false;
|
|
bool s_bUpdateConstantColorValue4State = false;
|
|
|
|
bool s_bForceChromaKeyAndAlphaStateUpdate = false;
|
|
|
|
/*
|
|
inline void SetTextureState_update()
|
|
{
|
|
glReportErrors("SetTextureState_update");
|
|
|
|
if (OpenGL.ColorAlphaUnit2 == 0)
|
|
{
|
|
if (OpenGL.Texture)
|
|
{
|
|
glEnable(GL_TEXTURE_2D);
|
|
if (InternalConfig.EXT_compiled_vertex_array)
|
|
{
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (InternalConfig.EXT_compiled_vertex_array)
|
|
{
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
}
|
|
glDisable(GL_TEXTURE_2D);
|
|
}
|
|
glReportError();
|
|
}
|
|
else
|
|
{
|
|
// If no texture is used, TMU0 provides 0
|
|
for(long unit_index = 1; unit_index >= 0; unit_index--)
|
|
{
|
|
glActiveTextureARB(OpenGL.ColorAlphaUnit1 + unit_index);
|
|
glReportError();
|
|
if (OpenGL.Texture == false)
|
|
{
|
|
glBindTexture(GL_TEXTURE_2D, OpenGL.DummyTextureName);
|
|
glReportError();
|
|
}
|
|
if (OpenGL.ColorAlphaUnitColorEnabledState[unit_index] || OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index])
|
|
{
|
|
glEnable(GL_TEXTURE_2D);
|
|
if (InternalConfig.EXT_compiled_vertex_array)
|
|
{
|
|
glClientActiveTextureARB(OpenGL.ColorAlphaUnit1 + unit_index);
|
|
glReportError();
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
}
|
|
glReportError();
|
|
}
|
|
else
|
|
{
|
|
if (InternalConfig.EXT_compiled_vertex_array)
|
|
{
|
|
glClientActiveTextureARB(OpenGL.ColorAlphaUnit1 + unit_index);
|
|
glReportError();
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
}
|
|
glDisable(GL_TEXTURE_2D);
|
|
glReportError();
|
|
}
|
|
}
|
|
#ifdef OPENGL_DEBUG
|
|
for(long unit_index = 0; unit_index < 2; unit_index++)
|
|
{
|
|
GlideMsg( "OpenGL.ColorAlphaUnitColorEnabledState[%d] = %d\n", unit_index, OpenGL.ColorAlphaUnitColorEnabledState[unit_index]);
|
|
GlideMsg( "OpenGL.ColorAlphaUnitAlphaEnabledState[%d] = %d\n", unit_index, OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index]);
|
|
GlideMsg("Texture unit GL_TEXTURE%d_ARB ", unit_index, GL_TEXTURE0_ARB + unit_index);
|
|
if (OpenGL.ColorAlphaUnitColorEnabledState[unit_index] || OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index])
|
|
{
|
|
GlideMsg("enabled\n");
|
|
}
|
|
else
|
|
{
|
|
GlideMsg("disabled\n");
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
*/
|
|
|
|
/*
|
|
// Setup color combine for extended color alpha model
|
|
inline void SetColorCombineState_update()
|
|
{
|
|
glReportErrors("SetColorCombine_update");
|
|
|
|
GrCombineFunction_t function = Glide.State.ColorCombineFunction;
|
|
GrCombineFactor_t factor = Glide.State.ColorCombineFactor;
|
|
GrCombineLocal_t local = Glide.State.ColorCombineLocal;
|
|
GrCombineOther_t other = Glide.State.ColorCombineOther;
|
|
|
|
if (OpenGL.ColorAlphaUnit2 == 0)
|
|
{
|
|
glActiveTextureARB(OpenGL.ColorAlphaUnit1);
|
|
if ( ( Glide.State.ColorCombineFactor == GR_COMBINE_FACTOR_TEXTURE_ALPHA ) &&
|
|
( Glide.State.ColorCombineOther == GR_COMBINE_OTHER_TEXTURE ) )
|
|
{
|
|
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );
|
|
}
|
|
else
|
|
if ( ( Glide.State.ColorCombineFactor == GR_COMBINE_FACTOR_TEXTURE_RGB ) &&
|
|
( Glide.State.ColorCombineOther == GR_COMBINE_OTHER_TEXTURE ) )
|
|
{
|
|
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND );
|
|
}
|
|
else
|
|
if (InternalConfig.EXT_texture_env_add &&
|
|
( Glide.State.ColorCombineFactor == GR_COMBINE_FACTOR_ONE ) &&
|
|
( Glide.State.ColorCombineOther == GR_COMBINE_OTHER_TEXTURE ) &&
|
|
( ( Glide.State.ColorCombineFunction == GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA ) ||
|
|
( Glide.State.ColorCombineFunction == GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL ) ) )
|
|
{
|
|
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD );
|
|
}
|
|
else
|
|
{
|
|
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
|
}
|
|
glReportError();
|
|
}
|
|
else
|
|
{
|
|
// Reduce function for constant factors?
|
|
if (factor == GR_COMBINE_FACTOR_ZERO)
|
|
{
|
|
function = ColorCombineFunctionsFactorZero[function].ReducedTerm;
|
|
}
|
|
else if (factor == GR_COMBINE_FACTOR_ONE)
|
|
{
|
|
function = ColorCombineFunctionsFactorOne[function].ReducedTerm;
|
|
}
|
|
const CombineArgument** combine_argument = &OpenGL.ColorCombineArguments[0];
|
|
combine_argument[CFARG_Local] = &ColorCombineLocals[local];
|
|
combine_argument[CFARG_Other] = Glide.State.TextureCombineRGBInvert ? &ColorCombineOthersInverted[other] : &ColorCombineOthers[other];
|
|
combine_argument[CFARG_LocalAlpha] = &AlphaCombineLocals[Glide.State.AlphaLocal];
|
|
combine_argument[CFARG_OtherAlpha] = Glide.State.TextureCombineAInvert ? &AlphaCombineOthersInverted[Glide.State.AlphaOther] : &AlphaCombineOthers[Glide.State.AlphaOther];
|
|
combine_argument[CFARG_Factor] = Glide.State.TextureCombineRGBInvert ? &ColorCombineFactorsInverted[factor] : &ColorCombineFactors[factor];
|
|
GLint source;
|
|
GLint operand;
|
|
CombineFunctionColorAlphaArg arg;
|
|
for(long unit_index = 1; unit_index >= 0; unit_index--)
|
|
{
|
|
// unit 2 has to be the next one after unit 1
|
|
glActiveTextureARB(OpenGL.ColorAlphaUnit1 + unit_index);
|
|
glReportError();
|
|
const CombineFunctionGLTextureUnit& unit = OpenGL.ColorCombineFunctions[function].ColorAlphaUnit[unit_index];
|
|
if (unit.Function == CF_Unused)
|
|
{
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
|
|
glReportError();
|
|
OpenGL.ColorAlphaUnitColorEnabledState[unit_index] = false;
|
|
}
|
|
else
|
|
{
|
|
OpenGL.ColorAlphaUnitColorEnabledState[unit_index] = true;
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, unit.Function);
|
|
glReportError();
|
|
for(unsigned long arg_index = 0; arg_index < 3; arg_index++)
|
|
{
|
|
arg = unit.CombineArg[arg_index];
|
|
if (arg < CFARG_None)
|
|
{
|
|
if (arg == CFARG_Factor); // || arg == CFARG_FactorAlpha)
|
|
{
|
|
if (combine_argument[arg]->Source < CFARG_None)
|
|
{
|
|
// Resolve factor to local/other:
|
|
// The factor source references to the local/other,
|
|
// which can be retrieved via the combine_argument[] array
|
|
source = combine_argument[combine_argument[arg]->Source]->Source;
|
|
// but the operand of the factor specifies already the
|
|
// correct component of the pixel (rgb or alpha) to be used.
|
|
// Example: if factor == GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA
|
|
// then the other alpha in AlphaCombineOthers is GL_SRC_ALPHA
|
|
// but the factor operand is correctly GL_ONE_MINUS_SRC_ALPHA.
|
|
operand = combine_argument[arg]->Operand;
|
|
// operand = combine_argument[combine_argument[arg]->Source]->Operand; // No
|
|
}
|
|
else
|
|
{
|
|
source = combine_argument[arg]->Source;
|
|
operand = combine_argument[arg]->Operand;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// combinearg = local or other (alpha)
|
|
source = combine_argument[arg]->Source;
|
|
operand = combine_argument[arg]->Operand;
|
|
}
|
|
}
|
|
else if (arg > CFARG_None)
|
|
{
|
|
source = unit.CombineArg[arg_index];
|
|
operand = GL_SRC_COLOR;
|
|
}
|
|
else
|
|
{
|
|
// arg == CFARG_None -> argument not used
|
|
continue;
|
|
}
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT + arg_index, source);
|
|
glReportError();
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT + arg_index, operand);
|
|
glReportError();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
|
|
}
|
|
*/
|
|
|
|
/*
|
|
// Setup alpha combine for extended color alpha model
|
|
inline void SetAlphaCombineState_update()
|
|
{
|
|
glReportErrors("SetAlphaCombine_update");
|
|
|
|
if (OpenGL.ColorAlphaUnit2 == 0)
|
|
{
|
|
glActiveTextureARB(OpenGL.ColorAlphaUnit1);
|
|
}
|
|
else
|
|
{
|
|
// Handle chromakey special case
|
|
if (OpenGL.ChromaKey && OpenGL.Texture && !OpenGL.Blend)
|
|
{
|
|
// need to disable alpha combining until an additional
|
|
// texture unit can be used to mask out the chroma key color.
|
|
// Note that the second unit must be setup because the
|
|
// texture unit might be turned on due to the color setup.
|
|
glActiveTextureARB(OpenGL.ColorAlphaUnit1 + 1);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_EXT);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA);
|
|
glActiveTextureARB(OpenGL.ColorAlphaUnit1);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA);
|
|
glReportError();
|
|
OpenGL.ColorAlphaUnitAlphaEnabledState[0] = true;
|
|
OpenGL.ColorAlphaUnitAlphaEnabledState[1] = false;
|
|
}
|
|
else
|
|
{
|
|
GrCombineFunction_t function = Glide.State.AlphaFunction;
|
|
GrCombineFactor_t factor = Glide.State.AlphaFactor;
|
|
GrCombineLocal_t local = Glide.State.AlphaLocal;
|
|
GrCombineOther_t other = Glide.State.AlphaOther;
|
|
// Reduce function for constant factors?
|
|
if (factor == GR_COMBINE_FACTOR_ZERO)
|
|
{
|
|
function = AlphaCombineFunctionsFactorZero[function].ReducedTerm;
|
|
}
|
|
else if (factor == GR_COMBINE_FACTOR_ONE)
|
|
{
|
|
function = AlphaCombineFunctionsFactorOne[function].ReducedTerm;
|
|
}
|
|
const CombineArgument** combine_argument = &OpenGL.AlphaCombineArguments[0];
|
|
// @todo: colors are unused, aren't they?
|
|
combine_argument[CFARG_Local] = &ColorCombineLocals[local];
|
|
combine_argument[CFARG_Other] = Glide.State.TextureCombineAInvert ? &ColorCombineOthersInverted[other] : &ColorCombineOthers[other];
|
|
combine_argument[CFARG_LocalAlpha] = &AlphaCombineLocals[local];
|
|
combine_argument[CFARG_OtherAlpha] = Glide.State.TextureCombineAInvert ? &AlphaCombineOthersInverted[other] : &AlphaCombineOthers[other];
|
|
combine_argument[CFARG_Factor] = Glide.State.TextureCombineAInvert ? &AlphaCombineFactorsInverted[factor] : &AlphaCombineFactors[factor];
|
|
GLint source;
|
|
GLint operand;
|
|
CombineFunctionColorAlphaArg arg;
|
|
for(long unit_index = 1; unit_index >= 0; unit_index--)
|
|
{
|
|
// unit 2 must be the next one after unit 1
|
|
glActiveTextureARB(OpenGL.ColorAlphaUnit1 + unit_index);
|
|
glReportError();
|
|
CombineFunctionGLTextureUnit unit = OpenGL.AlphaCombineFunctions[function].ColorAlphaUnit[unit_index];
|
|
if (unit.Function == CF_Unused)
|
|
{
|
|
if (OpenGL.ChromaKey && OpenGL.Texture && OpenGL.Blend)
|
|
{
|
|
// Modulate the alpha mask with the output of the previous unit
|
|
// to make chromakey-colored pixels invisible (so they wouldn't pass the alpha test)
|
|
// (chromakey-colored pixels have an alpha value of 0.0, the others 1.0)
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_EXT);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_TEXTURE);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_SRC_ALPHA);
|
|
glReportError();
|
|
OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index] = true;
|
|
}
|
|
else
|
|
{
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_EXT);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA);
|
|
glReportError();
|
|
OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index] = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, unit.Function);
|
|
glReportError();
|
|
OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index] = true;
|
|
for(unsigned long arg_index = 0; arg_index < 3; arg_index++)
|
|
{
|
|
arg = unit.CombineArg[arg_index];
|
|
if (arg < CFARG_None)
|
|
{
|
|
if (arg == CFARG_Factor); // Alpha)
|
|
{
|
|
if (combine_argument[arg]->Source < CFARG_None)
|
|
{
|
|
// Resolve factor to local/other:
|
|
// The factor source references to local/other,
|
|
// which can be retrieved via the combine_argument[] array.
|
|
source = combine_argument[combine_argument[arg]->Source]->Source;
|
|
// but the operand of the factor specifies already which
|
|
// component of the pixel and how it should be used.
|
|
// Example: if factor == GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA
|
|
// then the other alpha in AlphaCombineOthers is GL_SRC_ALPHA
|
|
// but the factor operand is correctly GL_ONE_MINUS_SRC_ALPHA.
|
|
operand = combine_argument[arg]->Operand;
|
|
}
|
|
else
|
|
{
|
|
source = combine_argument[arg]->Source;
|
|
operand = combine_argument[arg]->Operand;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
source = combine_argument[arg]->Source;
|
|
operand = combine_argument[arg]->Operand;
|
|
}
|
|
}
|
|
else if (arg > CFARG_None)
|
|
{
|
|
source = unit.CombineArg[arg_index];
|
|
operand = GL_SRC_ALPHA;
|
|
}
|
|
else
|
|
{
|
|
// arg == CFARG_None -> argument not used
|
|
continue;
|
|
}
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT + arg_index, source);
|
|
glReportError();
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT + arg_index, operand);
|
|
glReportError();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
|
|
}
|
|
*/
|
|
|
|
/*************************************************
|
|
* Avoid setting blending, alpha and chromakeying
|
|
* each time triangles are rendered, May cause
|
|
* some overhead when the state is changed more
|
|
* than once but the effect is reduced by using
|
|
* the CHECK_STATE_CHANGED macro
|
|
************************************************/
|
|
inline void SetChromaKeyAndAlphaState_update()
|
|
{
|
|
glReportErrors("SetChromaKeyAndAlpha_update");
|
|
|
|
// Setup alpha and chrma keying
|
|
// Chromakeying really works for textures only, and chroma keying
|
|
// without textures doesn't make sense anyway.
|
|
if(!OpenGL.Blend && OpenGL.ChromaKey && OpenGL.Texture)
|
|
{
|
|
#ifdef OPENGL_DEBUG
|
|
GlideMsg("Changing Chromakeymode state to enabled\n");
|
|
#endif
|
|
// setup chroma keying
|
|
glAlphaFunc(GL_GEQUAL, 0.5);
|
|
glEnable(GL_ALPHA_TEST);
|
|
if (InternalConfig.EXT_compiled_vertex_array)
|
|
{
|
|
glColorPointer(3, GL_FLOAT, 4 * sizeof(GLfloat), &OGLRender.TColor[0]);
|
|
}
|
|
glReportError();
|
|
}
|
|
else
|
|
{
|
|
#ifdef OPENGL_DEBUG
|
|
GlideMsg("Changing Chromakeymode state to disabled\n");
|
|
#endif
|
|
// Alpha Fix
|
|
// (todo: find out why this is a fix)
|
|
if (Glide.State.AlphaOther != GR_COMBINE_OTHER_TEXTURE)
|
|
{
|
|
glDisable(GL_ALPHA_TEST);
|
|
}
|
|
else
|
|
{
|
|
if ( Glide.State.AlphaTestFunction != GR_CMP_ALWAYS )
|
|
{
|
|
glEnable(GL_ALPHA_TEST);
|
|
glAlphaFunc(OpenGL.AlphaTestFunction, OpenGL.AlphaReferenceValue);
|
|
}
|
|
else
|
|
{
|
|
glDisable(GL_ALPHA_TEST);
|
|
}
|
|
}
|
|
if (InternalConfig.EXT_compiled_vertex_array)
|
|
{
|
|
glColorPointer(4, GL_FLOAT, 0, &OGLRender.TColor[0]);
|
|
}
|
|
glReportError();
|
|
}
|
|
|
|
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
|
|
}
|
|
|
|
/*
|
|
static const GLfloat ZeroColor[ 4 ] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
|
inline void SetFogModeState_update()
|
|
{
|
|
glReportErrors("SetFogMode_update");
|
|
|
|
if (InternalConfig.FogMode == OpenGLideFogEmulation_EnvCombine)
|
|
{
|
|
if (InternalConfig.EXT_compiled_vertex_array)
|
|
{
|
|
glClientActiveTextureARB(OpenGL.FogTextureUnit);
|
|
glReportError();
|
|
}
|
|
glActiveTextureARB(OpenGL.FogTextureUnit);
|
|
glReportError();
|
|
if (Glide.State.FogMode & (GR_FOG_WITH_ITERATED_ALPHA | GR_FOG_WITH_TABLE))
|
|
{
|
|
glEnable(GL_TEXTURE_2D);
|
|
if (InternalConfig.EXT_compiled_vertex_array)
|
|
{
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
glTexCoordPointer(1, GL_FLOAT, 0, &OGLRender.TFog[0]);
|
|
glReportError();
|
|
}
|
|
OGLRender.UseEnvCombineFog = true;
|
|
// Now set the fog function
|
|
GrFogMode_t modeAdd = Glide.State.FogMode & (GR_FOG_MULT2 | GR_FOG_ADD2);
|
|
switch (modeAdd)
|
|
{
|
|
case GR_FOG_ADD2:
|
|
// Cout = (1 - f) * Cin
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_ONE_MINUS_SRC_COLOR);
|
|
break;
|
|
case GR_FOG_MULT2:
|
|
// Cout = f * Cfog
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
|
break;
|
|
default:
|
|
// The usual blending
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_INTERPOLATE_EXT);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_CONSTANT_EXT);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
|
|
break;
|
|
}
|
|
glReportError();
|
|
}
|
|
else if (Glide.State.ColorCombineInvert || Glide.State.AlphaInvert)
|
|
{
|
|
// If the texture unit is turned on to invert color or alpha then we need to supply
|
|
// fog coords anyway and the combine function can still be GL_INTERPOLATE_EXT
|
|
// because the minimal fog value is chosen. However, choosing replace might
|
|
// save some vram memory access cycles
|
|
glEnable(GL_TEXTURE_2D);
|
|
if (InternalConfig.EXT_compiled_vertex_array)
|
|
{
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
glTexCoordPointer(1, GL_FLOAT, 0, &OGLRender.TFog[0]);
|
|
glReportError();
|
|
}
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
|
|
glReportError();
|
|
OGLRender.UseEnvCombineFog = true;
|
|
}
|
|
else
|
|
{
|
|
if (InternalConfig.EXT_compiled_vertex_array)
|
|
{
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
// On MacOS9 (Classic?) the texcoord pointer needs to be reset
|
|
// to the default value when glLockArrays/glUnlockArrays is used
|
|
glTexCoordPointer( 4, GL_FLOAT, 0, NULL );
|
|
glReportError();
|
|
}
|
|
glDisable(GL_TEXTURE_2D);
|
|
// If the texture unit is disabled, the combine env function doesn't matter
|
|
OGLRender.UseEnvCombineFog = false;
|
|
}
|
|
if (InternalConfig.EXT_compiled_vertex_array)
|
|
{
|
|
glClientActiveTextureARB(OpenGL.ColorAlphaUnit1);
|
|
}
|
|
glActiveTextureARB(OpenGL.ColorAlphaUnit1);
|
|
glReportError();
|
|
}
|
|
else if (InternalConfig.FogMode != OpenGLideFogEmulation_None)
|
|
{
|
|
if (Glide.State.FogMode & (GR_FOG_WITH_ITERATED_ALPHA | GR_FOG_WITH_TABLE))
|
|
{
|
|
glEnable(GL_FOG);
|
|
}
|
|
else
|
|
{
|
|
glDisable(GL_FOG);
|
|
}
|
|
glReportError();
|
|
// Change the fog color in order to emulate the correct fog equation
|
|
// (Imperfect emulation)
|
|
GrFogMode_t modeAdd = Glide.State.FogMode & (GR_FOG_MULT2 | GR_FOG_ADD2);
|
|
switch (modeAdd)
|
|
{
|
|
case GR_FOG_MULT2:
|
|
case GR_FOG_ADD2:
|
|
glFogfv( GL_FOG_COLOR, &ZeroColor[0]);
|
|
glReportError();
|
|
break;
|
|
default:
|
|
SetFogColorState();
|
|
break;
|
|
}
|
|
glReportError();
|
|
}
|
|
|
|
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
|
|
}
|
|
*/
|
|
|
|
/*
|
|
inline void SetFogColorState_update()
|
|
{
|
|
glReportErrors("SetFogColor_update");
|
|
|
|
if (Glide.State.FogMode < GR_FOG_MULT2)
|
|
{
|
|
if (InternalConfig.FogMode == OpenGLideFogEmulation_EnvCombine)
|
|
{
|
|
glActiveTextureARB(OpenGL.FogTextureUnit);
|
|
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &OpenGL.FogColor[0]);
|
|
glActiveTextureARB(OpenGL.ColorAlphaUnit1);
|
|
glReportError();
|
|
}
|
|
else if (InternalConfig.FogMode != OpenGLideFogEmulation_None )
|
|
{
|
|
glFogfv( GL_FOG_COLOR, &OpenGL.FogColor[0] );
|
|
glReportError();
|
|
}
|
|
}
|
|
|
|
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
|
|
}
|
|
*/
|
|
|
|
inline void SetBlendState_update()
|
|
{
|
|
glReportErrors("SetBlendState_update");
|
|
|
|
#ifdef OPENGLIDE_SYSTEM_HAS_BLENDFUNC_SEPERATE
|
|
if (!InternalConfig.EXT_blend_func_separate)
|
|
{
|
|
glBlendFuncSeparateEXT(OpenGL.SrcBlend, OpenGL.DstBlend,
|
|
OpenGL.SrcAlphaBlend, OpenGL.DstAlphaBlend);
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
glBlendFunc(OpenGL.SrcBlend, OpenGL.DstBlend);
|
|
#ifdef OPENGLIDE_SYSTEM_HAS_BLENDFUNC_SEPERATE
|
|
}
|
|
#endif
|
|
|
|
if ( OpenGL.Blend )
|
|
{
|
|
#ifdef OPENGL_DEBUG
|
|
GlideMsg("Changing Blend state to enabled\n");
|
|
#endif
|
|
glEnable(GL_BLEND);
|
|
}
|
|
else
|
|
{
|
|
#ifdef OPENGL_DEBUG
|
|
GlideMsg("Changing Blend state to disabled\n");
|
|
#endif
|
|
glDisable(GL_BLEND);
|
|
}
|
|
glReportError();
|
|
|
|
// I'd like to see this in the Set*() function,
|
|
// but it's more optimal placed here
|
|
#ifdef OPTIMISE_OPENGL_STATE_CHANGES
|
|
if (OpenGL.ChromaKey && OpenGL.Texture)
|
|
{
|
|
#endif
|
|
SetChromaKeyAndAlphaState();
|
|
#ifdef OPTIMISE_OPENGL_STATE_CHANGES
|
|
}
|
|
else
|
|
{
|
|
SetAlphaCombineState();
|
|
}
|
|
#endif
|
|
|
|
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
|
|
}
|
|
|
|
/*
|
|
void SetColorInvertState_update()
|
|
{
|
|
glReportErrors("SetColorInvert_update");
|
|
|
|
// Setup color inversion on fog texture unit
|
|
if (OpenGL.FogTextureUnit)
|
|
{
|
|
FxBool invert = Glide.State.ColorCombineInvert;
|
|
glActiveTextureARB(OpenGL.FogTextureUnit);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, invert ? GL_ONE_MINUS_SRC_COLOR : GL_SRC_COLOR);
|
|
glActiveTextureARB(OpenGL.ColorAlphaUnit1);
|
|
glReportError();
|
|
}
|
|
|
|
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
|
|
}
|
|
*/
|
|
|
|
/*
|
|
void SetAlphaInvertState_update()
|
|
{
|
|
glReportErrors("SetAlphaInvert_update");
|
|
|
|
// Setup alpha inversion on fog texture unit
|
|
if (OpenGL.FogTextureUnit)
|
|
{
|
|
FxBool invert = Glide.State.AlphaInvert;
|
|
glActiveTextureARB(OpenGL.FogTextureUnit);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, invert ? GL_ONE_MINUS_SRC_ALPHA : GL_SRC_ALPHA);
|
|
glActiveTextureARB(OpenGL.ColorAlphaUnit1);
|
|
glReportError();
|
|
}
|
|
|
|
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
|
|
}
|
|
*/
|
|
|
|
/*
|
|
void SetConstantColorValueState_update()
|
|
{
|
|
glReportErrors("SetConstantColorState_update");
|
|
|
|
GLfloat* color;
|
|
if (Glide.State.Delta0Mode)
|
|
{
|
|
color = &OpenGL.Delta0Color[0];
|
|
s_bUpdateConstantColorValue4State = false;
|
|
}
|
|
else
|
|
{
|
|
color = &OpenGL.ConstantColor[0];
|
|
s_bUpdateConstantColorValueState = false;
|
|
}
|
|
|
|
#ifdef OPENGL_DEBUG
|
|
GlideMsg("OpenGL.ConstantColor=(%g, %g, %g, %g)\n",
|
|
color[0],
|
|
color[1],
|
|
color[2],
|
|
color[3]);
|
|
#endif
|
|
|
|
if (OpenGL.ColorAlphaUnit2)
|
|
{
|
|
for(long unit_index = 1; unit_index >= 0; unit_index--)
|
|
{
|
|
glActiveTextureARB(OpenGL.ColorAlphaUnit1 + unit_index);
|
|
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &color[0]);
|
|
}
|
|
}
|
|
|
|
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
|
|
}
|
|
*/
|
|
|
|
/*
|
|
void RenderUpdateState_old()
|
|
{
|
|
glReportErrors("RenderUpdateState");
|
|
|
|
// This filters out a few state changes in Carmageddon
|
|
// (changing chromakey mode is expensive)
|
|
if (OldGlideState.ChromaKeyMode != Glide.State.ChromaKeyMode)
|
|
{
|
|
OldGlideState.ChromaKeyMode = Glide.State.ChromaKeyMode;
|
|
#ifdef OPTIMISE_OPENGL_STATE_CHANGES
|
|
if (!OpenGL.Blend)
|
|
#endif
|
|
SetChromaKeyAndAlphaState();
|
|
}
|
|
else
|
|
{
|
|
#ifdef OPENGL_DEBUG
|
|
GlideMsg( "Calls to grChromakeyMode() didn't change ChromaKeyAndAlphaState\n");
|
|
#endif
|
|
}
|
|
|
|
// Triggered by the frambuffer
|
|
if (s_bForceChromaKeyAndAlphaStateUpdate)
|
|
{
|
|
s_bForceChromaKeyAndAlphaStateUpdate = false;
|
|
SetChromaKeyAndAlphaState();
|
|
}
|
|
|
|
if (s_bUpdateFogModeState)
|
|
{
|
|
s_bUpdateFogModeState = false;
|
|
SetFogModeState_update();
|
|
}
|
|
|
|
if (s_bUpdateFogColorState)
|
|
{
|
|
s_bUpdateFogColorState = false;
|
|
SetFogColorState_update();
|
|
}
|
|
|
|
if (s_bUpdateBlendState)
|
|
{
|
|
s_bUpdateBlendState = false;
|
|
SetBlendState_update();
|
|
}
|
|
|
|
if (s_bUpdateChromaKeyAndAlphaState)
|
|
{
|
|
s_bUpdateChromaKeyAndAlphaState = false;
|
|
SetChromaKeyAndAlphaState_update();
|
|
}
|
|
|
|
if (s_bUpdateAlphaCombineState)
|
|
{
|
|
s_bUpdateAlphaCombineState = false;
|
|
SetAlphaCombineState_update();
|
|
}
|
|
|
|
if (s_bUpdateColorCombineState)
|
|
{
|
|
s_bUpdateColorCombineState = false;
|
|
SetColorCombineState_update();
|
|
}
|
|
|
|
if (s_bUpdateColorInvertState)
|
|
{
|
|
s_bUpdateColorInvertState = false;
|
|
SetColorInvertState_update();
|
|
}
|
|
|
|
if (s_bUpdateAlphaInvertState)
|
|
{
|
|
s_bUpdateAlphaInvertState = false;
|
|
SetAlphaInvertState_update();
|
|
}
|
|
|
|
if (s_bUpdateTextureState)
|
|
{
|
|
s_bUpdateTextureState = false;
|
|
SetTextureState_update();
|
|
}
|
|
|
|
if (s_bUpdateConstantColorValueState || s_bUpdateConstantColorValue4State)
|
|
{
|
|
SetConstantColorValueState_update();
|
|
}
|
|
|
|
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
|
|
VERIFY_TEXTURE_ENABLED_STATE();
|
|
}
|
|
*/
|
|
|
|
void RenderUpdateState()
|
|
{
|
|
glReportErrors("RenderUpdateState");
|
|
|
|
// This filters out a few state changes in Carmageddon
|
|
// (changing chromakey mode is expensive)
|
|
if (OldGlideState.ChromaKeyMode != Glide.State.ChromaKeyMode)
|
|
{
|
|
OldGlideState.ChromaKeyMode = Glide.State.ChromaKeyMode;
|
|
#ifdef OPTIMISE_OPENGL_STATE_CHANGES
|
|
if (!OpenGL.Blend)
|
|
#endif
|
|
SetChromaKeyAndAlphaState();
|
|
}
|
|
else
|
|
{
|
|
#ifdef OPENGL_DEBUG
|
|
GlideMsg( "Calls to grChromakeyMode() didn't change ChromaKeyAndAlphaState\n");
|
|
#endif
|
|
}
|
|
|
|
// Triggered by the framebuffer
|
|
if (s_bForceChromaKeyAndAlphaStateUpdate)
|
|
{
|
|
s_bForceChromaKeyAndAlphaStateUpdate = false;
|
|
SetChromaKeyAndAlphaState();
|
|
}
|
|
|
|
if (s_bUpdateBlendState)
|
|
{
|
|
s_bUpdateBlendState = false;
|
|
SetBlendState_update();
|
|
}
|
|
|
|
if (s_bUpdateChromaKeyAndAlphaState)
|
|
{
|
|
s_bUpdateChromaKeyAndAlphaState = false;
|
|
SetChromaKeyAndAlphaState_update();
|
|
}
|
|
|
|
bool active_texture_unit_not_coloralpha1 = false;
|
|
bool active_texture_unit_client_state_not_coloralpha1 = false;
|
|
if (s_bUpdateFogModeState ||
|
|
s_bUpdateFogColorState ||
|
|
s_bUpdateColorInvertState ||
|
|
s_bUpdateAlphaInvertState)
|
|
{
|
|
if (InternalConfig.FogMode == OpenGLideFogEmulation_EnvCombine)
|
|
{
|
|
if (s_bUpdateFogModeState || s_bUpdateFogColorState)
|
|
{
|
|
glActiveTextureARB(OpenGL.FogTextureUnit);
|
|
if (InternalConfig.EXT_compiled_vertex_array)
|
|
{
|
|
glClientActiveTextureARB(OpenGL.FogTextureUnit);
|
|
active_texture_unit_client_state_not_coloralpha1 = true;
|
|
}
|
|
active_texture_unit_not_coloralpha1 = true;
|
|
glReportError();
|
|
}
|
|
|
|
if (s_bUpdateFogModeState)
|
|
{
|
|
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.FogTextureUnit);
|
|
|
|
s_bUpdateFogModeState = false;
|
|
if (Glide.State.FogMode & (GR_FOG_WITH_ITERATED_ALPHA | GR_FOG_WITH_TABLE))
|
|
{
|
|
glEnable(GL_TEXTURE_2D);
|
|
if (InternalConfig.EXT_compiled_vertex_array)
|
|
{
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
glTexCoordPointer(1, GL_FLOAT, 0, &OGLRender.TFog[0]);
|
|
glReportError();
|
|
}
|
|
OGLRender.UseEnvCombineFog = true;
|
|
// Now set the fog function
|
|
GrFogMode_t modeAdd = Glide.State.FogMode & (GR_FOG_MULT2 | GR_FOG_ADD2);
|
|
switch (modeAdd)
|
|
{
|
|
case GR_FOG_ADD2:
|
|
// Cout = (1 - f) * Cin
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_ONE_MINUS_SRC_COLOR);
|
|
break;
|
|
case GR_FOG_MULT2:
|
|
// Cout = f * Cfog
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
|
|
break;
|
|
default:
|
|
// The usual blending
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_INTERPOLATE_EXT);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_CONSTANT_EXT);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
|
|
break;
|
|
}
|
|
glReportError();
|
|
}
|
|
else if (Glide.State.ColorCombineInvert || Glide.State.AlphaInvert)
|
|
{
|
|
// If the texture unit is turned on to invert color or alpha then we need to supply
|
|
// fog coords anyway and the combine function can still be GL_INTERPOLATE_EXT
|
|
// because the minimal fog value is chosen. However, choosing replace might
|
|
// save some vram memory access cycles
|
|
glEnable(GL_TEXTURE_2D);
|
|
if (InternalConfig.EXT_compiled_vertex_array)
|
|
{
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
glTexCoordPointer(1, GL_FLOAT, 0, &OGLRender.TFog[0]);
|
|
glReportError();
|
|
}
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
|
|
glReportError();
|
|
OGLRender.UseEnvCombineFog = true;
|
|
}
|
|
else
|
|
{
|
|
if (InternalConfig.EXT_compiled_vertex_array)
|
|
{
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
// On MacOS9 (Classic?) the texcoord pointer needs to be reset
|
|
// to the default value when glLockArrays/glUnlockArrays is used
|
|
glTexCoordPointer( 4, GL_FLOAT, 0, NULL );
|
|
glReportError();
|
|
}
|
|
glDisable(GL_TEXTURE_2D);
|
|
// If the texture unit is disabled, the combine env function doesn't matter
|
|
OGLRender.UseEnvCombineFog = false;
|
|
}
|
|
}
|
|
|
|
// Fog Color
|
|
if (s_bUpdateFogColorState)
|
|
{
|
|
s_bUpdateFogColorState = false;
|
|
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &OpenGL.FogColor[0]);
|
|
glReportError();
|
|
}
|
|
}
|
|
else if (InternalConfig.FogMode != OpenGLideFogEmulation_None)
|
|
{
|
|
if (s_bUpdateFogModeState)
|
|
{
|
|
s_bUpdateFogModeState = false;
|
|
if (Glide.State.FogMode & (GR_FOG_WITH_ITERATED_ALPHA | GR_FOG_WITH_TABLE))
|
|
{
|
|
glEnable(GL_FOG);
|
|
}
|
|
else
|
|
{
|
|
glDisable(GL_FOG);
|
|
}
|
|
glReportError();
|
|
// Change the fog color in order to emulate the correct fog equation
|
|
// (Imperfect emulation)
|
|
static const GLfloat ZeroColor[ 4 ] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
|
GrFogMode_t modeAdd = Glide.State.FogMode & (GR_FOG_MULT2 | GR_FOG_ADD2);
|
|
switch (modeAdd)
|
|
{
|
|
case GR_FOG_MULT2:
|
|
case GR_FOG_ADD2:
|
|
glFogfv( GL_FOG_COLOR, &ZeroColor[0]);
|
|
glReportError();
|
|
break;
|
|
default:
|
|
SetFogColorState();
|
|
break;
|
|
}
|
|
glReportError();
|
|
}
|
|
|
|
if (s_bUpdateFogColorState)
|
|
{
|
|
s_bUpdateFogColorState = false;
|
|
glFogfv(GL_FOG_COLOR, &OpenGL.FogColor[0]);
|
|
glReportError();
|
|
}
|
|
}
|
|
|
|
if (active_texture_unit_not_coloralpha1 == false &&
|
|
(s_bUpdateColorInvertState || s_bUpdateAlphaInvertState))
|
|
{
|
|
glActiveTextureARB(OpenGL.FogTextureUnit);
|
|
if (InternalConfig.EXT_compiled_vertex_array)
|
|
{
|
|
glClientActiveTextureARB(OpenGL.FogTextureUnit);
|
|
active_texture_unit_client_state_not_coloralpha1 = true;
|
|
}
|
|
glReportError();
|
|
active_texture_unit_not_coloralpha1 = true;
|
|
}
|
|
|
|
if (s_bUpdateColorInvertState)
|
|
{
|
|
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.FogTextureUnit);
|
|
|
|
s_bUpdateColorInvertState = false;
|
|
FxBool invert = Glide.State.ColorCombineInvert;
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, invert ? GL_ONE_MINUS_SRC_COLOR : GL_SRC_COLOR);
|
|
}
|
|
|
|
if (s_bUpdateAlphaInvertState)
|
|
{
|
|
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.FogTextureUnit);
|
|
|
|
s_bUpdateAlphaInvertState = false;
|
|
FxBool invert = Glide.State.AlphaInvert;
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, invert ? GL_ONE_MINUS_SRC_ALPHA : GL_SRC_ALPHA);
|
|
}
|
|
}
|
|
|
|
// Coloralpha state changes
|
|
if (s_bUpdateTextureState ||
|
|
s_bUpdateAlphaCombineState ||
|
|
s_bUpdateColorCombineState ||
|
|
s_bUpdateConstantColorValueState ||
|
|
s_bUpdateConstantColorValue4State)
|
|
{
|
|
// Find out which texture units need to be setup
|
|
if (OpenGL.ColorAlphaUnit2)
|
|
{
|
|
// Reduce alpha combine function for constant factors
|
|
GrCombineFunction_t a_function = Glide.State.AlphaFunction;
|
|
const GrCombineFactor_t a_factor = Glide.State.AlphaFactor;
|
|
if (a_factor == GR_COMBINE_FACTOR_ZERO)
|
|
{
|
|
a_function = AlphaCombineFunctionsFactorZero[a_function].ReducedTerm;
|
|
}
|
|
else if (a_factor == GR_COMBINE_FACTOR_ONE)
|
|
{
|
|
a_function = AlphaCombineFunctionsFactorOne[a_function].ReducedTerm;
|
|
}
|
|
// Color
|
|
GrCombineFunction_t c_function = Glide.State.ColorCombineFunction;
|
|
const GrCombineFactor_t c_factor = Glide.State.ColorCombineFactor;
|
|
// Reduce color combine function for constant factors
|
|
if (c_factor == GR_COMBINE_FACTOR_ZERO)
|
|
{
|
|
c_function = ColorCombineFunctionsFactorZero[c_function].ReducedTerm;
|
|
}
|
|
else if (c_factor == GR_COMBINE_FACTOR_ONE)
|
|
{
|
|
c_function = ColorCombineFunctionsFactorOne[c_function].ReducedTerm;
|
|
}
|
|
// Determine which texture units must be enabled
|
|
bool enable_texture_unit[2];
|
|
bool previously_enabled_texture_unit[2];
|
|
// ColorCombine
|
|
for(long unit_index = 1; unit_index >= 0; unit_index--)
|
|
{
|
|
// Remember last state because if a unit gets enabled, we have to update it's whole state
|
|
previously_enabled_texture_unit[unit_index] = OpenGL.ColorAlphaUnitColorEnabledState[unit_index] ||
|
|
OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index];
|
|
if (OpenGL.ColorCombineFunctions[c_function].ColorAlphaUnit[unit_index].Function == CF_Unused)
|
|
{
|
|
OpenGL.ColorAlphaUnitColorEnabledState[unit_index] = false;
|
|
}
|
|
else
|
|
{
|
|
OpenGL.ColorAlphaUnitColorEnabledState[unit_index] = true;
|
|
}
|
|
// AlphaCombine
|
|
if (OpenGL.ChromaKey && OpenGL.Texture && !OpenGL.Blend)
|
|
{
|
|
// OpenGL.ColorAlphaUnitAlphaEnabledState[0] = true;
|
|
// OpenGL.ColorAlphaUnitAlphaEnabledState[1] = false;
|
|
OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index] = (unit_index == 0) ? true : false;
|
|
}
|
|
else
|
|
{
|
|
if (OpenGL.AlphaCombineFunctions[a_function].ColorAlphaUnit[unit_index].Function == CF_Unused)
|
|
{
|
|
if (OpenGL.ChromaKey && OpenGL.Texture && OpenGL.Blend)
|
|
{
|
|
// Modulate the alpha mask with the output of the previous unit
|
|
// to make chromakey-colored pixels invisible (so they wouldn't pass the alpha test)
|
|
// (chromakey-colored pixels have an alpha value of 0.0, the others 1.0)
|
|
OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index] = true;
|
|
}
|
|
else
|
|
{
|
|
OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index] = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index] = true;
|
|
}
|
|
}
|
|
enable_texture_unit[unit_index] = OpenGL.ColorAlphaUnitColorEnabledState[unit_index] ||
|
|
OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index];
|
|
}
|
|
#ifdef OPENGL_DEBUG
|
|
for(long unit_index = 0; unit_index < 2; unit_index++)
|
|
{
|
|
GlideMsg( "OpenGL.ColorAlphaUnitColorEnabledState[%d] = %d\n", unit_index, OpenGL.ColorAlphaUnitColorEnabledState[unit_index]);
|
|
GlideMsg( "OpenGL.ColorAlphaUnitAlphaEnabledState[%d] = %d\n", unit_index, OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index]);
|
|
const char* enabled = OpenGL.ColorAlphaUnitColorEnabledState[unit_index] || OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index]
|
|
? "enabled" : "disabled";
|
|
GlideMsg("Texture unit GL_TEXTURE%d_ARB = %s\n", unit_index, enabled);
|
|
}
|
|
#endif
|
|
// Loop through the texture units and set some state
|
|
// but reset the state change flags on the last iteration only
|
|
// (nothing is setup if both units are disabled, but then the
|
|
// state has to be set later on anyway)
|
|
bool reset_state = false;
|
|
for(long unit_index = 1; unit_index >= 0; unit_index--)
|
|
{
|
|
if (!enable_texture_unit[unit_index])
|
|
{
|
|
if (s_bUpdateTextureState)
|
|
{
|
|
if (reset_state) s_bUpdateTextureState = false;
|
|
// Update texture unit that has just been enabled?
|
|
if (!enable_texture_unit[unit_index] && previously_enabled_texture_unit[unit_index])
|
|
{
|
|
#ifdef OPENGL_DEBUG
|
|
GlideMsg("Disabling unused texture unit GL_TEXTURE%d_ARB\n", unit_index);
|
|
#endif
|
|
// Save state changes if fog state hasn't been changed
|
|
// and only coloralpha texture unit 0 is used
|
|
const bool set_active_texture_unit = active_texture_unit_not_coloralpha1 || unit_index != 0;
|
|
if (set_active_texture_unit)
|
|
{
|
|
glActiveTextureARB(OpenGL.ColorAlphaUnit1 + unit_index);
|
|
if (InternalConfig.EXT_compiled_vertex_array)
|
|
{
|
|
if (set_active_texture_unit)
|
|
{
|
|
glClientActiveTextureARB(OpenGL.ColorAlphaUnit1 + unit_index);
|
|
}
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
active_texture_unit_client_state_not_coloralpha1 = (unit_index != 0);
|
|
}
|
|
active_texture_unit_not_coloralpha1 = (unit_index != 0);
|
|
glReportError();
|
|
}
|
|
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1 + unit_index);
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
glReportError();
|
|
}
|
|
else
|
|
{
|
|
#ifdef OPENGL_DEBUG
|
|
GlideMsg("Unused texture unit GL_TEXTURE%d_ARB already disabled\n", unit_index);
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Save state changes if fog state hasn't been changed
|
|
// and only coloralpha texture unit 0 is used
|
|
const bool set_active_texture_unit = active_texture_unit_not_coloralpha1 || unit_index != 0;
|
|
if (set_active_texture_unit)
|
|
{
|
|
glActiveTextureARB(OpenGL.ColorAlphaUnit1 + unit_index);
|
|
glReportError();
|
|
active_texture_unit_not_coloralpha1 = (unit_index != 0);
|
|
}
|
|
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1 + unit_index);
|
|
|
|
// Texture state
|
|
if (s_bUpdateTextureState)
|
|
{
|
|
if (reset_state) s_bUpdateTextureState = false;
|
|
// Update texture unit that has just been enabled?
|
|
if (enable_texture_unit[unit_index] && !previously_enabled_texture_unit[unit_index])
|
|
{
|
|
#ifdef OPENGL_DEBUG
|
|
GlideMsg("Enabling texture unit GL_TEXTURE%d_ARB\n", unit_index);
|
|
#endif
|
|
// Enable the texture unit
|
|
glEnable(GL_TEXTURE_2D);
|
|
if (InternalConfig.EXT_compiled_vertex_array && set_active_texture_unit)
|
|
{
|
|
glClientActiveTextureARB(OpenGL.ColorAlphaUnit1 + unit_index);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
active_texture_unit_client_state_not_coloralpha1 = (unit_index != 0);
|
|
}
|
|
glReportError();
|
|
// Update the texture unit
|
|
SetColorCombineState();
|
|
SetAlphaCombineState();
|
|
if (Glide.State.Delta0Mode) SetConstantColorValue4State();
|
|
else SetConstantColorValueState();
|
|
}
|
|
else
|
|
{
|
|
#ifdef OPENGL_DEBUG
|
|
GlideMsg("Texture unit GL_TEXTURE%d_ARB already enabled\n", unit_index);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1 + unit_index);
|
|
|
|
// ColorCombineState
|
|
if (s_bUpdateColorCombineState)
|
|
{
|
|
if (reset_state) s_bUpdateColorCombineState = false;
|
|
const CombineFunctionGLTextureUnit& unit = OpenGL.ColorCombineFunctions[c_function].ColorAlphaUnit[unit_index];
|
|
if (unit.Function == CF_Unused)
|
|
{
|
|
#ifdef OPENGL_DEBUG
|
|
GlideMsg("OpenGL ColorCombine unit %d = unused\n", unit_index);
|
|
#endif
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
|
|
glReportError();
|
|
}
|
|
else
|
|
{
|
|
#ifdef OPENGL_DEBUG
|
|
GlideMsg("OpenGL ColorCombine Function for unit %d = 0x%x\n", unit_index, unit.Function);
|
|
#endif
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, unit.Function);
|
|
glReportError();
|
|
CombineFunctionColorAlphaArg arg;
|
|
GLint source;
|
|
GLint operand;
|
|
const GrCombineLocal_t c_local = Glide.State.ColorCombineLocal;
|
|
const GrCombineOther_t c_other = Glide.State.ColorCombineOther;
|
|
const GrCombineLocal_t a_local = Glide.State.AlphaLocal;
|
|
const GrCombineOther_t a_other = Glide.State.AlphaOther;
|
|
const CombineArgument** combine_argument = &OpenGL.ColorCombineArguments[0];
|
|
combine_argument[CFARG_Local] = &ColorCombineLocals[c_local];
|
|
combine_argument[CFARG_Other] = Glide.State.TextureCombineRGBInvert ? &ColorCombineOthersInverted[c_other] : &ColorCombineOthers[c_other];
|
|
combine_argument[CFARG_LocalAlpha] = &AlphaCombineLocals[a_local];
|
|
combine_argument[CFARG_OtherAlpha] = Glide.State.TextureCombineAInvert ? &AlphaCombineOthersInverted[a_other] : &AlphaCombineOthers[a_other];
|
|
combine_argument[CFARG_Factor] = Glide.State.TextureCombineRGBInvert ? &ColorCombineFactorsInverted[c_factor] : &ColorCombineFactors[c_factor];
|
|
for(unsigned long arg_index = 0; arg_index < 3; arg_index++)
|
|
{
|
|
arg = unit.CombineArg[arg_index];
|
|
if (arg < CFARG_None)
|
|
{
|
|
if (arg == CFARG_Factor /* ||arg == CFARG_FactorAlpha*/)
|
|
{
|
|
if (combine_argument[arg]->Source < CFARG_None)
|
|
{
|
|
// Resolve factor to local/other:
|
|
// The factor source references to the local/other,
|
|
// which can be retrieved via the combine_argument[] array
|
|
source = combine_argument[combine_argument[arg]->Source]->Source;
|
|
// but the operand of the factor specifies already the
|
|
// correct component of the pixel (rgb or alpha) to be used.
|
|
// Example: if factor == GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA
|
|
// then the other alpha in AlphaCombineOthers is GL_SRC_ALPHA
|
|
// but the factor operand is correctly GL_ONE_MINUS_SRC_ALPHA.
|
|
// operand = combine_argument[arg]->Operand;
|
|
// Not after color inversion has been added
|
|
operand = combine_argument[combine_argument[arg]->Source]->Operand; // No
|
|
}
|
|
else
|
|
{
|
|
source = combine_argument[arg]->Source;
|
|
operand = combine_argument[arg]->Operand;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// combinearg = local or other (alpha)
|
|
source = combine_argument[arg]->Source;
|
|
operand = combine_argument[arg]->Operand;
|
|
}
|
|
}
|
|
else if (arg > CFARG_None)
|
|
{
|
|
source = unit.CombineArg[arg_index];
|
|
operand = GL_SRC_COLOR;
|
|
}
|
|
else
|
|
{
|
|
// arg == CFARG_None -> argument not used
|
|
continue;
|
|
}
|
|
#ifdef OPENGL_DEBUG
|
|
GlideMsg("Arg %d = Source:0x%x, Operand:0x%x\n", arg_index, source, operand);
|
|
#endif
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT + arg_index, source);
|
|
glReportError();
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT + arg_index, operand);
|
|
glReportError();
|
|
}
|
|
}
|
|
glReportError();
|
|
}
|
|
|
|
// Alpha Combine State
|
|
if (s_bUpdateAlphaCombineState)
|
|
{
|
|
if (reset_state) s_bUpdateAlphaCombineState = false;
|
|
// Handle chromakey special case
|
|
if (OpenGL.ChromaKey && OpenGL.Texture && !OpenGL.Blend)
|
|
{
|
|
// need to disable alpha combining until an additional
|
|
// texture unit can be used to mask out the chroma key color.
|
|
// Note that the second unit must be setup because the
|
|
// texture unit might be turned on due to the color setup.
|
|
if (unit_index == 1)
|
|
{
|
|
#ifdef OPENGL_DEBUG
|
|
GlideMsg("OpenGL AlphaCombine unit %d = unused\n", unit_index);
|
|
#endif
|
|
// OpenGL.ColorAlphaUnitAlphaEnabledState[1] = false;
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_EXT);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA);
|
|
}
|
|
else
|
|
{
|
|
#ifdef OPENGL_DEBUG
|
|
GlideMsg("OpenGL AlphaCombine unit %d = texture_alpha\n", unit_index);
|
|
#endif
|
|
// OpenGL.ColorAlphaUnitAlphaEnabledState[0] = true;
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA);
|
|
}
|
|
glReportError();
|
|
}
|
|
else
|
|
{
|
|
CombineFunctionGLTextureUnit unit = OpenGL.AlphaCombineFunctions[a_function].ColorAlphaUnit[unit_index];
|
|
if (unit.Function == CF_Unused)
|
|
{
|
|
if (OpenGL.ChromaKey && OpenGL.Texture && OpenGL.Blend)
|
|
{
|
|
// Modulate the alpha mask with the output of the previous unit
|
|
// to make chromakey-colored pixels invisible (so they wouldn't pass the alpha test)
|
|
// (chromakey-colored pixels have an alpha value of 0.0, the others 1.0)
|
|
#ifdef OPENGL_DEBUG
|
|
GlideMsg("OpenGL AlphaCombine unit %d = chromakey mask\n", unit_index);
|
|
#endif
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_EXT);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_TEXTURE);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_SRC_ALPHA);
|
|
glReportError();
|
|
// OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index] = true;
|
|
}
|
|
else
|
|
{
|
|
#ifdef OPENGL_DEBUG
|
|
GlideMsg("OpenGL AlphaCombine unit %d = unused\n", unit_index);
|
|
#endif
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_EXT);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA);
|
|
glReportError();
|
|
// OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index] = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
#ifdef OPENGL_DEBUG
|
|
GlideMsg("OpenGL AlphaCombine Function for unit %d = 0x%x\n", unit_index, unit.Function);
|
|
#endif
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, unit.Function);
|
|
glReportError();
|
|
CombineFunctionColorAlphaArg arg;
|
|
GLint source;
|
|
GLint operand;
|
|
// Alpha @todo: colors are unused, aren't they?
|
|
const GrCombineLocal_t a_local = Glide.State.AlphaLocal;
|
|
const GrCombineOther_t a_other = Glide.State.AlphaOther;
|
|
const CombineArgument** combine_argument = &OpenGL.AlphaCombineArguments[0];
|
|
// combine_argument[CFARG_Local] = 0; // This is set to 0 onn initialising OpenGL
|
|
// combine_argument[CFARG_Other] = 0;
|
|
combine_argument[CFARG_LocalAlpha] = &AlphaCombineLocals[a_local];
|
|
combine_argument[CFARG_OtherAlpha] = Glide.State.TextureCombineAInvert ? &AlphaCombineOthersInverted[a_other] : &AlphaCombineOthers[a_other];
|
|
combine_argument[CFARG_Factor] = Glide.State.TextureCombineAInvert ? &AlphaCombineFactorsInverted[a_factor] : &AlphaCombineFactors[a_factor];
|
|
// Color
|
|
// OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index] = true;
|
|
for(unsigned long arg_index = 0; arg_index < 3; arg_index++)
|
|
{
|
|
arg = unit.CombineArg[arg_index];
|
|
if (arg < CFARG_None)
|
|
{
|
|
if (arg == CFARG_Factor /*Alpha*/)
|
|
{
|
|
if (combine_argument[arg]->Source < CFARG_None)
|
|
{
|
|
// Resolve factor to local/other:
|
|
// The factor source references to local/other,
|
|
// which can be retrieved via the combine_argument[] array.
|
|
source = combine_argument[combine_argument[arg]->Source]->Source;
|
|
// but the operand of the factor specifies already which
|
|
// component of the pixel and how it should be used.
|
|
// Example: if factor == GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA
|
|
// then the other alpha in AlphaCombineOthers is GL_SRC_ALPHA
|
|
// but the factor operand is correctly GL_ONE_MINUS_SRC_ALPHA.
|
|
// operand = combine_argument[arg]->Operand;
|
|
// After color inversion has been added, the operand must be taken
|
|
// from the inversion table
|
|
operand = combine_argument[combine_argument[arg]->Source]->Operand;
|
|
}
|
|
else
|
|
{
|
|
source = combine_argument[arg]->Source;
|
|
operand = combine_argument[arg]->Operand;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
source = combine_argument[arg]->Source;
|
|
operand = combine_argument[arg]->Operand;
|
|
}
|
|
}
|
|
else if (arg > CFARG_None)
|
|
{
|
|
source = unit.CombineArg[arg_index];
|
|
operand = GL_SRC_ALPHA;
|
|
}
|
|
else
|
|
{
|
|
// arg == CFARG_None -> argument not used
|
|
continue;
|
|
}
|
|
#ifdef OPENGL_DEBUG
|
|
GlideMsg("Arg %d = Source:0x%x, Operand:0x%x\n", arg_index, source, operand);
|
|
#endif
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT + arg_index, source);
|
|
glReportError();
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT + arg_index, operand);
|
|
glReportError();
|
|
}
|
|
}
|
|
}
|
|
glReportError();
|
|
}
|
|
|
|
// Constant Color State
|
|
if (s_bUpdateConstantColorValueState || s_bUpdateConstantColorValue4State)
|
|
{
|
|
GLfloat* color;
|
|
if (Glide.State.Delta0Mode)
|
|
{
|
|
if (reset_state) s_bUpdateConstantColorValue4State = false;
|
|
color = &OpenGL.Delta0Color[0];
|
|
}
|
|
else
|
|
{
|
|
if (reset_state) s_bUpdateConstantColorValueState = false;
|
|
color = &OpenGL.ConstantColor[0];
|
|
}
|
|
#ifdef OPENGL_DEBUG
|
|
if (reset_state) GlideMsg("OpenGL.ConstantColor=(%g, %g, %g, %g)\n",
|
|
color[0],
|
|
color[1],
|
|
color[2],
|
|
color[3]);
|
|
#endif
|
|
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &color[0]);
|
|
glReportError();
|
|
}
|
|
}
|
|
// Ensure the state change flags are reset during the last iteration
|
|
reset_state = true;
|
|
}
|
|
glReportError();
|
|
}
|
|
else // OpenGL.ColorAlphaTectureUnit2 == 0
|
|
{
|
|
if (active_texture_unit_not_coloralpha1)
|
|
{
|
|
glActiveTextureARB(OpenGL.ColorAlphaUnit1);
|
|
active_texture_unit_not_coloralpha1 = false;
|
|
}
|
|
if (s_bUpdateTextureState)
|
|
{
|
|
s_bUpdateTextureState = false;
|
|
if (active_texture_unit_client_state_not_coloralpha1)
|
|
{
|
|
glClientActiveTextureARB(OpenGL.ColorAlphaUnit1);
|
|
active_texture_unit_client_state_not_coloralpha1 = false;
|
|
}
|
|
if (OpenGL.Texture)
|
|
{
|
|
glEnable(GL_TEXTURE_2D);
|
|
if (InternalConfig.EXT_compiled_vertex_array)
|
|
{
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (InternalConfig.EXT_compiled_vertex_array)
|
|
{
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
}
|
|
glDisable(GL_TEXTURE_2D);
|
|
}
|
|
glReportError();
|
|
}
|
|
|
|
if (s_bUpdateColorCombineState)
|
|
{
|
|
s_bUpdateColorCombineState = false;
|
|
if ( ( Glide.State.ColorCombineFactor == GR_COMBINE_FACTOR_TEXTURE_ALPHA ) &&
|
|
( Glide.State.ColorCombineOther == GR_COMBINE_OTHER_TEXTURE ) )
|
|
{
|
|
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );
|
|
}
|
|
else
|
|
if ( ( Glide.State.ColorCombineFactor == GR_COMBINE_FACTOR_TEXTURE_RGB ) &&
|
|
( Glide.State.ColorCombineOther == GR_COMBINE_OTHER_TEXTURE ) )
|
|
{
|
|
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND );
|
|
}
|
|
else
|
|
if (InternalConfig.EXT_texture_env_add &&
|
|
( Glide.State.ColorCombineFactor == GR_COMBINE_FACTOR_ONE ) &&
|
|
( Glide.State.ColorCombineOther == GR_COMBINE_OTHER_TEXTURE ) &&
|
|
( ( Glide.State.ColorCombineFunction == GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA ) ||
|
|
( Glide.State.ColorCombineFunction == GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL ) ) )
|
|
{
|
|
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD );
|
|
}
|
|
else
|
|
{
|
|
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
|
}
|
|
glReportError();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (active_texture_unit_not_coloralpha1)
|
|
{
|
|
if (active_texture_unit_client_state_not_coloralpha1)
|
|
{
|
|
glClientActiveTextureARB(OpenGL.ColorAlphaUnit1);
|
|
}
|
|
glActiveTextureARB(OpenGL.ColorAlphaUnit1);
|
|
glReportError();
|
|
}
|
|
|
|
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
|
|
VERIFY_TEXTURE_ENABLED_STATE();
|
|
}
|
|
|
|
void SetClipVerticesState_Update(bool clip_vertices)
|
|
{
|
|
OpenGL.ClipVerticesEnabledState = clip_vertices;
|
|
if (InternalConfig.EXT_clip_volume_hint)
|
|
{
|
|
RenderDrawTriangles();
|
|
glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, clip_vertices ? GL_DONT_CARE : GL_FASTEST);
|
|
#ifdef OPENGL_DEBUG
|
|
GlideMsg("OpenGL.ClipVerticesEnabledState = %s\n", clip_vertices ? "GL_DONT_CARE" : "GL_FASTEST");
|
|
#endif
|
|
}
|
|
}
|