Correctly restoring the client state, enhanced error handling

This commit is contained in:
Jens Hemprich 2006-08-22 21:14:13 +00:00
parent 44b073af49
commit 20f46da51d
1 changed files with 96 additions and 81 deletions

View File

@ -831,6 +831,9 @@ void RenderUpdateState_old()
void RenderUpdateState() void RenderUpdateState()
{ {
glReportErrors("RenderUpdateState"); glReportErrors("RenderUpdateState");
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
VERIFY_TEXTURE_ENABLED_STATE();
// This filters out a few state changes in Carmageddon // This filters out a few state changes in Carmageddon
// (changing chromakey mode is expensive) // (changing chromakey mode is expensive)
@ -870,29 +873,30 @@ void RenderUpdateState()
bool active_texture_unit_not_coloralpha1 = false; bool active_texture_unit_not_coloralpha1 = false;
bool active_texture_unit_client_state_not_coloralpha1 = false; bool active_texture_unit_client_state_not_coloralpha1 = false;
if (s_bUpdateFogModeState || // color or alpha inversion also triggers a fog mode state so we don't have to check explicitly
s_bUpdateFogColorState || if (s_bUpdateFogModeState || s_bUpdateFogColorState)
s_bUpdateColorInvertState ||
s_bUpdateAlphaInvertState)
{ {
if (InternalConfig.FogMode == OpenGLideFogEmulation_EnvCombine) if (InternalConfig.FogMode == OpenGLideFogEmulation_EnvCombine)
{ {
if (s_bUpdateFogModeState || s_bUpdateFogColorState) glActiveTextureARB(OpenGL.FogTextureUnit);
if (InternalConfig.EXT_compiled_vertex_array)
{ {
glActiveTextureARB(OpenGL.FogTextureUnit); glClientActiveTextureARB(OpenGL.FogTextureUnit);
if (InternalConfig.EXT_compiled_vertex_array) active_texture_unit_client_state_not_coloralpha1 = true;
{ }
glClientActiveTextureARB(OpenGL.FogTextureUnit); active_texture_unit_not_coloralpha1 = true;
active_texture_unit_client_state_not_coloralpha1 = true; glReportError();
} VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.FogTextureUnit);
active_texture_unit_not_coloralpha1 = true; // Fog color
if (s_bUpdateFogColorState)
{
s_bUpdateFogColorState = false;
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &OpenGL.FogColor[0]);
glReportError(); glReportError();
} }
// Fog mode
if (s_bUpdateFogModeState) if (s_bUpdateFogModeState)
{ {
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.FogTextureUnit);
s_bUpdateFogModeState = false; s_bUpdateFogModeState = false;
if (Glide.State.FogMode & (GR_FOG_WITH_ITERATED_ALPHA | GR_FOG_WITH_TABLE)) if (Glide.State.FogMode & (GR_FOG_WITH_ITERATED_ALPHA | GR_FOG_WITH_TABLE))
{ {
@ -963,17 +967,16 @@ void RenderUpdateState()
OGLRender.UseEnvCombineFog = false; 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) else if (InternalConfig.FogMode != OpenGLideFogEmulation_None)
{ {
if (s_bUpdateFogColorState)
{
s_bUpdateFogColorState = false;
glFogfv(GL_FOG_COLOR, &OpenGL.FogColor[0]);
glReportError();
}
if (s_bUpdateFogModeState) if (s_bUpdateFogModeState)
{ {
s_bUpdateFogModeState = false; s_bUpdateFogModeState = false;
@ -1003,47 +1006,42 @@ void RenderUpdateState()
} }
glReportError(); glReportError();
} }
}
if (s_bUpdateFogColorState)
if (s_bUpdateColorInvertState || s_bUpdateAlphaInvertState)
{
if (active_texture_unit_not_coloralpha1 == false)
{ {
s_bUpdateFogColorState = false; active_texture_unit_not_coloralpha1 = true;
glFogfv(GL_FOG_COLOR, &OpenGL.FogColor[0]); glActiveTextureARB(OpenGL.FogTextureUnit);
if (InternalConfig.EXT_compiled_vertex_array)
{
glClientActiveTextureARB(OpenGL.FogTextureUnit);
active_texture_unit_client_state_not_coloralpha1 = true;
}
glReportError(); glReportError();
} }
} if (s_bUpdateColorInvertState)
// Means fog texture unit is active
if (active_texture_unit_not_coloralpha1 == false &&
(s_bUpdateColorInvertState || s_bUpdateAlphaInvertState))
{
glActiveTextureARB(OpenGL.FogTextureUnit);
if (InternalConfig.EXT_compiled_vertex_array)
{ {
glClientActiveTextureARB(OpenGL.FogTextureUnit); VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.FogTextureUnit);
active_texture_unit_client_state_not_coloralpha1 = true;
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);
} }
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);
} }
} }
VERIFY_TEXTURE_ENABLED_STATE();
// Coloralpha state changes // Coloralpha state changes
if (s_bUpdateTextureState || if (s_bUpdateTextureState ||
@ -1151,7 +1149,7 @@ void RenderUpdateState()
{ {
#ifdef OPENGL_DEBUG #ifdef OPENGL_DEBUG
GlideMsg("Disabling unused texture unit GL_TEXTURE%d_ARB\n", unit_index); GlideMsg("Disabling unused texture unit GL_TEXTURE%d_ARB\n", unit_index);
#endif #endif
// Save state changes if fog state hasn't been changed // Save state changes if fog state hasn't been changed
// and only coloralpha texture unit 0 is used // and only coloralpha texture unit 0 is used
const bool set_active_texture_unit = active_texture_unit_not_coloralpha1 || unit_index != 0; const bool set_active_texture_unit = active_texture_unit_not_coloralpha1 || unit_index != 0;
@ -1161,38 +1159,43 @@ void RenderUpdateState()
if (InternalConfig.EXT_compiled_vertex_array) if (InternalConfig.EXT_compiled_vertex_array)
{ {
glClientActiveTextureARB(OpenGL.ColorAlphaUnit1 + unit_index); glClientActiveTextureARB(OpenGL.ColorAlphaUnit1 + unit_index);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(4, GL_FLOAT, 0, NULL);
active_texture_unit_client_state_not_coloralpha1 = (unit_index != 0); active_texture_unit_client_state_not_coloralpha1 = (unit_index != 0);
} }
active_texture_unit_not_coloralpha1 = (unit_index != 0); active_texture_unit_not_coloralpha1 = (unit_index != 0);
glReportError(); glReportError();
} }
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1 + unit_index); if (InternalConfig.EXT_compiled_vertex_array)
{
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(4, GL_FLOAT, 0, NULL);
}
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
glReportError(); glReportError();
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1 + unit_index);
} }
#ifdef OPENGL_DEBUG
else else
{ {
#ifdef OPENGL_DEBUG
GlideMsg("Unused texture unit GL_TEXTURE%d_ARB already disabled\n", unit_index); GlideMsg("Unused texture unit GL_TEXTURE%d_ARB already disabled\n", unit_index);
#endif
} }
#endif
} }
} }
else else
{ {
// Save state changes if fog state hasn't been changed // Any of the updates needs the active texture unit set, but not the client state
// and only coloralpha texture unit 0 is used // 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; const bool set_active_texture_unit = active_texture_unit_not_coloralpha1 || unit_index != 0;
if (set_active_texture_unit) if (set_active_texture_unit)
{ {
glActiveTextureARB(OpenGL.ColorAlphaUnit1 + unit_index); glActiveTextureARB(OpenGL.ColorAlphaUnit1 + unit_index);
glReportError(); glReportError();
active_texture_unit_not_coloralpha1 = (unit_index != 0); active_texture_unit_not_coloralpha1 = (unit_index != 0);
// The client state is changed only if the texture unit must be enabled, otherwise the
// active client texture unit is restored to color alpha unit 1 at the end
} }
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1 + unit_index); // Don't check VERIFY_ACTIVE_TEXTURE_UNIT yet as it hasn't been set up completely yet
// Texture state // Texture state
if (s_bUpdateTextureState) if (s_bUpdateTextureState)
@ -1203,7 +1206,7 @@ void RenderUpdateState()
{ {
#ifdef OPENGL_DEBUG #ifdef OPENGL_DEBUG
GlideMsg("Enabling texture unit GL_TEXTURE%d_ARB\n", unit_index); GlideMsg("Enabling texture unit GL_TEXTURE%d_ARB\n", unit_index);
#endif #endif
// Enable the texture unit // Enable the texture unit
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
if (InternalConfig.EXT_compiled_vertex_array) if (InternalConfig.EXT_compiled_vertex_array)
@ -1224,12 +1227,24 @@ void RenderUpdateState()
{ {
#ifdef OPENGL_DEBUG #ifdef OPENGL_DEBUG
GlideMsg("Texture unit GL_TEXTURE%d_ARB already enabled\n", unit_index); GlideMsg("Texture unit GL_TEXTURE%d_ARB already enabled\n", unit_index);
#endif #endif
} }
} }
#ifdef OPENGL_DEBUG
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1 + unit_index); // At this point, the client state doesn't matter anymore, and we just need to check the active texture
GLint y;
const GLint x = OpenGL.ColorAlphaUnit1 + unit_index;
glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &y);
glReportError();
const bool verified = x == y;
if (!verified)
{
GlideMsg("Warning: %s() active texture unit is GL_TEXTURE%d_ARB, but should be GL_TEXTURE%d_ARB\n", __glide_functionname, y - GL_TEXTURE0_ARB, x - GL_TEXTURE0_ARB);
}
#ifdef OGL_STOP_ON_GL_ERROR
assert(verified);
#endif
#endif
// ColorCombineState // ColorCombineState
if (s_bUpdateColorCombineState) if (s_bUpdateColorCombineState)
{ {
@ -1238,7 +1253,7 @@ void RenderUpdateState()
if (unit.Function == CF_Unused) if (unit.Function == CF_Unused)
{ {
#ifdef OPENGL_DEBUG #ifdef OPENGL_DEBUG
GlideMsg("OpenGL ColorCombine unit %d = unused\n", unit_index); GlideMsg("OpenGL ColorCombine unit %d = unused\n", unit_index);
#endif #endif
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE); 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_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
@ -1248,7 +1263,7 @@ void RenderUpdateState()
else else
{ {
#ifdef OPENGL_DEBUG #ifdef OPENGL_DEBUG
GlideMsg("OpenGL ColorCombine Function for unit %d = 0x%x\n", unit_index, unit.Function); GlideMsg("OpenGL ColorCombine Function for unit %d = 0x%x\n", unit_index, unit.Function);
#endif #endif
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, unit.Function); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, unit.Function);
glReportError(); glReportError();
@ -1402,7 +1417,7 @@ void RenderUpdateState()
const GrCombineLocal_t a_local = Glide.State.AlphaLocal; const GrCombineLocal_t a_local = Glide.State.AlphaLocal;
const GrCombineOther_t a_other = Glide.State.AlphaOther; const GrCombineOther_t a_other = Glide.State.AlphaOther;
const CombineArgument** combine_argument = &OpenGL.AlphaCombineArguments[0]; const CombineArgument** combine_argument = &OpenGL.AlphaCombineArguments[0];
// combine_argument[CFARG_Local] = 0; // This is set to 0 onn initialising OpenGL // combine_argument[CFARG_Local] = 0; // This is set to 0 on initialising OpenGL
// combine_argument[CFARG_Other] = 0; // combine_argument[CFARG_Other] = 0;
combine_argument[CFARG_LocalAlpha] = &AlphaCombineLocals[a_local]; combine_argument[CFARG_LocalAlpha] = &AlphaCombineLocals[a_local];
combine_argument[CFARG_OtherAlpha] = Glide.State.TextureCombineAInvert ? &AlphaCombineOthersInverted[a_other] : &AlphaCombineOthers[a_other]; combine_argument[CFARG_OtherAlpha] = Glide.State.TextureCombineAInvert ? &AlphaCombineOthersInverted[a_other] : &AlphaCombineOthers[a_other];
@ -1565,17 +1580,17 @@ void RenderUpdateState()
} }
} }
} }
// Restore state
if (active_texture_unit_not_coloralpha1) if (active_texture_unit_not_coloralpha1)
{ {
if (active_texture_unit_client_state_not_coloralpha1)
{
glClientActiveTextureARB(OpenGL.ColorAlphaUnit1);
}
glActiveTextureARB(OpenGL.ColorAlphaUnit1); glActiveTextureARB(OpenGL.ColorAlphaUnit1);
glReportError(); glReportError();
} }
if (active_texture_unit_client_state_not_coloralpha1)
{
glClientActiveTextureARB(OpenGL.ColorAlphaUnit1);
}
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1); VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
VERIFY_TEXTURE_ENABLED_STATE(); VERIFY_TEXTURE_ENABLED_STATE();
} }