Cleanup, refactoring, state update, optimisations
This commit is contained in:
parent
acc2264181
commit
23a7356fb8
File diff suppressed because one or more lines are too long
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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++)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;};
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//*************************************************
|
//*************************************************
|
||||||
|
|
Loading…
Reference in New Issue