Moved two-sided stencil to common code
This commit is contained in:
parent
a70e1bccb3
commit
8e0ae5c0ff
6 changed files with 182 additions and 186 deletions
12
gl_bumparb.c
12
gl_bumparb.c
|
@ -53,9 +53,6 @@ void FormatError () {
|
||||||
PFNGLPNTRIANGLESIATIPROC qglPNTrianglesiATI;
|
PFNGLPNTRIANGLESIATIPROC qglPNTrianglesiATI;
|
||||||
PFNGLPNTRIANGLESFATIPROC qglPNTrianglesfATI;
|
PFNGLPNTRIANGLESFATIPROC qglPNTrianglesfATI;
|
||||||
|
|
||||||
PFNGLSTENCILOPSEPARATEATIPROC qglStencilOpSeparateATI;
|
|
||||||
PFNGLSTENCILFUNCSEPARATEATIPROC qglStencilFuncSeparateATI;
|
|
||||||
|
|
||||||
// ARB_vertex_program
|
// ARB_vertex_program
|
||||||
|
|
||||||
typedef void (APIENTRY * glVertexAttrib1sARBPROC) (GLuint index, GLshort x);
|
typedef void (APIENTRY * glVertexAttrib1sARBPROC) (GLuint index, GLshort x);
|
||||||
|
@ -965,15 +962,10 @@ void ARB_CreateShaders()
|
||||||
|
|
||||||
if ( strstr(gl_extensions, "GL_ATI_pn_triangles") )
|
if ( strstr(gl_extensions, "GL_ATI_pn_triangles") )
|
||||||
{
|
{
|
||||||
SAFE_GET_PROC( qglPNTrianglesiATI, PFNGLPNTRIANGLESIATIPROC, "glPNTrianglesiATI");
|
SAFE_GET_PROC( qglPNTrianglesiATI, PFNGLPNTRIANGLESIATIPROC, "glPNTrianglesiATI");
|
||||||
SAFE_GET_PROC( qglPNTrianglesfATI, PFNGLPNTRIANGLESFATIPROC, "glPNTrianglesfATI");
|
SAFE_GET_PROC( qglPNTrianglesfATI, PFNGLPNTRIANGLESFATIPROC, "glPNTrianglesfATI");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( strstr(gl_extensions, "GL_ATI_separate_stencil") )
|
|
||||||
{
|
|
||||||
SAFE_GET_PROC( qglStencilOpSeparateATI, PFNGLSTENCILOPSEPARATEATIPROC, "glStencilOpSeparateATI");
|
|
||||||
SAFE_GET_PROC( qglStencilFuncSeparateATI, PFNGLSTENCILFUNCSEPARATEATIPROC, "glStencilFuncSeparateATI");
|
|
||||||
}
|
|
||||||
#endif /* !__APPLE__ && !MACOSX */
|
#endif /* !__APPLE__ && !MACOSX */
|
||||||
|
|
||||||
glEnable(GL_VERTEX_PROGRAM_ARB);
|
glEnable(GL_VERTEX_PROGRAM_ARB);
|
||||||
|
|
|
@ -64,18 +64,6 @@ typedef void (APIENTRY * glProgramLocalParameter4fARBPROC) (GLenum target, GLuin
|
||||||
glProgramLocalParameter4fARBPROC qglProgramLocalParameter4fARB;
|
glProgramLocalParameter4fARBPROC qglProgramLocalParameter4fARB;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// EXT_stencil_two_side
|
|
||||||
#ifndef GL_EXT_stencil_two_side
|
|
||||||
#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910
|
|
||||||
#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef GL_EXT_stencil_two_side
|
|
||||||
#define GL_EXT_stencil_two_side 1
|
|
||||||
typedef void (APIENTRY * PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face);
|
|
||||||
PFNGLACTIVESTENCILFACEEXTPROC qglActiveStencilFaceEXT;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static char bump_vertex_program[] =
|
static char bump_vertex_program[] =
|
||||||
"!!VP1.1\n"
|
"!!VP1.1\n"
|
||||||
"OPTION NV_position_invariant;\n"
|
"OPTION NV_position_invariant;\n"
|
||||||
|
@ -536,7 +524,7 @@ void NV3x_EnableBumpShader(const transform_t *tr, const lightobject_t *lo,
|
||||||
|
|
||||||
if (currentshadowlight->shader->stages[0].texture[0]->gltype == GL_TEXTURE_CUBE_MAP_ARB)
|
if (currentshadowlight->shader->stages[0].texture[0]->gltype == GL_TEXTURE_CUBE_MAP_ARB)
|
||||||
{
|
{
|
||||||
NV3x_SetupTcMods(¤tshadowlight->shader->stages[0]);
|
SH_SetupTcMods(¤tshadowlight->shader->stages[0]);
|
||||||
GL_SetupCubeMapMatrix(tr);
|
GL_SetupCubeMapMatrix(tr);
|
||||||
|
|
||||||
GL_SelectTexture(GL_TEXTURE4_ARB);
|
GL_SelectTexture(GL_TEXTURE4_ARB);
|
||||||
|
@ -564,7 +552,7 @@ void NV3x_EnableBumpShader(const transform_t *tr, const lightobject_t *lo,
|
||||||
glScalef(1.0f/(currentshadowlight->radiusv[0]),
|
glScalef(1.0f/(currentshadowlight->radiusv[0]),
|
||||||
1.0f/(currentshadowlight->radiusv[1]),
|
1.0f/(currentshadowlight->radiusv[1]),
|
||||||
1.0f/(currentshadowlight->radiusv[2]));
|
1.0f/(currentshadowlight->radiusv[2]));
|
||||||
NV3x_SetupTcMods(¤tshadowlight->shader->stages[0]);
|
SH_SetupTcMods(¤tshadowlight->shader->stages[0]);
|
||||||
GL_SetupCubeMapMatrix(tr);
|
GL_SetupCubeMapMatrix(tr);
|
||||||
|
|
||||||
GL_SelectTexture(GL_TEXTURE4_ARB);
|
GL_SelectTexture(GL_TEXTURE4_ARB);
|
||||||
|
@ -644,76 +632,6 @@ void NV3x_DisableDeluxShader(shader_t* shader)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************
|
|
||||||
|
|
||||||
Shader utility routines
|
|
||||||
|
|
||||||
*************************/
|
|
||||||
|
|
||||||
void NV3x_SetupTcMod(tcmod_t *tc)
|
|
||||||
{
|
|
||||||
switch (tc->type)
|
|
||||||
{
|
|
||||||
case TCMOD_ROTATE:
|
|
||||||
glTranslatef(0.5,0.5,0.0);
|
|
||||||
glRotatef(realtime * tc->params[0],0,0,1);
|
|
||||||
glTranslatef(-0.5, -0.5, 0.0);
|
|
||||||
break;
|
|
||||||
case TCMOD_SCROLL:
|
|
||||||
glTranslatef(realtime * tc->params[0], realtime * tc->params[1], 0.0);
|
|
||||||
break;
|
|
||||||
case TCMOD_SCALE:
|
|
||||||
glScalef(tc->params[0],tc->params[1],1.0);
|
|
||||||
break;
|
|
||||||
case TCMOD_STRETCH:
|
|
||||||
//PENTA: fixme
|
|
||||||
glScalef(1.0, 1.0, 1.0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NV3x_SetupTcMods(stage_t *s)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < s->numtcmods; i++)
|
|
||||||
NV3x_SetupTcMod(&s->tcmods[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void NV3x_SetupSimpleStage(stage_t *s)
|
|
||||||
{
|
|
||||||
tcmod_t *tc;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (s->type != STAGE_SIMPLE)
|
|
||||||
{
|
|
||||||
Con_Printf("Non simple stage, in simple stage list");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
glMatrixMode(GL_TEXTURE);
|
|
||||||
glPushMatrix();
|
|
||||||
|
|
||||||
for (i=0; i<s->numtcmods; i++)
|
|
||||||
{
|
|
||||||
NV3x_SetupTcMod(&s->tcmods[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s->src_blend > -1)
|
|
||||||
{
|
|
||||||
glBlendFunc(s->src_blend, s->dst_blend);
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s->alphatresh > 0)
|
|
||||||
{
|
|
||||||
glEnable(GL_ALPHA_TEST);
|
|
||||||
glAlphaFunc(GL_GREATER, s->alphatresh);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((s->numtextures > 0) && (s->texture[0]))
|
|
||||||
GL_BindAdvanced(s->texture[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************
|
/************************
|
||||||
|
|
||||||
|
@ -807,7 +725,7 @@ void NV3x_drawTriangleListBase (vertexdef_t *verts, int *indecies,
|
||||||
|
|
||||||
for ( i = 0; i < shader->numstages; i++)
|
for ( i = 0; i < shader->numstages; i++)
|
||||||
{
|
{
|
||||||
NV3x_SetupSimpleStage(&shader->stages[i]);
|
SH_SetupSimpleStage(&shader->stages[i]);
|
||||||
glDrawElements(GL_TRIANGLES,numIndecies,GL_UNSIGNED_INT,indecies);
|
glDrawElements(GL_TRIANGLES,numIndecies,GL_UNSIGNED_INT,indecies);
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
@ -1160,7 +1078,7 @@ void NV3x_drawSurfaceListBase (vertexdef_t* verts, msurface_t** surfs,
|
||||||
|
|
||||||
for (i = 0; i < shader->numstages; i++)
|
for (i = 0; i < shader->numstages; i++)
|
||||||
{
|
{
|
||||||
NV3x_SetupSimpleStage(&shader->stages[i]);
|
SH_SetupSimpleStage(&shader->stages[i]);
|
||||||
NV3x_sendSurfacesBase(surfs, numSurfaces, false);
|
NV3x_sendSurfacesBase(surfs, numSurfaces, false);
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
30
gl_common.c
30
gl_common.c
|
@ -33,7 +33,7 @@ qcardtype gl_cardtype = GENERIC;
|
||||||
qboolean gl_vbo = false; //PENTA: vertex buffer object is available
|
qboolean gl_vbo = false; //PENTA: vertex buffer object is available
|
||||||
qboolean gl_texcomp = false; // JP: texture compression available
|
qboolean gl_texcomp = false; // JP: texture compression available
|
||||||
qboolean gl_mirroronce = false; //GL_ATI_texture_mirror_once extension is available
|
qboolean gl_mirroronce = false; //GL_ATI_texture_mirror_once extension is available
|
||||||
|
int gl_twosidedstencil = 0; // none
|
||||||
|
|
||||||
//void (*qglColorTableEXT) (int, int, int, int, int, const void*);
|
//void (*qglColorTableEXT) (int, int, int, int, int, const void*);
|
||||||
//void (*qgl3DfxSetPaletteEXT) (GLuint *);
|
//void (*qgl3DfxSetPaletteEXT) (GLuint *);
|
||||||
|
@ -46,6 +46,12 @@ GL3DFXSETPALETTEEXTPFN qgl3DfxSetPaletteEXT;
|
||||||
|
|
||||||
PFNBLENDCOLORPROC qglBlendColorEXT;
|
PFNBLENDCOLORPROC qglBlendColorEXT;
|
||||||
|
|
||||||
|
// EXT_stencil_two_side
|
||||||
|
PFNGLACTIVESTENCILFACEEXTPROC qglActiveStencilFaceEXT;
|
||||||
|
|
||||||
|
// ATI_separate_stencil
|
||||||
|
PFNGLSTENCILOPSEPARATEATIPROC qglStencilOpSeparateATI;
|
||||||
|
PFNGLSTENCILFUNCSEPARATEATIPROC qglStencilFuncSeparateATI;
|
||||||
|
|
||||||
|
|
||||||
//int texture_mode = GL_NEAREST;
|
//int texture_mode = GL_NEAREST;
|
||||||
|
@ -449,6 +455,26 @@ void CheckMirrorOnce(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CheckTwoSidedStencil(void)
|
||||||
|
{
|
||||||
|
if (COM_CheckParm ("-notwosidedstencil"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (strstr(gl_extensions, "GL_EXT_stencil_two_side"))
|
||||||
|
{
|
||||||
|
SAFE_GET_PROC( qglActiveStencilFaceEXT, PFNGLACTIVESTENCILFACEEXTPROC, "glActiveStencilFaceEXT");
|
||||||
|
gl_twosidedstencil = 1;
|
||||||
|
Con_Printf("Using EXT_stencil_two_side\n");
|
||||||
|
}
|
||||||
|
else if (strstr(gl_extensions, "GL_ATI_separate_stencil"))
|
||||||
|
{
|
||||||
|
SAFE_GET_PROC( qglStencilOpSeparateATI, PFNGLSTENCILOPSEPARATEATIPROC, "glStencilOpSeparateATI");
|
||||||
|
SAFE_GET_PROC( qglStencilFuncSeparateATI, PFNGLSTENCILFUNCSEPARATEATIPROC, "glStencilFuncSeparateATI");
|
||||||
|
gl_twosidedstencil = 2;
|
||||||
|
Con_Printf("Using ATI_separate_stencil\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int supportedTmu;
|
static int supportedTmu;
|
||||||
/*
|
/*
|
||||||
===============
|
===============
|
||||||
|
@ -514,6 +540,8 @@ void GL_Init (void)
|
||||||
CheckOcclusionTest();
|
CheckOcclusionTest();
|
||||||
Con_Printf ("Checking MO\n");
|
Con_Printf ("Checking MO\n");
|
||||||
CheckMirrorOnce();
|
CheckMirrorOnce();
|
||||||
|
Con_Printf ("Checking two-sided stencil\n");
|
||||||
|
CheckTwoSidedStencil();
|
||||||
|
|
||||||
//if something goes wrong here throw an sys_error as we don't want to end up
|
//if something goes wrong here throw an sys_error as we don't want to end up
|
||||||
//having invalid function pointers called...
|
//having invalid function pointers called...
|
||||||
|
|
155
gl_rmain.c
155
gl_rmain.c
|
@ -178,9 +178,6 @@ typedef void (APIENTRY *PFNGLPNTRIANGLESFATIPROC)(GLenum pname, GLfloat param);
|
||||||
extern PFNGLPNTRIANGLESIATIPROC qglPNTrianglesiATI;
|
extern PFNGLPNTRIANGLESIATIPROC qglPNTrianglesiATI;
|
||||||
extern PFNGLPNTRIANGLESFATIPROC qglPNTrianglesfATI;
|
extern PFNGLPNTRIANGLESFATIPROC qglPNTrianglesfATI;
|
||||||
|
|
||||||
#define GL_INCR_WRAP_EXT 0x8507
|
|
||||||
#define GL_DECR_WRAP_EXT 0x8508
|
|
||||||
|
|
||||||
|
|
||||||
#define MIN_PLAYER_MIRROR 48 //max size of player bounding box
|
#define MIN_PLAYER_MIRROR 48 //max size of player bounding box
|
||||||
|
|
||||||
|
@ -648,45 +645,51 @@ R_DrawAliasShadowVolume
|
||||||
|
|
||||||
void R_DrawAliasSurfaceShadowVolume (aliashdr_t *paliashdr, aliasframeinstant_t *aliasframeinstant)
|
void R_DrawAliasSurfaceShadowVolume (aliashdr_t *paliashdr, aliasframeinstant_t *aliasframeinstant)
|
||||||
{
|
{
|
||||||
|
if (paliashdr->shader->flags & SURF_NOSHADOW)
|
||||||
|
return;
|
||||||
|
|
||||||
if (paliashdr->shader->flags & SURF_NOSHADOW)
|
switch(gl_twosidedstencil)
|
||||||
return;
|
{
|
||||||
|
case 0:
|
||||||
#if 1
|
|
||||||
//
|
//
|
||||||
//Pass 1 increase
|
//Pass 1 increase
|
||||||
//
|
//
|
||||||
glCullFace(GL_BACK);
|
|
||||||
glStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
|
|
||||||
glCullFace(GL_FRONT);
|
glCullFace(GL_FRONT);
|
||||||
|
glStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
|
||||||
|
|
||||||
R_DrawAliasFrameShadowVolume2 (paliashdr, aliasframeinstant);
|
R_DrawAliasFrameShadowVolume2 (paliashdr, aliasframeinstant);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Second Pass. Decrease Stencil Value In The Shadow
|
// Second Pass. Decrease Stencil Value In The Shadow
|
||||||
//
|
//
|
||||||
glCullFace(GL_FRONT);
|
glCullFace(GL_BACK);
|
||||||
glStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
|
glStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
|
||||||
glCullFace(GL_BACK);
|
|
||||||
|
|
||||||
R_DrawAliasFrameShadowVolume2 (paliashdr, aliasframeinstant);
|
R_DrawAliasFrameShadowVolume2 (paliashdr, aliasframeinstant);
|
||||||
#else
|
break;
|
||||||
glDisable(GL_CULL_FACE);
|
case 1:
|
||||||
glCullFace(GL_FRONT_AND_BACK);
|
// EXT_stencil_two_side
|
||||||
checkerror();
|
glDisable(GL_CULL_FACE);
|
||||||
|
qglActiveStencilFaceEXT(GL_BACK);
|
||||||
glStencilOp(GL_KEEP, GL_INCR_WRAP_EXT, GL_KEEP);
|
glStencilOp(GL_KEEP, GL_INCR_WRAP_EXT, GL_KEEP);
|
||||||
checkerror();
|
glStencilFunc(GL_ALWAYS, 0, ~0);
|
||||||
qglStencilFuncSeparateATI(GL_ALWAYS, GL_ALWAYS, 0, ~0);
|
qglActiveStencilFaceEXT(GL_FRONT);
|
||||||
checkerror();
|
glStencilOp(GL_KEEP, GL_DECR_WRAP_EXT, GL_KEEP);
|
||||||
qglStencilOpSeparateATI(GL_FRONT, GL_KEEP, GL_DECR_WRAP_EXT, GL_KEEP);
|
glStencilFunc(GL_ALWAYS, 0, ~0);
|
||||||
checkerror();
|
|
||||||
qglStencilOpSeparateATI(GL_BACK, GL_KEEP, GL_INCR_WRAP_EXT, GL_KEEP);
|
|
||||||
checkerror();
|
|
||||||
R_DrawAliasFrameShadowVolume2 (paliashdr, aliasframeinstant);
|
R_DrawAliasFrameShadowVolume2 (paliashdr, aliasframeinstant);
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
glEnable(GL_CULL_FACE);
|
break;
|
||||||
glCullFace(GL_BACK);
|
|
||||||
#endif
|
case 2:
|
||||||
|
// ATI_separate_stencil
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
glStencilOp(GL_KEEP, GL_INCR_WRAP_EXT, GL_KEEP);
|
||||||
|
qglStencilFuncSeparateATI(GL_ALWAYS, GL_ALWAYS, 0, ~0);
|
||||||
|
qglStencilOpSeparateATI(GL_FRONT, GL_KEEP, GL_DECR_WRAP_EXT, GL_KEEP);
|
||||||
|
qglStencilOpSeparateATI(GL_BACK, GL_KEEP, GL_INCR_WRAP_EXT, GL_KEEP);
|
||||||
|
R_DrawAliasFrameShadowVolume2 (paliashdr, aliasframeinstant);
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1799,23 +1802,6 @@ void pentaGlFrustum( GLdouble xmin, GLdouble xmax, GLdouble ymin, GLdouble ymax,
|
||||||
glLoadMatrixd(&p[0][0]);
|
glLoadMatrixd(&p[0][0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MYgluPerspective( GLdouble fovy, GLdouble aspect,
|
|
||||||
GLdouble zNear, GLdouble zFar )
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
<AWE> Unused. Can be removed.
|
|
||||||
GLdouble xmin, xmax, ymin, ymax;
|
|
||||||
|
|
||||||
ymax = zNear * tan (fovy * M_PI / 360.0);
|
|
||||||
ymin = -ymax;
|
|
||||||
|
|
||||||
xmin = ymin * aspect;
|
|
||||||
xmax = ymax * aspect;
|
|
||||||
|
|
||||||
pentaGlFrustum( xmin, xmax, ymin, ymax, zNear);
|
|
||||||
*/
|
|
||||||
pentaGlPerspective(fovy * M_PI / 360.0, aspect, zNear);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PENTA:
|
PENTA:
|
||||||
|
@ -1986,7 +1972,7 @@ void R_SetupGL (void)
|
||||||
//PENTA: decreased zfar from 4096 to reduce z-fighting on alias models
|
//PENTA: decreased zfar from 4096 to reduce z-fighting on alias models
|
||||||
// is this ok for quake or do we need to be able to look that far??
|
// is this ok for quake or do we need to be able to look that far??
|
||||||
// seems to work, I incr. znear to 5 instead of 4
|
// seems to work, I incr. znear to 5 instead of 4
|
||||||
MYgluPerspective (2.0 *atan((GLdouble) r_refdef.vrect.height / (GLdouble) r_refdef.vrect.width) * 180.0 / M_PI /* r_refdef.fov_y */, screenaspect, 5.0, 2048.0);
|
pentaGlPerspective (atan((GLdouble) r_refdef.vrect.height / (GLdouble) r_refdef.vrect.width), screenaspect, 5.0);
|
||||||
|
|
||||||
if (mirror || glare)
|
if (mirror || glare)
|
||||||
{
|
{
|
||||||
|
@ -2152,10 +2138,14 @@ void R_RenderScene (void)
|
||||||
R_MarkEntitiesOnList();
|
R_MarkEntitiesOnList();
|
||||||
|
|
||||||
//Shadow casting is on by default
|
//Shadow casting is on by default
|
||||||
if (l->castShadow) {
|
if (l->castShadow)
|
||||||
//Calculate the shadow volume (does nothing when static)
|
{
|
||||||
R_ConstructShadowVolume(l);
|
//Calculate the shadow volume (does nothing when static)
|
||||||
#if 1
|
R_ConstructShadowVolume(l);
|
||||||
|
|
||||||
|
switch(gl_twosidedstencil)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
//Pass 1 increase
|
//Pass 1 increase
|
||||||
glCullFace(GL_BACK);
|
glCullFace(GL_BACK);
|
||||||
glStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
|
glStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
|
||||||
|
@ -2176,39 +2166,52 @@ void R_RenderScene (void)
|
||||||
glCullFace(GL_FRONT);
|
glCullFace(GL_FRONT);
|
||||||
glStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
|
glStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
|
||||||
if (sh_entityshadows.value) R_DrawEntitiesShadowVolumes(mod_brush);
|
if (sh_entityshadows.value) R_DrawEntitiesShadowVolumes(mod_brush);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
// EXT_stencil_two_side
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
qglActiveStencilFaceEXT(GL_BACK);
|
||||||
|
glStencilOp(GL_KEEP, GL_INCR_WRAP_EXT, GL_KEEP);
|
||||||
|
glStencilFunc(GL_ALWAYS, 0, ~0);
|
||||||
|
qglActiveStencilFaceEXT(GL_FRONT);
|
||||||
|
glStencilOp(GL_KEEP, GL_DECR_WRAP_EXT, GL_KEEP);
|
||||||
|
glStencilFunc(GL_ALWAYS, 0, ~0);
|
||||||
|
if (sh_worldshadows.value) R_DrawShadowVolume(l);
|
||||||
|
|
||||||
#else
|
//PENTA: we could do the same thing for brushes as for aliasses
|
||||||
// glCullFace(GL_FRONT_AND_BACK);
|
//Pass 1 increase
|
||||||
glDisable(GL_CULL_FACE);
|
if (sh_entityshadows.value) R_DrawEntitiesShadowVolumes(mod_brush);
|
||||||
checkerror();
|
glEnable(GL_CULL_FACE);
|
||||||
glStencilOp(GL_KEEP, GL_INCR_WRAP_EXT, GL_KEEP);
|
qglActiveStencilFaceEXT(GL_FRONT_AND_BACK);
|
||||||
checkerror();
|
break;
|
||||||
qglStencilFuncSeparateATI(GL_ALWAYS, GL_ALWAYS, 0, ~0);
|
|
||||||
checkerror();
|
case 2:
|
||||||
qglStencilOpSeparateATI(GL_FRONT, GL_KEEP, GL_DECR_WRAP_EXT, GL_KEEP);
|
// ATI_separate_stencil
|
||||||
checkerror();
|
glDisable(GL_CULL_FACE);
|
||||||
qglStencilOpSeparateATI(GL_BACK, GL_KEEP, GL_INCR_WRAP_EXT, GL_KEEP);
|
glStencilOp(GL_KEEP, GL_INCR_WRAP_EXT, GL_KEEP);
|
||||||
checkerror();
|
qglStencilFuncSeparateATI(GL_ALWAYS, GL_ALWAYS, 0, ~0);
|
||||||
|
qglStencilOpSeparateATI(GL_FRONT, GL_KEEP, GL_DECR_WRAP_EXT, GL_KEEP);
|
||||||
|
qglStencilOpSeparateATI(GL_BACK, GL_KEEP, GL_INCR_WRAP_EXT, GL_KEEP);
|
||||||
|
|
||||||
if (sh_worldshadows.value) R_DrawShadowVolume(l);
|
if (sh_worldshadows.value) R_DrawShadowVolume(l);
|
||||||
|
|
||||||
//PENTA: we could do the same thing for brushes as for aliasses
|
//PENTA: we could do the same thing for brushes as for aliasses
|
||||||
//Pass 1 increase
|
//Pass 1 increase
|
||||||
if (sh_entityshadows.value) R_DrawEntitiesShadowVolumes(mod_brush);
|
if (sh_entityshadows.value) R_DrawEntitiesShadowVolumes(mod_brush);
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (sh_entityshadows.value)
|
||||||
|
R_DrawEntitiesShadowVolumes(mod_alias);
|
||||||
|
|
||||||
glEnable(GL_CULL_FACE);
|
if (sh_meshshadows.value)
|
||||||
#endif
|
StencilMeshVolumes();
|
||||||
if (sh_entityshadows.value)
|
|
||||||
R_DrawEntitiesShadowVolumes(mod_alias);
|
|
||||||
|
|
||||||
if (sh_meshshadows.value)
|
//Reenable drawing
|
||||||
StencilMeshVolumes();
|
glCullFace(GL_FRONT);
|
||||||
|
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||||
//Reenable drawing
|
glDepthFunc(GL_LEQUAL);
|
||||||
glCullFace(GL_FRONT);
|
glStencilFunc(GL_EQUAL, 0, 0xffffffff);
|
||||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
|
||||||
glDepthFunc(GL_LEQUAL);
|
|
||||||
glStencilFunc(GL_EQUAL, 0, 0xffffffff);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
48
gl_shadow.c
48
gl_shadow.c
|
@ -1967,13 +1967,51 @@ void StencilMeshVolume(mesh_t *mesh) {
|
||||||
glCullFace(GL_BACK);
|
glCullFace(GL_BACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StencilMeshVolumes() {
|
void StencilMeshVolume2(mesh_t *mesh)
|
||||||
|
{
|
||||||
|
if (mesh->shader->shader->flags & SURF_NOSHADOW) return;
|
||||||
|
SetupMeshToLightVisibility(currentshadowlight, mesh);
|
||||||
|
DrawMeshVolume(mesh);
|
||||||
|
}
|
||||||
|
|
||||||
int i;
|
void StencilMeshVolumes()
|
||||||
for (i=0; i<currentshadowlight->numlightcmdsmesh-1; i++) {
|
{
|
||||||
StencilMeshVolume((mesh_t *)currentshadowlight->lightCmdsMesh[i].asVoid);
|
int i;
|
||||||
}
|
switch(gl_twosidedstencil)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
for (i=0; i<currentshadowlight->numlightcmdsmesh-1; i++)
|
||||||
|
StencilMeshVolume((mesh_t *)currentshadowlight->lightCmdsMesh[i].asVoid);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
// EXT_stencil_two_side
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
qglActiveStencilFaceEXT(GL_BACK);
|
||||||
|
glStencilOp(GL_KEEP, GL_INCR_WRAP_EXT, GL_KEEP);
|
||||||
|
glStencilFunc(GL_ALWAYS, 0, ~0);
|
||||||
|
qglActiveStencilFaceEXT(GL_FRONT);
|
||||||
|
glStencilOp(GL_KEEP, GL_DECR_WRAP_EXT, GL_KEEP);
|
||||||
|
glStencilFunc(GL_ALWAYS, 0, ~0);
|
||||||
|
|
||||||
|
for (i=0; i<currentshadowlight->numlightcmdsmesh-1; i++)
|
||||||
|
StencilMeshVolume2((mesh_t *)currentshadowlight->lightCmdsMesh[i].asVoid);
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
qglActiveStencilFaceEXT(GL_FRONT_AND_BACK);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
// ATI_separate_stencil
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
glStencilOp(GL_KEEP, GL_INCR_WRAP_EXT, GL_KEEP);
|
||||||
|
qglStencilFuncSeparateATI(GL_ALWAYS, GL_ALWAYS, 0, ~0);
|
||||||
|
qglStencilOpSeparateATI(GL_FRONT, GL_KEEP, GL_DECR_WRAP_EXT, GL_KEEP);
|
||||||
|
qglStencilOpSeparateATI(GL_BACK, GL_KEEP, GL_INCR_WRAP_EXT, GL_KEEP);
|
||||||
|
|
||||||
|
for (i=0; i<currentshadowlight->numlightcmdsmesh-1; i++)
|
||||||
|
StencilMeshVolume2((mesh_t *)currentshadowlight->lightCmdsMesh[i].asVoid);
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
33
glquake.h
33
glquake.h
|
@ -485,6 +485,22 @@ extern int occlusion_cut_meshes;
|
||||||
extern int occlusion_cut_entities;
|
extern int occlusion_cut_entities;
|
||||||
extern int occlusion_cut_lights;
|
extern int occlusion_cut_lights;
|
||||||
|
|
||||||
|
// EXT_stencil_two_side
|
||||||
|
#define GL_INCR_WRAP_EXT 0x8507
|
||||||
|
#define GL_DECR_WRAP_EXT 0x8508
|
||||||
|
|
||||||
|
#ifndef GL_EXT_stencil_two_side
|
||||||
|
#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910
|
||||||
|
#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef GL_EXT_stencil_two_side
|
||||||
|
#define GL_EXT_stencil_two_side 1
|
||||||
|
typedef void (APIENTRY * PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face);
|
||||||
|
#endif
|
||||||
|
extern PFNGLACTIVESTENCILFACEEXTPROC qglActiveStencilFaceEXT;
|
||||||
|
|
||||||
|
// ATI_separate_stencil
|
||||||
#define GL_STENCIL_BACK_FUNC_ATI 0x8800
|
#define GL_STENCIL_BACK_FUNC_ATI 0x8800
|
||||||
#define GL_STENCIL_BACK_FAIL_ATI 0x8801
|
#define GL_STENCIL_BACK_FAIL_ATI 0x8801
|
||||||
#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802
|
#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802
|
||||||
|
@ -1059,17 +1075,18 @@ extern PFNGLGETBUFFERPOINTERVARBPROC qglGetBufferPointervARB;
|
||||||
|
|
||||||
extern qboolean gl_mtexable;
|
extern qboolean gl_mtexable;
|
||||||
extern qboolean gl_texturefilteranisotropic; // <AWE> true if anisotropic texture filtering available.
|
extern qboolean gl_texturefilteranisotropic; // <AWE> true if anisotropic texture filtering available.
|
||||||
|
extern int gl_twosidedstencil;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
GENERIC = 0,
|
GENERIC = 0,
|
||||||
GEFORCE,
|
GEFORCE,
|
||||||
GEFORCE3,
|
GEFORCE3,
|
||||||
RADEON,
|
RADEON,
|
||||||
PARHELIA,
|
PARHELIA,
|
||||||
ARB,
|
ARB,
|
||||||
NV3x,
|
NV3x,
|
||||||
GL2
|
GL2
|
||||||
} qcardtype;
|
} qcardtype;
|
||||||
extern qcardtype gl_cardtype;
|
extern qcardtype gl_cardtype;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue