Fixed GL1 stencil shadow when gl1_stereo = 3 to 5

Disabling stencil for shadowing in these stereo modes,
otherwise entities appear behind solid walls.
This commit is contained in:
Jaime Moreira 2024-09-20 16:56:58 -03:00
parent 7b013d5009
commit 676e05ad1f
3 changed files with 38 additions and 33 deletions

View file

@ -508,7 +508,8 @@ it's `+set busywait 0` (setting the `busywait` cvar) and `-portable`
squares.
* **gl1_stencilshadow**: If `gl_shadows` is set to `1`, this makes them
look a bit better (no flickering) by using the stencil buffer.
look a bit better (no flickering) by using the stencil buffer. Does
not work when `gl1_stereo` is `3`, `4` or `5`.
* **gl1_lightmapcopies**: When enabled (`1`), keep 3 copies of the same
lightmap rotating, shifting to another one when drawing a new frame.

View file

@ -809,53 +809,59 @@ R_SetupGL(void)
void
R_Clear(void)
{
// Check whether the stencil buffer needs clearing, and do so if need be.
GLbitfield stencilFlags = 0;
if (gl_state.stereo_mode >= STEREO_MODE_ROW_INTERLEAVED && gl_state.stereo_mode <= STEREO_MODE_PIXEL_INTERLEAVED) {
glClearStencil(GL_FALSE);
stencilFlags |= GL_STENCIL_BUFFER_BIT;
// Define which buffers need clearing
GLbitfield clearFlags = 0;
GLenum depthFunc = GL_LEQUAL;
// This breaks stereo modes, but we'll leave that responsibility to the user
if (r_clear->value)
{
clearFlags |= GL_COLOR_BUFFER_BIT;
}
// No stencil shadows allowed when using certain stereo modes, otherwise "wallhack" happens
if (gl_state.stereo_mode >= STEREO_MODE_ROW_INTERLEAVED && gl_state.stereo_mode <= STEREO_MODE_PIXEL_INTERLEAVED)
{
glClearStencil(0);
clearFlags |= GL_STENCIL_BUFFER_BIT;
}
else if (gl_shadows->value && gl_state.stencil && gl1_stencilshadow->value)
{
glClearStencil(1);
clearFlags |= GL_STENCIL_BUFFER_BIT;
}
if (gl1_ztrick->value)
{
static int trickframe;
if (r_clear->value)
{
glClear(GL_COLOR_BUFFER_BIT | stencilFlags);
}
trickframe++;
if (trickframe & 1)
{
gldepthmin = 0;
gldepthmax = 0.49999;
glDepthFunc(GL_LEQUAL);
}
else
{
gldepthmin = 1;
gldepthmax = 0.5;
glDepthFunc(GL_GEQUAL);
depthFunc = GL_GEQUAL;
}
}
else
{
if (r_clear->value)
{
glClear(GL_COLOR_BUFFER_BIT | stencilFlags | GL_DEPTH_BUFFER_BIT);
}
else
{
glClear(GL_DEPTH_BUFFER_BIT | stencilFlags);
}
clearFlags |= GL_DEPTH_BUFFER_BIT;
gldepthmin = 0;
gldepthmax = 1;
glDepthFunc(GL_LEQUAL);
}
if (clearFlags)
{
glClear(clearFlags);
}
glDepthFunc(depthFunc);
glDepthRange(gldepthmin, gldepthmax);
if (gl_zfix->value)
@ -869,13 +875,6 @@ R_Clear(void)
glPolygonOffset(-0.05, -1);
}
}
/* stencilbuffer shadows */
if (gl_shadows->value && gl_state.stencil && gl1_stencilshadow->value)
{
glClearStencil(GL_TRUE);
glClear(GL_STENCIL_BUFFER_BIT);
}
}
void
@ -1872,12 +1871,12 @@ RI_BeginFrame(float camera_separation)
gl1_particle_square->modified = false;
}
#ifndef YQ2_GL1_GLES
/* draw buffer stuff */
if (gl_drawbuffer->modified)
{
gl_drawbuffer->modified = false;
#ifndef YQ2_GL1_GLES
if ((gl_state.camera_separation == 0) || gl_state.stereo_mode != STEREO_MODE_OPENGL)
{
if (Q_stricmp(gl_drawbuffer->string, "GL_FRONT") == 0)
@ -1889,8 +1888,8 @@ RI_BeginFrame(float camera_separation)
glDrawBuffer(GL_BACK);
}
}
}
#endif
}
/* texturemode stuff */
if (gl_texturemode->modified || (gl_config.anisotropic && gl_anisotropic->modified)

View file

@ -207,6 +207,11 @@ R_DrawAliasFrameLerp(entity_t *currententity, dmdl_t *paliashdr, float backlerp)
static void
R_DrawAliasShadow(entity_t *currententity, dmdl_t *paliashdr, int posenum)
{
// Don't do stencil test on unsupported stereo modes
const qboolean stencilt = ( gl_state.stencil && gl1_stencilshadow->value &&
( gl_state.stereo_mode < STEREO_MODE_ROW_INTERLEAVED
|| gl_state.stereo_mode > STEREO_MODE_PIXEL_INTERLEAVED ) );
int *order;
vec3_t point;
float height = 0, lheight;
@ -219,7 +224,7 @@ R_DrawAliasShadow(entity_t *currententity, dmdl_t *paliashdr, int posenum)
R_UpdateGLBuffer(buf_shadow, 0, 0, 0, 1);
/* stencilbuffer shadows */
if (gl_state.stencil && gl1_stencilshadow->value)
if (stencilt)
{
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_EQUAL, 1, 2);
@ -265,7 +270,7 @@ R_DrawAliasShadow(entity_t *currententity, dmdl_t *paliashdr, int posenum)
R_ApplyGLBuffer();
/* stencilbuffer shadows */
if (gl_state.stencil && gl1_stencilshadow->value)
if (stencilt)
{
glDisable(GL_STENCIL_TEST);
}