cvar_t r_shadow_realtime_dlight = {0, "r_shadow_realtime_dlight", "0"};
cvar_t r_shadow_visiblevolumes = {0, "r_shadow_visiblevolumes", "0"};
cvar_t r_shadow_gloss = {0, "r_shadow_gloss", "1"};
+cvar_t r_shadow_glossintensity = {0, "r_shadow_glossintensity", "1"};
+cvar_t r_shadow_gloss2intensity = {0, "r_shadow_gloss2intensity", "0.25"};
cvar_t r_shadow_debuglight = {0, "r_shadow_debuglight", "-1"};
cvar_t r_shadow_scissor = {0, "r_shadow_scissor", "1"};
cvar_t r_shadow_bumpscale_bumpmap = {0, "r_shadow_bumpscale_bumpmap", "4"};
Cvar_RegisterVariable(&r_shadow_realtime_dlight);
Cvar_RegisterVariable(&r_shadow_visiblevolumes);
Cvar_RegisterVariable(&r_shadow_gloss);
+ Cvar_RegisterVariable(&r_shadow_glossintensity);
+ Cvar_RegisterVariable(&r_shadow_gloss2intensity);
Cvar_RegisterVariable(&r_shadow_debuglight);
Cvar_RegisterVariable(&r_shadow_scissor);
Cvar_RegisterVariable(&r_shadow_bumpscale_bumpmap);
return shadowelements;
}
+/*
+// readable version of some code found below
+//if ((t >= trianglerange_start && t < trianglerange_end) ? (t < i && !trianglefacinglight[t]) : (t < 0 || (te = inelement3i + t * 3, v[0] = invertex3f + te[0] * 3, v[1] = invertex3f + te[1] * 3, v[2] = invertex3f + te[2] * 3, !PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2]))))
+int PointInfrontOfTriangle(const float *p, const float *a, const float *b, const float *c)
+{
+ float dir0[3], dir1[3], normal[3];
+
+ // calculate two mostly perpendicular edge directions
+ VectorSubtract(a, b, dir0);
+ VectorSubtract(c, b, dir1);
+
+ // we have two edge directions, we can calculate a third vector from
+ // them, which is the direction of the surface normal (it's magnitude
+ // is not 1 however)
+ CrossProduct(dir0, dir1, normal);
+
+ // compare distance of light along normal, with distance of any point
+ // of the triangle along the same normal (the triangle is planar,
+ // I.E. flat, so all points give the same answer)
+ return DotProduct(p, normal) > DotProduct(a, normal);
+}
+int checkcastshadowfromedge(int t, int i)
+{
+ int *te;
+ float *v[3];
+ if (t >= trianglerange_start && t < trianglerange_end)
+ {
+ if (t < i && !trianglefacinglight[t])
+ return true;
+ else
+ return false;
+ }
+ else
+ {
+ if (t < 0)
+ return true;
+ else
+ {
+ te = inelement3i + t * 3;
+ v[0] = invertex3f + te[0] * 3;
+ v[1] = invertex3f + te[1] * 3;
+ v[2] = invertex3f + te[2] * 3;
+ if (!PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2]))))
+ return true;
+ else
+ return false;
+ }
+ }
+}
+*/
+
int R_Shadow_ConstructShadowVolume(int innumvertices, int trianglerange_start, int trianglerange_end, const int *inelement3i, const int *inneighbor3i, const float *invertex3f, int *outnumvertices, int *outelement3i, float *outvertex3f, const float *relativelightorigin, float projectdistance)
{
int i, j, tris = 0, numfacing = 0, vr[3], t, outvertices = 0;
if (r_shadow_texture3d.integer && !gl_texture3d)
Cvar_SetValueQuick(&r_shadow_texture3d, 0);
- //cl.worldmodel->numlights = min(cl.worldmodel->numlights, 1);
+ //cl.worldmodel->brushq1.numlights = min(cl.worldmodel->brushq1.numlights, 1);
if (!r_shadow_attenuation2dtexture
|| (!r_shadow_attenuation3dtexture && r_shadow_texture3d.integer)
|| r_shadow_lightattenuationpower.value != r_shadow_attenpower
void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elements, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const float *texcoord2f, const float *relativelightorigin, const float *relativeeyeorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *glosstexture, rtexture_t *bumptexture, rtexture_t *lightcubemap)
{
int renders;
- float color[3], color2[3];
+ float color[3], color2[3], colorscale;
rmeshstate_t m;
if (!gl_dot3arb || !gl_texturecubemap || !gl_combine.integer || !gl_stencil)
return;
- if (!bumptexture)
- bumptexture = r_shadow_blankbumptexture;
if (!glosstexture)
glosstexture = r_shadow_blankglosstexture;
if (r_shadow_gloss.integer >= 2 || (r_shadow_gloss.integer >= 1 && glosstexture != r_shadow_blankglosstexture))
{
+ colorscale = r_colorscale * r_shadow_glossintensity.value;
+ if (!bumptexture)
+ bumptexture = r_shadow_blankbumptexture;
+ if (glosstexture == r_shadow_blankglosstexture)
+ colorscale *= r_shadow_gloss2intensity.value;
GL_VertexPointer(vertex3f);
GL_Color(1,1,1,1);
if (r_shadow_texture3d.integer && r_textureunits.integer >= 2 && lightcubemap /*&& gl_support_blendsquare*/) // FIXME: detect blendsquare!
GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
if (lightcubemap)
R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
- VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value * 0.25f, color2);
+ VectorScale(lightcolor, colorscale, color2);
for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
{
color[0] = bound(0, color2[0], 1);
qglColorMask(1,1,1,0);
GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltoattenuationxyz);
- VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value * 0.25f, color2);
+ VectorScale(lightcolor, colorscale, color2);
for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
{
color[0] = bound(0, color2[0], 1);
GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
if (lightcubemap)
R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
- VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value * 0.25f, color2);
+ VectorScale(lightcolor, colorscale, color2);
for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
{
color[0] = bound(0, color2[0], 1);
if (cl.worldmodel)
{
castshadowcount++;
- i = cl.worldmodel->PointContents(cl.worldmodel, e->origin);
+ i = CL_PointContents(e->origin);
if (r_shadow_portallight.integer && i != CONTENTS_SOLID && i != CONTENTS_SKY)
{
qbyte *byteleafpvs;
qbyte *bytesurfacepvs;
- byteleafpvs = Mem_Alloc(tempmempool, cl.worldmodel->numleafs + 1);
- bytesurfacepvs = Mem_Alloc(tempmempool, cl.worldmodel->numsurfaces);
+ byteleafpvs = Mem_Alloc(tempmempool, cl.worldmodel->brushq1.numleafs + 1);
+ bytesurfacepvs = Mem_Alloc(tempmempool, cl.worldmodel->brushq1.numsurfaces);
Portal_Visibility(cl.worldmodel, e->origin, byteleafpvs, bytesurfacepvs, NULL, 0, true, RadiusFromBoundsAndOrigin(e->mins, e->maxs, e->origin));
- for (i = 0, leaf = cl.worldmodel->leafs + 1;i < cl.worldmodel->numleafs;i++, leaf++)
+ for (i = 0, leaf = cl.worldmodel->brushq1.leafs + 1;i < cl.worldmodel->brushq1.numleafs;i++, leaf++)
if (byteleafpvs[i+1] && BoxesOverlap(leaf->mins, leaf->maxs, e->mins, e->maxs))
leaf->worldnodeframe = castshadowcount;
- for (i = 0, surf = cl.worldmodel->surfaces;i < cl.worldmodel->numsurfaces;i++, surf++)
+ for (i = 0, surf = cl.worldmodel->brushq1.surfaces;i < cl.worldmodel->brushq1.numsurfaces;i++, surf++)
if (bytesurfacepvs[i] && BoxesOverlap(surf->poly_mins, surf->poly_maxs, e->mins, e->maxs))
surf->castshadow = castshadowcount;
}
else
{
- leaf = cl.worldmodel->PointInLeaf(cl.worldmodel, origin);
- pvs = cl.worldmodel->LeafPVS(cl.worldmodel, leaf);
- for (i = 0, leaf = cl.worldmodel->leafs + 1;i < cl.worldmodel->numleafs;i++, leaf++)
+ leaf = cl.worldmodel->brushq1.PointInLeaf(cl.worldmodel, origin);
+ pvs = cl.worldmodel->brushq1.LeafPVS(cl.worldmodel, leaf);
+ for (i = 0, leaf = cl.worldmodel->brushq1.leafs + 1;i < cl.worldmodel->brushq1.numleafs;i++, leaf++)
{
if (pvs[i >> 3] & (1 << (i & 7)) && BoxesOverlap(leaf->mins, leaf->maxs, e->mins, e->maxs))
{
leaf->worldnodeframe = castshadowcount;
for (j = 0, mark = leaf->firstmarksurface;j < leaf->nummarksurfaces;j++, mark++)
{
- surf = cl.worldmodel->surfaces + *mark;
+ surf = cl.worldmodel->brushq1.surfaces + *mark;
if (surf->castshadow != castshadowcount && BoxesOverlap(surf->poly_mins, surf->poly_maxs, e->mins, e->maxs))
surf->castshadow = castshadowcount;
}
}
e->numleafs = 0;
- for (i = 0, leaf = cl.worldmodel->leafs + 1;i < cl.worldmodel->numleafs;i++, leaf++)
+ for (i = 0, leaf = cl.worldmodel->brushq1.leafs + 1;i < cl.worldmodel->brushq1.numleafs;i++, leaf++)
if (leaf->worldnodeframe == castshadowcount)
e->numleafs++;
e->numsurfaces = 0;
- for (i = 0, surf = cl.worldmodel->surfaces + cl.worldmodel->firstmodelsurface;i < cl.worldmodel->nummodelsurfaces;i++, surf++)
+ for (i = 0, surf = cl.worldmodel->brushq1.surfaces + cl.worldmodel->brushq1.firstmodelsurface;i < cl.worldmodel->brushq1.nummodelsurfaces;i++, surf++)
if (surf->castshadow == castshadowcount)
e->numsurfaces++;
if (e->numsurfaces)
e->surfaces = Mem_Alloc(r_shadow_mempool, e->numsurfaces * sizeof(msurface_t *));
e->numleafs = 0;
- for (i = 0, leaf = cl.worldmodel->leafs + 1;i < cl.worldmodel->numleafs;i++, leaf++)
+ for (i = 0, leaf = cl.worldmodel->brushq1.leafs + 1;i < cl.worldmodel->brushq1.numleafs;i++, leaf++)
if (leaf->worldnodeframe == castshadowcount)
e->leafs[e->numleafs++] = leaf;
e->numsurfaces = 0;
- for (i = 0, surf = cl.worldmodel->surfaces + cl.worldmodel->firstmodelsurface;i < cl.worldmodel->nummodelsurfaces;i++, surf++)
+ for (i = 0, surf = cl.worldmodel->brushq1.surfaces + cl.worldmodel->brushq1.firstmodelsurface;i < cl.worldmodel->brushq1.nummodelsurfaces;i++, surf++)
if (surf->castshadow == castshadowcount)
e->surfaces[e->numsurfaces++] = surf;
Con_Printf("No map loaded.\n");
return;
}
- data = cl.worldmodel->entities;
+ data = cl.worldmodel->brush.entities;
if (!data)
return;
- for (entnum = 0;COM_ParseToken(&data) && com_token[0] == '{';entnum++)
+ for (entnum = 0;COM_ParseToken(&data, false) && com_token[0] == '{';entnum++)
{
light = 0;
origin[0] = origin[1] = origin[2] = 0;
islight = false;
while (1)
{
- if (!COM_ParseToken(&data))
+ if (!COM_ParseToken(&data, false))
break; // error
if (com_token[0] == '}')
break; // end of entity
strcpy(key, com_token);
while (key[strlen(key)-1] == ' ') // remove trailing spaces
key[strlen(key)-1] = 0;
- if (!COM_ParseToken(&data))
+ if (!COM_ParseToken(&data, false))
break; // error
strcpy(value, com_token);