Changes to the way shadow volumes are calculated, to support the new render drivers

This commit is contained in:
cholleme 2003-02-15 17:56:45 +00:00
parent bd5cbfb9b0
commit a1aa8c1cf4

View file

@ -36,11 +36,15 @@ shadowlight_t *currentshadowlight;
int volumeCmdsBuff[MAX_VOLUME_COMMANDS+128]; //Hack protect against slight overflows int volumeCmdsBuff[MAX_VOLUME_COMMANDS+128]; //Hack protect against slight overflows
float volumeVertsBuff[MAX_VOLUME_VERTS+128]; float volumeVertsBuff[MAX_VOLUME_VERTS+128];
lightcmd_t lightCmdsBuff[MAX_LIGHT_COMMANDS+128]; lightcmd_t lightCmdsBuff[MAX_LIGHT_COMMANDS+128];
lightcmd_t lightCmdsBuffMesh[MAX_LIGHT_COMMANDS+128];
int numVolumeCmds; int numVolumeCmds;
int numLightCmds; int numLightCmds;
int numLightCmdsMesh;
int numVolumeVerts; int numVolumeVerts;
msurface_t *shadowchain; //linked list of polygons that are shadowed msurface_t *shadowchain; //linked list of polygons that are shadowed
mesh_t *meshshadowchain;
byte *lightvis; byte *lightvis;
byte worldvis[MAX_MAP_LEAFS/8]; byte worldvis[MAX_MAP_LEAFS/8];
@ -585,6 +589,7 @@ void R_MarkShadowCasting (shadowlight_t *light, mnode_t *node)
msurface_t **surf; msurface_t **surf;
mleaf_t *leaf; mleaf_t *leaf;
int c,leafindex; int c,leafindex;
mesh_t *mesh;
if (node->contents & CONTENTS_LEAF) { if (node->contents & CONTENTS_LEAF) {
//we are in a leaf //we are in a leaf
@ -608,6 +613,15 @@ void R_MarkShadowCasting (shadowlight_t *light, mnode_t *node)
} }
} }
c = leaf->nummeshes;
for (c=0; c<leaf->nummeshes; c++) {
mesh = &cl.worldmodel->meshes[cl.worldmodel->leafmeshes[leaf->firstmesh+c]];
if (mesh->lightTimestamp == r_lightTimestamp) continue;
mesh->shadowchain = meshshadowchain;
meshshadowchain = mesh;
mesh->lightTimestamp = r_lightTimestamp;
}
return; return;
} }
@ -665,6 +679,12 @@ qboolean R_ContributeFrame (shadowlight_t *light)
//verry soft light, don't bother. //verry soft light, don't bother.
if (b < 0.1) return false; if (b < 0.1) return false;
//not in a visible area => skip it
if (!(r_refdef.areabits[light->area>>3] & (1<<(light->area&7)))) {
return false;
}
//frustum scissor testing //frustum scissor testing
dist = SphereInFrustum(light->origin, light->radius); dist = SphereInFrustum(light->origin, light->radius);
if (dist == 0) { if (dist == 0) {
@ -698,6 +718,7 @@ qboolean R_ContributeFrame (shadowlight_t *light)
//r_lightTimestamp++; //r_lightTimestamp++;
shadowchain = NULL; shadowchain = NULL;
meshshadowchain = NULL;
if (light->isStatic) { if (light->isStatic) {
lightvis = &light->vis[0]; lightvis = &light->vis[0];
} else { } else {
@ -705,6 +726,7 @@ qboolean R_ContributeFrame (shadowlight_t *light)
lightvis = Mod_LeafPVS (lightleaf, cl.worldmodel); lightvis = Mod_LeafPVS (lightleaf, cl.worldmodel);
Q_memcpy(&light->vis,lightvis,MAX_MAP_LEAFS/8); Q_memcpy(&light->vis,lightvis,MAX_MAP_LEAFS/8);
Q_memcpy(&light->entvis, lightvis, MAX_MAP_LEAFS/8); Q_memcpy(&light->entvis, lightvis, MAX_MAP_LEAFS/8);
light->area = lightleaf->area;
} }
if (HasSharedLeafs(lightvis,&worldvis[0])) { if (HasSharedLeafs(lightvis,&worldvis[0])) {
@ -744,6 +766,7 @@ qboolean R_FillShadowChain (shadowlight_t *light)
r_lightTimestamp++; r_lightTimestamp++;
shadowchain = NULL; shadowchain = NULL;
meshshadowchain = NULL;
lightvis = &light->vis[0]; lightvis = &light->vis[0];
//numUsedShadowLights++; //numUsedShadowLights++;
@ -758,7 +781,7 @@ qboolean R_FillShadowChain (shadowlight_t *light)
return true; return true;
} }
return (shadowchain) ? true : false; return (shadowchain || meshshadowchain) ? true : false;
} }
void *VolumeVertsPointer; void *VolumeVertsPointer;
@ -777,6 +800,7 @@ void R_ConstructShadowVolume(shadowlight_t *light) {
light->volumeCmds = &volumeCmdsBuff[0]; light->volumeCmds = &volumeCmdsBuff[0];
light->volumeVerts = &volumeVertsBuff[0]; light->volumeVerts = &volumeVertsBuff[0];
light->lightCmds = &lightCmdsBuff[0]; light->lightCmds = &lightCmdsBuff[0];
light->numlightcmds = numLightCmds;
} }
VolumeVertsPointer = light->volumeVerts; VolumeVertsPointer = light->volumeVerts;
@ -1074,7 +1098,7 @@ void R_DrawBrushModelVolumes(entity_t *e) {
glpoly_t *poly; glpoly_t *poly;
int i, j, count; int i, j, count;
brushlightinstant_t *ins = e->brushlightinstant; brushlightinstant_t *ins = e->brushlightinstant;
float *v;
count = 0; count = 0;
@ -1091,21 +1115,27 @@ void R_DrawBrushModelVolumes(entity_t *e) {
poly = surf->polys; poly = surf->polys;
//extrude edges //extrude edges
for (j=0 ; j<surf->numedges ; j++) for (j=0 ; j<poly->numneighbours ; j++)
{ {
mneighbour_t *neigh = &poly->neighbours[j];
if (ins->neighbourVis[count+j]) { if (ins->neighbourVis[count+j]) {
glBegin(GL_QUAD_STRIP); glBegin(GL_QUAD_STRIP);
//Note: The neighbour p1,p2 are absolute vertex indecies, for the extruded ones
//we want polygon relative indecies.
//glVertex3fv(&poly->verts[j][0]); //glVertex3fv(&poly->verts[j][0]);
glVertex3fv((float *)(&globalVertexTable[surf->polys->firstvertex+j])); glVertex3fv((float *)(&globalVertexTable[neigh->p1]));
glVertex3fv(&ins->extvertices[count+j][0]); glVertex3fv(&ins->extvertices[count+neigh->p1-poly->firstvertex][0]);
//glVertex3fv(&poly->verts[((j+1)% poly->numverts)][0]); //glVertex3fv(&poly->verts[((j+1)% poly->numverts)][0]);
glVertex3fv((float *)(&globalVertexTable[surf->polys->firstvertex+((j+1)% poly->numverts)])); glVertex3fv((float *)(&globalVertexTable[neigh->p2]));
glVertex3fv(&ins->extvertices[count+((j+1)% poly->numverts) ][0]); glVertex3fv(&ins->extvertices[count+neigh->p2-poly->firstvertex][0]);
glEnd(); glEnd();
} }
} }
//Draw near light cap //Draw near light cap
/*
glBegin(GL_TRIANGLE_FAN); glBegin(GL_TRIANGLE_FAN);
for (j=0; j<surf->numedges ; j++) for (j=0; j<surf->numedges ; j++)
{ {
@ -1113,14 +1143,32 @@ void R_DrawBrushModelVolumes(entity_t *e) {
glVertex3fv((float *)(&globalVertexTable[surf->polys->firstvertex+j])); glVertex3fv((float *)(&globalVertexTable[surf->polys->firstvertex+j]));
} }
glEnd(); glEnd();
*/
glBegin(GL_TRIANGLES);
//v = surf->polys->verts[0];
for (j=0; j<surf->polys->numindecies; j++) {
v = (float *)(&globalVertexTable[surf->polys->indecies[j]]);
glVertex3fv(&v[0]);
}
glEnd();
//Draw extruded cap //Draw extruded cap
/*
glBegin(GL_TRIANGLE_FAN); glBegin(GL_TRIANGLE_FAN);
for (j=surf->numedges-1; j>=0 ; j--) for (j=surf->numedges-1; j>=0 ; j--)
{ {
glVertex3fv(&ins->extvertices[count+j][0]); glVertex3fv(&ins->extvertices[count+j][0]);
} }
glEnd(); glEnd();
*/
glBegin(GL_TRIANGLES);
//v = surf->polys->verts[0];
for (j=surf->polys->numindecies-1; j>=0; j--) {
v = (float *)(&ins->extvertices[count+surf->polys->indecies[j]-surf->polys->firstvertex]);
glVertex3fv(&v[0]);
}
glEnd();
count+=surf->numedges; count+=surf->numedges;
} }
@ -1184,9 +1232,11 @@ void PrecalcVolumesForLight(model_t *model) {
int *volumeCmds = &volumeCmdsBuff[0]; int *volumeCmds = &volumeCmdsBuff[0];
lightcmd_t *lightCmds = &lightCmdsBuff[0]; lightcmd_t *lightCmds = &lightCmdsBuff[0];
lightcmd_t *lightCmdsMesh = &lightCmdsBuffMesh[0];
float *volumeVerts = &volumeVertsBuff[0]; float *volumeVerts = &volumeVertsBuff[0];
int volumePos = 0; int volumePos = 0;
int lightPos = 0; int lightPos = 0;
int lightPosMesh = 0;
int vertPos = 0; int vertPos = 0;
int startVerts, startNearVerts, numPos = 0, stripLen = 0, i; int startVerts, startNearVerts, numPos = 0, stripLen = 0, i;
glpoly_t *poly; glpoly_t *poly;
@ -1200,6 +1250,7 @@ void PrecalcVolumesForLight(model_t *model) {
mplane_t *splitplane; mplane_t *splitplane;
int j; int j;
float *v; float *v;
mesh_t *mesh;
surf = shadowchain; surf = shadowchain;
@ -1219,9 +1270,10 @@ void PrecalcVolumesForLight(model_t *model) {
//a. far cap //a. far cap
// volumeCmds[volumePos++] = GL_POLYGON; // volumeCmds[volumePos++] = GL_POLYGON;
volumeCmds[volumePos++] = GL_TRIANGLE_FAN; volumeCmds[volumePos++] = GL_TRIANGLES;
volumeCmds[volumePos++] = surf->numedges; volumeCmds[volumePos++] = poly->numindecies;
//extrude verts
startVerts = (int)vertPos/3; startVerts = (int)vertPos/3;
for (i=0 ; i<surf->numedges ; i++) for (i=0 ; i<surf->numedges ; i++)
{ {
@ -1243,8 +1295,12 @@ void PrecalcVolumesForLight(model_t *model) {
VectorAdd (v1, (*v2) ,vert1); VectorAdd (v1, (*v2) ,vert1);
VectorCopy (vert1, ((vec3_t *)(volumeVerts+vertPos))[0]); VectorCopy (vert1, ((vec3_t *)(volumeVerts+vertPos))[0]);
vertPos+=3; vertPos+=3;
}
volumeCmds[volumePos++] = startVerts+(surf->numedges-(i+1)); //create indexes
for (i=poly->numindecies-1; i>=0; i--)
{
volumeCmds[volumePos++] = startVerts+poly->indecies[i]-poly->firstvertex;
} }
//copy vertices //copy vertices
@ -1269,22 +1325,22 @@ void PrecalcVolumesForLight(model_t *model) {
//we make quad strips if we have continuous borders //we make quad strips if we have continuous borders
lastshadow = false; lastshadow = false;
for (i=0 ; i<surf->numedges ; i++) for (i=0 ; i<poly->numneighbours ; i++)
{ {
mneighbour_t *neigh = &poly->neighbours[i];
shadow = false; shadow = false;
if (poly->neighbours[i] != NULL) { if (neigh->n != NULL) {
if ( poly->neighbours[i]->lightTimestamp != poly->lightTimestamp) { if ( neigh->n->lightTimestamp != poly->lightTimestamp) {
shadow = true; shadow = true;
} }
} else { } else {
shadow = true; shadow = true;
} }
if (shadow) { //if (shadow) {
if (!lastshadow) { // if (!lastshadow) {
//begin new strip //begin new strip
volumeCmds[volumePos++] = GL_QUAD_STRIP; volumeCmds[volumePos++] = GL_QUAD_STRIP;
numPos = volumePos; numPos = volumePos;
@ -1292,23 +1348,23 @@ void PrecalcVolumesForLight(model_t *model) {
stripLen = 2; stripLen = 2;
//copy vertices //copy vertices
volumeCmds[volumePos++] = startNearVerts+i;//-getVertexIndexFromSurf(surf, i, model); volumeCmds[volumePos++] = startNearVerts+neigh->p1-poly->firstvertex;//-getVertexIndexFromSurf(surf, i, model);
volumeCmds[volumePos++] = startVerts+i; volumeCmds[volumePos++] = startVerts+neigh->p1-poly->firstvertex;
} // }
volumeCmds[volumePos++] = startNearVerts+((i+1)%poly->numverts);//-getVertexIndexFromSurf(surf, (i+1)%poly->numverts, model); volumeCmds[volumePos++] = startNearVerts+neigh->p2-poly->firstvertex;//-getVertexIndexFromSurf(surf, (i+1)%poly->numverts, model);
volumeCmds[volumePos++] = startVerts+((i+1)%poly->numverts); volumeCmds[volumePos++] = startVerts+neigh->p2-poly->firstvertex;
stripLen+=2; stripLen+=2;
} else { // } else {
if (lastshadow) { // if (lastshadow) {
//close list up //close list up
volumeCmds[numPos] = stripLen; volumeCmds[numPos] = stripLen;
} // }
} // }
lastshadow = shadow; // lastshadow = shadow;
} }
if (lastshadow) { if (lastshadow) {
@ -1321,15 +1377,20 @@ void PrecalcVolumesForLight(model_t *model) {
break; break;
} }
lightCmds[lightPos++].asVoid = surf;
//c. glow surfaces/texture coordinates //c. glow surfaces/texture coordinates
//leftright vectors of plane //leftright vectors of plane
s = (vec3_t *)&surf->texinfo->vecs[0];
t = (vec3_t *)&surf->texinfo->vecs[1];
/* /*
VectorNormalize(*s); s = (vec3_t *)&surf->tangent;
VectorNormalize(*t); t = (vec3_t *)&surf->binormal;
*/
//VectorNormalize(*s);
//VectorNormalize(*t);
splitplane = surf->plane; splitplane = surf->plane;
@ -1384,6 +1445,7 @@ void PrecalcVolumesForLight(model_t *model) {
lightCmds[lightPos++].asVec = tsLightDir[2]; lightCmds[lightPos++].asVec = tsLightDir[2];
} }
} }
*/
if (lightPos > MAX_LIGHT_COMMANDS) { if (lightPos > MAX_LIGHT_COMMANDS) {
Con_Printf ("More than MAX_LIGHT_COMMANDS commands %i\n", lightPos); Con_Printf ("More than MAX_LIGHT_COMMANDS commands %i\n", lightPos);
break; break;
@ -1392,12 +1454,21 @@ void PrecalcVolumesForLight(model_t *model) {
surf = surf->shadowchain; surf = surf->shadowchain;
} }
lightPosMesh = 0;
mesh = meshshadowchain;
while (mesh) {
lightCmdsMesh[lightPosMesh++].asVoid = mesh;
mesh = mesh->shadowchain;
}
//Con_Printf("used %i\n",volumePos); //Con_Printf("used %i\n",volumePos);
//finish them off with 0 //finish them off with 0
lightCmds[lightPos++].asInt = 0; lightCmds[lightPos++].asVoid = NULL;
lightCmdsMesh[lightPosMesh++].asVoid = NULL;
volumeCmds[volumePos++] = 0; volumeCmds[volumePos++] = 0;
numLightCmds = lightPos; numLightCmds = lightPos;
numLightCmdsMesh = lightPosMesh;
numVolumeCmds = volumePos; numVolumeCmds = volumePos;
numVolumeVerts = vertPos; numVolumeVerts = vertPos;
} }
@ -1459,13 +1530,27 @@ void DrawVolumeFromCmds(int *volumeCmds, lightcmd_t *lightCmds, float *volumeVer
while (1) { while (1) {
/*
command = lightCmds[lightPos++].asInt; command = lightCmds[lightPos++].asInt;
if (command == 0) break; //end of list if (command == 0) break; //end of list
surf = lightCmds[lightPos++].asVoid; surf = lightCmds[lightPos++].asVoid;
lightPos+=4; //skip color lightPos+=4; //skip color
num = surf->polys->numverts; num = surf->polys->numverts;
*/
surf = lightCmds[lightPos++].asVoid;
if (surf == NULL)
break;
glBegin(GL_TRIANGLES);
//v = surf->polys->verts[0];
for (i=0; i<surf->polys->numindecies; i++) {
v = (float *)(&globalVertexTable[surf->polys->indecies[i]]);
glVertex3fv(&v[0]);
}
glEnd();
/*
glBegin(command); glBegin(command);
//v = surf->polys->verts[0]; //v = surf->polys->verts[0];
v = (float *)(&globalVertexTable[surf->polys->firstvertex]); v = (float *)(&globalVertexTable[surf->polys->firstvertex]);
@ -1477,6 +1562,7 @@ void DrawVolumeFromCmds(int *volumeCmds, lightcmd_t *lightCmds, float *volumeVer
glVertex3fv(&v[0]); glVertex3fv(&v[0]);
} }
glEnd(); glEnd();
*/
} }
} }
@ -1896,7 +1982,7 @@ void R_CalcSvBsp(entity_t *ent) {
int i; int i;
msurface_t *surf; msurface_t *surf;
msurface_t *s; msurface_t *s;
texture_t *t; mapshader_t *t;
//Con_Printf("Shadow volumes start\n"); //Con_Printf("Shadow volumes start\n");
@ -1912,6 +1998,7 @@ void R_CalcSvBsp(entity_t *ent) {
|| !strcmp (ent->model->name, "progs/w_light.spr")) || !strcmp (ent->model->name, "progs/w_light.spr"))
{ {
shadowchain = NULL; shadowchain = NULL;
meshshadowchain = NULL;
done++; done++;
Con_Printf("->Light %i\n",done); Con_Printf("->Light %i\n",done);
@ -1966,10 +2053,9 @@ void R_CalcSvBsp(entity_t *ent) {
surf = shadowchain; surf = shadowchain;
//Clear texture chains //Clear texture chains
for (i=0 ; i<cl.worldmodel->numtextures ; i++) for (i=0 ; i<cl.worldmodel->nummapshaders; i++)
{ {
if (!cl.worldmodel->textures[i]) continue; cl.worldmodel->mapshaders[i].texturechain = NULL;
cl.worldmodel->textures[i]->texturechain = NULL;
} }
//Remark polys since polygons may have been removed since the last time stamp //Remark polys since polygons may have been removed since the last time stamp
@ -1978,15 +2064,16 @@ void R_CalcSvBsp(entity_t *ent) {
surf->polys->lightTimestamp = r_lightTimestamp; surf->polys->lightTimestamp = r_lightTimestamp;
currentshadowlight->visSurf[i] = surf; currentshadowlight->visSurf[i] = surf;
//put it in the correct texture chain //put it in the correct texture chain
surf->texturechain = surf->texinfo->texture->texturechain; surf->texturechain = surf->shader->texturechain;
surf->texinfo->texture->texturechain = surf; surf->shader->texturechain = surf;
} }
//Sort surfs in our list per texture //Sort surfs in our list per texture
shadowchain = NULL; shadowchain = NULL;
for (i=0 ; i<cl.worldmodel->numtextures ; i++) //meshshadowchain = NULL;
for (i=0 ; i<cl.worldmodel->nummapshaders ; i++)
{ {
t = cl.worldmodel->textures[i]; t = &cl.worldmodel->mapshaders[i];
if (!t) if (!t)
continue; continue;
s = t->texturechain; s = t->texturechain;
@ -2005,6 +2092,7 @@ void R_CalcSvBsp(entity_t *ent) {
//Recalculate vis for this light //Recalculate vis for this light
currentshadowlight->leaf = Mod_PointInLeaf (currentshadowlight->origin, cl.worldmodel); currentshadowlight->leaf = Mod_PointInLeaf (currentshadowlight->origin, cl.worldmodel);
lightvis = Mod_LeafPVS (currentshadowlight->leaf, cl.worldmodel); lightvis = Mod_LeafPVS (currentshadowlight->leaf, cl.worldmodel);
currentshadowlight->area = currentshadowlight->leaf->area;
Q_memcpy(&currentshadowlight->vis[0], lightvis, MAX_MAP_LEAFS/8); Q_memcpy(&currentshadowlight->vis[0], lightvis, MAX_MAP_LEAFS/8);
Q_memcpy(&currentshadowlight->entvis[0], lightvis, MAX_MAP_LEAFS/8); Q_memcpy(&currentshadowlight->entvis[0], lightvis, MAX_MAP_LEAFS/8);
CutLeafs(currentshadowlight->vis); CutLeafs(currentshadowlight->vis);
@ -2020,6 +2108,12 @@ void R_CalcSvBsp(entity_t *ent) {
currentshadowlight->lightCmds = Hunk_Alloc(4*numLightCmds); currentshadowlight->lightCmds = Hunk_Alloc(4*numLightCmds);
Q_memcpy(currentshadowlight->lightCmds, &lightCmdsBuff, 4*numLightCmds); Q_memcpy(currentshadowlight->lightCmds, &lightCmdsBuff, 4*numLightCmds);
currentshadowlight->numlightcmds = numLightCmds;
currentshadowlight->lightCmdsMesh = Hunk_Alloc(4*numLightCmdsMesh);
Q_memcpy(currentshadowlight->lightCmdsMesh, &lightCmdsBuffMesh, 4*numLightCmdsMesh);
currentshadowlight->numlightcmdsmesh = numLightCmdsMesh;
//Con_Printf("light done\n"); //Con_Printf("light done\n");
} else { } else {
//Con_Printf("thrown away"); //Con_Printf("thrown away");