rtexture_t *r_shadow_normalcubetexture;
rtexture_t *r_shadow_attenuation2dtexture;
rtexture_t *r_shadow_attenuation3dtexture;
-rtexture_t *r_shadow_blankbumptexture;
-rtexture_t *r_shadow_blankglosstexture;
-rtexture_t *r_shadow_blankwhitetexture;
rtexture_t *r_shadow_blankwhitecubetexture;
-rtexture_t *r_shadow_blankblacktexture;
// lights are reloaded when this changes
char r_shadow_mapname[MAX_QPATH];
r_shadow_normalcubetexture = NULL;
r_shadow_attenuation2dtexture = NULL;
r_shadow_attenuation3dtexture = NULL;
- r_shadow_blankbumptexture = NULL;
- r_shadow_blankglosstexture = NULL;
- r_shadow_blankwhitetexture = NULL;
r_shadow_blankwhitecubetexture = NULL;
- r_shadow_blankblacktexture = NULL;
r_shadow_texturepool = NULL;
r_shadow_filters_texturepool = NULL;
R_Shadow_ValidateCvars();
r_shadow_normalcubetexture = NULL;
r_shadow_attenuation2dtexture = NULL;
r_shadow_attenuation3dtexture = NULL;
- r_shadow_blankbumptexture = NULL;
- r_shadow_blankglosstexture = NULL;
- r_shadow_blankwhitetexture = NULL;
r_shadow_blankwhitecubetexture = NULL;
- r_shadow_blankblacktexture = NULL;
R_FreeTexturePool(&r_shadow_texturepool);
R_FreeTexturePool(&r_shadow_filters_texturepool);
maxshadowelements = 0;
int R_Shadow_ConstructShadowVolume(int innumvertices, int innumtris, const int *inelement3i, const int *inneighbor3i, const float *invertex3f, int *outnumvertices, int *outelement3i, float *outvertex3f, const float *projectorigin, float projectdistance, int numshadowmarktris, const int *shadowmarktris)
{
- int i, j, tris = 0, vr[3], t, outvertices = 0;
- float f, temp[3];
- const int *e, *n;
- const float *v;
+ int i, j;
+ int outtriangles = 0, outvertices = 0;
+ const int *element;
+ const float *vertex;
if (maxvertexupdate < innumvertices)
{
for (i = 0;i < numshadowmarktris;i++)
{
- t = shadowmarktris[i];
- e = inelement3i + t * 3;
+ element = inelement3i + shadowmarktris[i] * 3;
// make sure the vertices are created
for (j = 0;j < 3;j++)
{
- if (vertexupdate[e[j]] != vertexupdatenum)
+ if (vertexupdate[element[j]] != vertexupdatenum)
{
- vertexupdate[e[j]] = vertexupdatenum;
- vertexremap[e[j]] = outvertices;
- v = invertex3f + e[j] * 3;
+ float ratio, direction[3];
+ vertexupdate[element[j]] = vertexupdatenum;
+ vertexremap[element[j]] = outvertices;
+ vertex = invertex3f + element[j] * 3;
// project one copy of the vertex to the sphere radius of the light
// (FIXME: would projecting it to the light box be better?)
- VectorSubtract(v, projectorigin, temp);
- f = projectdistance / VectorLength(temp);
- VectorCopy(v, outvertex3f);
- VectorMA(projectorigin, f, temp, (outvertex3f + 3));
+ VectorSubtract(vertex, projectorigin, direction);
+ ratio = projectdistance / VectorLength(direction);
+ VectorCopy(vertex, outvertex3f);
+ VectorMA(projectorigin, ratio, direction, (outvertex3f + 3));
outvertex3f += 6;
outvertices += 2;
}
for (i = 0;i < numshadowmarktris;i++)
{
- t = shadowmarktris[i];
- e = inelement3i + t * 3;
- n = inneighbor3i + t * 3;
+ int remappedelement[3];
+ int markindex;
+ const int *neighbortriangle;
+
+ markindex = shadowmarktris[i] * 3;
+ element = inelement3i + markindex;
+ neighbortriangle = inneighbor3i + markindex;
// output the front and back triangles
- outelement3i[0] = vertexremap[e[0]];
- outelement3i[1] = vertexremap[e[1]];
- outelement3i[2] = vertexremap[e[2]];
- outelement3i[3] = vertexremap[e[2]] + 1;
- outelement3i[4] = vertexremap[e[1]] + 1;
- outelement3i[5] = vertexremap[e[0]] + 1;
+ outelement3i[0] = vertexremap[element[0]];
+ outelement3i[1] = vertexremap[element[1]];
+ outelement3i[2] = vertexremap[element[2]];
+ outelement3i[3] = vertexremap[element[2]] + 1;
+ outelement3i[4] = vertexremap[element[1]] + 1;
+ outelement3i[5] = vertexremap[element[0]] + 1;
+
outelement3i += 6;
- tris += 2;
+ outtriangles += 2;
// output the sides (facing outward from this triangle)
- if (shadowmark[n[0]] != shadowmarkcount)
+ if (shadowmark[neighbortriangle[0]] != shadowmarkcount)
{
- vr[0] = vertexremap[e[0]];
- vr[1] = vertexremap[e[1]];
- outelement3i[0] = vr[1];
- outelement3i[1] = vr[0];
- outelement3i[2] = vr[0] + 1;
- outelement3i[3] = vr[1];
- outelement3i[4] = vr[0] + 1;
- outelement3i[5] = vr[1] + 1;
+ remappedelement[0] = vertexremap[element[0]];
+ remappedelement[1] = vertexremap[element[1]];
+ outelement3i[0] = remappedelement[1];
+ outelement3i[1] = remappedelement[0];
+ outelement3i[2] = remappedelement[0] + 1;
+ outelement3i[3] = remappedelement[1];
+ outelement3i[4] = remappedelement[0] + 1;
+ outelement3i[5] = remappedelement[1] + 1;
+
outelement3i += 6;
- tris += 2;
+ outtriangles += 2;
}
- if (shadowmark[n[1]] != shadowmarkcount)
+ if (shadowmark[neighbortriangle[1]] != shadowmarkcount)
{
- vr[1] = vertexremap[e[1]];
- vr[2] = vertexremap[e[2]];
- outelement3i[0] = vr[2];
- outelement3i[1] = vr[1];
- outelement3i[2] = vr[1] + 1;
- outelement3i[3] = vr[2];
- outelement3i[4] = vr[1] + 1;
- outelement3i[5] = vr[2] + 1;
+ remappedelement[1] = vertexremap[element[1]];
+ remappedelement[2] = vertexremap[element[2]];
+ outelement3i[0] = remappedelement[2];
+ outelement3i[1] = remappedelement[1];
+ outelement3i[2] = remappedelement[1] + 1;
+ outelement3i[3] = remappedelement[2];
+ outelement3i[4] = remappedelement[1] + 1;
+ outelement3i[5] = remappedelement[2] + 1;
+
outelement3i += 6;
- tris += 2;
+ outtriangles += 2;
}
- if (shadowmark[n[2]] != shadowmarkcount)
+ if (shadowmark[neighbortriangle[2]] != shadowmarkcount)
{
- vr[0] = vertexremap[e[0]];
- vr[2] = vertexremap[e[2]];
- outelement3i[0] = vr[0];
- outelement3i[1] = vr[2];
- outelement3i[2] = vr[2] + 1;
- outelement3i[3] = vr[0];
- outelement3i[4] = vr[2] + 1;
- outelement3i[5] = vr[0] + 1;
+ remappedelement[0] = vertexremap[element[0]];
+ remappedelement[2] = vertexremap[element[2]];
+ outelement3i[0] = remappedelement[0];
+ outelement3i[1] = remappedelement[2];
+ outelement3i[2] = remappedelement[2] + 1;
+ outelement3i[3] = remappedelement[0];
+ outelement3i[4] = remappedelement[2] + 1;
+ outelement3i[5] = remappedelement[0] + 1;
+
outelement3i += 6;
- tris += 2;
+ outtriangles += 2;
}
}
if (outnumvertices)
*outnumvertices = outvertices;
- return tris;
+ return outtriangles;
}
void R_Shadow_VolumeFromList(int numverts, int numtris, const float *invertex3f, const int *elements, const int *neighbors, const vec3_t projectorigin, float projectdistance, int nummarktris, const int *marktris)
R_Shadow_RenderVolume(outverts, tris, varray_vertex3f2, shadowelements);
}
-void R_Shadow_MarkVolumeFromBox(int firsttriangle, int numtris, const float *invertex3f, const int *elements, const vec3_t projectorigin, vec3_t lightmins, vec3_t lightmaxs, vec3_t surfacemins, vec3_t surfacemaxs)
+void R_Shadow_MarkVolumeFromBox(int firsttriangle, int numtris, const float *invertex3f, const int *elements, const vec3_t projectorigin, const vec3_t lightmins, const vec3_t lightmaxs, const vec3_t surfacemins, const vec3_t surfacemaxs)
{
int t, tend;
const int *e;
#define ATTEN2DSIZE 64
#define ATTEN3DSIZE 32
data = Mem_Alloc(tempmempool, max(6*NORMSIZE*NORMSIZE*4, max(ATTEN3DSIZE*ATTEN3DSIZE*ATTEN3DSIZE*4, ATTEN2DSIZE*ATTEN2DSIZE*4)));
- data[0] = 128; // normal X
- data[1] = 128; // normal Y
- data[2] = 255; // normal Z
- data[3] = 128; // height
- r_shadow_blankbumptexture = R_LoadTexture2D(r_shadow_texturepool, "blankbump", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
- data[0] = 255;
- data[1] = 255;
- data[2] = 255;
- data[3] = 255;
- r_shadow_blankglosstexture = R_LoadTexture2D(r_shadow_texturepool, "blankgloss", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
- data[0] = 255;
- data[1] = 255;
- data[2] = 255;
- data[3] = 255;
- r_shadow_blankwhitetexture = R_LoadTexture2D(r_shadow_texturepool, "blankwhite", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
- data[0] = 0;
- data[1] = 0;
- data[2] = 0;
- data[3] = 255;
- r_shadow_blankblacktexture = R_LoadTexture2D(r_shadow_texturepool, "blankblack", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
r_shadow_blankwhitecubetexture = NULL;
r_shadow_normalcubetexture = NULL;
if (gl_texturecubemap)
GL_DepthMask(false);
GL_DepthTest(true);
if (!bumptexture)
- bumptexture = r_shadow_blankbumptexture;
+ bumptexture = r_texture_blanknormalmap;
specularscale *= r_shadow_glossintensity.value;
if (!glosstexture)
{
if (r_shadow_gloss.integer >= 2)
{
- glosstexture = r_shadow_blankglosstexture;
+ glosstexture = r_texture_white;
specularscale *= r_shadow_gloss2intensity.value;
}
else
{
- glosstexture = r_shadow_blankblacktexture;
+ glosstexture = r_texture_black;
specularscale = 0;
}
}
m.tex[2] = R_GetTexture(glosstexture);
m.texcubemap[3] = R_GetTexture(lightcubemap);
// TODO: support fog (after renderer is converted to texture fog)
- m.tex[4] = R_GetTexture(r_shadow_blankwhitetexture);
+ m.tex[4] = R_GetTexture(r_texture_white);
m.texmatrix[3] = *matrix_modeltolight;
R_Mesh_State(&m);
GL_BlendFunc(GL_ONE, GL_ONE);
else if (gl_dot3arb && gl_texturecubemap && gl_combine.integer && gl_stencil)
{
if (!bumptexture)
- bumptexture = r_shadow_blankbumptexture;
+ bumptexture = r_texture_blanknormalmap;
if (!glosstexture)
- glosstexture = r_shadow_blankglosstexture;
+ glosstexture = r_texture_white;
if (ambientscale)
{
GL_Color(1,1,1,1);
}
GL_LockArrays(0, 0);
}
- if (specularscale && glosstexture != r_shadow_blankblacktexture)
+ if (specularscale && glosstexture != r_texture_black)
{
// FIXME: detect blendsquare!
//if (gl_support_blendsquare)
void R_RTLight_Compile(rtlight_t *rtlight)
{
int shadowmeshes, shadowtris, lightmeshes, lighttris, numclusters, numsurfaces;
- entity_render_t *ent = &cl_entities[0].render;
- model_t *model = ent->model;
+ entity_render_t *ent = r_refdef.worldentity;
+ model_t *model = r_refdef.worldmodel;
// compile the light
rtlight->compiled = true;
if (model->DrawShadowVolume && rtlight->shadow)
{
rtlight->static_meshchain_shadow = Mod_ShadowMesh_Begin(r_shadow_mempool, 32768, 32768, NULL, NULL, NULL, false, false, true);
- model->DrawShadowVolume(ent, rtlight->shadoworigin, rtlight->radius, numsurfaces, r_shadow_buffer_surfacelist);
+ model->DrawShadowVolume(ent, rtlight->shadoworigin, rtlight->radius, numsurfaces, r_shadow_buffer_surfacelist, rtlight->cullmins, rtlight->cullmaxs);
rtlight->static_meshchain_shadow = Mod_ShadowMesh_Finish(r_shadow_mempool, rtlight->static_meshchain_shadow, false, false);
}
if (model->DrawLight)
int numclusters, numsurfaces;
int *clusterlist, *surfacelist;
qbyte *clusterpvs;
- vec3_t cullmins, cullmaxs;
+ vec3_t cullmins, cullmaxs, relativelightmins, relativelightmaxs;
shadowmesh_t *mesh;
rmeshstate_t m;
if (numclusters)
{
for (i = 0;i < numclusters;i++)
- if (r_worldleafvisible[clusterlist[i]])
+ if (CHECKPVSBIT(r_pvsbits, clusterlist[i]))
break;
if (i == numclusters)
return;
else if (numsurfaces)
{
Matrix4x4_Transform(&ent->inversematrix, rtlight->shadoworigin, relativelightorigin);
- ent->model->DrawShadowVolume(ent, relativelightorigin, rtlight->radius, numsurfaces, surfacelist);
+ ent->model->DrawShadowVolume(ent, relativelightorigin, rtlight->radius, numsurfaces, surfacelist, rtlight->cullmins, rtlight->cullmaxs);
}
if (r_drawentities.integer)
{
// light emitting entities should not cast their own shadow
if (VectorLength2(relativelightorigin) < 0.1)
continue;
- ent->model->DrawShadowVolume(ent, relativelightorigin, rtlight->radius, ent->model->nummodelsurfaces, ent->model->surfacelist);
+ relativelightmins[0] = relativelightorigin[0] - rtlight->radius;
+ relativelightmins[1] = relativelightorigin[1] - rtlight->radius;
+ relativelightmins[2] = relativelightorigin[2] - rtlight->radius;
+ relativelightmaxs[0] = relativelightorigin[0] + rtlight->radius;
+ relativelightmaxs[1] = relativelightorigin[1] + rtlight->radius;
+ relativelightmaxs[2] = relativelightorigin[2] + rtlight->radius;
+ ent->model->DrawShadowVolume(ent, relativelightorigin, rtlight->radius, ent->model->nummodelsurfaces, ent->model->surfacelist, relativelightmins, relativelightmaxs);
}
}
}