Added shadow volume bboxes to determine if a volume shadow should be drawn, even if the model isn't in view.

Added z-pass shadows (Doom3 GPL method) when r_shadow_zfail is set to 0.
Removed direct writes to value field of r_lightlevel cvar.
Replaced Com_sprintf() calls in console drawing that fed a buffer into itself with Q_strncatz().
This commit is contained in:
Knightmare66 2020-03-19 22:28:18 -04:00
parent d1c1e87940
commit c8ce7c05f9
6 changed files with 487 additions and 146 deletions

View file

@ -610,7 +610,7 @@ void Con_DrawInput (void)
{ {
int y; int y;
int i; int i;
char *text, output[2048]; char *text, output[2048], addch[8];
float conLeft = 0; float conLeft = 0;
if (!cls.consoleActive && cls.state == ca_active) if (!cls.consoleActive && cls.state == ca_active)
@ -645,10 +645,18 @@ void Con_DrawInput (void)
Com_sprintf (output, sizeof(output), ""); Com_sprintf (output, sizeof(output), "");
for (i=0; i<con.linewidth; i++) for (i=0; i<con.linewidth; i++)
{ {
if (con.backedit == key_linepos-i && ((int)(cls.realtime>>8)&1)) if (con.backedit == key_linepos-i && ((int)(cls.realtime>>8)&1)) {
Com_sprintf (output, sizeof(output), "%s%c", output, 11 ); // Com_sprintf (output, sizeof(output), "%s%c", output, 11 );
else addch[0] = 11;
Com_sprintf (output, sizeof(output), "%s%c", output, text[i]); addch[1] = '\0';
Q_strncatz (output, addch, sizeof(output));
}
else {
// Com_sprintf (output, sizeof(output), "%s%c", output, text[i]);
addch[0] = text[i];
addch[1] = '\0';
Q_strncatz (output, addch, sizeof(output));
}
} }
Con_DrawString ( (int)conLeft + FONT_SIZE/2, con.vislines - (int)(2.75*FONT_SIZE), output, 255); Con_DrawString ( (int)conLeft + FONT_SIZE/2, con.vislines - (int)(2.75*FONT_SIZE), output, 255);
@ -666,7 +674,7 @@ Draws the last few lines of output transparently over the game top
void Con_DrawNotify (void) void Con_DrawNotify (void)
{ {
int x; int x;
char *text, output[2048]; char *text, output[2048], addch[8];
int i, j; int i, j;
//int time; //int time;
char *s; char *s;
@ -697,16 +705,28 @@ void Con_DrawNotify (void)
while(s[x]) while(s[x])
{ {
if (chat_backedit && chat_backedit == chat_bufferlen-x && ((int)(cls.realtime>>8)&1)) if (chat_backedit && chat_backedit == chat_bufferlen-x && ((int)(cls.realtime>>8)&1)) {
Com_sprintf (output, sizeof(output), "%s%c", output, 11 ); // Com_sprintf (output, sizeof(output), "%s%c", output, 11 );
else addch[0] = 11;
Com_sprintf (output, sizeof(output), "%s%c", output, (char)s[x]); addch[1] = '\0';
Q_strncatz (output, addch, sizeof(output));
}
else {
// Com_sprintf (output, sizeof(output), "%s%c", output, (char)s[x]);
addch[0] = s[x];
addch[1] = '\0';
Q_strncatz (output, addch, sizeof(output));
}
x++; x++;
} }
if (!chat_backedit) if (!chat_backedit) {
Com_sprintf (output, sizeof(output), "%s%c", output, 10+((int)(cls.realtime>>8)&1) ); // Com_sprintf (output, sizeof(output), "%s%c", output, 10+((int)(cls.realtime>>8)&1) );
addch[0] = 10+((int)(cls.realtime>>8)&1);
addch[1] = '\0';
Q_strncatz (output, addch, sizeof(output));
}
Con_DrawString ((int)conLeft, v, output, 255); Con_DrawString ((int)conLeft, v, output, 255);
@ -749,8 +769,12 @@ void Con_DrawNotify (void)
if (alpha > 255) alpha=255; if (alpha > 255) alpha=255;
Com_sprintf (output, sizeof(output), ""); Com_sprintf (output, sizeof(output), "");
for (x = 0 ; x < con.linewidth ; x++) for (x = 0 ; x < con.linewidth ; x++) {
Com_sprintf (output, sizeof(output), "%s%c", output, (char)text[x]); // Com_sprintf (output, sizeof(output), "%s%c", output, (char)text[x]);
addch[0] = (char)text[x];
addch[1] = '\0';
Q_strncatz (output, addch, sizeof(output));
}
Con_DrawString ((int)conLeft + FONT_SIZE/2, v, output, alpha); Con_DrawString ((int)conLeft + FONT_SIZE/2, v, output, alpha);
@ -844,7 +868,7 @@ void Con_DrawConsole (float frac, qboolean trans)
{ {
int i, x, y; int i, x, y;
int rows; int rows;
char *text, output[1024]; char *text, output[1024], addch[8];
int row; int row;
int lines; int lines;
char version[64]; char version[64];
@ -943,8 +967,12 @@ void Con_DrawConsole (float frac, qboolean trans)
text = con.text + (row % con.totallines)*con.linewidth; text = con.text + (row % con.totallines)*con.linewidth;
Com_sprintf (output, sizeof(output), ""); Com_sprintf (output, sizeof(output), "");
for (x=0; x<con.linewidth; x++) for (x=0; x<con.linewidth; x++) {
Com_sprintf (output, sizeof(output), "%s%c", output, text[x]); // Com_sprintf (output, sizeof(output), "%s%c", output, text[x]);
addch[0] = text[x];
addch[1] = '\0';
Q_strncatz (output, addch, sizeof(output));
}
Con_DrawString ((int)conLeft + 4, y, output, 255); Con_DrawString ((int)conLeft + 4, y, output, 255);
} }

View file

@ -51,6 +51,8 @@ Changes as of v0.20 update 8:
- Fixed fog disappearing after a vid_restart. - Fixed fog disappearing after a vid_restart.
- Shadow volumes will now be drawn even if the model isn't in view.
- Fixed text scale not changing after changing video modes. - Fixed text scale not changing after changing video modes.
- Fixed handling of high-bit alt color strings. - Fixed handling of high-bit alt color strings.

View file

@ -47,18 +47,18 @@ void R_LightAliasVertex (vec3_t baselight, vec3_t normal, vec3_t lightOut, byte
int i; int i;
float l; float l;
if (r_fullbright->value != 0) { if (r_fullbright->integer != 0) {
VectorSet (lightOut, 1.0f, 1.0f, 1.0f); VectorSet (lightOut, 1.0f, 1.0f, 1.0f);
return; return;
} }
if (r_model_shading->value) if (r_model_shading->integer)
{ {
if (shaded) if (shaded)
{ {
if (r_model_shading->value == 3) if (r_model_shading->integer == 3)
l = 2.0 * shadedots[normalindex] - 1; l = 2.0 * shadedots[normalindex] - 1;
else if (r_model_shading->value == 2) else if (r_model_shading->integer == 2)
l = 1.5 * shadedots[normalindex] - 0.5; l = 1.5 * shadedots[normalindex] - 0.5;
else else
l = shadedots[normalindex]; l = shadedots[normalindex];
@ -372,7 +372,8 @@ void RB_RenderAliasMesh (maliasmodel_t *paliashdr, unsigned meshnum, unsigned sk
R_DrawAliasMeshes R_DrawAliasMeshes
================= =================
*/ */
void R_DrawAliasMeshes (maliasmodel_t *paliashdr, entity_t *e, qboolean lerpOnly, qboolean mirrored, qboolean viewFlipped) //void R_DrawAliasMeshes (maliasmodel_t *paliashdr, entity_t *e, qboolean lerpOnly, qboolean mirrored, qboolean viewFlipped)
void R_DrawAliasMeshes (maliasmodel_t *paliashdr, entity_t *e, qboolean mirrored, qboolean viewFlipped, qboolean preLerped, qboolean lerpOnly)
{ {
int i, k, meshnum, skinnum, baseindex; // numCalls int i, k, meshnum, skinnum, baseindex; // numCalls
maliasframe_t *frame, *oldframe; maliasframe_t *frame, *oldframe;
@ -389,6 +390,8 @@ void R_DrawAliasMeshes (maliasmodel_t *paliashdr, entity_t *e, qboolean lerpOnly
qboolean shellModel = e->flags & RF_MASK_SHELL; qboolean shellModel = e->flags & RF_MASK_SHELL;
qboolean meshCelShaded; // added for cel shading qboolean meshCelShaded; // added for cel shading
if (lerpOnly) preLerped = false;
frontlerp = 1.0 - backlerp; frontlerp = 1.0 - backlerp;
if (shellModel && FlowingShell()) if (shellModel && FlowingShell())
@ -401,23 +404,26 @@ void R_DrawAliasMeshes (maliasmodel_t *paliashdr, entity_t *e, qboolean lerpOnly
frame = paliashdr->frames + e->frame; frame = paliashdr->frames + e->frame;
oldframe = paliashdr->frames + e->oldframe; oldframe = paliashdr->frames + e->oldframe;
VectorScale(frame->scale, frontlerp, curScale); if (!preLerped)
VectorScale(oldframe->scale, backlerp, oldScale); {
VectorScale(frame->scale, frontlerp, curScale);
VectorScale(oldframe->scale, backlerp, oldScale);
mirrormult = (mirrored) ? -1.0f : 1.0f; mirrormult = (mirrored) ? -1.0f : 1.0f;
// move should be the delta back to the previous frame * backlerp // move should be the delta back to the previous frame * backlerp
VectorSubtract (e->oldorigin, e->origin, delta); VectorSubtract (e->oldorigin, e->origin, delta);
AngleVectors (e->angles, vectors[0], vectors[1], vectors[2]); AngleVectors (e->angles, vectors[0], vectors[1], vectors[2]);
move[0] = DotProduct (delta, vectors[0]); // forward move[0] = DotProduct (delta, vectors[0]); // forward
move[1] = -DotProduct (delta, vectors[1]); // left move[1] = -DotProduct (delta, vectors[1]); // left
move[2] = DotProduct (delta, vectors[2]); // up move[2] = DotProduct (delta, vectors[2]); // up
VectorAdd (move, oldframe->translate, move); VectorAdd (move, oldframe->translate, move);
for (i=0 ; i<3 ; i++) for (i=0 ; i<3 ; i++)
move[i] = backlerp*move[i] + frontlerp*frame->translate[i]; move[i] = backlerp*move[i] + frontlerp*frame->translate[i];
}
GL_ShadeModel (GL_SMOOTH); GL_ShadeModel (GL_SMOOTH);
GL_TexEnv (GL_MODULATE); GL_TexEnv (GL_MODULATE);
@ -482,34 +488,37 @@ void R_DrawAliasMeshes (maliasmodel_t *paliashdr, entity_t *e, qboolean lerpOnly
for (i=0; i<mesh.num_verts; i++, v++, ov++) for (i=0; i<mesh.num_verts; i++, v++, ov++)
{ {
// lerp verts // lerp verts
curNormal[0] = r_sinTable[v->normal[0]] * r_cosTable[v->normal[1]]; if (!preLerped)
curNormal[1] = r_sinTable[v->normal[0]] * r_sinTable[v->normal[1]]; {
curNormal[2] = r_cosTable[v->normal[0]]; curNormal[0] = r_sinTable[v->normal[0]] * r_cosTable[v->normal[1]];
curNormal[1] = r_sinTable[v->normal[0]] * r_sinTable[v->normal[1]];
curNormal[2] = r_cosTable[v->normal[0]];
oldNormal[0] = r_sinTable[ov->normal[0]] * r_cosTable[ov->normal[1]]; oldNormal[0] = r_sinTable[ov->normal[0]] * r_cosTable[ov->normal[1]];
oldNormal[1] = r_sinTable[ov->normal[0]] * r_sinTable[ov->normal[1]]; oldNormal[1] = r_sinTable[ov->normal[0]] * r_sinTable[ov->normal[1]];
oldNormal[2] = r_cosTable[ov->normal[0]]; oldNormal[2] = r_cosTable[ov->normal[0]];
VectorSet ( tempNormalsArray[i], VectorSet ( tempNormalsArray[i],
curNormal[0] + (oldNormal[0] - curNormal[0])*backlerp, curNormal[0] + (oldNormal[0] - curNormal[0])*backlerp,
curNormal[1] + (oldNormal[1] - curNormal[1])*backlerp, curNormal[1] + (oldNormal[1] - curNormal[1])*backlerp,
curNormal[2] + (oldNormal[2] - curNormal[2])*backlerp ); curNormal[2] + (oldNormal[2] - curNormal[2])*backlerp );
if (shellModel) if (shellModel)
shellscale = (e->flags & RF_WEAPONMODEL) ? WEAPON_SHELL_SCALE: POWERSUIT_SCALE; shellscale = (e->flags & RF_WEAPONMODEL) ? WEAPON_SHELL_SCALE: POWERSUIT_SCALE;
else else
shellscale = 0.0; shellscale = 0.0;
VectorSet ( tempVertexArray[meshnum][i], VectorSet ( tempVertexArray[meshnum][i],
move[0] + ov->xyz[0]*oldScale[0] + v->xyz[0]*curScale[0] + tempNormalsArray[i][0]*shellscale, move[0] + ov->xyz[0]*oldScale[0] + v->xyz[0]*curScale[0] + tempNormalsArray[i][0]*shellscale,
mirrormult * (move[1] + ov->xyz[1]*oldScale[1] + v->xyz[1]*curScale[1] + tempNormalsArray[i][1]*shellscale), mirrormult * (move[1] + ov->xyz[1]*oldScale[1] + v->xyz[1]*curScale[1] + tempNormalsArray[i][1]*shellscale),
move[2] + ov->xyz[2]*oldScale[2] + v->xyz[2]*curScale[2] + tempNormalsArray[i][2]*shellscale ); move[2] + ov->xyz[2]*oldScale[2] + v->xyz[2]*curScale[2] + tempNormalsArray[i][2]*shellscale );
tempNormalsArray[i][1] *= mirrormult;
}
// skip drawing if we're only lerping the verts for a shadow-only rendering pass // skip drawing if we're only lerping the verts for a shadow-only rendering pass
if (lerpOnly) continue; if (lerpOnly) continue;
tempNormalsArray[i][1] *= mirrormult;
// calc lighting and alpha // calc lighting and alpha
if (shellModel) if (shellModel)
VectorCopy(meshlight, lightcolor); VectorCopy(meshlight, lightcolor);
@ -538,6 +547,7 @@ void R_DrawAliasMeshes (maliasmodel_t *paliashdr, entity_t *e, qboolean lerpOnly
} }
rb_vertex++; rb_vertex++;
} }
if (!shellModel) if (!shellModel)
RB_ModifyTextureCoords (&texCoordArray[0][baseindex][0], &vertexArray[baseindex][0], mesh.num_verts, &skinParms); RB_ModifyTextureCoords (&texCoordArray[0][baseindex][0], &vertexArray[baseindex][0], mesh.num_verts, &skinParms);
@ -702,26 +712,22 @@ void R_BuildShadowVolume (maliasmodel_t *hdr, int meshnum, vec3_t light, float p
if (!triangleFacingLight[i]) // changed to draw only front facing polys- thanx to Kirk Barnes if (!triangleFacingLight[i]) // changed to draw only front facing polys- thanx to Kirk Barnes
continue; continue;
// if (triangleFacingLight[i]) VectorCopy(tempVertexArray[meshnum][mesh.indexes[3*i+0]], v0);
// { VectorCopy(tempVertexArray[meshnum][mesh.indexes[3*i+1]], v1);
VectorCopy(tempVertexArray[meshnum][mesh.indexes[3*i+0]], v0); VectorCopy(tempVertexArray[meshnum][mesh.indexes[3*i+2]], v2);
VectorCopy(tempVertexArray[meshnum][mesh.indexes[3*i+1]], v1);
VectorCopy(tempVertexArray[meshnum][mesh.indexes[3*i+2]], v2);
VA_SetElem3(vertexArray[shadow_va], v0[0], v0[1], v0[2]); VA_SetElem3(vertexArray[shadow_va], v0[0], v0[1], v0[2]);
VA_SetElem4(colorArray[shadow_va], 0, 0, 0, thisAlpha); VA_SetElem4(colorArray[shadow_va], 0, 0, 0, thisAlpha);
indexArray[shadow_index++] = shadow_va; indexArray[shadow_index++] = shadow_va;
shadow_va++; shadow_va++;
VA_SetElem3(vertexArray[shadow_va], v1[0], v1[1], v1[2]); VA_SetElem3(vertexArray[shadow_va], v1[0], v1[1], v1[2]);
VA_SetElem4(colorArray[shadow_va], 0, 0, 0, thisAlpha); VA_SetElem4(colorArray[shadow_va], 0, 0, 0, thisAlpha);
indexArray[shadow_index++] = shadow_va; indexArray[shadow_index++] = shadow_va;
shadow_va++; shadow_va++;
VA_SetElem3(vertexArray[shadow_va], v2[0], v2[1], v2[2]); VA_SetElem3(vertexArray[shadow_va], v2[0], v2[1], v2[2]);
VA_SetElem4(colorArray[shadow_va], 0, 0, 0, thisAlpha); VA_SetElem4(colorArray[shadow_va], 0, 0, 0, thisAlpha);
indexArray[shadow_index++] = shadow_va; indexArray[shadow_index++] = shadow_va;
shadow_va++; shadow_va++;
// continue;
// }
// rear with reverse order // rear with reverse order
for (j=0; j<3; j++) for (j=0; j<3; j++)
@ -764,6 +770,85 @@ void R_DrawShadowVolume (void)
} }
/*
=============
R_CalcAliasVolumeShadowLightVector
=============
*/
float R_CalcAliasVolumeShadowLightVector (vec3_t bbox[8], vec3_t lightVec)
{
vec3_t temp, vecAdd;
int i, lnum;
float dist, highest, lowest, projected_distance;
float angle, cosp, sinp, cosy, siny, cosr, sinr, ix, iy, iz;
dlight_t *dl;
dl = r_newrefdef.dlights;
VectorSet(vecAdd, 680, 0, 1024); // set base vector, was 576,0,1024
// compute average light vector from dlights
for (i=0, lnum=0; i<r_newrefdef.num_dlights; i++, dl++)
{
if (VectorCompare(dl->origin, currententity->origin))
continue;
VectorSubtract(dl->origin, currententity->origin, temp);
dist = dl->intensity - VectorLength(temp);
if (dist <= 0)
continue;
lnum++;
// Factor in the intensity of a dlight
VectorScale (temp, dist*0.25, temp);
VectorAdd (vecAdd, temp, vecAdd);
}
VectorNormalize(vecAdd);
VectorScale(vecAdd, 1024, vecAdd);
// get projection distance from lightspot height
highest = lowest = bbox[0][2];
for (i=0; i<8; i++) {
if (bbox[i][2] > highest) highest = bbox[i][2];
if (bbox[i][2] < lowest) lowest = bbox[i][2];
}
projected_distance = fabs((highest - lightspot[2]) + (highest-lowest)) / fabs(vecAdd[2]);
// projected_distance = 1.5f * (fabs(highest - lightspot[2])) / fabs(vecAdd[2]);
VectorCopy(vecAdd, lightVec);
// reverse-rotate light vector based on angles
angle = -currententity->angles[PITCH] / 180 * M_PI;
cosp = cos(angle), sinp = sin(angle);
angle = -currententity->angles[YAW] / 180 * M_PI;
cosy = cos(angle), siny = sin(angle);
angle = -currententity->angles[ROLL] / 180 * M_PI * R_RollMult(); // roll is backwards
cosr = cos(angle), sinr = sin(angle);
// rotate for yaw (z axis)
ix = lightVec[0], iy = lightVec[1];
lightVec[0] = cosy * ix - siny * iy + 0;
lightVec[1] = siny * ix + cosy * iy + 0;
// rotate for pitch (y axis)
ix = lightVec[0], iz = lightVec[2];
lightVec[0] = cosp * ix + 0 + sinp * iz;
lightVec[2] = -sinp * ix + 0 + cosp * iz;
// rotate for roll (x axis)
iy = lightVec[1], iz = lightVec[2];
lightVec[1] = 0 + cosr * iy - sinr * iz;
lightVec[2] = 0 + sinr * iy + cosr * iz;
// for (i=0; i<3; i++)
// shadowVec[i] = -lightVec[i] * projected_distance;
// for (i=0; i<8; i++)
// VectorAdd (bbox[i], shadowVec, endBBox[i]);
return projected_distance;
}
/* /*
============= =============
R_DrawAliasVolumeShadow R_DrawAliasVolumeShadow
@ -772,13 +857,18 @@ based on code from BeefQuake R6
*/ */
void R_DrawAliasVolumeShadow (maliasmodel_t *paliashdr, vec3_t bbox[8]) void R_DrawAliasVolumeShadow (maliasmodel_t *paliashdr, vec3_t bbox[8])
{ {
vec3_t light, temp, vecAdd; vec3_t light, vecAdd; // temp
float dist, highest, lowest, projected_distance; vec3_t shadowVec, endBBox[8], volumeMins, volumeMaxs;
float angle, cosp, sinp, cosy, siny, cosr, sinr, ix, iy, iz; float projected_distance;
int i, lnum, skinnum; int i, j, skinnum; // lnum
//GLenum incr, decr; qboolean zFail = (r_shadow_zfail->integer != 0);
dlight_t *dl; qboolean inVolume = false;
// GLenum incr, decr;
// float dist, highest, lowest;
// float angle, cosp, sinp, cosy, siny, cosr, sinr, ix, iy, iz;
// dlight_t *dl;
#if 0
dl = r_newrefdef.dlights; dl = r_newrefdef.dlights;
VectorSet(vecAdd, 680,0,1024); // set base vector, was 576,0,1024 VectorSet(vecAdd, 680,0,1024); // set base vector, was 576,0,1024
@ -834,10 +924,45 @@ void R_DrawAliasVolumeShadow (maliasmodel_t *paliashdr, vec3_t bbox[8])
iy = light[1], iz = light[2]; iy = light[1], iz = light[2];
light[1] = 0 + cosr * iy - sinr * iz; light[1] = 0 + cosr * iy - sinr * iz;
light[2] = 0 + sinr * iy + cosr * iz; light[2] = 0 + sinr * iy + cosr * iz;
#endif
projected_distance = R_CalcAliasVolumeShadowLightVector (bbox, light);
// For Z-Pass method, calc bbox for shadow volume to see if vieworg is likely to be inside it
if (!zFail)
{
// calc bbox for end of shadow volume
for (i=0; i<3; i++)
shadowVec[i] = -vecAdd[i] * projected_distance;
for (i=0; i<8; i++)
VectorAdd (bbox[i], shadowVec, endBBox[i]);
// get bbox for entire shadow volume
VectorCopy (currententity->origin, volumeMaxs);
VectorCopy (currententity->origin, volumeMins);
for (i=0; i<8; i++)
{
for (j=0; j<3; j++)
{
if (bbox[i][j] < volumeMins[j])
volumeMins[j] = bbox[i][j];
if (endBBox[i][j] < volumeMins[j])
volumeMins[j] = endBBox[i][j];
if (bbox[i][j] > volumeMaxs[j])
volumeMaxs[j] = bbox[i][j];
if (endBBox[i][j] > volumeMaxs[j])
volumeMaxs[j] = endBBox[i][j];
}
}
// if the vieworg is inside the volume bbox, assume it's inside the volume
if ( (r_newrefdef.vieworg[0] >= volumeMins[0] && r_newrefdef.vieworg[1] >= volumeMins[1] && r_newrefdef.vieworg[2] >= volumeMins[2]) &&
(r_newrefdef.vieworg[0] <= volumeMaxs[0] && r_newrefdef.vieworg[1] <= volumeMaxs[1] && r_newrefdef.vieworg[2] <= volumeMaxs[2]) )
inVolume = true;
}
// set up stenciling // set up stenciling
if (!r_shadowvolumes->value) if (!r_shadowvolumes->integer)
{ {
/*if (glConfig.extStencilWrap) /*if (glConfig.extStencilWrap)
{ incr = GL_INCR_WRAP_EXT; decr = GL_DECR_WRAP_EXT; } { incr = GL_INCR_WRAP_EXT; decr = GL_DECR_WRAP_EXT; }
@ -864,12 +989,12 @@ void R_DrawAliasVolumeShadow (maliasmodel_t *paliashdr, vec3_t bbox[8])
if (paliashdr->meshes[i].skins[skinnum].renderparms.noshadow) if (paliashdr->meshes[i].skins[skinnum].renderparms.noshadow)
continue; continue;
R_BuildShadowVolume (paliashdr, i, light, projected_distance, r_shadowvolumes->value); R_BuildShadowVolume (paliashdr, i, light, projected_distance, r_shadowvolumes->integer);
GL_LockArrays (shadow_va); GL_LockArrays (shadow_va);
if (!r_shadowvolumes->value) if (!r_shadowvolumes->integer)
{ {
if (glConfig.atiSeparateStencil && glConfig.extStencilWrap) // Barnes ATI stenciling if (zFail &&glConfig.atiSeparateStencil && glConfig.extStencilWrap && r_stencilTwoSide->integer) // Barnes ATI stenciling
{ {
GL_Disable(GL_CULL_FACE); GL_Disable(GL_CULL_FACE);
@ -880,7 +1005,7 @@ void R_DrawAliasVolumeShadow (maliasmodel_t *paliashdr, vec3_t bbox[8])
GL_Enable(GL_CULL_FACE); GL_Enable(GL_CULL_FACE);
} }
else if (glConfig.extStencilTwoSide && glConfig.extStencilWrap) // Echon's two-sided stenciling else if (zFail && glConfig.extStencilTwoSide && glConfig.extStencilWrap && r_stencilTwoSide->integer) // Echon's two-sided stenciling
{ {
GL_Disable(GL_CULL_FACE); GL_Disable(GL_CULL_FACE);
qglEnable (GL_STENCIL_TEST_TWO_SIDE_EXT); qglEnable (GL_STENCIL_TEST_TWO_SIDE_EXT);
@ -895,8 +1020,9 @@ void R_DrawAliasVolumeShadow (maliasmodel_t *paliashdr, vec3_t bbox[8])
qglDisable (GL_STENCIL_TEST_TWO_SIDE_EXT); qglDisable (GL_STENCIL_TEST_TWO_SIDE_EXT);
GL_Enable(GL_CULL_FACE); GL_Enable(GL_CULL_FACE);
} }
else else if (zFail)
{ // increment stencil if backface is behind depthbuffer {
// increment stencil if backface is behind depthbuffer
GL_CullFace(GL_BACK); // quake is backwards, this culls front faces GL_CullFace(GL_BACK); // quake is backwards, this culls front faces
qglStencilOp(GL_KEEP, GL_INCR, GL_KEEP); qglStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
R_DrawShadowVolume (); R_DrawShadowVolume ();
@ -906,6 +1032,32 @@ void R_DrawAliasVolumeShadow (maliasmodel_t *paliashdr, vec3_t bbox[8])
qglStencilOp(GL_KEEP, GL_DECR, GL_KEEP); qglStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
R_DrawShadowVolume (); R_DrawShadowVolume ();
} }
else // Z-Pass
{
// Fix for z-Pass shadows if viewpoint is inside volume
// Same as Carmack's patent-free method for Doom3 GPL source
// This pre-loads the stencil buffer with # of volumes
// that get clipped by the near or far clip plane.
if (inVolume)
{
GL_CullFace(GL_BACK); // quake is backwards, this culls front faces
qglStencilOp(GL_KEEP, GL_INCR, GL_INCR);
R_DrawShadowVolume ();
GL_CullFace(GL_FRONT); // quake is backwards, this culls back faces
qglStencilOp(GL_KEEP, GL_DECR, GL_DECR);
R_DrawShadowVolume ();
}
// increment stencil if frontface is behind depthbuffer
GL_CullFace(GL_FRONT); // quake is backwards, this culls back faces
qglStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
R_DrawShadowVolume ();
// decrement stencil if backface is behind depthbuffer
GL_CullFace(GL_BACK); // quake is backwards, this culls front faces
qglStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
R_DrawShadowVolume ();
}
} }
else else
R_DrawShadowVolume (); R_DrawShadowVolume ();
@ -914,7 +1066,7 @@ void R_DrawAliasVolumeShadow (maliasmodel_t *paliashdr, vec3_t bbox[8])
} }
// end stenciling and draw stenciled volume // end stenciling and draw stenciled volume
if (!r_shadowvolumes->value) if (!r_shadowvolumes->integer)
{ {
GL_CullFace(GL_FRONT); GL_CullFace(GL_FRONT);
GL_Disable(GL_STENCIL_TEST); GL_Disable(GL_STENCIL_TEST);
@ -997,14 +1149,15 @@ void R_DrawAliasPlanarShadow (maliasmodel_t *paliashdr)
R_CullAliasModel R_CullAliasModel
================= =================
*/ */
static qboolean R_CullAliasModel ( vec3_t bbox[8], entity_t *e ) //static qboolean R_CullAliasModel ( vec3_t bbox[8], entity_t *e )
static qboolean R_CullAliasModel (vec3_t bbox[8], vec3_t shadowBBox[8], entity_t *e, qboolean volumeShadow)
{ {
int i, j; int i, j, mask, aggregatemask = ~0;
vec3_t mins, maxs, tmp; //angles; float dp, volProjDist;
vec3_t vectors[3]; vec3_t mins, maxs, tmp, vectors[3]; //angles;
vec3_t lightVec, shadowVec, tmp_bbox[8], end_bbox[8], volumeMins, volumeMaxs;
maliasmodel_t *paliashdr; maliasmodel_t *paliashdr;
maliasframe_t *pframe, *poldframe; maliasframe_t *pframe, *poldframe;
int mask, aggregatemask = ~0;
paliashdr = (maliasmodel_t *)currentmodel->extradata; paliashdr = (maliasmodel_t *)currentmodel->extradata;
@ -1058,18 +1211,61 @@ static qboolean R_CullAliasModel ( vec3_t bbox[8], entity_t *e )
tmp[1] = ((i & 2) ? mins[1] : maxs[1]); tmp[1] = ((i & 2) ? mins[1] : maxs[1]);
tmp[2] = ((i & 4) ? mins[2] : maxs[2]); tmp[2] = ((i & 4) ? mins[2] : maxs[2]);
VectorCopy(tmp, tmp_bbox[i]); // save off un-rotated bbox
VectorAdd(tmp, e->origin, end_bbox[i]); // version with e->origin added for light vector calc
bbox[i][0] = vectors[0][0] * tmp[0] + vectors[1][0] * tmp[1] + vectors[2][0] * tmp[2] + e->origin[0]; bbox[i][0] = vectors[0][0] * tmp[0] + vectors[1][0] * tmp[1] + vectors[2][0] * tmp[2] + e->origin[0];
bbox[i][1] = vectors[0][1] * tmp[0] + vectors[1][1] * tmp[1] + vectors[2][1] * tmp[2] + e->origin[1]; bbox[i][1] = vectors[0][1] * tmp[0] + vectors[1][1] * tmp[1] + vectors[2][1] * tmp[2] + e->origin[1];
bbox[i][2] = vectors[0][2] * tmp[0] + vectors[1][2] * tmp[1] + vectors[2][2] * tmp[2] + e->origin[2]; bbox[i][2] = vectors[0][2] * tmp[0] + vectors[1][2] * tmp[1] + vectors[2][2] * tmp[2] + e->origin[2];
} }
// calc shadow volume bbox and rotate
if (volumeShadow)
{
R_LightPoint (e->origin, shadelight, false);
volProjDist = R_CalcAliasVolumeShadowLightVector (end_bbox, lightVec);
for (i=0; i<3; i++)
shadowVec[i] = -lightVec[i] * volProjDist;
VectorCopy (vec3_origin, volumeMaxs);
VectorCopy (vec3_origin, volumeMins);
for (i = 0; i < 8; i++)
{
VectorAdd(tmp_bbox[i], shadowVec, end_bbox[i]);
// VectorCopy(end_bbox[i], tmp);
for (j=0; j<3; j++)
{
if (tmp_bbox[i][j] < volumeMins[j])
volumeMins[j] = tmp_bbox[i][j];
if (end_bbox[i][j] < volumeMins[j])
volumeMins[j] = end_bbox[i][j];
if (tmp_bbox[i][j] > volumeMaxs[j])
volumeMaxs[j] = tmp_bbox[i][j];
if (end_bbox[i][j] > volumeMaxs[j])
volumeMaxs[j] = end_bbox[i][j];
}
tmp[0] = ((i & 1) ? volumeMins[0] : volumeMaxs[0]);
tmp[1] = ((i & 2) ? volumeMins[1] : volumeMaxs[1]);
tmp[2] = ((i & 4) ? volumeMins[2] : volumeMaxs[2]);
shadowBBox[i][0] = vectors[0][0] * tmp[0] + vectors[1][0] * tmp[1] + vectors[2][0] * tmp[2] + e->origin[0];
shadowBBox[i][1] = vectors[0][1] * tmp[0] + vectors[1][1] * tmp[1] + vectors[2][1] * tmp[2] + e->origin[1];
shadowBBox[i][2] = vectors[0][2] * tmp[0] + vectors[1][2] * tmp[1] + vectors[2][2] * tmp[2] + e->origin[2];
}
}
// cull // cull
for (i=0; i<8; i++) for (i=0; i<8; i++)
{ {
mask = 0; mask = 0;
for (j=0; j<4; j++) for (j=0; j<4; j++)
{ {
float dp = DotProduct(frustum[j].normal, bbox[i]); dp = DotProduct(frustum[j].normal, bbox[i]);
if ( ( dp - frustum[j].dist ) < 0 ) if ( ( dp - frustum[j].dist ) < 0 )
mask |= (1<<j); mask |= (1<<j);
} }
@ -1084,6 +1280,35 @@ static qboolean R_CullAliasModel ( vec3_t bbox[8], entity_t *e )
} }
/*
=================
R_CullAliasShadow
=================
*/
static qboolean R_CullAliasShadow (vec3_t bbox[8], entity_t *e)
{
int i, j, mask, aggregatemask = ~0;
float dp;
for (i=0; i<8; i++)
{
mask = 0;
for (j=0; j<4; j++)
{
dp = DotProduct(frustum[j].normal, bbox[i]);
if ( ( dp - frustum[j].dist ) < 0 )
mask |= (1<<j);
}
aggregatemask &= mask;
}
if ( aggregatemask )
return true;
return false;
}
/* /*
================= =================
R_DrawAliasModel R_DrawAliasModel
@ -1092,28 +1317,56 @@ R_DrawAliasModel
void R_DrawAliasModel (entity_t *e) void R_DrawAliasModel (entity_t *e)
{ {
maliasmodel_t *paliashdr; maliasmodel_t *paliashdr;
vec3_t bbox[8]; vec3_t bbox[8], shadowBBox[8];
qboolean mirrorview = false, mirrormodel = false; qboolean mirrorview = false, mirrormodel = false;
qboolean planarShadow = false, volumeShadow = false, volumeShadowOnly = false;
qboolean preLerped = false;
int i; int i;
// determine if this model will have a volume shadow
if ( (r_shadows->integer >= 1) &&
!(r_newrefdef.rdflags & RDF_NOWORLDMODEL) &&
(r_worldmodel != NULL) && (r_worldmodel->lightdata != 0) &&
!(e->flags & (RF_WEAPONMODEL | RF_NOSHADOW)) &&
!( (e->flags & RF_MASK_SHELL) && (e->flags & RF_TRANSLUCENT) ) ) // no shadows from shells
{
aliasShadowAlpha = R_CalcShadowAlpha(e);
if ( (r_shadows->integer == 3) && (aliasShadowAlpha >= DIV255) )
volumeShadow = true;
else if (aliasShadowAlpha >= DIV255)
planarShadow = true;
}
// also skip this for viewermodels and cameramodels // also skip this for viewermodels and cameramodels
if ( !(e->flags & RF_WEAPONMODEL || e->flags & RF_VIEWERMODEL || e->renderfx & RF2_CAMERAMODEL) ) if ( !(e->flags & RF_WEAPONMODEL || e->flags & RF_VIEWERMODEL || e->renderfx & RF2_CAMERAMODEL) )
{ {
if (R_CullAliasModel(bbox, e)) // if (R_CullAliasModel(bbox, e))
// return;
qboolean culled = R_CullAliasModel(bbox, shadowBBox, e, volumeShadow);
if (volumeShadow)
{
if (culled) {
if ( R_CullAliasShadow(shadowBBox, e) )
return;
else
volumeShadowOnly = true;
}
}
else if (culled)
return; return;
} }
// mirroring support // mirroring support
if (e->flags & RF_WEAPONMODEL) if (e->flags & RF_WEAPONMODEL)
{ {
if (r_lefthand->value == 2) if (r_lefthand->integer == 2)
return; return;
else if (r_lefthand->value == 1) else if (r_lefthand->integer == 1)
mirrorview = true; mirrorview = true;
} }
else if (e->renderfx & RF2_CAMERAMODEL) else if (e->renderfx & RF2_CAMERAMODEL)
{ {
if (r_lefthand->value == 1) if (r_lefthand->integer == 1)
mirrormodel = true; mirrormodel = true;
} }
else if (e->flags & RF_MIRRORMODEL) else if (e->flags & RF_MIRRORMODEL)
@ -1167,10 +1420,42 @@ void R_DrawAliasModel (entity_t *e)
e->oldframe = 0; e->oldframe = 0;
} }
if (!r_lerpmodels->value) if (!r_lerpmodels->integer)
e->backlerp = 0; e->backlerp = 0;
R_DrawAliasMeshes (paliashdr, e, false, mirrormodel, mirrorview); // draw shadow only here
if ( volumeShadowOnly || (volumeShadow && r_shadow_self->integer == 0) )
{
preLerped = true;
R_DrawAliasMeshes (paliashdr, e, mirrormodel, mirrorview, false, true);
GL_DisableTexture(0);
GL_Enable (GL_BLEND);
R_DrawAliasVolumeShadow (paliashdr, bbox);
GL_Disable (GL_BLEND);
GL_EnableTexture(0);
// the following is not called if drawing shadow volume before model
if ( volumeShadowOnly )
{
qglPopMatrix ();
if (mirrorview || mirrormodel)
R_FlipModel (false, mirrormodel);
if (e->flags & RF_DEPTHHACK)
GL_DepthRange (gldepthmin, gldepthmax);
if (r_showbbox->integer) {
GL_Disable (GL_DEPTH_TEST);
R_DrawAliasModelBBox (shadowBBox, e, 0.0f, 0.0f, 1.0f, 1.0f);
GL_Enable (GL_DEPTH_TEST);
}
return;
}
}
// R_DrawAliasMeshes (paliashdr, e, false, mirrormodel, mirrorview);
R_DrawAliasMeshes (paliashdr, e, mirrormodel, mirrorview, preLerped, false);
qglPopMatrix (); qglPopMatrix ();
@ -1181,29 +1466,40 @@ void R_DrawAliasModel (entity_t *e)
R_FlipModel (false, mirrormodel); R_FlipModel (false, mirrormodel);
// show model bounding box // show model bounding box
R_DrawAliasModelBBox (bbox, e, 1.0f, 1.0f, 1.0f, 1.0f); // R_DrawAliasModelBBox (bbox, e, 1.0f, 1.0f, 1.0f, 1.0f);
if (r_showbbox->integer) {
R_DrawAliasModelBBox (bbox, e, 1.0f, 1.0f, 1.0f, 1.0f);
if (volumeShadow) {
GL_Disable (GL_DEPTH_TEST);
R_DrawAliasModelBBox (shadowBBox, e, 0.0f, 0.0f, 1.0f, 1.0f);
GL_Enable (GL_DEPTH_TEST);
}
}
if (e->flags & RF_DEPTHHACK) if (e->flags & RF_DEPTHHACK)
GL_DepthRange (gldepthmin, gldepthmax); GL_DepthRange (gldepthmin, gldepthmax);
aliasShadowAlpha = R_CalcShadowAlpha(e); // aliasShadowAlpha = R_CalcShadowAlpha(e);
if ( !(e->flags & (RF_WEAPONMODEL | RF_NOSHADOW)) /* if ( !(e->flags & (RF_WEAPONMODEL | RF_NOSHADOW))
// no shadows from shells // no shadows from shells
&& !( (e->flags & RF_MASK_SHELL) && (e->flags & RF_TRANSLUCENT) ) && !( (e->flags & RF_MASK_SHELL) && (e->flags & RF_TRANSLUCENT) )
&& r_shadows->value >= 1 && aliasShadowAlpha >= DIV255) && r_shadows->integer >= 1 && aliasShadowAlpha >= DIV255) */
if ( volumeShadow || planarShadow)
{ {
qglPushMatrix (); qglPushMatrix ();
GL_DisableTexture(0); GL_DisableTexture(0);
GL_Enable (GL_BLEND); GL_Enable (GL_BLEND);
if (r_shadows->value == 3) { // if (r_shadows->integer == 3) {
if (volumeShadow && r_shadow_self->integer != 0) {
e->angles[ROLL] = e->angles[ROLL] * R_RollMult(); // roll is backwards e->angles[ROLL] = e->angles[ROLL] * R_RollMult(); // roll is backwards
R_RotateForEntity (e, true); R_RotateForEntity (e, true);
e->angles[ROLL] = e->angles[ROLL] * R_RollMult(); // roll is backwards e->angles[ROLL] = e->angles[ROLL] * R_RollMult(); // roll is backwards
R_DrawAliasVolumeShadow (paliashdr, bbox); R_DrawAliasVolumeShadow (paliashdr, bbox);
} }
else { // else {
else if (planarShadow) {
R_RotateForEntity (e, false); R_RotateForEntity (e, false);
R_DrawAliasPlanarShadow (paliashdr); R_DrawAliasPlanarShadow (paliashdr);
} }
@ -1227,7 +1523,7 @@ void R_DrawAliasModelShadow (entity_t *e)
vec3_t bbox[8]; vec3_t bbox[8];
qboolean mirrormodel = false; qboolean mirrormodel = false;
if (!r_shadows->value) if (!r_shadows->integer)
return; return;
if (e->flags & (RF_WEAPONMODEL | RF_NOSHADOW)) if (e->flags & (RF_WEAPONMODEL | RF_NOSHADOW))
return; return;
@ -1248,7 +1544,7 @@ void R_DrawAliasModelShadow (entity_t *e)
if (e->renderfx & RF2_CAMERAMODEL) if (e->renderfx & RF2_CAMERAMODEL)
{ {
if (r_lefthand->value == 1) if (r_lefthand->integer == 1)
mirrormodel = true; mirrormodel = true;
} }
else if (e->flags & RF_MIRRORMODEL) else if (e->flags & RF_MIRRORMODEL)
@ -1256,10 +1552,6 @@ void R_DrawAliasModelShadow (entity_t *e)
paliashdr = (maliasmodel_t *)currentmodel->extradata; paliashdr = (maliasmodel_t *)currentmodel->extradata;
// mirroring support
// if (mirrormodel)
// R_FlipModel(true);
if ( (e->frame >= paliashdr->num_frames) || (e->frame < 0) ) if ( (e->frame >= paliashdr->num_frames) || (e->frame < 0) )
{ {
e->frame = 0; e->frame = 0;
@ -1272,16 +1564,17 @@ void R_DrawAliasModelShadow (entity_t *e)
e->oldframe = 0; e->oldframe = 0;
} }
//if ( !r_lerpmodels->value ) // if ( !r_lerpmodels->integer )
// e->backlerp = 0; // e->backlerp = 0;
R_DrawAliasMeshes (paliashdr, e, true, mirrormodel, false); // R_DrawAliasMeshes (paliashdr, e, true, mirrormodel);
R_DrawAliasMeshes (paliashdr, e, mirrormodel, false, false, true);
qglPushMatrix (); qglPushMatrix ();
GL_DisableTexture(0); GL_DisableTexture(0);
GL_Enable (GL_BLEND); GL_Enable (GL_BLEND);
if (r_shadows->value == 3) { if (r_shadows->integer == 3) {
e->angles[ROLL] = e->angles[ROLL] * R_RollMult(); // roll is backwards e->angles[ROLL] = e->angles[ROLL] * R_RollMult(); // roll is backwards
R_RotateForEntity (e, true); R_RotateForEntity (e, true);
e->angles[ROLL] = e->angles[ROLL] * R_RollMult(); // roll is backwards e->angles[ROLL] = e->angles[ROLL] * R_RollMult(); // roll is backwards
@ -1295,9 +1588,5 @@ void R_DrawAliasModelShadow (entity_t *e)
GL_Disable (GL_BLEND); GL_Disable (GL_BLEND);
GL_EnableTexture(0); GL_EnableTexture(0);
qglPopMatrix (); qglPopMatrix ();
// mirroring support
// if (mirrormodel)
// R_FlipModel(false);
} }
#endif #endif

View file

@ -450,17 +450,25 @@ void R_SetShadeLight (void)
// as the mono value returned by software // as the mono value returned by software
if (shadelight[0] > shadelight[1]) if (shadelight[0] > shadelight[1])
{ {
if (shadelight[0] > shadelight[2]) if (shadelight[0] > shadelight[2]) {
r_lightlevel->value = 150*shadelight[0]; // r_lightlevel->value = 150*shadelight[0];
else Cvar_SetValue ("r_lightlevel", 150.0f*shadelight[0]);
r_lightlevel->value = 150*shadelight[2]; }
else {
// r_lightlevel->value = 150*shadelight[2];
Cvar_SetValue ("r_lightlevel", 150.0f*shadelight[2]);
}
} }
else else
{ {
if (shadelight[1] > shadelight[2]) if (shadelight[1] > shadelight[2]) {
r_lightlevel->value = 150*shadelight[1]; // r_lightlevel->value = 150*shadelight[1];
else Cvar_SetValue ("r_lightlevel", 150.0f*shadelight[1]);
r_lightlevel->value = 150*shadelight[2]; }
else {
// r_lightlevel->value = 150*shadelight[2];
Cvar_SetValue ("r_lightlevel", 150.0f*shadelight[2]);
}
} }
} }

View file

@ -287,6 +287,8 @@ extern cvar_t *r_shadows;
extern cvar_t *r_shadowalpha; extern cvar_t *r_shadowalpha;
extern cvar_t *r_shadowrange; extern cvar_t *r_shadowrange;
extern cvar_t *r_shadowvolumes; extern cvar_t *r_shadowvolumes;
extern cvar_t *r_shadow_self;
extern cvar_t *r_shadow_zfail;
extern cvar_t *r_stencil; // stenciling for color shells extern cvar_t *r_stencil; // stenciling for color shells
extern cvar_t *r_transrendersort; // correct trasparent sorting extern cvar_t *r_transrendersort; // correct trasparent sorting
extern cvar_t *r_particle_lighting; // particle lighting extern cvar_t *r_particle_lighting; // particle lighting

View file

@ -147,6 +147,8 @@ cvar_t *r_shadows;
cvar_t *r_shadowalpha; cvar_t *r_shadowalpha;
cvar_t *r_shadowrange; cvar_t *r_shadowrange;
cvar_t *r_shadowvolumes; cvar_t *r_shadowvolumes;
cvar_t *r_shadow_self;
cvar_t *r_shadow_zfail;
cvar_t *r_stencil; cvar_t *r_stencil;
cvar_t *r_transrendersort; // correct trasparent sorting cvar_t *r_transrendersort; // correct trasparent sorting
cvar_t *r_particle_lighting; // particle lighting cvar_t *r_particle_lighting; // particle lighting
@ -835,17 +837,25 @@ void R_SetLightLevel (void)
// as the mono value returned by software // as the mono value returned by software
if (shadelight[0] > shadelight[1]) if (shadelight[0] > shadelight[1])
{ {
if (shadelight[0] > shadelight[2]) if (shadelight[0] > shadelight[2]) {
r_lightlevel->value = 150*shadelight[0]; // r_lightlevel->value = 150*shadelight[0];
else Cvar_SetValue ("r_lightlevel", 150.0f*shadelight[0]);
r_lightlevel->value = 150*shadelight[2]; }
else {
// r_lightlevel->value = 150*shadelight[2];
Cvar_SetValue ("r_lightlevel", 150.0f*shadelight[2]);
}
} }
else else
{ {
if (shadelight[1] > shadelight[2]) if (shadelight[1] > shadelight[2]) {
r_lightlevel->value = 150*shadelight[1]; // r_lightlevel->value = 150*shadelight[1];
else Cvar_SetValue ("r_lightlevel", 150.0f*shadelight[1]);
r_lightlevel->value = 150*shadelight[2]; }
else {
// r_lightlevel->value = 150*shadelight[2];
Cvar_SetValue ("r_lightlevel", 150.0f*shadelight[2]);
}
} }
} }
@ -946,6 +956,8 @@ void R_Register (void)
r_shadowalpha = Cvar_Get ("r_shadowalpha", "0.4", CVAR_ARCHIVE ); r_shadowalpha = Cvar_Get ("r_shadowalpha", "0.4", CVAR_ARCHIVE );
r_shadowrange = Cvar_Get ("r_shadowrange", "768", CVAR_ARCHIVE ); r_shadowrange = Cvar_Get ("r_shadowrange", "768", CVAR_ARCHIVE );
r_shadowvolumes = Cvar_Get ("r_shadowvolumes", "0", CVAR_CHEAT ); r_shadowvolumes = Cvar_Get ("r_shadowvolumes", "0", CVAR_CHEAT );
r_shadow_self = Cvar_Get ("r_shadow_self", "1", CVAR_ARCHIVE );
r_shadow_zfail = Cvar_Get ("r_shadow_zfail", "1", CVAR_ARCHIVE );
r_stencil = Cvar_Get ("r_stencil", "1", CVAR_ARCHIVE ); r_stencil = Cvar_Get ("r_stencil", "1", CVAR_ARCHIVE );
r_dynamic = Cvar_Get ("r_dynamic", "1", 0); r_dynamic = Cvar_Get ("r_dynamic", "1", 0);
@ -1410,8 +1422,8 @@ qboolean R_CheckGLExtensions (char *reason)
glConfig.atiSeparateStencil = false; glConfig.atiSeparateStencil = false;
if (StringContainsToken(glConfig.extensions_string, "GL_ATI_separate_stencil")) if (StringContainsToken(glConfig.extensions_string, "GL_ATI_separate_stencil"))
{ {
if (r_stencilTwoSide->value) // if (r_stencilTwoSide->value)
{ // {
qglStencilOpSeparateATI = (void *) qwglGetProcAddress("glStencilOpSeparateATI"); qglStencilOpSeparateATI = (void *) qwglGetProcAddress("glStencilOpSeparateATI");
qglStencilFuncSeparateATI = (void *) qwglGetProcAddress("glStencilFuncSeparateATI"); qglStencilFuncSeparateATI = (void *) qwglGetProcAddress("glStencilFuncSeparateATI");
if (!qglStencilOpSeparateATI) { if (!qglStencilOpSeparateATI) {
@ -1422,9 +1434,9 @@ qboolean R_CheckGLExtensions (char *reason)
VID_Printf (PRINT_ALL, "...using GL_ATI_separate_stencil\n"); VID_Printf (PRINT_ALL, "...using GL_ATI_separate_stencil\n");
glConfig.atiSeparateStencil = true; glConfig.atiSeparateStencil = true;
} }
} // }
else // else
VID_Printf (PRINT_ALL, "...ignoring GL_ATI_separate_stencil\n"); // VID_Printf (PRINT_ALL, "...ignoring GL_ATI_separate_stencil\n");
} }
else else
VID_Printf (PRINT_ALL, "...GL_ATI_separate_stencil not found\n"); VID_Printf (PRINT_ALL, "...GL_ATI_separate_stencil not found\n");
@ -1433,8 +1445,8 @@ qboolean R_CheckGLExtensions (char *reason)
glConfig.extStencilTwoSide = false; glConfig.extStencilTwoSide = false;
if (StringContainsToken(glConfig.extensions_string, "GL_EXT_stencil_two_side")) if (StringContainsToken(glConfig.extensions_string, "GL_EXT_stencil_two_side"))
{ {
if (r_stencilTwoSide->value) // if (r_stencilTwoSide->value)
{ // {
qglActiveStencilFaceEXT = (void *) qwglGetProcAddress( "glActiveStencilFaceEXT" ); qglActiveStencilFaceEXT = (void *) qwglGetProcAddress( "glActiveStencilFaceEXT" );
if (!qglActiveStencilFaceEXT) { if (!qglActiveStencilFaceEXT) {
VID_Printf (PRINT_ALL, "..." S_COLOR_RED "GL_EXT_stencil_two_side not properly supported!\n"); VID_Printf (PRINT_ALL, "..." S_COLOR_RED "GL_EXT_stencil_two_side not properly supported!\n");
@ -1444,9 +1456,9 @@ qboolean R_CheckGLExtensions (char *reason)
VID_Printf (PRINT_ALL, "...using GL_EXT_stencil_two_side\n"); VID_Printf (PRINT_ALL, "...using GL_EXT_stencil_two_side\n");
glConfig.extStencilTwoSide = true; glConfig.extStencilTwoSide = true;
} }
} // }
else // else
VID_Printf (PRINT_ALL, "...ignoring GL_EXT_stencil_two_side\n"); // VID_Printf (PRINT_ALL, "...ignoring GL_EXT_stencil_two_side\n");
} }
else else
Com_Printf("...GL_EXT_stencil_two_side not found\n"); Com_Printf("...GL_EXT_stencil_two_side not found\n");