Fixed GapFix artefacts in last pixel row/column
This commit is contained in:
parent
992d8d2719
commit
3764f4e6cf
|
@ -17,6 +17,110 @@
|
||||||
#include "GLRenderUpdateState.h"
|
#include "GLRenderUpdateState.h"
|
||||||
#include "GLUtil.h"
|
#include "GLUtil.h"
|
||||||
|
|
||||||
|
// Write colored pixels only
|
||||||
|
void gapfixSetSimpleColorState()
|
||||||
|
{
|
||||||
|
// Disable the cull mode
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
// Disable clip volume hint manually to avoid recursion
|
||||||
|
if (InternalConfig.EXT_clip_volume_hint && OpenGL.ClipVerticesEnabledState)
|
||||||
|
{
|
||||||
|
glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_FASTEST);
|
||||||
|
}
|
||||||
|
// Blend
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
SetBlendState();
|
||||||
|
// Alpha
|
||||||
|
glDisable(GL_ALPHA_TEST);
|
||||||
|
SetChromaKeyAndAlphaState();
|
||||||
|
// disable depth buffer
|
||||||
|
glDepthMask(false);
|
||||||
|
// Enable colormask
|
||||||
|
glColorMask(true, true, true, false);
|
||||||
|
// Needed for displaying in-game menus
|
||||||
|
if (Glide.State.DepthBufferMode != GR_DEPTHBUFFER_DISABLE)
|
||||||
|
{
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
}
|
||||||
|
if (InternalConfig.EXT_secondary_color)
|
||||||
|
{
|
||||||
|
glDisable(GL_COLOR_SUM_EXT);
|
||||||
|
}
|
||||||
|
if (OpenGL.Fog && OpenGL.FogTextureUnit)
|
||||||
|
{
|
||||||
|
glActiveTextureARB(OpenGL.FogTextureUnit);
|
||||||
|
if (InternalConfig.EXT_compiled_vertex_array)
|
||||||
|
{
|
||||||
|
glClientActiveTextureARB(OpenGL.FogTextureUnit);
|
||||||
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glTexCoordPointer(4, GL_FLOAT, 0, NULL);
|
||||||
|
}
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
OpenGL.FogTextureUnitEnabledState = false;
|
||||||
|
SetFogModeState();
|
||||||
|
}
|
||||||
|
for(long unit_index = 1; unit_index >= 0; unit_index--)
|
||||||
|
{
|
||||||
|
glActiveTextureARB(OpenGL.ColorAlphaUnit1 + unit_index);
|
||||||
|
if (InternalConfig.EXT_compiled_vertex_array)
|
||||||
|
{
|
||||||
|
glClientActiveTextureARB(OpenGL.ColorAlphaUnit1 + unit_index);
|
||||||
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glTexCoordPointer(4, GL_FLOAT, 0, NULL);
|
||||||
|
}
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
OpenGL.ColorAlphaUnitColorEnabledState[unit_index] = false;
|
||||||
|
OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index] = false;
|
||||||
|
}
|
||||||
|
SetTextureState();
|
||||||
|
SetColorCombineState();
|
||||||
|
SetAlphaCombineState();
|
||||||
|
|
||||||
|
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
|
||||||
|
VERIFY_TEXTURE_ENABLED_STATE();
|
||||||
|
}
|
||||||
|
|
||||||
|
void gapfixRestoreFromSimpleColorState()
|
||||||
|
{
|
||||||
|
// Restore state
|
||||||
|
switch (Glide.State.CullMode)
|
||||||
|
{
|
||||||
|
case GR_CULL_DISABLE:
|
||||||
|
break;
|
||||||
|
case GR_CULL_NEGATIVE:
|
||||||
|
case GR_CULL_POSITIVE:
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (InternalConfig.EXT_clip_volume_hint && OpenGL.ClipVerticesEnabledState)
|
||||||
|
{
|
||||||
|
glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_NICEST);
|
||||||
|
}
|
||||||
|
// restore previous state
|
||||||
|
if (OpenGL.DepthBufferWritting)
|
||||||
|
{
|
||||||
|
glDepthMask(true);
|
||||||
|
}
|
||||||
|
const bool colormask = Glide.State.ColorMask;
|
||||||
|
glColorMask(colormask, colormask, colormask, Glide.State.AlphaMask);
|
||||||
|
if (Glide.State.DepthBufferMode != GR_DEPTHBUFFER_DISABLE)
|
||||||
|
{
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
}
|
||||||
|
// Restore colormask
|
||||||
|
bool rgb = Glide.State.ColorMask;
|
||||||
|
glColorMask(rgb, rgb, rgb, Glide.State.AlphaMask);
|
||||||
|
if (InternalConfig.EXT_secondary_color)
|
||||||
|
{
|
||||||
|
glEnable(GL_COLOR_SUM_EXT);
|
||||||
|
}
|
||||||
|
// Return to normal rendering
|
||||||
|
glStencilFunc(GL_ALWAYS, 0x02, 0x03);
|
||||||
|
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
|
||||||
|
|
||||||
|
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
|
||||||
|
VERIFY_TEXTURE_ENABLED_STATE();
|
||||||
|
}
|
||||||
|
|
||||||
//*************************************************
|
//*************************************************
|
||||||
//* Clear buffer
|
//* Clear buffer
|
||||||
|
@ -71,6 +175,48 @@ grBufferClear( GrColor_t color, GrAlpha_t alpha, FxU16 depth )
|
||||||
glReportError();
|
glReportError();
|
||||||
glDisable( GL_SCISSOR_TEST );
|
glDisable( GL_SCISSOR_TEST );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In Tomb Raider 1, the last column/row of framebuffer pixels contains gapfix rendering artefacts.
|
||||||
|
// This happens, because TR1 doesn't render the last column/row. Because the gapfix actually renders
|
||||||
|
// into this area the stencil buffer value must be set to "pixel normally renderded"
|
||||||
|
if ((InternalConfig.GapFix & OpenGLideGapFixFlag_Enabled) && (s_GlideApplication.GetType() == GlideApplication::TombRaiderI))
|
||||||
|
{
|
||||||
|
// write "pixel normally rendered" stencil value in the last column/row
|
||||||
|
gapfixSetSimpleColorState();
|
||||||
|
if (InternalConfig.GapFix & OpenGLideGapFixFlag_Debug)
|
||||||
|
{
|
||||||
|
// Write Cyan colored pixels
|
||||||
|
GLfloat clearcolor[] =
|
||||||
|
{
|
||||||
|
0.0f, 1.0f, 1.0f, 0.0f
|
||||||
|
};
|
||||||
|
glColorMask(true, true, true, false);
|
||||||
|
glColor4fv(clearcolor);
|
||||||
|
}
|
||||||
|
// Stencil already set to "pixel normally rendered"
|
||||||
|
const GLfloat xmin = 0.0;
|
||||||
|
const GLfloat ymin = 0.0;
|
||||||
|
const GLfloat xmax = Glide.WindowWidth;
|
||||||
|
const GLfloat ymax = Glide.WindowHeight;
|
||||||
|
const GLfloat depth = 1.0f;
|
||||||
|
// Because we're rendering a quad, one more line maybe not gap-fixed
|
||||||
|
// Bottom
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glVertex3f(xmin, ymax - 1.0, depth);
|
||||||
|
glVertex3f(xmax, ymax - 1.0, depth);
|
||||||
|
glVertex3f(xmax, ymax, depth);
|
||||||
|
glVertex3f(xmin, ymax, depth);
|
||||||
|
glEnd();
|
||||||
|
// right
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glVertex3f(xmax - 1.0, ymin, depth);
|
||||||
|
glVertex3f(xmax - 1.0, ymax, depth);
|
||||||
|
glVertex3f(xmax, ymax, depth);
|
||||||
|
glVertex3f(xmax, ymin, depth);
|
||||||
|
glEnd();
|
||||||
|
gapfixRestoreFromSimpleColorState();
|
||||||
|
}
|
||||||
|
|
||||||
glReportError();
|
glReportError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,18 +224,18 @@ grBufferClear( GrColor_t color, GrAlpha_t alpha, FxU16 depth )
|
||||||
//* Swaps front and back Buffer
|
//* Swaps front and back Buffer
|
||||||
//*************************************************
|
//*************************************************
|
||||||
FX_ENTRY void FX_CALL
|
FX_ENTRY void FX_CALL
|
||||||
grBufferSwap( int swap_interval )
|
grBufferSwap(int swap_interval)
|
||||||
{
|
{
|
||||||
#if defined( OGL_DONE ) || defined( OGL_COMBINE )
|
#if defined( OGL_DONE ) || defined( OGL_COMBINE )
|
||||||
GlideMsg( "grBufferSwap( %d )\n", swap_interval );
|
GlideMsg( "grBufferSwap( %d )\n", swap_interval );
|
||||||
#endif
|
#endif
|
||||||
glReportErrors("grBufferSwap");
|
glReportErrors("grBufferSwap");
|
||||||
|
|
||||||
RenderDrawTriangles( );
|
RenderDrawTriangles();
|
||||||
|
|
||||||
#ifdef OGL_DEBUG
|
#ifdef OGL_DEBUG
|
||||||
static float Temp = 1.0f;
|
static float Temp = 1.0f;
|
||||||
if ( OGLRender.FrameTriangles > OGLRender.MaxTriangles )
|
if (OGLRender.FrameTriangles > OGLRender.MaxTriangles)
|
||||||
{
|
{
|
||||||
OGLRender.MaxTriangles = OGLRender.FrameTriangles;
|
OGLRender.MaxTriangles = OGLRender.FrameTriangles;
|
||||||
}
|
}
|
||||||
|
@ -101,65 +247,7 @@ grBufferSwap( int swap_interval )
|
||||||
|
|
||||||
if (InternalConfig.GapFix & OpenGLideGapFixFlag_Enabled)
|
if (InternalConfig.GapFix & OpenGLideGapFixFlag_Enabled)
|
||||||
{
|
{
|
||||||
// Disable the cull mode
|
gapfixSetSimpleColorState();
|
||||||
glDisable(GL_CULL_FACE);
|
|
||||||
// Disable clip volume hint manually to avoid recursion
|
|
||||||
if (InternalConfig.EXT_clip_volume_hint && OpenGL.ClipVerticesEnabledState)
|
|
||||||
{
|
|
||||||
glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_FASTEST);
|
|
||||||
}
|
|
||||||
// Blend
|
|
||||||
glDisable(GL_BLEND);
|
|
||||||
SetBlendState();
|
|
||||||
// Alpha
|
|
||||||
glDisable(GL_ALPHA_TEST);
|
|
||||||
SetChromaKeyAndAlphaState();
|
|
||||||
// disable depth buffer
|
|
||||||
glDepthMask(false);
|
|
||||||
// Enable colormask
|
|
||||||
glColorMask(true, true, true, false);
|
|
||||||
// Needed for displaying in-game menus
|
|
||||||
if (Glide.State.DepthBufferMode != GR_DEPTHBUFFER_DISABLE)
|
|
||||||
{
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
|
||||||
}
|
|
||||||
if (InternalConfig.EXT_secondary_color)
|
|
||||||
{
|
|
||||||
glDisable(GL_COLOR_SUM_EXT);
|
|
||||||
}
|
|
||||||
if (OpenGL.Fog && OpenGL.FogTextureUnit)
|
|
||||||
{
|
|
||||||
glActiveTextureARB(OpenGL.FogTextureUnit);
|
|
||||||
if (InternalConfig.EXT_compiled_vertex_array)
|
|
||||||
{
|
|
||||||
glClientActiveTextureARB(OpenGL.FogTextureUnit);
|
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
glTexCoordPointer(4, GL_FLOAT, 0, NULL);
|
|
||||||
}
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
OpenGL.FogTextureUnitEnabledState = false;
|
|
||||||
SetFogModeState();
|
|
||||||
}
|
|
||||||
for(long unit_index = 1; unit_index >= 0; unit_index--)
|
|
||||||
{
|
|
||||||
glActiveTextureARB(OpenGL.ColorAlphaUnit1 + unit_index);
|
|
||||||
if (InternalConfig.EXT_compiled_vertex_array)
|
|
||||||
{
|
|
||||||
glClientActiveTextureARB(OpenGL.ColorAlphaUnit1 + unit_index);
|
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
glTexCoordPointer(4, GL_FLOAT, 0, NULL);
|
|
||||||
}
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
OpenGL.ColorAlphaUnitColorEnabledState[unit_index] = false;
|
|
||||||
OpenGL.ColorAlphaUnitAlphaEnabledState[unit_index] = false;
|
|
||||||
}
|
|
||||||
SetTextureState();
|
|
||||||
SetColorCombineState();
|
|
||||||
SetAlphaCombineState();
|
|
||||||
|
|
||||||
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
|
|
||||||
VERIFY_TEXTURE_ENABLED_STATE();
|
|
||||||
|
|
||||||
glStencilFunc(GL_NOTEQUAL, 0x02, 0x03);
|
glStencilFunc(GL_NOTEQUAL, 0x02, 0x03);
|
||||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||||
glReportError();
|
glReportError();
|
||||||
|
@ -175,58 +263,31 @@ grBufferSwap( int swap_interval )
|
||||||
clearcolor[0] = 1.0f;
|
clearcolor[0] = 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GLfloat depth = 1.0f;
|
// @todo: Turn off clipping
|
||||||
|
const FxU32 xmin = 0;
|
||||||
|
const FxU32 ymin = 0;
|
||||||
|
const GlideApplication::Type application = s_GlideApplication.GetType();
|
||||||
|
const FxU32 xmax = Glide.WindowWidth - ((application == GlideApplication::TombRaiderI) ? 1 : 0);
|
||||||
|
const FxU32 ymax = Glide.WindowHeight - ((application == GlideApplication::TombRaiderI) ? 1 : 0);
|
||||||
|
const GLfloat depth = 1.0f;
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
glColor4fv(clearcolor);
|
glColor4fv(clearcolor);
|
||||||
glVertex3f(Glide.State.ClipMinX, Glide.State.ClipMinY, depth);
|
glVertex3f(xmin, ymin, depth);
|
||||||
glColor4fv(clearcolor);
|
glColor4fv(clearcolor);
|
||||||
glVertex3f(Glide.State.ClipMaxX, Glide.State.ClipMinY, depth);
|
glVertex3f(xmax, ymin, depth);
|
||||||
glColor4fv(clearcolor);
|
glColor4fv(clearcolor);
|
||||||
glVertex3f(Glide.State.ClipMaxX, Glide.State.ClipMaxY, depth);
|
glVertex3f(xmax, ymax, depth);
|
||||||
glColor4fv(clearcolor);
|
glColor4fv(clearcolor);
|
||||||
glVertex3f(Glide.State.ClipMinX, Glide.State.ClipMaxY, depth);
|
glVertex3f(xmin, ymax, depth);
|
||||||
glEnd();
|
glEnd();
|
||||||
glStencilFunc(GL_ALWAYS, 0x02, 0x03);
|
|
||||||
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
|
|
||||||
// Restore state
|
|
||||||
switch (Glide.State.CullMode)
|
|
||||||
{
|
|
||||||
case GR_CULL_DISABLE:
|
|
||||||
break;
|
|
||||||
case GR_CULL_NEGATIVE:
|
|
||||||
case GR_CULL_POSITIVE:
|
|
||||||
glEnable(GL_CULL_FACE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (InternalConfig.EXT_clip_volume_hint && OpenGL.ClipVerticesEnabledState)
|
|
||||||
{
|
|
||||||
glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_NICEST);
|
|
||||||
}
|
|
||||||
// restore previous state
|
|
||||||
if (OpenGL.DepthBufferWritting)
|
|
||||||
{
|
|
||||||
glDepthMask(true);
|
|
||||||
}
|
|
||||||
if (Glide.State.DepthBufferMode != GR_DEPTHBUFFER_DISABLE)
|
|
||||||
{
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
}
|
|
||||||
// Restore colormask
|
|
||||||
bool rgb = Glide.State.ColorMask;
|
|
||||||
glColorMask(rgb, rgb, rgb, Glide.State.AlphaMask);
|
|
||||||
if (InternalConfig.EXT_secondary_color)
|
|
||||||
{
|
|
||||||
glEnable( GL_COLOR_SUM_EXT );
|
|
||||||
}
|
|
||||||
|
|
||||||
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
|
gapfixRestoreFromSimpleColorState();
|
||||||
VERIFY_TEXTURE_ENABLED_STATE();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @todo: setting the swap interval doesn't seem to work
|
// @todo: setting the swap interval doesn't seem to work
|
||||||
// - the 3dfx splash animation appears a bit to fast
|
// - the 3Dfx splash animation appears a bit to fast
|
||||||
// and using higher values doesn't work
|
// and using higher values doesn't work
|
||||||
// -> might be a bug in Classic
|
// - happens in Classic as well as in OS9 native
|
||||||
GLint swap = swap_interval;
|
GLint swap = swap_interval;
|
||||||
aglSetInteger(pWindowInfo->aglContext, AGL_SWAP_INTERVAL, &swap);
|
aglSetInteger(pWindowInfo->aglContext, AGL_SWAP_INTERVAL, &swap);
|
||||||
aglReportError();
|
aglReportError();
|
||||||
|
|
Loading…
Reference in New Issue