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

View File

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

View File

@ -105,7 +105,7 @@ void RenderInitialize(void)
pTS->aq = pTS->bq = pTS->cq = 0.0f;
}
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
OGLRender.BufferLocked = false;
OGLRender.BufferStart = 0;

View File

@ -32,373 +32,9 @@ bool s_bUpdateColorInvertState = false;
bool s_bUpdateAlphaInvertState = false;
bool s_bUpdateConstantColorValueState = false;
bool s_bUpdateConstantColorValue4State = false;
//bool s_bUpdateClipVerticesState = 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
@ -478,153 +114,6 @@ inline void SetChromaKeyAndAlphaState_update()
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");
@ -643,7 +132,7 @@ inline void SetBlendState_update()
}
#endif
if ( OpenGL.Blend )
if (OpenGL.Blend)
{
#ifdef OPENGL_DEBUG
GlideMsg("Changing Blend state to enabled\n");
@ -677,175 +166,6 @@ inline void SetBlendState_update()
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");
@ -1102,15 +422,9 @@ void RenderUpdateState()
{
// 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;
}
OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index];
OpenGL.ColorAlphaUnitColorEnabledState[unit_index] =
OpenGL.ColorCombineFunctions[c_function].ColorAlphaUnit[unit_index].Function != CF_Unused;
// AlphaCombine
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.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;
}
// 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] =
OpenGL.ChromaKey && OpenGL.Texture && OpenGL.Blend;
}
else
{
@ -1138,7 +446,7 @@ void RenderUpdateState()
}
}
enable_texture_unit[unit_index] = OpenGL.ColorAlphaUnitColorEnabledState[unit_index] ||
OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index];
OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index];
}
#ifdef OPENGL_DEBUG
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_bUpdateConstantColorValueState;
extern bool s_bUpdateConstantColorValue4State;
//extern bool s_bUpdateClipVerticesState;
extern bool s_bForceChromaKeyAndAlphaStateUpdate;
@ -179,11 +178,6 @@ inline void SetConstantColorValue4State()
s_bUpdateConstantColorValue4State = true;
}
//inline void SetClipVerticesState()
//{
// s_bUpdateClipVerticesState = true;
//}
// Also called from FrameBuffer class
extern void SetClipVerticesState_Update(bool clip_vertices);

View File

@ -81,6 +81,7 @@ union OGLByteColor
struct CombineFunction;
struct CombineArgument;
// The current glide state, valid anytime
struct GlideState
{
GrBuffer_t RenderBuffer;
@ -140,6 +141,7 @@ struct GlideState
FxFloat Gamma;
};
// Additional internal Glide state information
struct GlideStruct
{
int ActiveVoodoo;
@ -165,62 +167,73 @@ struct GlideStruct
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
{
// Session static
bool GlideInit;
bool WinOpen;
unsigned long WindowWidth;
unsigned long WindowHeight;
FxU32 OriginX;
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 ClipMaxX;
FxU32 ClipMinY;
FxU32 ClipMaxY;
GLfloat Gamma;
bool Clipping;
GLfloat AlphaReferenceValue;
GLenum AlphaTestFunction;
GLboolean DepthBufferWritting;
GLfloat DepthBiasLevel;
GLenum DepthFunction;
int DepthBufferType;
GLfloat ZNear;
GLfloat ZFar;
GLenum RenderBuffer;
GLenum SClampMode;
GLenum TClampMode;
GLenum MinFilterMode;
GLenum MagFilterMode;
GLenum SrcBlend;
GLenum DstBlend;
GLenum SrcAlphaBlend;
GLenum DstAlphaBlend;
GLuint Refresh;
GLfloat Gamma;
GLfloat ConstantColor[4];
GLfloat Delta0Color[4];
GLfloat ZNear;
GLfloat ZFar;
GLint ColorAlphaUnit1;
GLint ColorAlphaUnit2;
bool ColorAlphaUnitColorEnabledState[2];
bool ColorAlphaUnitAlphaEnabledState[2];
GLuint DummyTextureName;
GLint FogTextureUnit;
bool FogTextureUnitEnabledState;
GLfloat FogColor[4];
OGLByteColor ChromaColor;
bool Fog;
bool ColorTexture;
bool AlphaTexture;
bool Blend;
bool Texture;
bool ChromaKey;
bool Clipping;
bool ClipVerticesEnabledState;
int MultiTextureTMUs;
const CombineFunction* ColorCombineFunctions;
const CombineFunction* AlphaCombineFunctions;
const CombineArgument* ColorCombineArguments[5];
const CombineArgument* AlphaCombineArguments[5];
FxU32 WaitSignal;
bool FogTextureUnitEnabledState; // @todo: currently not used
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
// might be a bug in here (in conjunction with clipping??).
// Also be careful regarding performance issues.
WriteFrameBuffer(m_framebuffer->PixelPipeline);
WriteFrameBuffer();
m_must_write = false;
}
// Change format?
@ -263,7 +263,7 @@ void GlideFramebuffer::OnBufferUnlockEndWrite(GrBuffer_t dwBuffer)
// pixel pipeline state before the buffer will eventtually be written out.
if (m_framebuffer->PixelPipeline)
{
WriteFrameBuffer(true);
WriteFrameBuffer();
// This write is finished
m_must_write = false;
}
@ -328,7 +328,7 @@ void GlideFramebuffer::OnClipWindow()
// @todo: This must be reconsidered because it triggers all the time
if (m_framebuffer->PixelPipeline)
{
WriteFrameBuffer(true);
WriteFrameBuffer();
// Keep writing as the frame buffer may still be locked
m_must_write = m_framebuffer->Lock;
// @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)
{
WriteFrameBuffer(m_framebuffer->PixelPipeline);
WriteFrameBuffer();
}
// Need to start a new write
if (InternalConfig.PedanticFrameBufferEmulation)
@ -489,24 +489,24 @@ void GlideFramebuffer::OnBeforeBufferSwap()
}
else if (m_must_write)
{
WriteFrameBuffer(m_framebuffer->PixelPipeline);
WriteFrameBuffer();
}
else if (BackBufferIsLocked())
{
WriteFrameBuffer(m_framebuffer->PixelPipeline);
WriteFrameBuffer();
}
m_must_write = false;
// optionally render the 3Dfx powerfield logo overlay on top of the frame
if (InternalConfig.ShamelessPlug)
{
// @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();
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
@ -530,10 +530,10 @@ void GlideFramebuffer::OnAfterBufferSwap()
begin_write();
}
void GlideFramebuffer::WriteFrameBuffer(bool pixelpipeline)
void GlideFramebuffer::WriteFrameBuffer()
{
#ifdef OGL_FRAMEBUFFER
GlideMsg( "GlideFrameBuffer::WriteFrameBuffer(%d)\n", pixelpipeline);
GlideMsg( "GlideFrameBuffer::WriteFrameBuffer()\n");
#endif
// apply the framebuffer changes?
@ -541,16 +541,19 @@ void GlideFramebuffer::WriteFrameBuffer(bool pixelpipeline)
{
// Only the back buffer is supported because games like Carmageddon
// 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
// 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
{
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
@ -614,7 +617,7 @@ void GlideFramebuffer::OnChromaKeyValueChanged()
if (m_chromakeyvalue_changed && m_framebuffer->PixelPipeline)
{
// Flush the current contents of the framebuffer
WriteFrameBuffer(m_framebuffer->PixelPipeline);
WriteFrameBuffer();
SetChromaKeyValue(m_chromakeyvalue_new);
m_chromakeyvalue_changed = false;
// Fill the framebuffer with the new chromakey value
@ -626,18 +629,18 @@ void GlideFramebuffer::OnChromaKeyValueChanged()
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)
{
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);
inline FxU16 GetChromaKeyValue() {return Framebuffer::GetChromaKeyValue();};
protected:
void WriteFrameBuffer(bool pixelpipline);
void WriteFrameBuffer();
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 )
{
FxU8 buf[ 128 * 128 ];
FxU32 mmwidth;
FxU32 mmheight;
FxU32 lod;
FxU32 skip;
mmwidth = width;
mmheight = height;
lod = 0;
skip = 1;
while ( ( mmwidth > 1 ) || ( mmheight > 1 ) )
{
FxU32 x,
y;
mmwidth = mmwidth > 1 ? mmwidth / 2 : 1;
mmheight = mmheight > 1 ? mmheight / 2 : 1;
lod += 1;
skip *= 2;
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 );
}
FxU8 buf[128 * 128];
FxU32 mmwidth = width;
FxU32 mmheight = height;
FxU32 lod = 0;
FxU32 skip = 1;
while ((mmwidth > 1) || (mmheight > 1))
{
mmwidth = mmwidth > 1 ? mmwidth / 2 : 1;
mmheight = mmheight > 1 ? mmheight / 2 : 1;
lod += 1;
skip *= 2;
for (FxU32 y = 0; y < mmheight; y++)
{
const FxU8* in = data + width * y * skip;
FxU8* out = buf + mmwidth * y;
for (FxU32 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)
@ -634,7 +620,7 @@ bool PGTexture::MakeReady(TTextureStruct* tex_coords, unsigned long number_of_tr
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_ROWS, subtexcoords->top);
glPixelStorei(GL_UNPACK_ROW_LENGTH, texVals.width);
@ -684,7 +670,7 @@ bool PGTexture::MakeReady(TTextureStruct* tex_coords, unsigned long number_of_tr
break;
case GR_TEXFMT_P_8:
// 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);
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;
case GR_TEXFMT_AP_88:
if ( use_two_textures )
if (use_two_textures)
{
FxU32 *texBuffer2 = texBuffer + 256 * 128;
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);
}
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);
glReportError();
}
@ -736,11 +722,9 @@ bool PGTexture::MakeReady(TTextureStruct* tex_coords, unsigned long number_of_tr
}
break;
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);
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;
case GR_TEXFMT_ALPHA_INTENSITY_88:
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 total = 0;
GrLOD_t i;
for( i = info->largeLod; i < info->smallLod; i++ )
{
total += MipMapMemRequired( i, info->aspectRatio, info->format );
}
total = ( total + 7 ) & ~7;
return total;
FxU32 total = 0;
for(GrLOD_t i = info->largeLod; i < info->smallLod; i++)
{
total += MipMapMemRequired( i, info->aspectRatio, info->format);
}
total = (total + 7) & ~7;
return total;
}
FxU32 PGTexture::TextureMemRequired( FxU32 evenOdd, const GrTexInfo *info )
{
//
// If the format is one of these:
// 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
// Reduces the size by 2
//
return nSquareTexLod[ info->format < GR_TEXFMT_16BIT ][ info->aspectRatio ][ info->largeLod ][ info->smallLod ];
//
// If the format is one of these:
// 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
// Reduces the size by 2
//
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 )
@ -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
// 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
@ -867,53 +847,51 @@ void PGTexture::ChromakeyValue( GrColor_t value )
void PGTexture::ChromakeyMode( GrChromakeyMode_t mode )
{
m_chromakey_mode = mode;
m_palette_dirty = true;
m_chromakey_mode = mode;
m_palette_dirty = true;
}
void PGTexture::ApplyKeyToPalette( void )
{
FxU32 hash;
int i;
if ( m_palette_dirty )
if (m_palette_dirty)
{
hash = 0;
{
for ( i = 0; i < 256; i++ )
{
if ( ( m_chromakey_mode )
&& ( ( m_palette[i] & 0xffffff00 ) == m_chromakey_value_8888))
{
m_palette[i] &= 0xffffff00;
}
else
{
m_palette[i] |= 0x000000ff;
}
hash = ( ( hash << 5 ) | ( hash >> 27 ) );
hash += ( InternalConfig.IgnorePaletteChange
? ( m_palette[ i ] & 0x000000ff )
: m_palette[ i ]);
}
}
m_palette_hash = hash;
m_palette_dirty = false;
FxU32 hash = 0;
{
for (int i = 0; i < 256; i++)
{
if ((m_chromakey_mode) &&
((m_palette[i] & 0xffffff00) == m_chromakey_value_8888))
{
m_palette[i] &= 0xffffff00;
}
else
{
m_palette[i] |= 0x000000ff;
}
hash = ((hash << 5) | (hash >> 27));
hash += (InternalConfig.IgnorePaletteChange
? (m_palette[i] & 0x000000ff)
: m_palette[i]);
}
}
m_palette_hash = hash;
m_palette_dirty = false;
}
}
void PGTexture::NCCTable( GrNCCTable_t tab )
{
switch ( tab )
{
case GR_NCCTABLE_NCC0:
case GR_NCCTABLE_NCC1:
m_ncc_select = tab;
}
switch ( tab )
{
case GR_NCCTABLE_NCC0:
case GR_NCCTABLE_NCC1:
m_ncc_select = tab;
}
}
FxU32 PGTexture::GetMemorySize( void ) const
{
return m_tex_memory_size;
return m_tex_memory_size;
}
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 );
grTexLodBiasValue( tmu, mm_info[ id ].lod_bias );
// Download the ncc table
// @todo: the linux driver utilises both tables and optimises download
// -> No download, no texture recreation
grTexDownloadTable(tmu, GR_NCCTABLE_NCC0, &mm_info[ id ].ncc_table);
// @todo: only necessary when the format uses the table?
if ((info.format == GR_TEXFMT_YIQ_422) ||
(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;
}
#ifdef OGL_UTEX

View File

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

View File

@ -648,56 +648,10 @@ guTexCombineFunction( GrChipID_t tmu, GrTextureCombineFnc_t func )
#if defined( OGL_PARTDONE ) || defined( OGL_COMBINE )
GlideMsg( "guTexCombineFunction( %d, %d )\n", tmu, func );
#endif
// Ignoring TMU as we are only emulating Glide and assuming a well behaviored program
if ( tmu != GR_TMU0 )
{
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;
}
// @todo: guTexCombineFunction() also keeps track of which TMUs
// require texture coordinates for the rendering routines.
// (see glide24pgm page 139)
grTexCombineFunction(tmu, func);
}
//*************************************************