Cleanup, refactoring, state update, optimisations

This commit is contained in:
Jens Hemprich 2007-06-04 11:13:28 +00:00
parent acc2264181
commit 23a7356fb8
13 changed files with 189 additions and 921 deletions

File diff suppressed because one or more lines are too long

View File

@ -23,10 +23,9 @@ public:
void free_buffers(); void free_buffers();
void initialise_format(GrLfbWriteMode_t format); void initialise_format(GrLfbWriteMode_t format);
bool begin_write(); bool begin_write();
bool end_write(); void end_write();
bool end_write(FxU32 alpha); void end_write(FxU32 alpha, GLfloat depth);
bool end_write(FxU32 alpha, GLfloat depth, bool pixelpipeline); void end_write_opaque();
bool end_write_opaque();
inline FxU16 GetChromaKeyValue() {return m_ChromaKey.Scalar;}; inline FxU16 GetChromaKeyValue() {return m_ChromaKey.Scalar;};
inline void SetChromaKeyValue(FxU16 chromakey) inline void SetChromaKeyValue(FxU16 chromakey)
{ {
@ -41,11 +40,11 @@ public:
} }
protected: protected:
void Clear(); void Clear();
bool draw(const tilesize* tilesizetable, bool pixelpipeline); void draw(const tilesize* tilesizetable);
bool drawCompiledVertexArrays(const tilesize* tilesizetable, int vertexarrayindex, int tilecount, bool pixelpipeline); void drawCompiledVertexArrays(const tilesize* tilesizetable, int vertexarrayindex, int tilecount);
int buildVertexArrays(const tilesize* tilesizetable, int vertexarrayindex); int buildVertexArrays(const tilesize* tilesizetable, int vertexarrayindex);
void set_gl_state(bool pixelpipeline); void set_gl_state();
void restore_gl_state(bool pixelpipeline); void restore_gl_state();
// Pixel conversion // Pixel conversion
enum TileUpdateState enum TileUpdateState
{ {

View File

@ -357,21 +357,20 @@ void GLExtensions(void)
{ {
OpenGL.ColorAlphaUnit2 = GL_TEXTURE1_ARB; OpenGL.ColorAlphaUnit2 = GL_TEXTURE1_ARB;
OpenGL.FogTextureUnit = GL_TEXTURE2_ARB; OpenGL.FogTextureUnit = GL_TEXTURE2_ARB;
// All texture units are enabled all the time // env combine
glActiveTextureARB(OpenGL.ColorAlphaUnit1); glActiveTextureARB(OpenGL.ColorAlphaUnit1);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glActiveTextureARB(OpenGL.ColorAlphaUnit2); glActiveTextureARB(OpenGL.ColorAlphaUnit2);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glReportError(); glReportError();
// Secondary color not neded in the enhanced color alpha rendering model // Secondary color not needed in the enhanced color alpha rendering model
InternalConfig.EXT_secondary_color = false; InternalConfig.EXT_secondary_color = false;
if (InternalConfig.ColorAlphaRenderMode == OpenGLideColorAlphaRenderMode_Automatic) if (InternalConfig.ColorAlphaRenderMode == OpenGLideColorAlphaRenderMode_Automatic)
{ {
if (InternalConfig.ATI_texture_env_combine3) if (InternalConfig.ATI_texture_env_combine3)
{ {
// With GL_ATI_texture_env_combine3, more combine functions can be modeled as // With GL_ATI_texture_env_combine3, more combine functions can be modeled
// exactly as the original combine functions. They can also be rendered more // equivalently to the Glide combine functions. They can also be rendered more
// often with one texture unit, which leaves more space for correct rendering // often with one texture unit, which leaves more space for correct rendering
// of textures that use both chromakeying and alpha blending together. // of textures that use both chromakeying and alpha blending together.
InternalConfig.ColorAlphaRenderMode = OpenGLideColorAlphaRenderMode_EnvCombine3_ATI; InternalConfig.ColorAlphaRenderMode = OpenGLideColorAlphaRenderMode_EnvCombine3_ATI;
@ -437,7 +436,7 @@ void GLExtensions(void)
InternalConfig.FogMode = OpenGLideFogEmulation_Simple; InternalConfig.FogMode = OpenGLideFogEmulation_Simple;
} }
if (InternalConfig.EXT_secondary_color && OpenGL.ColorAlphaUnit2 == 0) if (InternalConfig.EXT_secondary_color)
{ {
glEnable(GL_COLOR_SUM_EXT); glEnable(GL_COLOR_SUM_EXT);
glReportError(); glReportError();

View File

@ -105,7 +105,7 @@ void RenderInitialize(void)
pTS->aq = pTS->bq = pTS->cq = 0.0f; pTS->aq = pTS->bq = pTS->cq = 0.0f;
} }
OGLRender.TVertex = (TVertexStruct*) AllocBuffer(triangles, sizeof(TVertexStruct)); OGLRender.TVertex = (TVertexStruct*) AllocBuffer(triangles, sizeof(TVertexStruct));
OGLRender.TFog = (TFogStruct*) AllocBuffer(OGLRender.FrameBufferStartIndex, sizeof(TFogStruct)); OGLRender.TFog = (TFogStruct*) AllocBuffer(triangles, sizeof(TFogStruct));
// Initialise compiled vertex arrays // Initialise compiled vertex arrays
OGLRender.BufferLocked = false; OGLRender.BufferLocked = false;
OGLRender.BufferStart = 0; OGLRender.BufferStart = 0;

View File

@ -32,373 +32,9 @@ bool s_bUpdateColorInvertState = false;
bool s_bUpdateAlphaInvertState = false; bool s_bUpdateAlphaInvertState = false;
bool s_bUpdateConstantColorValueState = false; bool s_bUpdateConstantColorValueState = false;
bool s_bUpdateConstantColorValue4State = false; bool s_bUpdateConstantColorValue4State = false;
//bool s_bUpdateClipVerticesState = false;
bool s_bForceChromaKeyAndAlphaStateUpdate = 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 * Avoid setting blending, alpha and chromakeying
* each time triangles are rendered, May cause * each time triangles are rendered, May cause
@ -478,153 +114,6 @@ inline void SetChromaKeyAndAlphaState_update()
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1); 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() inline void SetBlendState_update()
{ {
glReportErrors("SetBlendState_update"); glReportErrors("SetBlendState_update");
@ -643,7 +132,7 @@ inline void SetBlendState_update()
} }
#endif #endif
if ( OpenGL.Blend ) if (OpenGL.Blend)
{ {
#ifdef OPENGL_DEBUG #ifdef OPENGL_DEBUG
GlideMsg("Changing Blend state to enabled\n"); GlideMsg("Changing Blend state to enabled\n");
@ -677,175 +166,6 @@ inline void SetBlendState_update()
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1); 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() void RenderUpdateState()
{ {
glReportErrors("RenderUpdateState"); glReportErrors("RenderUpdateState");
@ -1102,15 +422,9 @@ void RenderUpdateState()
{ {
// Remember last state because if a unit gets enabled, we have to update it's whole state // 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] || previously_enabled_texture_unit[unit_index] = OpenGL.ColorAlphaUnitColorEnabledState[unit_index] ||
OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index]; OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index];
if (OpenGL.ColorCombineFunctions[c_function].ColorAlphaUnit[unit_index].Function == CF_Unused) OpenGL.ColorAlphaUnitColorEnabledState[unit_index] =
{ OpenGL.ColorCombineFunctions[c_function].ColorAlphaUnit[unit_index].Function != CF_Unused;
OpenGL.ColorAlphaUnitColorEnabledState[unit_index] = false;
}
else
{
OpenGL.ColorAlphaUnitColorEnabledState[unit_index] = true;
}
// AlphaCombine // AlphaCombine
if (OpenGL.ChromaKey && OpenGL.Texture && !OpenGL.Blend) if (OpenGL.ChromaKey && OpenGL.Texture && !OpenGL.Blend)
{ {
@ -1120,17 +434,11 @@ void RenderUpdateState()
{ {
if (OpenGL.AlphaCombineFunctions[a_function].ColorAlphaUnit[unit_index].Function == CF_Unused) 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)
// Modulate the alpha mask with the output of the previous unit // (chromakey-colored pixels have an alpha value of 0.0, the others 1.0)
// to make chromakey-colored pixels invisible (so they wouldn't pass the alpha test) OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index] =
// (chromakey-colored pixels have an alpha value of 0.0, the others 1.0) OpenGL.ChromaKey && OpenGL.Texture && OpenGL.Blend;
OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index] = true;
}
else
{
OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index] = false;
}
} }
else else
{ {
@ -1138,7 +446,7 @@ void RenderUpdateState()
} }
} }
enable_texture_unit[unit_index] = OpenGL.ColorAlphaUnitColorEnabledState[unit_index] || enable_texture_unit[unit_index] = OpenGL.ColorAlphaUnitColorEnabledState[unit_index] ||
OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index]; OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index];
} }
#ifdef OPENGL_DEBUG #ifdef OPENGL_DEBUG
for(long unit_index = 0; unit_index < 2; unit_index++) for(long unit_index = 0; unit_index < 2; unit_index++)

View File

@ -22,7 +22,6 @@ extern bool s_bUpdateColorInvertState;
extern bool s_bUpdateAlphaInvertState; extern bool s_bUpdateAlphaInvertState;
extern bool s_bUpdateConstantColorValueState; extern bool s_bUpdateConstantColorValueState;
extern bool s_bUpdateConstantColorValue4State; extern bool s_bUpdateConstantColorValue4State;
//extern bool s_bUpdateClipVerticesState;
extern bool s_bForceChromaKeyAndAlphaStateUpdate; extern bool s_bForceChromaKeyAndAlphaStateUpdate;
@ -179,11 +178,6 @@ inline void SetConstantColorValue4State()
s_bUpdateConstantColorValue4State = true; s_bUpdateConstantColorValue4State = true;
} }
//inline void SetClipVerticesState()
//{
// s_bUpdateClipVerticesState = true;
//}
// Also called from FrameBuffer class // Also called from FrameBuffer class
extern void SetClipVerticesState_Update(bool clip_vertices); extern void SetClipVerticesState_Update(bool clip_vertices);

View File

@ -81,6 +81,7 @@ union OGLByteColor
struct CombineFunction; struct CombineFunction;
struct CombineArgument; struct CombineArgument;
// The current glide state, valid anytime
struct GlideState struct GlideState
{ {
GrBuffer_t RenderBuffer; GrBuffer_t RenderBuffer;
@ -140,6 +141,7 @@ struct GlideState
FxFloat Gamma; FxFloat Gamma;
}; };
// Additional internal Glide state information
struct GlideStruct struct GlideStruct
{ {
int ActiveVoodoo; int ActiveVoodoo;
@ -165,62 +167,73 @@ struct GlideStruct
FxU32 TextureMemory; FxU32 TextureMemory;
}; };
// The current OpenGL state
// Vadility of members:
// - session static - these don't change during the lifetime of the OpenGL context
// - up to date - they are always up to date
// - forthcoming up to date on the next call to RenderUpdateState()
//
// @todo: Some state variables are considered not until the next call to RenderUpdateState
// while the others reflect the actual state
struct OpenGLStruct struct OpenGLStruct
{ {
// Session static
bool GlideInit; bool GlideInit;
bool WinOpen; bool WinOpen;
unsigned long WindowWidth;
unsigned long WindowHeight;
FxU32 OriginX; FxU32 OriginX;
FxU32 OriginY; FxU32 OriginY;
unsigned long WindowWidth;
unsigned long WindowHeight;
GLint ColorAlphaUnit1;
GLint ColorAlphaUnit2;
GLuint DummyTextureName;
GLint FogTextureUnit;
int MultiTextureTMUs;
GLuint Refresh;
FxU32 WaitSignal;
// up to date on the next call to RenderUpdateState()
bool Blend;
bool ChromaKey;
bool ClipVerticesEnabledState;
bool Fog;
GLfloat FogColor[4];
const CombineFunction* ColorCombineFunctions;
const CombineFunction* AlphaCombineFunctions;
const CombineArgument* ColorCombineArguments[5];
const CombineArgument* AlphaCombineArguments[5];
GLenum SrcBlend;
GLenum DstBlend;
GLenum SrcAlphaBlend;
GLenum DstAlphaBlend;
// always up to date
FxU32 ClipMinX; FxU32 ClipMinX;
FxU32 ClipMaxX; FxU32 ClipMaxX;
FxU32 ClipMinY; FxU32 ClipMinY;
FxU32 ClipMaxY; FxU32 ClipMaxY;
GLfloat Gamma; bool Clipping;
GLfloat AlphaReferenceValue; GLfloat AlphaReferenceValue;
GLenum AlphaTestFunction; GLenum AlphaTestFunction;
GLboolean DepthBufferWritting; GLboolean DepthBufferWritting;
GLfloat DepthBiasLevel; GLfloat DepthBiasLevel;
GLenum DepthFunction; GLenum DepthFunction;
int DepthBufferType; int DepthBufferType;
GLfloat ZNear;
GLfloat ZFar;
GLenum RenderBuffer; GLenum RenderBuffer;
GLenum SClampMode; GLenum SClampMode;
GLenum TClampMode; GLenum TClampMode;
GLenum MinFilterMode; GLenum MinFilterMode;
GLenum MagFilterMode; GLenum MagFilterMode;
GLenum SrcBlend; GLfloat Gamma;
GLenum DstBlend;
GLenum SrcAlphaBlend;
GLenum DstAlphaBlend;
GLuint Refresh;
GLfloat ConstantColor[4]; GLfloat ConstantColor[4];
GLfloat Delta0Color[4]; GLfloat Delta0Color[4];
GLfloat ZNear;
GLfloat ZFar;
GLint ColorAlphaUnit1;
GLint ColorAlphaUnit2;
bool ColorAlphaUnitColorEnabledState[2]; bool ColorAlphaUnitColorEnabledState[2];
bool ColorAlphaUnitAlphaEnabledState[2]; bool ColorAlphaUnitAlphaEnabledState[2];
GLuint DummyTextureName;
GLint FogTextureUnit;
bool FogTextureUnitEnabledState;
GLfloat FogColor[4];
OGLByteColor ChromaColor; OGLByteColor ChromaColor;
bool Fog;
bool ColorTexture; bool ColorTexture;
bool AlphaTexture; bool AlphaTexture;
bool Blend;
bool Texture; bool Texture;
bool ChromaKey; bool FogTextureUnitEnabledState; // @todo: currently not used
bool Clipping;
bool ClipVerticesEnabledState;
int MultiTextureTMUs;
const CombineFunction* ColorCombineFunctions;
const CombineFunction* AlphaCombineFunctions;
const CombineArgument* ColorCombineArguments[5];
const CombineArgument* AlphaCombineArguments[5];
FxU32 WaitSignal;
FxU8 FogTable[OPENGLFOGTABLESIZE]; FxU8 FogTable[OPENGLFOGTABLESIZE];
}; };

View File

@ -200,7 +200,7 @@ void GlideFramebuffer::OnBufferLockStartWrite(GrLock_t dwType, GrBuffer_t dwBuff
// would appear twice or at unexpected places. This suggests there // would appear twice or at unexpected places. This suggests there
// might be a bug in here (in conjunction with clipping??). // might be a bug in here (in conjunction with clipping??).
// Also be careful regarding performance issues. // Also be careful regarding performance issues.
WriteFrameBuffer(m_framebuffer->PixelPipeline); WriteFrameBuffer();
m_must_write = false; m_must_write = false;
} }
// Change format? // Change format?
@ -263,7 +263,7 @@ void GlideFramebuffer::OnBufferUnlockEndWrite(GrBuffer_t dwBuffer)
// pixel pipeline state before the buffer will eventtually be written out. // pixel pipeline state before the buffer will eventtually be written out.
if (m_framebuffer->PixelPipeline) if (m_framebuffer->PixelPipeline)
{ {
WriteFrameBuffer(true); WriteFrameBuffer();
// This write is finished // This write is finished
m_must_write = false; m_must_write = false;
} }
@ -328,7 +328,7 @@ void GlideFramebuffer::OnClipWindow()
// @todo: This must be reconsidered because it triggers all the time // @todo: This must be reconsidered because it triggers all the time
if (m_framebuffer->PixelPipeline) if (m_framebuffer->PixelPipeline)
{ {
WriteFrameBuffer(true); WriteFrameBuffer();
// Keep writing as the frame buffer may still be locked // Keep writing as the frame buffer may still be locked
m_must_write = m_framebuffer->Lock; m_must_write = m_framebuffer->Lock;
// @todo: Think this is obsolete as the case is catched by OnChromaKeyValueChanged() // @todo: Think this is obsolete as the case is catched by OnChromaKeyValueChanged()
@ -448,7 +448,7 @@ void GlideFramebuffer::OnRenderDrawTriangles()
} }
else if (InternalConfig.PedanticFrameBufferEmulation || m_must_write) else if (InternalConfig.PedanticFrameBufferEmulation || m_must_write)
{ {
WriteFrameBuffer(m_framebuffer->PixelPipeline); WriteFrameBuffer();
} }
// Need to start a new write // Need to start a new write
if (InternalConfig.PedanticFrameBufferEmulation) if (InternalConfig.PedanticFrameBufferEmulation)
@ -489,24 +489,24 @@ void GlideFramebuffer::OnBeforeBufferSwap()
} }
else if (m_must_write) else if (m_must_write)
{ {
WriteFrameBuffer(m_framebuffer->PixelPipeline); WriteFrameBuffer();
} }
else if (BackBufferIsLocked()) else if (BackBufferIsLocked())
{ {
WriteFrameBuffer(m_framebuffer->PixelPipeline); WriteFrameBuffer();
} }
m_must_write = false; m_must_write = false;
// optionally render the 3Dfx powerfield logo overlay on top of the frame // optionally render the 3Dfx powerfield logo overlay on top of the frame
if (InternalConfig.ShamelessPlug) if (InternalConfig.ShamelessPlug)
{ {
// @todo: For apps that lock the frame buffer accross buffer swaps // @todo: For apps that lock the frame buffer accross buffer swaps
// (for instance Carmageddon) the current state must be saved... // (for instance Carmageddon) the current lock state must be saved...
_grShamelessPlug(); _grShamelessPlug();
if (m_must_write) if (m_must_write)
{ {
WriteFrameBuffer(m_framebuffer->PixelPipeline); WriteFrameBuffer();
} }
// ... and restored after rendering the shameless plug // @todo: ... and restored after rendering the shameless plug
} }
} }
else else
@ -530,10 +530,10 @@ void GlideFramebuffer::OnAfterBufferSwap()
begin_write(); begin_write();
} }
void GlideFramebuffer::WriteFrameBuffer(bool pixelpipeline) void GlideFramebuffer::WriteFrameBuffer()
{ {
#ifdef OGL_FRAMEBUFFER #ifdef OGL_FRAMEBUFFER
GlideMsg( "GlideFrameBuffer::WriteFrameBuffer(%d)\n", pixelpipeline); GlideMsg( "GlideFrameBuffer::WriteFrameBuffer()\n");
#endif #endif
// apply the framebuffer changes? // apply the framebuffer changes?
@ -541,16 +541,19 @@ void GlideFramebuffer::WriteFrameBuffer(bool pixelpipeline)
{ {
// Only the back buffer is supported because games like Carmageddon // Only the back buffer is supported because games like Carmageddon
// temporarily lock and unlock the front buffer while holding the lock // temporarily lock and unlock the front buffer while holding the lock
// to the back buffer. Becasue he current implementation of the framebuffer // to the back buffer. Because he current implementation of the framebuffer
// emulation doesn't support locks to multiple buffers, data is written to // emulation doesn't support locks to multiple buffers, data is written to
// the current buffer (which is usally the back buffer). // the current buffer (which is usally the back buffer).
if (pixelpipeline) if (m_framebuffer->PixelPipeline)
{ {
end_write(m_alpha, m_depth, pixelpipeline); end_write(m_alpha, m_depth);
} }
else else
{ {
end_write(); end_write();
// @todo: it would be nice to eleminate the condition,but
// m_alpha is always applied to the write and depth never
// end_write(m_alpha, m_depth);
} }
} }
else else
@ -614,7 +617,7 @@ void GlideFramebuffer::OnChromaKeyValueChanged()
if (m_chromakeyvalue_changed && m_framebuffer->PixelPipeline) if (m_chromakeyvalue_changed && m_framebuffer->PixelPipeline)
{ {
// Flush the current contents of the framebuffer // Flush the current contents of the framebuffer
WriteFrameBuffer(m_framebuffer->PixelPipeline); WriteFrameBuffer();
SetChromaKeyValue(m_chromakeyvalue_new); SetChromaKeyValue(m_chromakeyvalue_new);
m_chromakeyvalue_changed = false; m_chromakeyvalue_changed = false;
// Fill the framebuffer with the new chromakey value // Fill the framebuffer with the new chromakey value
@ -626,18 +629,18 @@ void GlideFramebuffer::OnChromaKeyValueChanged()
void GlideFramebuffer::SetAlpha(FxU32 alpha) void GlideFramebuffer::SetAlpha(FxU32 alpha)
{ {
if (m_must_write && (m_framebuffer->PixelPipeline & m_alpha) != alpha) if (m_must_write && m_framebuffer->PixelPipeline && m_alpha != alpha)
{ {
WriteFrameBuffer(m_framebuffer->PixelPipeline); WriteFrameBuffer();
m_alpha = alpha;
} }
m_alpha = alpha;
}; };
void GlideFramebuffer::SetDepth(GLfloat depth) void GlideFramebuffer::SetDepth(GLfloat depth)
{ {
if (m_must_write && (m_framebuffer->PixelPipeline && m_depth) != depth) if (m_must_write && m_framebuffer->PixelPipeline && m_depth != depth)
{ {
WriteFrameBuffer(m_framebuffer->PixelPipeline); WriteFrameBuffer();
m_depth = depth;
} }
m_depth = depth;
}; };

View File

@ -59,6 +59,6 @@ public:
void CopyFrameBuffer(FxU16* targetbuffer); void CopyFrameBuffer(FxU16* targetbuffer);
inline FxU16 GetChromaKeyValue() {return Framebuffer::GetChromaKeyValue();}; inline FxU16 GetChromaKeyValue() {return Framebuffer::GetChromaKeyValue();};
protected: protected:
void WriteFrameBuffer(bool pixelpipline); void WriteFrameBuffer();
inline bool BackBufferIsLocked() {return m_grLfbLockWriteMode[GR_BUFFER_BACKBUFFER] != GR_LFBWRITEMODE_UNUSED;}; inline bool BackBufferIsLocked() {return m_grLfbLockWriteMode[GR_BUFFER_BACKBUFFER] != GR_LFBWRITEMODE_UNUSED;};
}; };

View File

@ -22,42 +22,28 @@
void PGTexture::genPaletteMipmaps( FxU32 width, FxU32 height, const FxU8 *data ) void PGTexture::genPaletteMipmaps( FxU32 width, FxU32 height, const FxU8 *data )
{ {
FxU8 buf[ 128 * 128 ]; FxU8 buf[128 * 128];
FxU32 mmwidth; FxU32 mmwidth = width;
FxU32 mmheight; FxU32 mmheight = height;
FxU32 lod; FxU32 lod = 0;
FxU32 skip; FxU32 skip = 1;
while ((mmwidth > 1) || (mmheight > 1))
mmwidth = width; {
mmheight = height; mmwidth = mmwidth > 1 ? mmwidth / 2 : 1;
lod = 0; mmheight = mmheight > 1 ? mmheight / 2 : 1;
skip = 1; lod += 1;
skip *= 2;
while ( ( mmwidth > 1 ) || ( mmheight > 1 ) ) for (FxU32 y = 0; y < mmheight; y++)
{ {
FxU32 x, const FxU8* in = data + width * y * skip;
y; FxU8* out = buf + mmwidth * y;
for (FxU32 x = 0; x < mmwidth; x++)
mmwidth = mmwidth > 1 ? mmwidth / 2 : 1; {
mmheight = mmheight > 1 ? mmheight / 2 : 1; out[x] = in[x * skip];
lod += 1; }
skip *= 2; }
glTexImage2D( GL_TEXTURE_2D, lod, GL_COLOR_INDEX8_EXT, mmwidth, mmheight, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, buf );
for ( y = 0; y < mmheight; y++ ) }
{
const FxU8* in;
FxU8* out;
in = data + width * y * skip;
out = buf + mmwidth * y;
for ( x = 0; x < mmwidth; x++ )
{
out[ x ] = in[ x * skip ];
}
}
glTexImage2D( GL_TEXTURE_2D, lod, GL_COLOR_INDEX8_EXT, mmwidth, mmheight, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, buf );
}
} }
PGTexture::PGTexture(int mem_size) PGTexture::PGTexture(int mem_size)
@ -634,7 +620,7 @@ bool PGTexture::MakeReady(TTextureStruct* tex_coords, unsigned long number_of_tr
if (subtexcoords) if (subtexcoords)
{ {
// APPLE_client_storage doesn't explicitely forbid to adjust pixel unpack :^) // APPLE_client_storage doesn't explicitly forbid to adjust pixel unpack :^)
glPixelStorei(GL_UNPACK_SKIP_PIXELS, subtexcoords->left); glPixelStorei(GL_UNPACK_SKIP_PIXELS, subtexcoords->left);
glPixelStorei(GL_UNPACK_SKIP_ROWS, subtexcoords->top); glPixelStorei(GL_UNPACK_SKIP_ROWS, subtexcoords->top);
glPixelStorei(GL_UNPACK_ROW_LENGTH, texVals.width); glPixelStorei(GL_UNPACK_ROW_LENGTH, texVals.width);
@ -684,7 +670,7 @@ bool PGTexture::MakeReady(TTextureStruct* tex_coords, unsigned long number_of_tr
break; break;
case GR_TEXFMT_P_8: case GR_TEXFMT_P_8:
// Read about anisotropy and chromakey issues in macFormatConversions.cpp // Read about anisotropy and chromakey issues in macFormatConversions.cpp
if ( InternalConfig.EXT_paletted_texture && InternalConfig.AnisotropylLevel < 2) if (InternalConfig.EXT_paletted_texture && InternalConfig.AnisotropylLevel < 2)
{ {
glColorTable(GL_TEXTURE_2D, GL_RGBA, 256, GL_RGBA, GL_UNSIGNED_BYTE, m_palette); glColorTable(GL_TEXTURE_2D, GL_RGBA, 256, GL_RGBA, GL_UNSIGNED_BYTE, m_palette);
glTexImage2D( GL_TEXTURE_2D, texVals.lod, GL_COLOR_INDEX8_EXT, glTexImage2D( GL_TEXTURE_2D, texVals.lod, GL_COLOR_INDEX8_EXT,
@ -712,7 +698,7 @@ bool PGTexture::MakeReady(TTextureStruct* tex_coords, unsigned long number_of_tr
} }
break; break;
case GR_TEXFMT_AP_88: case GR_TEXFMT_AP_88:
if ( use_two_textures ) if (use_two_textures)
{ {
FxU32 *texBuffer2 = texBuffer + 256 * 128; FxU32 *texBuffer2 = texBuffer + 256 * 128;
glColorTable(GL_TEXTURE_2D, GL_RGBA, 256, GL_RGBA, GL_UNSIGNED_BYTE, m_palette); glColorTable(GL_TEXTURE_2D, GL_RGBA, 256, GL_RGBA, GL_UNSIGNED_BYTE, m_palette);
@ -725,7 +711,7 @@ bool PGTexture::MakeReady(TTextureStruct* tex_coords, unsigned long number_of_tr
genPaletteMipmaps(texVals.width, texVals.height, (FxU8*) texBuffer); genPaletteMipmaps(texVals.width, texVals.height, (FxU8*) texBuffer);
} }
glActiveTextureARB(OpenGL.ColorAlphaUnit1 + 1); glActiveTextureARB(OpenGL.ColorAlphaUnit1 + 1);
DownloadMipmapsToOpenGL( GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, texBuffer2, texVals, !use_mipmap_ext); DownloadMipmapsToOpenGL(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, texBuffer2, texVals, !use_mipmap_ext);
glActiveTextureARB(OpenGL.ColorAlphaUnit1); glActiveTextureARB(OpenGL.ColorAlphaUnit1);
glReportError(); glReportError();
} }
@ -736,11 +722,9 @@ bool PGTexture::MakeReady(TTextureStruct* tex_coords, unsigned long number_of_tr
} }
break; break;
case GR_TEXFMT_ALPHA_8: case GR_TEXFMT_ALPHA_8:
// the alpha value is used for red, green, and blue as well (see glide24pgm.pdf)
ConvertA8toAP88((FxU8*)data, (FxU16*) texBuffer, texVals.nPixels); ConvertA8toAP88((FxU8*)data, (FxU16*) texBuffer, texVals.nPixels);
DownloadMipmapsToOpenGL(2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, texBuffer, texVals, !use_mipmap_ext); DownloadMipmapsToOpenGL(2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, texBuffer, texVals, !use_mipmap_ext);
// @todo: The statement below breaks the overlay texts in Myth TFL.
// As a result, this optimsation has been undone for now
// DownloadMipmapsToOpenGL(1, GL_ALPHA, GL_UNSIGNED_BYTE, data, texVals, !use_mipmap_ext);
break; break;
case GR_TEXFMT_ALPHA_INTENSITY_88: case GR_TEXFMT_ALPHA_INTENSITY_88:
DownloadMipmapsToOpenGL(2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data, texVals, !use_mipmap_ext); DownloadMipmapsToOpenGL(2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data, texVals, !use_mipmap_ext);
@ -810,28 +794,24 @@ bool PGTexture::MakeReady(TTextureStruct* tex_coords, unsigned long number_of_tr
FxU32 PGTexture::LodOffset( FxU32 evenOdd, const GrTexInfo *info ) FxU32 PGTexture::LodOffset( FxU32 evenOdd, const GrTexInfo *info )
{ {
FxU32 total = 0; FxU32 total = 0;
GrLOD_t i; for(GrLOD_t i = info->largeLod; i < info->smallLod; i++)
{
for( i = info->largeLod; i < info->smallLod; i++ ) total += MipMapMemRequired( i, info->aspectRatio, info->format);
{ }
total += MipMapMemRequired( i, info->aspectRatio, info->format ); total = (total + 7) & ~7;
} return total;
total = ( total + 7 ) & ~7;
return total;
} }
FxU32 PGTexture::TextureMemRequired( FxU32 evenOdd, const GrTexInfo *info ) FxU32 PGTexture::TextureMemRequired( FxU32 evenOdd, const GrTexInfo *info )
{ {
// //
// If the format is one of these: // If the format is one of these:
// GR_TEXFMT_RGB_332, GR_TEXFMT_YIQ_422, GR_TEXFMT_ALPHA_8 // GR_TEXFMT_RGB_332, GR_TEXFMT_YIQ_422, GR_TEXFMT_ALPHA_8
// GR_TEXFMT_INTENSITY_8, GR_TEXFMT_ALPHA_INTENSITY_44, GR_TEXFMT_P_8 // GR_TEXFMT_INTENSITY_8, GR_TEXFMT_ALPHA_INTENSITY_44, GR_TEXFMT_P_8
// Reduces the size by 2 // Reduces the size by 2
// //
return nSquareTexLod[ info->format < GR_TEXFMT_16BIT ][ info->aspectRatio ][ info->largeLod ][ info->smallLod ]; return nSquareTexLod[ info->format < GR_TEXFMT_16BIT ][ info->aspectRatio ][ info->largeLod ][ info->smallLod ];
} }
FxU32 PGTexture::MipMapMemRequired( GrLOD_t lod, GrAspectRatio_t aspectRatio, GrTextureFormat_t format ) FxU32 PGTexture::MipMapMemRequired( GrLOD_t lod, GrAspectRatio_t aspectRatio, GrTextureFormat_t format )
@ -842,7 +822,7 @@ FxU32 PGTexture::MipMapMemRequired( GrLOD_t lod, GrAspectRatio_t aspectRatio, Gr
// GR_TEXFMT_INTENSITY_8, GR_TEXFMT_ALPHA_INTENSITY_44, GR_TEXFMT_P_8 // GR_TEXFMT_INTENSITY_8, GR_TEXFMT_ALPHA_INTENSITY_44, GR_TEXFMT_P_8
// Reduces the size by 2 // Reduces the size by 2
// //
return nSquareLod[ format >= GR_TEXFMT_16BIT ][ aspectRatio ][ lod ]; return nSquareLod[format >= GR_TEXFMT_16BIT][aspectRatio][lod];
} }
void PGTexture::GetTexValues( TexValues * tval ) const void PGTexture::GetTexValues( TexValues * tval ) const
@ -867,53 +847,51 @@ void PGTexture::ChromakeyValue( GrColor_t value )
void PGTexture::ChromakeyMode( GrChromakeyMode_t mode ) void PGTexture::ChromakeyMode( GrChromakeyMode_t mode )
{ {
m_chromakey_mode = mode; m_chromakey_mode = mode;
m_palette_dirty = true; m_palette_dirty = true;
} }
void PGTexture::ApplyKeyToPalette( void ) void PGTexture::ApplyKeyToPalette( void )
{ {
FxU32 hash; if (m_palette_dirty)
int i;
if ( m_palette_dirty )
{ {
hash = 0; FxU32 hash = 0;
{ {
for ( i = 0; i < 256; i++ ) for (int i = 0; i < 256; i++)
{ {
if ( ( m_chromakey_mode ) if ((m_chromakey_mode) &&
&& ( ( m_palette[i] & 0xffffff00 ) == m_chromakey_value_8888)) ((m_palette[i] & 0xffffff00) == m_chromakey_value_8888))
{ {
m_palette[i] &= 0xffffff00; m_palette[i] &= 0xffffff00;
} }
else else
{ {
m_palette[i] |= 0x000000ff; m_palette[i] |= 0x000000ff;
} }
hash = ( ( hash << 5 ) | ( hash >> 27 ) ); hash = ((hash << 5) | (hash >> 27));
hash += ( InternalConfig.IgnorePaletteChange hash += (InternalConfig.IgnorePaletteChange
? ( m_palette[ i ] & 0x000000ff ) ? (m_palette[i] & 0x000000ff)
: m_palette[ i ]); : m_palette[i]);
} }
} }
m_palette_hash = hash; m_palette_hash = hash;
m_palette_dirty = false; m_palette_dirty = false;
} }
} }
void PGTexture::NCCTable( GrNCCTable_t tab ) void PGTexture::NCCTable( GrNCCTable_t tab )
{ {
switch ( tab ) switch ( tab )
{ {
case GR_NCCTABLE_NCC0: case GR_NCCTABLE_NCC0:
case GR_NCCTABLE_NCC1: case GR_NCCTABLE_NCC1:
m_ncc_select = tab; m_ncc_select = tab;
} }
} }
FxU32 PGTexture::GetMemorySize( void ) const FxU32 PGTexture::GetMemorySize( void ) const
{ {
return m_tex_memory_size; return m_tex_memory_size;
} }
unsigned int PGTexture::PowerOfTwoCeiling(unsigned int x) unsigned int PGTexture::PowerOfTwoCeiling(unsigned int x)

View File

@ -177,9 +177,25 @@ void PGUTexture::Source( GrMipMapId_t id )
grTexClampMode( tmu, mm_info[ id ].s_clamp_mode, mm_info[ id ].t_clamp_mode ); grTexClampMode( tmu, mm_info[ id ].s_clamp_mode, mm_info[ id ].t_clamp_mode );
grTexLodBiasValue( tmu, mm_info[ id ].lod_bias ); grTexLodBiasValue( tmu, mm_info[ id ].lod_bias );
// Download the ncc table // Download the ncc table
// @todo: the linux driver utilises both tables and optimises download // @todo: only necessary when the format uses the table?
// -> No download, no texture recreation if ((info.format == GR_TEXFMT_YIQ_422) ||
grTexDownloadTable(tmu, GR_NCCTABLE_NCC0, &mm_info[ id ].ncc_table); (info.format == GR_TEXFMT_AYIQ_8422))
{
// @todo: the linux driver utilises both tables and optimises downloads
// MacGLide only uses gr* functions whereas
// the linux driver has extra internal state for gu* functions
// -> No download, no texture recreation (see gutex.c)
// /* Which table should we use? */
// table = gc->tmu_state[tmu].next_ncc_table;
// /* Download NCC table */ // using internal function
// _grTexDownloadNccTable( tmu, table, &mminfo->ncc_table, 0, 11 );
// /* Set the mmid so we known it's down there */
// gc->tmu_state[tmu].ncc_mmids[table] = mmid;
// /* Set the state to know which table was the LRA */
// gc->tmu_state[tmu].next_ncc_table =
// (table == 0 ? 1 : 0);
grTexDownloadTable(tmu, GR_NCCTABLE_NCC0, &mm_info[ id ].ncc_table);
}
m_current_id = id; m_current_id = id;
} }
#ifdef OGL_UTEX #ifdef OGL_UTEX

View File

@ -20,6 +20,8 @@
// Write colored pixels only // Write colored pixels only
void gapfixSetSimpleColorState() void gapfixSetSimpleColorState()
{ {
glReportErrors("gapfixSetSimpleColorState");
// Disable the cull mode // Disable the cull mode
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
// Disable clip volume hint manually to avoid recursion // Disable clip volume hint manually to avoid recursion
@ -82,6 +84,8 @@ void gapfixSetSimpleColorState()
void gapfixRestoreFromSimpleColorState() void gapfixRestoreFromSimpleColorState()
{ {
glReportErrors("gapfixRestoreFromSimpleColorState");
// Restore state // Restore state
switch (Glide.State.CullMode) switch (Glide.State.CullMode)
{ {

View File

@ -648,56 +648,10 @@ guTexCombineFunction( GrChipID_t tmu, GrTextureCombineFnc_t func )
#if defined( OGL_PARTDONE ) || defined( OGL_COMBINE ) #if defined( OGL_PARTDONE ) || defined( OGL_COMBINE )
GlideMsg( "guTexCombineFunction( %d, %d )\n", tmu, func ); GlideMsg( "guTexCombineFunction( %d, %d )\n", tmu, func );
#endif #endif
// @todo: guTexCombineFunction() also keeps track of which TMUs
// Ignoring TMU as we are only emulating Glide and assuming a well behaviored program // require texture coordinates for the rendering routines.
if ( tmu != GR_TMU0 ) // (see glide24pgm page 139)
{ grTexCombineFunction(tmu, func);
return;
}
switch ( func )
{
case GR_TEXTURECOMBINE_ZERO: // 0x00 per component
grTexCombine( tmu, GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_ZERO,
GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_ZERO, FXFALSE, FXFALSE );
break;
case GR_TEXTURECOMBINE_DECAL: // Clocal decal texture
grTexCombine( tmu, GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE,
GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE );
break;
case GR_TEXTURECOMBINE_OTHER: // Cother pass through
grTexCombine( tmu, GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE,
GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE );
break;
case GR_TEXTURECOMBINE_ADD: // Cother + Clocal additive texture
grTexCombine( tmu, GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE,
GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE );
break;
case GR_TEXTURECOMBINE_MULTIPLY: // Cother * Clocal modulated texture
grTexCombine( tmu, GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL,
GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, FXFALSE, FXFALSE );
break;
case GR_TEXTURECOMBINE_SUBTRACT: // Cother Clocal subtractive texture
grTexCombine( tmu, GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_ONE,
GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE );
break;
case GR_TEXTURECOMBINE_ONE: // 255 0xFF per component
grTexCombine( tmu, GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_ZERO,
GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_ZERO, FXTRUE, FXTRUE );
break;
// case GR_TEXTURECOMBINE_DETAIL: // blend (Cother, Clocal) detail textures with detail on selected TMU
// case GR_TEXTURECOMBINE_DETAIL_OTHER: // blend (Cother, Clocal) detail textures with detail on neighboring TMU
// case GR_TEXTURECOMBINE_TRILINEAR_ODD: // blend (Cother, Clocal) LOD blended textures with odd levels on selected TMU
// case GR_TEXTURECOMBINE_TRILINEAR_EVEN: // blend (Cother, Clocal) LOD blended textures with even levels on selected TMU
// break;
}
} }
//************************************************* //*************************************************