cvar_t r_shadow_glsl_offsetmapping_bias = {0, "r_shadow_glsl_offsetmapping_bias", "-0.04"};
cvar_t gl_ext_stenciltwoside = {0, "gl_ext_stenciltwoside", "1"};
cvar_t r_editlights = {0, "r_editlights", "0"};
-cvar_t r_editlights_cursordistance = {0, "r_editlights_distance", "1024"};
-cvar_t r_editlights_cursorpushback = {0, "r_editlights_pushback", "0"};
-cvar_t r_editlights_cursorpushoff = {0, "r_editlights_pushoff", "4"};
-cvar_t r_editlights_cursorgrid = {0, "r_editlights_grid", "4"};
+cvar_t r_editlights_cursordistance = {0, "r_editlights_cursordistance", "1024"};
+cvar_t r_editlights_cursorpushback = {0, "r_editlights_cursorpushback", "0"};
+cvar_t r_editlights_cursorpushoff = {0, "r_editlights_cursorpushoff", "4"};
+cvar_t r_editlights_cursorgrid = {0, "r_editlights_cursorgrid", "4"};
cvar_t r_editlights_quakelightsizescale = {CVAR_SAVE, "r_editlights_quakelightsizescale", "0.8"};
cvar_t r_editlights_rtlightssizescale = {CVAR_SAVE, "r_editlights_rtlightssizescale", "0.7"};
cvar_t r_editlights_rtlightscolorscale = {CVAR_SAVE, "r_editlights_rtlightscolorscale", "2"};
return shadowelements;
}
-void R_Shadow_EnlargeClusterBuffer(int numclusters)
+void R_Shadow_EnlargeClusterSurfaceBuffer(int numclusters, int numsurfaces)
{
int numclusterpvsbytes = (((numclusters + 7) >> 3) + 255) & ~255;
+ int numsurfacepvsbytes = (((numsurfaces + 7) >> 3) + 255) & ~255;
if (r_shadow_buffer_numclusterpvsbytes < numclusterpvsbytes)
{
if (r_shadow_buffer_clusterpvs)
r_shadow_buffer_clusterpvs = Mem_Alloc(r_shadow_mempool, r_shadow_buffer_numclusterpvsbytes);
r_shadow_buffer_clusterlist = Mem_Alloc(r_shadow_mempool, r_shadow_buffer_numclusterpvsbytes * 8 * sizeof(*r_shadow_buffer_clusterlist));
}
-}
-
-void R_Shadow_EnlargeSurfaceBuffer(int numsurfaces)
-{
- int numsurfacepvsbytes = (((numsurfaces + 7) >> 3) + 255) & ~255;
if (r_shadow_buffer_numsurfacepvsbytes < numsurfacepvsbytes)
{
if (r_shadow_buffer_surfacepvs)
}
}
-void R_Shadow_RenderLighting(int firstvertex, int numvertices, 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, const float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *basetexture, rtexture_t *bumptexture, rtexture_t *glosstexture, rtexture_t *lightcubemap, vec_t ambientscale, vec_t diffusescale, vec_t specularscale)
+void R_Shadow_RenderLighting(int firstvertex, int numvertices, 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, const float *lightcolorbase, const float *lightcolorpants, const float *lightcolorshirt, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *bumptexture, rtexture_t *glosstexture, rtexture_t *lightcubemap, vec_t ambientscale, vec_t diffusescale, vec_t specularscale)
{
int renders;
float color[3], color2[3], colorscale;
rmeshstate_t m;
- // FIXME: support EF_NODEPTHTEST
- GL_DepthMask(false);
- GL_DepthTest(true);
if (!bumptexture)
bumptexture = r_texture_blanknormalmap;
+ if (!lightcolorbase)
+ lightcolorbase = vec3_origin;
+ if (!lightcolorpants)
+ lightcolorpants = vec3_origin;
+ if (!lightcolorshirt)
+ lightcolorshirt = vec3_origin;
specularscale *= r_shadow_glossintensity.value;
if (!glosstexture)
{
specularscale = 0;
if (!lightcubemap)
lightcubemap = r_shadow_blankwhitecubetexture;
- if (ambientscale + diffusescale + specularscale < 0.01)
+ if ((ambientscale + diffusescale) * (VectorLength2(lightcolorbase) + VectorLength2(lightcolorpants) + VectorLength2(lightcolorshirt)) + specularscale * VectorLength2(lightcolorbase) <= 0.001)
return;
+ // FIXME: support EF_NODEPTHTEST
+ GL_DepthMask(false);
+ GL_DepthTest(true);
if (r_shadow_glsl.integer && r_shadow_program_light[0])
{
unsigned int perm, prog;
qglUniform1fARB(qglGetUniformLocationARB(prog, "SpecularPower"), 8);CHECKGLERROR
qglUniform1fARB(qglGetUniformLocationARB(prog, "SpecularScale"), specularscale);CHECKGLERROR
}
- qglUniform3fARB(qglGetUniformLocationARB(prog, "LightColor"), lightcolor[0], lightcolor[1], lightcolor[2]);CHECKGLERROR
+ qglUniform3fARB(qglGetUniformLocationARB(prog, "LightColor"), lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);CHECKGLERROR
qglUniform3fARB(qglGetUniformLocationARB(prog, "LightPosition"), relativelightorigin[0], relativelightorigin[1], relativelightorigin[2]);CHECKGLERROR
if (perm & (SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_FOG | SHADERPERMUTATION_OFFSETMAPPING))
{
R_Mesh_Draw(firstvertex, numvertices, numtriangles, elements);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
+ // TODO: add direct pants/shirt rendering
+ if (pantstexture && (ambientscale + diffusescale) * VectorLength2(lightcolorpants) > 0.001)
+ {
+ R_Mesh_TexBind(1, R_GetTexture(pantstexture));
+ qglUniform3fARB(qglGetUniformLocationARB(prog, "LightColor"), lightcolorpants[0], lightcolorpants[1], lightcolorpants[2]);CHECKGLERROR
+ R_Mesh_Draw(firstvertex, numvertices, numtriangles, elements);
+ c_rt_lightmeshes++;
+ c_rt_lighttris += numtriangles;
+ }
+ if (shirttexture && (ambientscale + diffusescale) * VectorLength2(lightcolorshirt) > 0.001)
+ {
+ R_Mesh_TexBind(1, R_GetTexture(shirttexture));
+ qglUniform3fARB(qglGetUniformLocationARB(prog, "LightColor"), lightcolorshirt[0], lightcolorshirt[1], lightcolorshirt[2]);CHECKGLERROR
+ R_Mesh_Draw(firstvertex, numvertices, numtriangles, elements);
+ c_rt_lightmeshes++;
+ c_rt_lighttris += numtriangles;
+ }
GL_LockArrays(0, 0);
qglUseProgramObjectARB(0);
// HACK HACK HACK: work around for stupid NVIDIA bug that causes GL_OUT_OF_MEMORY and/or software rendering
}
else if (gl_dot3arb && gl_texturecubemap && gl_combine.integer && gl_stencil)
{
+ // TODO: add direct pants/shirt rendering
+ if (pantstexture && (ambientscale + diffusescale) * VectorLength2(lightcolorpants) > 0.001)
+ R_Shadow_RenderLighting(firstvertex, numvertices, numtriangles, elements, vertex3f, svector3f, tvector3f, normal3f, texcoord2f, relativelightorigin, relativeeyeorigin, lightcolorpants, NULL, NULL, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, pantstexture, NULL, NULL, bumptexture, NULL, lightcubemap, ambientscale, diffusescale, specularscale);
+ if (shirttexture && (ambientscale + diffusescale) * VectorLength2(lightcolorshirt) > 0.001)
+ R_Shadow_RenderLighting(firstvertex, numvertices, numtriangles, elements, vertex3f, svector3f, tvector3f, normal3f, texcoord2f, relativelightorigin, relativeeyeorigin, lightcolorshirt, NULL, NULL, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, shirttexture, NULL, NULL, bumptexture, NULL, lightcubemap, ambientscale, diffusescale, specularscale);
if (!bumptexture)
bumptexture = r_texture_blanknormalmap;
if (!glosstexture)
// this final code is shared
R_Mesh_State(&m);
GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 0);
- VectorScale(lightcolor, colorscale, color2);
+ VectorScale(lightcolorbase, colorscale, color2);
GL_LockArrays(firstvertex, numvertices);
for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
{
// this final code is shared
R_Mesh_State(&m);
GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 0);
- VectorScale(lightcolor, colorscale, color2);
+ VectorScale(lightcolorbase, colorscale, color2);
GL_LockArrays(firstvertex, numvertices);
for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
{
}
R_Mesh_State(&m);
GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 0);
- VectorScale(lightcolor, colorscale, color2);
+ VectorScale(lightcolorbase, colorscale, color2);
GL_LockArrays(firstvertex, numvertices);
for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
{
}
else
{
+ // TODO: add direct pants/shirt rendering
+ if (pantstexture && (ambientscale + diffusescale) * VectorLength2(lightcolorpants) > 0.001)
+ R_Shadow_RenderLighting(firstvertex, numvertices, numtriangles, elements, vertex3f, svector3f, tvector3f, normal3f, texcoord2f, relativelightorigin, relativeeyeorigin, lightcolorpants, NULL, NULL, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, pantstexture, NULL, NULL, bumptexture, NULL, lightcubemap, ambientscale, diffusescale, specularscale);
+ if (shirttexture && (ambientscale + diffusescale) * VectorLength2(lightcolorshirt) > 0.001)
+ R_Shadow_RenderLighting(firstvertex, numvertices, numtriangles, elements, vertex3f, svector3f, tvector3f, normal3f, texcoord2f, relativelightorigin, relativeeyeorigin, lightcolorshirt, NULL, NULL, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, shirttexture, NULL, NULL, bumptexture, NULL, lightcubemap, ambientscale, diffusescale, specularscale);
if (ambientscale)
{
GL_BlendFunc(GL_ONE, GL_ONE);
- VectorScale(lightcolor, ambientscale, color2);
+ VectorScale(lightcolorbase, ambientscale, color2);
memset(&m, 0, sizeof(m));
m.pointer_vertex = vertex3f;
m.tex[0] = R_GetTexture(basetexture);
if (r_textureunits.integer >= 3)
GL_Color(color[0], color[1], color[2], 1);
else if (r_textureunits.integer >= 2)
- R_Shadow_VertexNoShadingWithZAttenuation(numvertices, vertex3f + 3 * firstvertex, color + 3 * firstvertex, matrix_modeltolight);
+ R_Shadow_VertexNoShadingWithZAttenuation(numvertices, vertex3f + 3 * firstvertex, color, matrix_modeltolight);
else
- R_Shadow_VertexNoShadingWithXYZAttenuation(numvertices, vertex3f + 3 * firstvertex, color + 3 * firstvertex, matrix_modeltolight);
+ R_Shadow_VertexNoShadingWithXYZAttenuation(numvertices, vertex3f + 3 * firstvertex, color, matrix_modeltolight);
GL_LockArrays(firstvertex, numvertices);
R_Mesh_Draw(firstvertex, numvertices, numtriangles, elements);
GL_LockArrays(0, 0);
if (diffusescale)
{
GL_BlendFunc(GL_ONE, GL_ONE);
- VectorScale(lightcolor, diffusescale, color2);
+ VectorScale(lightcolorbase, diffusescale, color2);
memset(&m, 0, sizeof(m));
m.pointer_vertex = vertex3f;
m.pointer_color = varray_color4f;
color[1] = bound(0, color2[1], 1);
color[2] = bound(0, color2[2], 1);
if (r_textureunits.integer >= 3)
- R_Shadow_VertexShading(numvertices, vertex3f + 3 * firstvertex, normal3f + 3 * firstvertex, color + 3 * firstvertex, matrix_modeltolight);
+ R_Shadow_VertexShading(numvertices, vertex3f + 3 * firstvertex, normal3f + 3 * firstvertex, color, matrix_modeltolight);
else if (r_textureunits.integer >= 2)
- R_Shadow_VertexShadingWithZAttenuation(numvertices, vertex3f + 3 * firstvertex, normal3f + 3 * firstvertex, color + 3 * firstvertex, matrix_modeltolight);
+ R_Shadow_VertexShadingWithZAttenuation(numvertices, vertex3f + 3 * firstvertex, normal3f + 3 * firstvertex, color, matrix_modeltolight);
else
- R_Shadow_VertexShadingWithXYZAttenuation(numvertices, vertex3f + 3 * firstvertex, normal3f + 3 * firstvertex, color + 3 * firstvertex, matrix_modeltolight);
+ R_Shadow_VertexShadingWithXYZAttenuation(numvertices, vertex3f + 3 * firstvertex, normal3f + 3 * firstvertex, color, matrix_modeltolight);
GL_LockArrays(firstvertex, numvertices);
R_Mesh_Draw(firstvertex, numvertices, numtriangles, elements);
GL_LockArrays(0, 0);
{
// this variable directs the DrawShadowVolume and DrawLight code to capture into the mesh chain instead of rendering
r_shadow_compilingrtlight = rtlight;
- R_Shadow_EnlargeClusterBuffer(model->brush.num_pvsclusters);
- R_Shadow_EnlargeSurfaceBuffer(model->nummodelsurfaces);
+ R_Shadow_EnlargeClusterSurfaceBuffer(model->brush.num_pvsclusters, model->nummodelsurfaces);
model->GetLightInfo(ent, rtlight->shadoworigin, rtlight->radius, rtlight->cullmins, rtlight->cullmaxs, r_shadow_buffer_clusterlist, r_shadow_buffer_clusterpvs, &numclusters, r_shadow_buffer_surfacelist, r_shadow_buffer_surfacepvs, &numsurfaces);
rtlight->static_numclusterpvsbytes = (model->brush.num_pvsclusters + 7) >> 3;
rtlight->static_clusterpvs = Mem_Alloc(r_shadow_mempool, rtlight->static_numclusterpvsbytes);
if (R_CullBox(cullmins, cullmaxs))
return;
// calculate lit surfaces and clusters
- R_Shadow_EnlargeClusterBuffer(r_refdef.worldmodel->brush.num_pvsclusters);
- R_Shadow_EnlargeSurfaceBuffer(r_refdef.worldmodel->nummodelsurfaces);
- r_refdef.worldmodel->GetLightInfo(&cl_entities[0].render, rtlight->shadoworigin, rtlight->radius, cullmins, cullmaxs, r_shadow_buffer_clusterlist, r_shadow_buffer_clusterpvs, &numclusters, r_shadow_buffer_surfacelist, r_shadow_buffer_surfacepvs, &numsurfaces);
+ R_Shadow_EnlargeClusterSurfaceBuffer(r_refdef.worldmodel->brush.num_pvsclusters, r_refdef.worldmodel->nummodelsurfaces);
+ r_refdef.worldmodel->GetLightInfo(r_refdef.worldentity, rtlight->shadoworigin, rtlight->radius, cullmins, cullmaxs, r_shadow_buffer_clusterlist, r_shadow_buffer_clusterpvs, &numclusters, r_shadow_buffer_surfacelist, r_shadow_buffer_surfacepvs, &numsurfaces);
clusterlist = r_shadow_buffer_clusterlist;
clusterpvs = r_shadow_buffer_clusterpvs;
surfacelist = r_shadow_buffer_surfacelist;
R_Shadow_Stage_ShadowVolumes();
usestencil = true;
}
- ent = &cl_entities[0].render;
+ ent = r_refdef.worldentity;
if (r_shadow_staticworldlights.integer && rtlight->compiled)
{
memset(&m, 0, sizeof(m));
{
R_Shadow_Stage_Light(usestencil);
- ent = &cl_entities[0].render;
+ ent = r_refdef.worldentity;
if (ent->model && ent->model->DrawLight && (ent->flags & RENDER_LIGHT))
{
lightcolor2[0] = lightcolor[0] * ent->colormod[0] * ent->alpha;
{
R_Mesh_Matrix(&ent->matrix);
for (mesh = rtlight->static_meshchain_light;mesh;mesh = mesh->next)
- R_Shadow_RenderLighting(0, mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoord2f, relativelightorigin, relativeeyeorigin, lightcolor2, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, mesh->map_diffuse, mesh->map_normal, mesh->map_specular, cubemaptexture, rtlight->ambientscale, rtlight->diffusescale, rtlight->specularscale);
+ R_Shadow_RenderLighting(0, mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoord2f, relativelightorigin, relativeeyeorigin, lightcolor2, NULL, NULL, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, mesh->map_diffuse, NULL, NULL, mesh->map_normal, mesh->map_specular, cubemaptexture, rtlight->ambientscale, rtlight->diffusescale, rtlight->specularscale);
}
else
ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, rtlight->radius, lightcolor2, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, cubemaptexture, rtlight->ambientscale, rtlight->diffusescale, rtlight->specularscale, numsurfaces, surfacelist);
for (i = 0;i < 5;i++)
{
lighttextures[i] = NULL;
- if ((pic = Draw_CachePic(va("gfx/crosshair%i.tga", i + 1))))
+ if ((pic = Draw_CachePic(va("gfx/crosshair%i.tga", i + 1), true)))
lighttextures[i] = pic->tex;
}
{
bufmaxchars = bufchars + strlen(line) + 2048;
oldbuf = buf;
- buf = Mem_Alloc(r_shadow_mempool, bufmaxchars);
+ buf = Mem_Alloc(tempmempool, bufmaxchars);
if (oldbuf)
{
if (bufchars)