{
VectorCopy(neworg, v);
// hack to make glowing player light shine on their gun
- if (i == cl.viewentity && !chase_active.integer)
+ if (i == cl.viewentity/* && !chase_active.integer*/)
v[2] += 30;
CL_AllocDlight (&ent->render, v, 1, dlightcolor[0], dlightcolor[1], dlightcolor[2], 0, 0);
}
{
unsigned int t1d, t2d, t3d, tcubemap;
unsigned int arrayenabled;
- float rgbscale;
+ float rgbscale, alphascale;
int combinergb, combinealpha;
// FIXME: add more combine stuff
}
unit->t3d = 0;
unit->tcubemap = 0;
unit->rgbscale = 1;
+ unit->alphascale = 1;
unit->combinergb = GL_MODULATE;
unit->combinealpha = GL_MODULATE;
unit->arrayenabled = false;
if (gl_combine.integer)
{
qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1);CHECKGLERROR
+ qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1);CHECKGLERROR
}
}
qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
void R_Mesh_TextureState(const rmeshstate_t *m)
{
int i, combinergb, combinealpha;
- float rgbscale;
+ float scale;
gltextureunit_t *unit;
BACKENDACTIVECHECK
qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, (unit->tcubemap = m->texcubemap[i]));CHECKGLERROR
}
}
- rgbscale = max(m->texrgbscale[i], 1);
- if (gl_state.units[i].rgbscale != rgbscale)
+ scale = max(m->texrgbscale[i], 1);
+ if (gl_state.units[i].rgbscale != scale)
+ {
+ if (gl_state.unit != i)
+ {
+ qglActiveTexture(GL_TEXTURE0_ARB + (gl_state.unit = i));CHECKGLERROR
+ }
+ qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, (gl_state.units[i].rgbscale = scale));CHECKGLERROR
+ }
+ scale = max(m->texalphascale[i], 1);
+ if (gl_state.units[i].alphascale != scale)
{
if (gl_state.unit != i)
{
qglActiveTexture(GL_TEXTURE0_ARB + (gl_state.unit = i));CHECKGLERROR
}
- qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, (gl_state.units[i].rgbscale = rgbscale));CHECKGLERROR
+ qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, (gl_state.units[i].alphascale = scale));CHECKGLERROR
}
}
}
// clear to black
qglClearColor(0,0,0,0);CHECKGLERROR
// clear the screen
- qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);CHECKGLERROR
+ qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | (gl_stencil ? GL_STENCIL_BUFFER_BIT : 0));CHECKGLERROR
// set dithering mode
if (gl_dither.integer)
{
int tex3d[MAX_TEXTUREUNITS];
int texcubemap[MAX_TEXTUREUNITS];
int texrgbscale[MAX_TEXTUREUNITS]; // used only if COMBINE is present
+ int texalphascale[MAX_TEXTUREUNITS]; // used only if COMBINE is present
int texcombinergb[MAX_TEXTUREUNITS]; // works with or without combine for some operations
int texcombinealpha[MAX_TEXTUREUNITS]; // does nothing without combine
}
varray_texcoord[0][i + 1] *= 8.0f;
}
R_LightModel(ent, model->numverts, varray_vertex, aliasvert_normals, varray_color, colorscale, colorscale, colorscale, false);
- GL_UseColorArray();
R_Mesh_Draw(model->numverts, model->numtris, model->mdlmd2data_indices);
return;
}
if (fullbright)
GL_Color(colorscale * ifog, colorscale * ifog, colorscale * ifog, ent->alpha);
else
- {
- GL_UseColorArray();
R_LightModel(ent, model->numverts, varray_vertex, aliasvert_normals, varray_color, colorscale * ifog, colorscale * ifog, colorscale * ifog, false);
- }
R_Mesh_Draw(model->numverts, model->numtris, model->mdlmd2data_indices);
c_alias_polys += model->numtris;
blendfunc1 = GL_SRC_ALPHA;
if (pantsfullbright)
GL_Color(pantscolor[0] * colorscale * ifog, pantscolor[1] * colorscale * ifog, pantscolor[2] * colorscale * ifog, ent->alpha);
else
- {
- GL_UseColorArray();
R_LightModel(ent, model->numverts, varray_vertex, aliasvert_normals, varray_color, pantscolor[0] * colorscale * ifog, pantscolor[1] * colorscale * ifog, pantscolor[2] * colorscale * ifog, false);
- }
R_Mesh_Draw(model->numverts, model->numtris, model->mdlmd2data_indices);
c_alias_polys += model->numtris;
blendfunc1 = GL_SRC_ALPHA;
if (shirtfullbright)
GL_Color(shirtcolor[0] * colorscale * ifog, shirtcolor[1] * colorscale * ifog, shirtcolor[2] * colorscale * ifog, ent->alpha);
else
- {
- GL_UseColorArray();
R_LightModel(ent, model->numverts, varray_vertex, aliasvert_normals, varray_color, shirtcolor[0] * colorscale * ifog, shirtcolor[1] * colorscale * ifog, shirtcolor[2] * colorscale * ifog, false);
- }
R_Mesh_Draw(model->numverts, model->numtris, model->mdlmd2data_indices);
c_alias_polys += model->numtris;
blendfunc1 = GL_SRC_ALPHA;
model_t *model;
float *v, planenormal[3], planedist, dist, projection[3], floororigin[3], surfnormal[3], lightdirection[3], v2[3];
- /*
- if (r_shadows.integer > 1)
- {
- float f, lightscale, lightcolor[3];
- vec3_t temp;
- mlight_t *sl;
- rdlight_t *rd;
- memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_ONE;
- m.blendfunc2 = GL_ONE;
- R_Mesh_State(&m);
- R_Mesh_Matrix(&ent->matrix);
- for (i = 0, sl = cl.worldmodel->lights;i < cl.worldmodel->numlights;i++, sl++)
- {
- if (d_lightstylevalue[sl->style] > 0)
- {
- VectorSubtract(ent->origin, sl->origin, temp);
- f = DotProduct(temp,temp);
- if (f < (ent->model->radius2 + sl->cullradius2))
- {
- model = ent->model;
- R_Mesh_ResizeCheck(model->numverts * 2);
- R_LerpMDLMD2Vertices(ent, varray_vertex, aliasvert_normals);
- Matrix4x4_Transform(&ent->inversematrix, sl->origin, temp);
- GL_Color(0.1 * r_colorscale, 0.025 * r_colorscale, 0.0125 * r_colorscale, 1);
- R_Shadow_Volume(model->numverts, model->numtris, varray_vertex, model->mdlmd2data_indices, model->mdlmd2data_triangleneighbors, temp, sl->cullradius + model->radius - sqrt(f), true);
- GL_UseColorArray();
- lightscale = d_lightstylevalue[sl->style] * (1.0f / 65536.0f);
- VectorScale(sl->light, lightscale, lightcolor);
- R_Shadow_VertexLight(model->numverts, varray_vertex, aliasvert_normals, temp, sl->cullradius2, sl->distbias, sl->subtract, lightcolor);
- R_Mesh_Draw(model->numverts, model->numtris, model->mdlmd2data_indices);
- }
- }
- }
- for (i = 0, rd = r_dlight;i < r_numdlights;i++, rd++)
- {
- if (ent != rd->ent)
- {
- VectorSubtract(ent->origin, rd->origin, temp);
- f = DotProduct(temp,temp);
- if (f < (ent->model->radius2 + rd->cullradius2))
- {
- model = ent->model;
- R_Mesh_ResizeCheck(model->numverts * 2);
- R_LerpMDLMD2Vertices(ent, varray_vertex, aliasvert_normals);
- Matrix4x4_Transform(&ent->inversematrix, rd->origin, temp);
- GL_Color(0.1 * r_colorscale, 0.025 * r_colorscale, 0.0125 * r_colorscale, 1);
- R_Shadow_Volume(model->numverts, model->numtris, varray_vertex, model->mdlmd2data_indices, model->mdlmd2data_triangleneighbors, temp, rd->cullradius + model->radius - sqrt(f), true);
- GL_UseColorArray();
- R_Shadow_VertexLight(model->numverts, varray_vertex, aliasvert_normals, temp, rd->cullradius2, LIGHTOFFSET, rd->subtract, rd->light);
- R_Mesh_Draw(model->numverts, model->numtris, model->mdlmd2data_indices);
- }
- }
- }
- return;
- }
- */
-
lightdirection[0] = 0.5;
lightdirection[1] = 0.2;
lightdirection[2] = -1;
R_Mesh_Draw(model->numverts, model->numtris, model->mdlmd2data_indices);
}
-void R_Model_Alias_DrawBaseLighting(entity_render_t *ent)
-{
- R_Mesh_Matrix(&ent->matrix);
- GL_Color(0, 0, 0, 1);
- R_Mesh_ResizeCheck(ent->model->numverts);
- R_LerpMDLMD2Vertices(ent, varray_vertex, aliasvert_normals);
- R_Mesh_Draw(ent->model->numverts, ent->model->numtris, ent->model->mdlmd2data_indices);
-}
-
-void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int visiblevolume)
+void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius)
{
float projectdistance;
projectdistance = lightradius + ent->model->radius - sqrt(DotProduct(relativelightorigin, relativelightorigin));
R_Mesh_Matrix(&ent->matrix);
R_Mesh_ResizeCheck(ent->model->numverts * 2);
R_LerpMDLMD2Vertices(ent, varray_vertex, aliasvert_normals);
- R_Shadow_Volume(ent->model->numverts, ent->model->numtris, varray_vertex, ent->model->mdlmd2data_indices, ent->model->mdlmd2data_triangleneighbors, relativelightorigin, lightradius, projectdistance, visiblevolume);
+ R_Shadow_Volume(ent->model->numverts, ent->model->numtris, varray_vertex, ent->model->mdlmd2data_indices, ent->model->mdlmd2data_triangleneighbors, relativelightorigin, lightradius, projectdistance);
}
}
Con_Printf ("\nengine extensions: %s\n", ENGINE_EXTENSIONS);
}
-int R_CullBox(const vec3_t emins, const vec3_t emaxs)
+int R_CullBox(const vec3_t mins, const vec3_t maxs)
{
int i;
mplane_t *p;
{
default:
case 0:
- if (p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2] < p->dist)
+ if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
return true;
break;
case 1:
- if (p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2] < p->dist)
+ if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
return true;
break;
case 2:
- if (p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2] < p->dist)
+ if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
return true;
break;
case 3:
- if (p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2] < p->dist)
+ if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
return true;
break;
case 4:
- if (p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2] < p->dist)
+ if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
return true;
break;
case 5:
- if (p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2] < p->dist)
+ if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
return true;
break;
case 6:
- if (p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2] < p->dist)
+ if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
return true;
break;
case 7:
- if (p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2] < p->dist)
+ if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
return true;
break;
}
return false;
}
-int R_NotCulledBox(const vec3_t emins, const vec3_t emaxs)
+int PVS_CullBox(const vec3_t mins, const vec3_t maxs)
{
- int i;
- mplane_t *p;
- for (i = 0;i < 4;i++)
+ int stackpos, sides;
+ mnode_t *node, *stack[4096];
+ stackpos = 0;
+ stack[stackpos++] = cl.worldmodel->nodes;
+ while (stackpos)
{
- p = frustum + i;
- switch(p->signbits)
+ node = stack[--stackpos];
+ if (node->contents < 0)
{
- default:
- case 0:
- if (p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2] < p->dist)
- return false;
- break;
- case 1:
- if (p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2] < p->dist)
+ if (((mleaf_t *)node)->pvsframe == cl.worldmodel->pvsframecount)
return false;
- break;
- case 2:
- if (p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2] < p->dist)
- return false;
- break;
- case 3:
- if (p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2] < p->dist)
- return false;
- break;
- case 4:
- if (p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2] < p->dist)
- return false;
- break;
- case 5:
- if (p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2] < p->dist)
- return false;
- break;
- case 6:
- if (p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2] < p->dist)
- return false;
- break;
- case 7:
- if (p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2] < p->dist)
+ }
+ else
+ {
+ sides = BoxOnPlaneSide(mins, maxs, node->plane);
+ if (sides & 2 && stackpos < 4096)
+ stack[stackpos++] = node->children[1];
+ if (sides & 1 && stackpos < 4096)
+ stack[stackpos++] = node->children[0];
+ }
+ }
+ return true;
+}
+
+int R_CullSphere(const vec3_t origin, vec_t radius)
+{
+ return (DotProduct(frustum[0].normal, origin) + radius < frustum[0].dist
+ || DotProduct(frustum[1].normal, origin) + radius < frustum[1].dist
+ || DotProduct(frustum[2].normal, origin) + radius < frustum[2].dist
+ || DotProduct(frustum[3].normal, origin) + radius < frustum[3].dist);
+}
+
+int PVS_CullSphere(const vec3_t origin, vec_t radius)
+{
+ int stackpos;
+ mnode_t *node, *stack[4096];
+ float dist;
+ stackpos = 0;
+ stack[stackpos++] = cl.worldmodel->nodes;
+ while (stackpos)
+ {
+ node = stack[--stackpos];
+ if (node->contents < 0)
+ {
+ if (((mleaf_t *)node)->pvsframe == cl.worldmodel->pvsframecount)
return false;
- break;
+ }
+ else
+ {
+ dist = PlaneDiff(origin, node->plane);
+ if (dist <= radius)
+ stack[stackpos++] = node->children[1];
+ if (dist >= -radius)
+ stack[stackpos++] = node->children[0];
}
}
return true;
Matrix4x4_Invert_Simple(&ent->inversematrix, &ent->matrix);
R_LerpAnimation(ent);
R_UpdateEntLights(ent);
- if (R_NotCulledBox(ent->mins, ent->maxs))
+ if (!R_CullSphere(ent->origin, ent->model->radius * ent->scale)
+ && !PVS_CullSphere(ent->origin, ent->model->radius * ent->scale)
+ && !R_CullBox(ent->mins, ent->maxs)
+ && !PVS_CullBox(ent->mins, ent->maxs))
{
ent->visframe = r_framecount;
R_FarClip_Box(ent->mins, ent->maxs);
}
void R_DrawNoModel(entity_render_t *ent);
-void R_DrawModels (int baselighting)
+void R_DrawModels ()
{
int i;
entity_render_t *ent;
ent = r_refdef.entities[i];
if (ent->visframe == r_framecount)
{
- if (ent->model)
- {
- if (baselighting && ent->model->DrawBaseLighting != NULL)
- {
- if (ent->model->DrawBaseLighting)
- ent->model->DrawBaseLighting(ent);
- }
- else if (ent->model->Draw)
- ent->model->Draw(ent);
- }
+ if (ent->model && ent->model->Draw != NULL)
+ ent->model->Draw(ent);
else
R_DrawNoModel(ent);
}
#include "r_shadow.h"
-void R_TestAndDrawShadowVolume(entity_render_t *ent, vec3_t lightorigin, float lightradius, int visiblevolume)
+void R_TestAndDrawShadowVolume(entity_render_t *ent, vec3_t lightorigin, float lightradius)
{
int i;
vec3_t p, p2, temp, relativelightorigin;
if (mins[1] > p2[1]) mins[1] = p2[1];if (maxs[1] < p2[1]) maxs[1] = p2[1];
if (mins[2] > p2[2]) mins[2] = p2[2];if (maxs[2] < p2[2]) maxs[2] = p2[2];
}
- if (R_NotCulledBox(mins, maxs))
+ if (!R_CullBox(mins, maxs))
#endif
{
Matrix4x4_Transform(&ent->inversematrix, lightorigin, relativelightorigin);
- ent->model->DrawShadowVolume (ent, relativelightorigin, lightradius, visiblevolume);
+ ent->model->DrawShadowVolume (ent, relativelightorigin, lightradius);
}
}
}
}
}
-void R_DrawWorldLightShadowVolume(mlight_t *sl, int visiblevolume)
+void R_DrawWorldLightShadowVolume(mlight_t *sl)
{
shadowmesh_t *mesh;
R_Mesh_Matrix(&cl_entities[0].render.matrix);
for (mesh = sl->shadowvolume;mesh;mesh = mesh->next)
{
memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
- R_Shadow_RenderVolume(mesh->numverts, mesh->numtriangles, mesh->elements, visiblevolume);
- }
-}
-
-void R_DrawShadowVolumes (void)
-{
- int i, lnum;
- entity_render_t *ent;
- vec3_t mins, maxs;//, relativelightorigin;
- mlight_t *sl;
- rdlight_t *rd;
- rmeshstate_t m;
-
- for (lnum = 0, sl = cl.worldmodel->lights;lnum < cl.worldmodel->numlights;lnum++, sl++)
- {
- if (d_lightstylevalue[sl->style] <= 0)
- continue;
- if (r_light_debuglight.integer >= 0 && lnum != r_light_debuglight.integer)
- continue;
- /*
- mins[0] = sl->origin[0] - sl->cullradius;
- maxs[0] = sl->origin[0] + sl->cullradius;
- mins[1] = sl->origin[1] - sl->cullradius;
- maxs[1] = sl->origin[1] + sl->cullradius;
- mins[2] = sl->origin[2] - sl->cullradius;
- maxs[2] = sl->origin[2] + sl->cullradius;
- if (R_CullBox(mins, maxs))
- continue;
- */
- if (R_CullBox(sl->mins, sl->maxs))
- continue;
- memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_ONE;
- m.blendfunc2 = GL_ONE;
- R_Mesh_State(&m);
- GL_Color(0.0 * r_colorscale, 0.0125 * r_colorscale, 0.1 * r_colorscale, 1);
- if (sl->shadowvolume && r_staticworldlights.integer)
- R_DrawWorldLightShadowVolume(sl, true);
- else
- {
- ent = &cl_entities[0].render;
- R_TestAndDrawShadowVolume(ent, sl->origin, sl->cullradius, true);
- }
- /*
- ent = &cl_entities[0].render;
- if (ent->model && ent->model->DrawShadowVolume && ent->maxs[0] >= mins[0] && ent->mins[0] <= maxs[0] && ent->maxs[1] >= mins[1] && ent->mins[1] <= maxs[1] && ent->maxs[2] >= mins[2] && ent->mins[2] <= maxs[2])
- {
- Matrix4x4_Transform(&ent->inversematrix, sl->origin, relativelightorigin);
- ent->model->DrawShadowVolume (ent, relativelightorigin, sl->cullradius, true);
- }
- */
- if (r_drawentities.integer)
- {
- for (i = 0;i < r_refdef.numentities;i++)
- {
- ent = r_refdef.entities[i];
- /*
- if (ent->mins[0] <= sl->maxs[0]
- && ent->maxs[0] >= sl->mins[0]
- && ent->mins[1] <= sl->maxs[1]
- && ent->maxs[1] >= sl->mins[1]
- && ent->mins[2] <= sl->maxs[2]
- && ent->maxs[2] >= sl->mins[2])
- */
- R_TestAndDrawShadowVolume(ent, sl->origin, sl->cullradius, true);
- /*
- ent = r_refdef.entities[i];
- if (ent->model && ent->model->DrawShadowVolume && ent->maxs[0] >= mins[0] && ent->mins[0] <= maxs[0] && ent->maxs[1] >= mins[1] && ent->mins[1] <= maxs[1] && ent->maxs[2] >= mins[2] && ent->mins[2] <= maxs[2])
- {
- Matrix4x4_Transform(&ent->inversematrix, sl->origin, relativelightorigin);
- ent->model->DrawShadowVolume (ent, relativelightorigin, sl->cullradius, true);
- }
- */
- }
- }
- }
-
- for (lnum = 0, rd = r_dlight;lnum < r_numdlights;lnum++, rd++)
- {
- mins[0] = rd->origin[0] - rd->cullradius;
- maxs[0] = rd->origin[0] + rd->cullradius;
- mins[1] = rd->origin[1] - rd->cullradius;
- maxs[1] = rd->origin[1] + rd->cullradius;
- mins[2] = rd->origin[2] - rd->cullradius;
- maxs[2] = rd->origin[2] + rd->cullradius;
- if (R_CullBox(mins, maxs))
- continue;
- memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_ONE;
- m.blendfunc2 = GL_ONE;
- R_Mesh_State(&m);
- GL_Color(0.1 * r_colorscale, 0.0125 * r_colorscale, 0.0 * r_colorscale, 1);
- ent = &cl_entities[0].render;
- if (ent != rd->ent)
- R_TestAndDrawShadowVolume(ent, rd->origin, rd->cullradius, true);
- /*
- ent = &cl_entities[0].render;
- if (ent != rd->ent && ent->model && ent->model->DrawShadowVolume && ent->maxs[0] >= mins[0] && ent->mins[0] <= maxs[0] && ent->maxs[1] >= mins[1] && ent->mins[1] <= maxs[1] && ent->maxs[2] >= mins[2] && ent->mins[2] <= maxs[2])
- {
- Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin);
- ent->model->DrawShadowVolume (ent, relativelightorigin, rd->cullradius, true);
- }
- */
- if (r_drawentities.integer)
- {
- for (i = 0;i < r_refdef.numentities;i++)
- {
- ent = r_refdef.entities[i];
- if (ent != rd->ent)
- R_TestAndDrawShadowVolume(ent, rd->origin, rd->cullradius, true);
- /*
- ent = r_refdef.entities[i];
- if (ent != rd->ent && ent->model && ent->model->DrawShadowVolume && ent->maxs[0] >= mins[0] && ent->mins[0] <= maxs[0] && ent->maxs[1] >= mins[1] && ent->mins[1] <= maxs[1] && ent->maxs[2] >= mins[2] && ent->mins[2] <= maxs[2])
- {
- Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin);
- ent->model->DrawShadowVolume (ent, relativelightorigin, rd->cullradius, true);
- }
- */
- }
- }
+ R_Shadow_RenderVolume(mesh->numverts, mesh->numtriangles, mesh->elements);
}
}
VectorScale(&verts[6], 1.0f, &verts[6]);
VectorScale(&verts[9], 1.0f, &verts[9]);
Mod_ShadowMesh_AddPolygon(zonemempool, shadowsphere, 4, verts);
- /*
- AngleVectorsFLU(angles, verts, NULL, NULL);
- AngleVectorsFLU(angles2, verts + 3, NULL, NULL);
- AngleVectorsFLU(angles3, verts + 6, NULL, NULL);
- AngleVectorsFLU(angles4, verts + 9, NULL, NULL);
- VectorScale(&verts[0], -4.0f, &verts[0]);
- VectorScale(&verts[3], -4.0f, &verts[3]);
- VectorScale(&verts[6], -4.0f, &verts[6]);
- VectorScale(&verts[9], -4.0f, &verts[9]);
- Mod_ShadowMesh_AddPolygon(zonemempool, shadowsphere, 4, verts);
- */
}
}
shadowsphere = Mod_ShadowMesh_Finish(zonemempool, shadowsphere);
}
-void R_DrawShadowSphere(vec3_t origin, float cullradius, float lightradius, int visiblevolume)
+void R_DrawShadowSphere(vec3_t origin, float cullradius, float lightradius)
{
shadowmesh_t *mesh;
matrix4x4_t matrix;
for (mesh = shadowsphere;mesh;mesh = mesh->next)
{
memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
- R_Shadow_RenderVolume(mesh->numverts, mesh->numtriangles, mesh->elements, visiblevolume);
+ R_Shadow_RenderVolume(mesh->numverts, mesh->numtriangles, mesh->elements);
}
Matrix4x4_CreateScale(&matrix, -cullradius);
Matrix4x4_ConcatTranslate(&matrix, origin[0], origin[1], origin[2]);
for (mesh = shadowsphere;mesh;mesh = mesh->next)
{
memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
- R_Shadow_RenderVolume(mesh->numverts, mesh->numtriangles, mesh->elements, visiblevolume);
+ R_Shadow_RenderVolume(mesh->numverts, mesh->numtriangles, mesh->elements);
}
}
-void R_ShadowVolumeLighting (void)
+void R_ShadowVolumeLighting (int visiblevolumes)
{
int i;
entity_render_t *ent;
int lnum;
- float f;
- vec3_t mins, maxs, relativelightorigin, relativeeyeorigin, lightcolor;
+ float f, lightradius, cullradius;
+ vec3_t relativelightorigin, relativeeyeorigin, lightcolor;
mlight_t *sl;
rdlight_t *rd;
+ rmeshstate_t m;
- R_Shadow_Stage_Begin();
+ if (visiblevolumes)
+ {
+ memset(&m, 0, sizeof(m));
+ m.blendfunc1 = GL_ONE;
+ m.blendfunc2 = GL_ONE;
+ R_Mesh_State(&m);
+ GL_Color(0.0 * r_colorscale, 0.0125 * r_colorscale, 0.1 * r_colorscale, 1);
+ }
+ else
+ R_Shadow_Stage_Begin();
for (lnum = 0, sl = cl.worldmodel->lights;lnum < cl.worldmodel->numlights;lnum++, sl++)
{
if (d_lightstylevalue[sl->style] <= 0)
continue;
if (r_light_debuglight.integer >= 0 && lnum != r_light_debuglight.integer)
continue;
- VectorCopy(sl->mins, mins);
- VectorCopy(sl->maxs, maxs);
- if (R_CullBox(mins, maxs))
+ cullradius = sl->cullradius;
+ lightradius = sl->lightradius;
+ if (R_CullBox(sl->mins, sl->maxs) || PVS_CullBox(sl->mins, sl->maxs) || R_CullSphere(sl->origin, cullradius) || PVS_CullSphere(sl->origin, cullradius))
continue;
f = d_lightstylevalue[sl->style] * (1.0f / 32768.0f);
VectorScale(sl->light, f, lightcolor);
- R_Shadow_Stage_ShadowVolumes();
- R_DrawShadowSphere(sl->origin, sl->cullradius, sl->lightradius * 2, false);
+ if (!visiblevolumes)
+ R_Shadow_Stage_ShadowVolumes();
+ R_DrawShadowSphere(sl->origin, cullradius, lightradius * 2);
if (sl->shadowvolume && r_staticworldlights.integer)
- R_DrawWorldLightShadowVolume(sl, false);
+ R_DrawWorldLightShadowVolume(sl);
else
- R_TestAndDrawShadowVolume(&cl_entities[0].render, sl->origin, sl->cullradius, false);
+ R_TestAndDrawShadowVolume(&cl_entities[0].render, sl->origin, cullradius);
if (r_drawentities.integer)
{
for (i = 0;i < r_refdef.numentities;i++)
{
ent = r_refdef.entities[i];
- /*
- if (ent->maxs[0] >= mins[0]
- && ent->mins[0] <= maxs[0]
- && ent->maxs[1] >= mins[1]
- && ent->mins[1] <= maxs[1]
- && ent->maxs[2] >= mins[2]
- && ent->mins[2] <= maxs[2])
- */
- R_TestAndDrawShadowVolume(r_refdef.entities[i], sl->origin, sl->cullradius, false);
+ if (ent->maxs[0] >= sl->mins[0] && ent->mins[0] <= sl->maxs[0]
+ && ent->maxs[1] >= sl->mins[1] && ent->mins[1] <= sl->maxs[1]
+ && ent->maxs[2] >= sl->mins[2] && ent->mins[2] <= sl->maxs[2])
+ R_TestAndDrawShadowVolume(r_refdef.entities[i], sl->origin, cullradius);
}
}
- R_Shadow_Stage_Light();
- ent = &cl_entities[0].render;
- if (ent->model && ent->model->DrawLight)
- {
- Matrix4x4_Transform(&ent->inversematrix, sl->origin, relativelightorigin);
- Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin);
- ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, sl->lightradius, sl->distbias, sl->subtract, lightcolor);
- }
- if (r_drawentities.integer)
+ if (!visiblevolumes)
{
- for (i = 0;i < r_refdef.numentities;i++)
+ R_Shadow_Stage_Light();
+ ent = &cl_entities[0].render;
+ if (ent->model && ent->model->DrawLight)
{
- ent = r_refdef.entities[i];
- if (ent->visframe == r_framecount && ent->model && ent->model->DrawLight
- /*
- && ent->maxs[0] >= mins[0]
- && ent->mins[0] <= maxs[0]
- && ent->maxs[1] >= mins[1]
- && ent->mins[1] <= maxs[1]
- && ent->maxs[2] >= mins[2]
- && ent->mins[2] <= maxs[2]*/)
+ Matrix4x4_Transform(&ent->inversematrix, sl->origin, relativelightorigin);
+ Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin);
+ ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius, sl->distbias, sl->subtract, lightcolor);
+ }
+ if (r_drawentities.integer)
+ {
+ for (i = 0;i < r_refdef.numentities;i++)
+ {
+ ent = r_refdef.entities[i];
+ if (ent->visframe == r_framecount && ent->model && ent->model->DrawLight
+ && ent->maxs[0] >= sl->mins[0] && ent->mins[0] <= sl->maxs[0]
+ && ent->maxs[1] >= sl->mins[1] && ent->mins[1] <= sl->maxs[1]
+ && ent->maxs[2] >= sl->mins[2] && ent->mins[2] <= sl->maxs[2])
+ {
+ Matrix4x4_Transform(&ent->inversematrix, sl->origin, relativelightorigin);
+ Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin);
+ ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius, sl->distbias, sl->subtract, lightcolor);
+ }
+ }
+ }
+
+ R_Shadow_Stage_EraseShadowVolumes();
+ R_DrawShadowSphere(sl->origin, cullradius, lightradius * 2);
+ if (sl->shadowvolume && r_staticworldlights.integer)
+ R_DrawWorldLightShadowVolume(sl);
+ else
+ R_TestAndDrawShadowVolume(&cl_entities[0].render, sl->origin, cullradius);
+ if (r_drawentities.integer)
+ {
+ for (i = 0;i < r_refdef.numentities;i++)
{
- Matrix4x4_Transform(&ent->inversematrix, sl->origin, relativelightorigin);
- Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin);
- ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, sl->lightradius, sl->distbias, sl->subtract, lightcolor);
+ ent = r_refdef.entities[i];
+ if (ent->maxs[0] >= sl->mins[0] && ent->mins[0] <= sl->maxs[0]
+ && ent->maxs[1] >= sl->mins[1] && ent->mins[1] <= sl->maxs[1]
+ && ent->maxs[2] >= sl->mins[2] && ent->mins[2] <= sl->maxs[2])
+ R_TestAndDrawShadowVolume(r_refdef.entities[i], sl->origin, cullradius);
}
}
}
}
for (lnum = 0, rd = r_dlight;lnum < r_numdlights;lnum++, rd++)
{
- mins[0] = rd->origin[0] - rd->cullradius;
- maxs[0] = rd->origin[0] + rd->cullradius;
- mins[1] = rd->origin[1] - rd->cullradius;
- maxs[1] = rd->origin[1] + rd->cullradius;
- mins[2] = rd->origin[2] - rd->cullradius;
- maxs[2] = rd->origin[2] + rd->cullradius;
- if (R_CullBox(mins, maxs))
+ cullradius = rd->cullradius;
+ lightradius = rd->cullradius;
+ if (R_CullSphere(rd->origin, cullradius) || PVS_CullSphere(rd->origin, cullradius))
continue;
- R_Shadow_Stage_ShadowVolumes();
- R_TestAndDrawShadowVolume(&cl_entities[0].render, rd->origin, rd->cullradius, false);
+ VectorScale(rd->light, 4.0f, lightcolor);
+
+ if (!visiblevolumes)
+ R_Shadow_Stage_ShadowVolumes();
+ R_TestAndDrawShadowVolume(&cl_entities[0].render, rd->origin, cullradius);
if (r_drawentities.integer)
{
for (i = 0;i < r_refdef.numentities;i++)
{
ent = r_refdef.entities[i];
- /*
- if (ent->maxs[0] >= mins[0]
- && ent->mins[0] <= maxs[0]
- && ent->maxs[1] >= mins[1]
- && ent->mins[1] <= maxs[1]
- && ent->maxs[2] >= mins[2]
- && ent->mins[2] <= maxs[2])
- */
- R_TestAndDrawShadowVolume(ent, rd->origin, rd->cullradius, false);
+ if (ent != rd->ent)
+ R_TestAndDrawShadowVolume(ent, rd->origin, cullradius);
}
}
- R_Shadow_Stage_Light();
- ent = &cl_entities[0].render;
- if (ent->model && ent->model->DrawLight)
- {
- Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin);
- Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin);
- ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, rd->cullradius, LIGHTOFFSET, rd->subtract, rd->light);
- }
- if (r_drawentities.integer)
+ if (!visiblevolumes)
{
- for (i = 0;i < r_refdef.numentities;i++)
+ R_Shadow_Stage_Light();
+ ent = &cl_entities[0].render;
+ if (ent->model && ent->model->DrawLight)
{
- ent = r_refdef.entities[i];
- if (ent->visframe == r_framecount && ent->model && ent->model->DrawLight
- /*
- && ent->maxs[0] >= mins[0]
- && ent->mins[0] <= maxs[0]
- && ent->maxs[1] >= mins[1]
- && ent->mins[1] <= maxs[1]
- && ent->maxs[2] >= mins[2]
- && ent->mins[2] <= maxs[2]*/)
+ Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin);
+ Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin);
+ ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, cullradius, LIGHTOFFSET, rd->subtract, lightcolor);
+ }
+ if (r_drawentities.integer)
+ {
+ for (i = 0;i < r_refdef.numentities;i++)
{
- Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin);
- Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin);
- ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, rd->cullradius, LIGHTOFFSET, rd->subtract, rd->light);
+ ent = r_refdef.entities[i];
+ if (ent->visframe == r_framecount && ent->model && ent->model->DrawLight)
+ {
+ Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin);
+ Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin);
+ ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, cullradius, LIGHTOFFSET, rd->subtract, lightcolor);
+ }
+ }
+ }
+
+ R_Shadow_Stage_EraseShadowVolumes();
+ R_TestAndDrawShadowVolume(&cl_entities[0].render, rd->origin, cullradius);
+ if (r_drawentities.integer)
+ {
+ for (i = 0;i < r_refdef.numentities;i++)
+ {
+ ent = r_refdef.entities[i];
+ if (ent != rd->ent)
+ R_TestAndDrawShadowVolume(ent, rd->origin, cullradius);
}
}
}
}
- R_Shadow_Stage_End();
+ if (!visiblevolumes)
+ R_Shadow_Stage_End();
}
static void R_SetFrustum (void)
R_TimeReport("bmodelsky");
// must occur early because it can draw sky
- R_DrawWorld(world, r_shadows.integer == 3);
+ R_DrawWorld(world);
R_TimeReport("world");
// don't let sound skip if going slow
if (r_shadows.integer == 1)
{
R_DrawFakeShadows();
- R_TimeReport("fakeshadows");
+ R_TimeReport("fakeshadow");
}
if (r_shadows.integer == 3)
- R_ShadowVolumeLighting();
+ {
+ R_ShadowVolumeLighting(false);
+ R_TimeReport("dynlight");
+ }
R_DrawParticles();
R_TimeReport("particles");
R_MeshQueue_EndScene();
if (r_shadows.integer == 2)
{
- R_DrawShadowVolumes();
- R_TimeReport("shadowvolumes");
+ R_ShadowVolumeLighting(true);
+ R_TimeReport("shadowvolume");
}
R_Mesh_Finish();
R_TimeReport("meshfinish");
RSurfShader_Wall_Pass_Fog(ent, surf);
}
+extern cvar_t r_shadows;
static void RSurfShader_Wall_Lightmap(const entity_render_t *ent, const texture_t *texture, const msurface_t *firstsurf)
{
const msurface_t *surf;
}
}
}
+ else if (r_shadows.integer == 3 && cl.worldmodel->numlights)
+ {
+ // opaque base lighting
+ RSurfShader_OpaqueWall_Pass_OpaqueGlow(ent, texture, firstsurf);
+ if (fogenabled)
+ RSurfShader_OpaqueWall_Pass_Fog(ent, texture, firstsurf);
+ }
else if (r_vertexsurfaces.integer)
{
// opaque vertex shaded from lightmap
}
}
-static void RSurfShader_Wall_Lightmap_BaseLighting(const entity_render_t *ent, const texture_t *texture, const msurface_t *firstsurf)
-{
- const msurface_t *surf;
- if (cl.worldmodel->numlights)
- RSurfShader_OpaqueWall_Pass_OpaqueGlow(ent, texture, firstsurf);
- else if (r_vertexsurfaces.integer)
- {
- // opaque vertex shaded from lightmap
- for (surf = firstsurf;surf;surf = surf->texturechain)
- if (surf->visframe == r_framecount)
- RSurfShader_Wall_Pass_BaseVertex(ent, surf);
- if (texture->glowtexture)
- for (surf = firstsurf;surf;surf = surf->texturechain)
- if (surf->visframe == r_framecount)
- RSurfShader_Wall_Pass_Glow(ent, surf);
- }
- else
- {
- // opaque lightmapped
- if (r_textureunits.integer >= 2)
- {
- if (r_textureunits.integer >= 3 && gl_combine.integer && r_detailtextures.integer)
- RSurfShader_OpaqueWall_Pass_BaseTripleTexCombine(ent, texture, firstsurf);
- else
- {
- RSurfShader_OpaqueWall_Pass_BaseDoubleTex(ent, texture, firstsurf);
- if (r_detailtextures.integer)
- RSurfShader_OpaqueWall_Pass_BaseDetail(ent, texture, firstsurf);
- }
- }
- else
- {
- RSurfShader_OpaqueWall_Pass_BaseTexture(ent, texture, firstsurf);
- RSurfShader_OpaqueWall_Pass_BaseLightmap(ent, texture, firstsurf);
- if (r_detailtextures.integer)
- RSurfShader_OpaqueWall_Pass_BaseDetail(ent, texture, firstsurf);
- }
- if (!r_dlightmap.integer && !(ent->effects & EF_FULLBRIGHT))
- RSurfShader_OpaqueWall_Pass_Light(ent, texture, firstsurf);
- if (texture->glowtexture)
- RSurfShader_OpaqueWall_Pass_Glow(ent, texture, firstsurf);
- }
-}
-
-Cshader_t Cshader_wall_lightmap = {{NULL, RSurfShader_Wall_Lightmap, RSurfShader_Wall_Lightmap_BaseLighting}, SHADERFLAGS_NEEDLIGHTMAP};
-Cshader_t Cshader_water = {{NULL, RSurfShader_Water, NULL}, 0};
-Cshader_t Cshader_sky = {{RSurfShader_Sky, NULL, NULL}, 0};
+Cshader_t Cshader_wall_lightmap = {{NULL, RSurfShader_Wall_Lightmap}, SHADERFLAGS_NEEDLIGHTMAP};
+Cshader_t Cshader_water = {{NULL, RSurfShader_Water}, 0};
+Cshader_t Cshader_sky = {{RSurfShader_Sky, NULL}, 0};
int Cshader_count = 3;
Cshader_t *Cshaders[3] =
&Cshader_sky
};
+extern cvar_t r_shadows;
void R_PrepareSurfaces(entity_render_t *ent)
{
int i, texframe, numsurfaces, *surfacevisframes;
}
}
- if (r_dynamic.integer)
+ if (r_dynamic.integer && r_shadows.integer != 3)
R_MarkLights(ent);
for (i = 0, surf = surfaces;i < numsurfaces;i++, surf++)
#if WORLDNODECULLBACKFACES
if (PlaneDist(modelorg, surf->plane) < surf->plane->dist)
{
- if ((surf->flags & SURF_PLANEBACK) && R_NotCulledBox (surf->poly_mins, surf->poly_maxs))
+ if ((surf->flags & SURF_PLANEBACK) && !R_CullBox (surf->poly_mins, surf->poly_maxs))
surfacevisframes[i] = r_framecount;
}
else
{
- if (!(surf->flags & SURF_PLANEBACK) && R_NotCulledBox (surf->poly_mins, surf->poly_maxs))
+ if (!(surf->flags & SURF_PLANEBACK) && !R_CullBox (surf->poly_mins, surf->poly_maxs))
surfacevisframes[i] = r_framecount;
}
#else
- if (R_NotCulledBox (surf->poly_mins, surf->poly_maxs))
+ if (!R_CullBox (surf->poly_mins, surf->poly_maxs))
surfacevisframes[i] = r_framecount;
#endif
}
if (leaf->worldnodeframe != r_framecount)
{
leaf->worldnodeframe = r_framecount;
- // FIXME: R_NotCulledBox is absolute, should be done relative
- if (leaf->pvsframe == ent->model->pvsframecount && R_NotCulledBox(leaf->mins, leaf->maxs))
+ // FIXME: R_CullBox is absolute, should be done relative
+ if (leaf->pvsframe == ent->model->pvsframecount && !R_CullBox(leaf->mins, leaf->maxs))
{
p->visframe = r_framecount;
pstack[portalstack++] = p;
if (leaf->worldnodeframe != r_framecount)
{
leaf->worldnodeframe = r_framecount;
- // FIXME: R_NotCulledBox is absolute, should be done relative
- if (leaf->pvsframe == ent->model->pvsframecount && R_NotCulledBox(leaf->mins, leaf->maxs))
+ // FIXME: R_CullBox is absolute, should be done relative
+ if (leaf->pvsframe == ent->model->pvsframecount && !R_CullBox(leaf->mins, leaf->maxs))
leafstack[leafstackpos++] = leaf;
}
}
R_DrawWorld
=============
*/
-void R_DrawWorld (entity_render_t *ent, int baselighting)
+void R_DrawWorld (entity_render_t *ent)
{
vec3_t modelorg;
mleaf_t *viewleaf;
R_PortalWorldNode (ent, viewleaf);
R_PrepareSurfaces(ent);
R_DrawSurfaces(ent, SHADERSTAGE_SKY);
- if (baselighting)
- R_DrawSurfaces(ent, SHADERSTAGE_BASELIGHTING);
- else
- R_DrawSurfaces(ent, SHADERSTAGE_NORMAL);
+ R_DrawSurfaces(ent, SHADERSTAGE_NORMAL);
}
void R_Model_Brush_DrawSky (entity_render_t *ent)
R_DrawSurfaces(ent, SHADERSTAGE_NORMAL);
}
-void R_Model_Brush_DrawBaseLighting (entity_render_t *ent)
-{
- c_bmodels++;
- if (ent != &cl_entities[0].render)
- R_PrepareBrushModel(ent);
- R_DrawSurfaces(ent, SHADERSTAGE_BASELIGHTING);
- /*
- shadowmesh_t *mesh;
- if (!cl.worldmodel->numlights)
- GL_Color(0.3, 0.3, 0.3, 1);
- for (mesh = ent->model->shadowmesh;mesh;mesh = mesh->next)
- {
- R_Mesh_ResizeCheck(mesh->numverts);
- memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
- R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->elements);
- }
- if (!cl.worldmodel->numlights)
- GL_Color(0, 0, 0, 1);
- */
-}
-
-void R_Model_Brush_DrawShadowVolume (entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int visiblevolume)
+void R_Model_Brush_DrawShadowVolume (entity_render_t *ent, vec3_t relativelightorigin, float lightradius)
{
#if 1
float projectdistance, temp[3];
{
R_Mesh_ResizeCheck(mesh->numverts * 2);
memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
- R_Shadow_Volume(mesh->numverts, mesh->numtriangles, varray_vertex, mesh->elements, mesh->neighbors, relativelightorigin, lightradius, projectdistance, visiblevolume);
+ R_Shadow_Volume(mesh->numverts, mesh->numtriangles, varray_vertex, mesh->elements, mesh->neighbors, relativelightorigin, lightradius, projectdistance);
}
}
#else
{
R_Mesh_ResizeCheck(mesh->numverts * 2);
memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
- R_Shadow_Volume(mesh->numverts, mesh->numtriangles, varray_vertex, mesh->index, mesh->triangleneighbors, relativelightorigin, lightradius, projectdistance, visiblevolume);
+ R_Shadow_Volume(mesh->numverts, mesh->numtriangles, varray_vertex, mesh->index, mesh->triangleneighbors, relativelightorigin, lightradius, projectdistance);
}
}
}
}
}
-/*
-extern cvar_t r_shadows;
-void R_DrawBrushModelFakeShadow (entity_render_t *ent)
-{
- int i;
- vec3_t relativelightorigin;
- rmeshstate_t m;
- mlight_t *sl;
- rdlight_t *rd;
- svbspmesh_t *mesh;
-
- if (r_shadows.integer < 2)
- return;
-
- memset(&m, 0, sizeof(m));
- m.blendfunc1 = GL_ONE;
- m.blendfunc2 = GL_ONE;
- R_Mesh_State(&m);
- R_Mesh_Matrix(&ent->matrix);
- GL_Color(0.0125 * r_colorscale, 0.025 * r_colorscale, 0.1 * r_colorscale, 1);
- if (0)//ent->model == cl.worldmodel)
- {
- for (i = 0, sl = cl.worldmodel->lights;i < cl.worldmodel->numlights;i++, sl++)
- {
- if (d_lightstylevalue[sl->style] > 0 && R_NotCulledBox(sl->shadowvolumemins, sl->shadowvolumemaxs))
- {
- for (mesh = sl->shadowvolume;mesh;mesh = mesh->next)
- {
- memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
- R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->elements);
- }
- }
- }
- }
- else
- {
- for (i = 0, sl = cl.worldmodel->lights;i < cl.worldmodel->numlights;i++, sl++)
- {
- if (d_lightstylevalue[sl->style] > 0
- && ent->maxs[0] >= sl->origin[0] - sl->cullradius
- && ent->mins[0] <= sl->origin[0] + sl->cullradius
- && ent->maxs[1] >= sl->origin[1] - sl->cullradius
- && ent->mins[1] <= sl->origin[1] + sl->cullradius
- && ent->maxs[2] >= sl->origin[2] - sl->cullradius
- && ent->mins[2] <= sl->origin[2] + sl->cullradius)
- {
- Matrix4x4_Transform(&ent->inversematrix, sl->origin, relativelightorigin);
- R_DrawBrushModelShadowVolume (ent, relativelightorigin, sl->cullradius, true);
- }
- }
- }
- for (i = 0, rd = r_dlight;i < r_numdlights;i++, rd++)
- {
- if (ent->maxs[0] >= rd->origin[0] - rd->cullradius
- && ent->mins[0] <= rd->origin[0] + rd->cullradius
- && ent->maxs[1] >= rd->origin[1] - rd->cullradius
- && ent->mins[1] <= rd->origin[1] + rd->cullradius
- && ent->maxs[2] >= rd->origin[2] - rd->cullradius
- && ent->mins[2] <= rd->origin[2] + rd->cullradius)
- {
- Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin);
- R_DrawBrushModelShadowVolume (ent, relativelightorigin, rd->cullradius, true);
- }
- }
-}
-*/
-
static void gl_surf_start(void)
{
}
CHECKGLERROR
qglTexParameteri(textureenum, GL_TEXTURE_WRAP_S, wrapmode);
- if (gltexturetypedimensions[texturetype] >= 2)
- qglTexParameteri(textureenum, GL_TEXTURE_WRAP_T, wrapmode);
+ qglTexParameteri(textureenum, GL_TEXTURE_WRAP_T, wrapmode);
if (gltexturetypedimensions[texturetype] >= 3)
qglTexParameteri(textureenum, GL_TEXTURE_WRAP_R, wrapmode);
{
// promote paletted to RGBA, so we only have to worry about RGB and
// RGBA in the rest of this code
- R_MakeResizeBufferBigger(glt->image->width * glt->image->height * glt->image->depth * glt->image->bytesperpixel);
+ R_MakeResizeBufferBigger(glt->image->width * glt->image->height * glt->image->depth * glt->image->sides * glt->image->bytesperpixel);
Image_Copy8bitRGBA(prevbuffer, colorconvertbuffer, glt->width * glt->height * glt->depth, glt->palette);
prevbuffer = colorconvertbuffer;
}
for (height = 1;height < glt->height;height <<= 1);
for (depth = 1;depth < glt->depth ;depth <<= 1);
- R_MakeResizeBufferBigger(width * height * depth * glt->image->bytesperpixel);
+ R_MakeResizeBufferBigger(width * height * depth * glt->image->sides * glt->image->bytesperpixel);
if (prevbuffer == NULL)
{
{
// promote paletted to RGBA, so we only have to worry about RGB and
// RGBA in the rest of this code
- Image_Copy8bitRGBA(prevbuffer, colorconvertbuffer, glt->width * glt->height * glt->depth, glt->palette);
+ Image_Copy8bitRGBA(prevbuffer, colorconvertbuffer, glt->width * glt->height * glt->depth * glt->image->sides, glt->palette);
prevbuffer = colorconvertbuffer;
}
+ }
+ // 3 and 4 are converted by the driver to it's preferred format for the current display mode
+ internalformat = 3;
+ if (glt->flags & TEXF_ALPHA)
+ internalformat = 4;
+
+ // cubemaps contain multiple images and thus get processed a bit differently
+ if (glt->image->texturetype != GLTEXTURETYPE_CUBEMAP)
+ {
if (glt->width != width || glt->height != height || glt->depth != depth)
{
Image_Resample(prevbuffer, glt->width, glt->height, glt->depth, resizebuffer, width, height, depth, glt->image->bytesperpixel, r_lerpimages.integer);
prevbuffer = resizebuffer;
}
-
- // apply picmip/max_size limitations
+ // picmip/max_size
while (width > glt->image->width || height > glt->image->height || depth > glt->image->depth)
{
Image_MipReduce(prevbuffer, resizebuffer, &width, &height, &depth, glt->image->width, glt->image->height, glt->image->depth, glt->image->bytesperpixel);
prevbuffer = resizebuffer;
}
}
-
- // 3 and 4 are converted by the driver to it's preferred format for the current display mode
- internalformat = 3;
- if (glt->flags & TEXF_ALPHA)
- internalformat = 4;
-
mip = 0;
switch(glt->image->texturetype)
{
{
prevbuffer = texturebuffer;
texturebuffer += width * height * depth * glt->textype->inputbytesperpixel;
+ if (glt->width != width || glt->height != height || glt->depth != depth)
+ {
+ Image_Resample(prevbuffer, glt->width, glt->height, glt->depth, resizebuffer, width, height, depth, glt->image->bytesperpixel, r_lerpimages.integer);
+ prevbuffer = resizebuffer;
+ }
+ // picmip/max_size
+ while (width > glt->image->width || height > glt->image->height || depth > glt->image->depth)
+ {
+ Image_MipReduce(prevbuffer, resizebuffer, &width, &height, &depth, glt->image->width, glt->image->height, glt->image->depth, glt->image->bytesperpixel);
+ prevbuffer = resizebuffer;
+ }
+ mip = 0;
qglTexImage2D(cubemapside[i], mip++, internalformat, width, height, 0, glt->image->glformat, GL_UNSIGNED_BYTE, prevbuffer);
CHECKGLERROR
if (glt->flags & TEXF_MIPMAP)
float iwidth, iheight, ibumpscale, n[3];
iwidth = 1.0f / width;
iheight = 1.0f / height;
- ibumpscale = (255.0f * 3.0f) / (bumpscale * 16.0f);
+ ibumpscale = (255.0f * 3.0f) / (bumpscale * 8.0f);
out = outpixels;
for (y = 0;y < height;y++)
{
#define BOUNDF(VALUE,MIN,MAX) if (VALUE < MIN || VALUE >= MAX) Host_Error("model %s has an invalid ##VALUE (%f exceeds %f - %f)\n", loadmodel->name, VALUE, MIN, MAX);
extern void R_Model_Alias_Draw(entity_render_t *ent);
extern void R_Model_Alias_DrawFakeShadow(entity_render_t *ent);
-extern void R_Model_Alias_DrawBaseLighting(entity_render_t *ent);
-extern void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int visiblevolume);
+extern void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius);
extern void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius2, float lightdistbias, float lightsubtract, float *lightcolor);
void Mod_LoadAliasModel (model_t *mod, void *buffer)
{
loadmodel->DrawSky = NULL;
loadmodel->Draw = R_Model_Alias_Draw;
loadmodel->DrawFakeShadow = R_Model_Alias_DrawFakeShadow;
- loadmodel->DrawBaseLighting = R_Model_Alias_DrawBaseLighting;
loadmodel->DrawShadowVolume = R_Model_Alias_DrawShadowVolume;
loadmodel->DrawLight = R_Model_Alias_DrawLight;
loadmodel->DrawSky = NULL;
loadmodel->Draw = R_Model_Alias_Draw;
loadmodel->DrawFakeShadow = R_Model_Alias_DrawFakeShadow;
- loadmodel->DrawBaseLighting = R_Model_Alias_DrawBaseLighting;
loadmodel->DrawShadowVolume = R_Model_Alias_DrawShadowVolume;
loadmodel->DrawLight = R_Model_Alias_DrawLight;
extern void R_Model_Zymotic_DrawSky(entity_render_t *ent);
extern void R_Model_Zymotic_Draw(entity_render_t *ent);
extern void R_Model_Zymotic_DrawFakeShadow(entity_render_t *ent);
-extern void R_Model_Zymotic_DrawBaseLighting(entity_render_t *ent);
-extern void R_Model_Zymotic_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int visiblevolume);
+extern void R_Model_Zymotic_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius);
extern void R_Model_Zymotic_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius2, float lightdistbias, float lightsubtract, float *lightcolor);
void Mod_LoadZymoticModel(model_t *mod, void *buffer)
{
loadmodel->DrawSky = NULL;
loadmodel->Draw = R_Model_Zymotic_Draw;
loadmodel->DrawFakeShadow = NULL;//R_Model_Zymotic_DrawFakeShadow;
- loadmodel->DrawBaseLighting = NULL;//R_Model_Zymotic_DrawBaseLighting;
loadmodel->DrawShadowVolume = NULL;//R_Model_Zymotic_DrawShadowVolume;
loadmodel->DrawLight = NULL;//R_Model_Zymotic_DrawLight;
Con_Printf("warning: unnamed texture in %s, renaming to %s\n", loadmodel->name, tx->name);
}
- basepixels = NULL;
- bumppixels = NULL;
- nmappixels = NULL;
- glosspixels = NULL;
- glowpixels = NULL;
- maskpixels = NULL;
+ basepixels = NULL;basepixels_width = 0;basepixels_height = 0;
+ bumppixels = NULL;bumppixels_width = 0;bumppixels_height = 0;
+ nmappixels = NULL;nmappixels_width = 0;nmappixels_height = 0;
+ glosspixels = NULL;glosspixels_width = 0;glosspixels_height = 0;
+ glowpixels = NULL;glowpixels_width = 0;glowpixels_height = 0;
+ maskpixels = NULL;maskpixels_width = 0;maskpixels_height = 0;
detailtexture = NULL;
// LordHavoc: HL sky textures are entirely different than quake
}
else
{
- basepixels = loadimagepixels(tx->name, false, 0, 0);
- if (basepixels)
+ if ((basepixels = loadimagepixels(tx->name, false, 0, 0)) != NULL)
{
- strcpy(name, tx->name);
- strcat(name, "_glow");
- glowpixels = loadimagepixels(name, false, 0, 0);
+ basepixels_width = image_width;
+ basepixels_height = image_height;
}
- else
+ // _luma is supported for tenebrae compatibility
+ // (I think it's a very stupid name, but oh well)
+ if ((glowpixels = loadimagepixels(va("%s_glow", tx->name), false, 0, 0)) != NULL
+ || (glowpixels = loadimagepixels(va("%s_luma", tx->name), false, 0, 0)) != NULL)
+ {
+ glowpixels_width = image_width;
+ glowpixels_height = image_height;
+ }
+ if ((bumppixels = loadimagepixels(va("%s_bump", tx->name), false, 0, 0)) != NULL)
+ {
+ bumppixels_width = image_width;
+ bumppixels_height = image_height;
+ }
+ if ((glosspixels = loadimagepixels(va("%s_gloss", tx->name), false, 0, 0)) != NULL)
+ {
+ glosspixels_width = image_width;
+ glosspixels_height = image_height;
+ }
+ if (!basepixels)
{
if (loadmodel->ishlbsp)
{
basepixels_height = tx->height;
basepixels = Mem_Alloc(loadmodel->mempool, basepixels_width * basepixels_height * 4);
Image_Copy8bitRGBA(mtdata, basepixels, basepixels_width * basepixels_height, palette_nofullbrights);
- for (j = 0;j < tx->width*tx->height;j++)
- if (((qbyte *)&palette_onlyfullbrights[mtdata[j]])[3] > 0) // fullbright
- break;
- if (j < tx->width * tx->height)
+ if (!glowpixels)
{
- glowpixels_width = tx->width;
- glowpixels_height = tx->height;
- glowpixels = Mem_Alloc(loadmodel->mempool, glowpixels_width * glowpixels_height * 4);
- Image_Copy8bitRGBA(mtdata, glowpixels, glowpixels_width * glowpixels_height, palette_onlyfullbrights);
+ for (j = 0;j < tx->width*tx->height;j++)
+ if (((qbyte *)&palette_onlyfullbrights[mtdata[j]])[3] > 0) // fullbright
+ break;
+ if (j < tx->width * tx->height)
+ {
+ glowpixels_width = tx->width;
+ glowpixels_height = tx->height;
+ glowpixels = Mem_Alloc(loadmodel->mempool, glowpixels_width * glowpixels_height * 4);
+ Image_Copy8bitRGBA(mtdata, glowpixels, glowpixels_width * glowpixels_height, palette_onlyfullbrights);
+ }
}
}
else
{
tx->texture = R_LoadTexture2D (loadmodel->texturepool, tx->name, basepixels_width, basepixels_height, basepixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL);
if (nmappixels)
- tx->nmaptexture = R_LoadTexture2D (loadmodel->texturepool, va("%s_nmap", tx->name), basepixels_width, basepixels_height, basepixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL);
+ tx->nmaptexture = R_LoadTexture2D (loadmodel->texturepool, va("%s_nmap", tx->name), basepixels_width, basepixels_height, nmappixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL);
if (glosspixels)
tx->glosstexture = R_LoadTexture2D (loadmodel->texturepool, va("%s_gloss", tx->name), glosspixels_width, glosspixels_height, glosspixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL);
if (glowpixels)
*/
extern void R_Model_Brush_DrawSky(entity_render_t *ent);
extern void R_Model_Brush_Draw(entity_render_t *ent);
-//extern void R_Model_Brush_DrawFakeShadow(entity_render_t *ent);
-extern void R_Model_Brush_DrawBaseLighting(entity_render_t *ent);
-extern void R_Model_Brush_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int visiblevolume);
+extern void R_Model_Brush_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius);
extern void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius2, float lightdistbias, float lightsubtract, float *lightcolor);
void Mod_LoadBrushModel (model_t *mod, void *buffer)
{
mod->DrawSky = NULL;
mod->Draw = R_Model_Brush_Draw;
mod->DrawFakeShadow = NULL;
- mod->DrawBaseLighting = R_Model_Brush_DrawBaseLighting;
mod->DrawShadowVolume = R_Model_Brush_DrawShadowVolume;
mod->DrawLight = R_Model_Brush_DrawLight;
mod->texturesurfacechains = Mem_Alloc(originalloadmodel->mempool, mod->numtextures * sizeof(msurface_t *));
#define SHADERSTAGE_SKY 0
#define SHADERSTAGE_NORMAL 1
-#define SHADERSTAGE_BASELIGHTING 2
-#define SHADERSTAGE_COUNT 3
+#define SHADERSTAGE_COUNT 2
#define SHADERFLAGS_NEEDLIGHTMAP 1
void(*DrawFakeShadow)(struct entity_render_s *ent);
// functions used only in shadow volume rendering mode
- // draw the base lighting for the model (glowing areas, etc)
- void(*DrawBaseLighting)(struct entity_render_s *ent);
// draw a shadow volume for the model based on light source
- void(*DrawShadowVolume)(struct entity_render_s *ent, vec3_t relativelightorigin, float lightradius, int visiblevolume);
+ void(*DrawShadowVolume)(struct entity_render_s *ent, vec3_t relativelightorigin, float lightradius);
// draw the lighting on a model (through stencil)
void(*DrawLight)(struct entity_render_s *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float lightdistbias, float lightsubtract, float *lightcolor);
loadmodel->DrawSky = NULL;
loadmodel->Draw = R_Model_Sprite_Draw;
loadmodel->DrawFakeShadow = NULL;
- loadmodel->DrawBaseLighting = NULL;
loadmodel->DrawShadowVolume = NULL;
loadmodel->DrawLight = NULL;
reversed_start = 128;
reversed_end = 224;
- memset(palette_nofullbrights, 0, sizeof(palette_nofullbrights));
for (i = 0;i < fullbright_start;i++)
palette_nofullbrights[i] = palette_complete[i];
+ for (i = fullbright_start;i < 255;i++)
+ palette_nofullbrights[i] = palette_complete[0];
+ palette_nofullbrights[255] = 0;
- memset(palette_onlyfullbrights, 0, sizeof(palette_onlyfullbrights));
+ for (i = 0;i < 256;i++)
+ palette_onlyfullbrights[i] = palette_complete[0];
for (i = fullbright_start;i < fullbright_end;i++)
palette_onlyfullbrights[i] = palette_complete[i];
+ palette_onlyfullbrights[255] = 0;
for (i = 0;i < 256;i++)
palette_nocolormapnofullbrights[i] = palette_complete[i];
for (i = pants_start;i < pants_end;i++)
- palette_nocolormapnofullbrights[i] = 0;
+ palette_nocolormapnofullbrights[i] = palette_complete[0];
for (i = shirt_start;i < shirt_end;i++)
- palette_nocolormapnofullbrights[i] = 0;
+ palette_nocolormapnofullbrights[i] = palette_complete[0];
for (i = fullbright_start;i < fullbright_end;i++)
- palette_nocolormapnofullbrights[i] = 0;
+ palette_nocolormapnofullbrights[i] = palette_complete[0];
+ palette_nocolormapnofullbrights[255] = 0;
- memset(palette_pantsaswhite, 0, sizeof(palette_pantsaswhite));
+ for (i = 0;i < 256;i++)
+ palette_pantsaswhite[i] = palette_complete[0];
for (i = pants_start;i < pants_end;i++)
{
if (i >= reversed_start && i < reversed_end)
- palette_pantsaswhite[i] = 15 - (i - pants_start);
+ palette_pantsaswhite[i] = palette_complete[15 - (i - pants_start)];
else
- palette_pantsaswhite[i] = i - pants_start;
+ palette_pantsaswhite[i] = palette_complete[i - pants_start];
}
- memset(palette_shirtaswhite, 0, sizeof(palette_shirtaswhite));
+ for (i = 0;i < 256;i++)
+ palette_shirtaswhite[i] = palette_complete[0];
for (i = shirt_start;i < shirt_end;i++)
{
if (i >= reversed_start && i < reversed_end)
- palette_shirtaswhite[i] = 15 - (i - shirt_start);
+ palette_shirtaswhite[i] = palette_complete[15 - (i - shirt_start)];
else
- palette_shirtaswhite[i] = i - shirt_start;
+ palette_shirtaswhite[i] = palette_complete[i - shirt_start];
}
- memset(palette_alpha, 0, sizeof(palette_alpha));
for (i = 0;i < 255;i++)
palette_alpha[i] = 0xFFFFFFFF;
+ palette_alpha[255] = 0;
- memset(palette_font, 0, sizeof(palette_font));
+ palette_font[0] = 0;
for (i = 1;i < 255;i++)
palette_font[i] = palette_complete[i];
+ palette_font[255] = 0;
}
RecursiveLightPoint (color, cl.worldmodel->nodes, p[0], p[1], p[2], p[2] - 65536);
}
+extern cvar_t r_shadows;
void R_LightModel(const entity_render_t *ent, int numverts, float *vertices, float *normals, float *colors, float colorr, float colorg, float colorb, int worldcoords)
{
int i, j, nearlights = 0, maxnearlights = r_modellights.integer;
{
R_ModelLightPoint(ent, basecolor, ent->origin);
- nl = &nearlight[0];
- for (i = 0;i < ent->numentlights;i++)
+ if (r_shadows.integer != 3)
{
- sl = cl.worldmodel->lights + ent->entlights[i];
- stylescale = d_lightstylevalue[sl->style] * (1.0f / 65536.0f);
- VectorSubtract (ent->origin, sl->origin, v);
- f = ((1.0f / (DotProduct(v, v) * sl->falloff + sl->distbias)) - sl->subtract) * stylescale;
- VectorScale(sl->light, f, ambientcolor);
- intensity = DotProduct(ambientcolor, ambientcolor);
- if (f < 0)
- intensity *= -1.0f;
- if (nearlights < maxnearlights)
- j = nearlights++;
- else
+ nl = &nearlight[0];
+ for (i = 0;i < ent->numentlights;i++)
{
- for (j = 0;j < maxnearlights;j++)
- {
- if (nearlight[j].intensity < intensity)
- {
- if (nearlight[j].intensity > 0)
- VectorAdd(basecolor, nearlight[j].ambientlight, basecolor);
- break;
- }
- }
- }
- if (j >= maxnearlights)
- {
- // this light is less significant than all others,
- // add it to ambient
- if (intensity > 0)
- VectorAdd(basecolor, ambientcolor, basecolor);
- }
- else
- {
- nl = nearlight + j;
- nl->intensity = intensity;
- // transform the light into the model's coordinate system
- if (worldcoords)
- VectorCopy(sl->origin, nl->origin);
- else
- Matrix4x4_Transform(&ent->inversematrix, sl->origin, nl->origin);
- // integrate mscale into falloff, for maximum speed
- nl->falloff = sl->falloff * mscale;
- VectorCopy(ambientcolor, nl->ambientlight);
- nl->light[0] = sl->light[0] * stylescale * colorr * 4.0f;
- nl->light[1] = sl->light[1] * stylescale * colorg * 4.0f;
- nl->light[2] = sl->light[2] * stylescale * colorb * 4.0f;
- nl->subtract = sl->subtract;
- nl->offset = sl->distbias;
- }
- }
- for (i = 0;i < r_numdlights;i++)
- {
- rd = r_dlight + i;
- VectorCopy(rd->origin, v);
- if (v[0] < ent->mins[0]) v[0] = ent->mins[0];if (v[0] > ent->maxs[0]) v[0] = ent->maxs[0];
- if (v[1] < ent->mins[1]) v[1] = ent->mins[1];if (v[1] > ent->maxs[1]) v[1] = ent->maxs[1];
- if (v[2] < ent->mins[2]) v[2] = ent->mins[2];if (v[2] > ent->maxs[2]) v[2] = ent->maxs[2];
- VectorSubtract (v, rd->origin, v);
- if (DotProduct(v, v) < rd->cullradius2)
- {
- if (CL_TraceLine(ent->origin, rd->origin, NULL, NULL, 0, false, NULL) != 1)
- continue;
- VectorSubtract (ent->origin, rd->origin, v);
- f = ((1.0f / (DotProduct(v, v) + LIGHTOFFSET)) - rd->subtract);
- VectorScale(rd->light, f, ambientcolor);
+ sl = cl.worldmodel->lights + ent->entlights[i];
+ stylescale = d_lightstylevalue[sl->style] * (1.0f / 65536.0f);
+ VectorSubtract (ent->origin, sl->origin, v);
+ f = ((1.0f / (DotProduct(v, v) * sl->falloff + sl->distbias)) - sl->subtract) * stylescale;
+ VectorScale(sl->light, f, ambientcolor);
intensity = DotProduct(ambientcolor, ambientcolor);
if (f < 0)
intensity *= -1.0f;
nl->intensity = intensity;
// transform the light into the model's coordinate system
if (worldcoords)
- VectorCopy(rd->origin, nl->origin);
+ VectorCopy(sl->origin, nl->origin);
else
- {
- Matrix4x4_Transform(&ent->inversematrix, rd->origin, nl->origin);
- /*
- Con_Printf("%i %s : %f %f %f : %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n"
- , rd - r_dlight, ent->model->name
- , rd->origin[0], rd->origin[1], rd->origin[2]
- , nl->origin[0], nl->origin[1], nl->origin[2]
- , ent->inversematrix.m[0][0], ent->inversematrix.m[0][1], ent->inversematrix.m[0][2], ent->inversematrix.m[0][3]
- , ent->inversematrix.m[1][0], ent->inversematrix.m[1][1], ent->inversematrix.m[1][2], ent->inversematrix.m[1][3]
- , ent->inversematrix.m[2][0], ent->inversematrix.m[2][1], ent->inversematrix.m[2][2], ent->inversematrix.m[2][3]
- , ent->inversematrix.m[3][0], ent->inversematrix.m[3][1], ent->inversematrix.m[3][2], ent->inversematrix.m[3][3]);
- */
- }
+ Matrix4x4_Transform(&ent->inversematrix, sl->origin, nl->origin);
// integrate mscale into falloff, for maximum speed
- nl->falloff = mscale;
+ nl->falloff = sl->falloff * mscale;
VectorCopy(ambientcolor, nl->ambientlight);
- nl->light[0] = rd->light[0] * colorr * 4.0f;
- nl->light[1] = rd->light[1] * colorg * 4.0f;
- nl->light[2] = rd->light[2] * colorb * 4.0f;
- nl->subtract = rd->subtract;
- nl->offset = LIGHTOFFSET;
+ nl->light[0] = sl->light[0] * stylescale * colorr * 4.0f;
+ nl->light[1] = sl->light[1] * stylescale * colorg * 4.0f;
+ nl->light[2] = sl->light[2] * stylescale * colorb * 4.0f;
+ nl->subtract = sl->subtract;
+ nl->offset = sl->distbias;
+ }
+ }
+ for (i = 0;i < r_numdlights;i++)
+ {
+ rd = r_dlight + i;
+ VectorCopy(rd->origin, v);
+ if (v[0] < ent->mins[0]) v[0] = ent->mins[0];if (v[0] > ent->maxs[0]) v[0] = ent->maxs[0];
+ if (v[1] < ent->mins[1]) v[1] = ent->mins[1];if (v[1] > ent->maxs[1]) v[1] = ent->maxs[1];
+ if (v[2] < ent->mins[2]) v[2] = ent->mins[2];if (v[2] > ent->maxs[2]) v[2] = ent->maxs[2];
+ VectorSubtract (v, rd->origin, v);
+ if (DotProduct(v, v) < rd->cullradius2)
+ {
+ if (CL_TraceLine(ent->origin, rd->origin, NULL, NULL, 0, false, NULL) != 1)
+ continue;
+ VectorSubtract (ent->origin, rd->origin, v);
+ f = ((1.0f / (DotProduct(v, v) + LIGHTOFFSET)) - rd->subtract);
+ VectorScale(rd->light, f, ambientcolor);
+ intensity = DotProduct(ambientcolor, ambientcolor);
+ if (f < 0)
+ intensity *= -1.0f;
+ if (nearlights < maxnearlights)
+ j = nearlights++;
+ else
+ {
+ for (j = 0;j < maxnearlights;j++)
+ {
+ if (nearlight[j].intensity < intensity)
+ {
+ if (nearlight[j].intensity > 0)
+ VectorAdd(basecolor, nearlight[j].ambientlight, basecolor);
+ break;
+ }
+ }
+ }
+ if (j >= maxnearlights)
+ {
+ // this light is less significant than all others,
+ // add it to ambient
+ if (intensity > 0)
+ VectorAdd(basecolor, ambientcolor, basecolor);
+ }
+ else
+ {
+ nl = nearlight + j;
+ nl->intensity = intensity;
+ // transform the light into the model's coordinate system
+ if (worldcoords)
+ VectorCopy(rd->origin, nl->origin);
+ else
+ {
+ Matrix4x4_Transform(&ent->inversematrix, rd->origin, nl->origin);
+ /*
+ Con_Printf("%i %s : %f %f %f : %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n"
+ , rd - r_dlight, ent->model->name
+ , rd->origin[0], rd->origin[1], rd->origin[2]
+ , nl->origin[0], nl->origin[1], nl->origin[2]
+ , ent->inversematrix.m[0][0], ent->inversematrix.m[0][1], ent->inversematrix.m[0][2], ent->inversematrix.m[0][3]
+ , ent->inversematrix.m[1][0], ent->inversematrix.m[1][1], ent->inversematrix.m[1][2], ent->inversematrix.m[1][3]
+ , ent->inversematrix.m[2][0], ent->inversematrix.m[2][1], ent->inversematrix.m[2][2], ent->inversematrix.m[2][3]
+ , ent->inversematrix.m[3][0], ent->inversematrix.m[3][1], ent->inversematrix.m[3][2], ent->inversematrix.m[3][3]);
+ */
+ }
+ // integrate mscale into falloff, for maximum speed
+ nl->falloff = mscale;
+ VectorCopy(ambientcolor, nl->ambientlight);
+ nl->light[0] = rd->light[0] * colorr * 4.0f;
+ nl->light[1] = rd->light[1] * colorg * 4.0f;
+ nl->light[2] = rd->light[2] * colorb * 4.0f;
+ nl->subtract = rd->subtract;
+ nl->offset = LIGHTOFFSET;
+ }
}
}
}
}
else
- {
R_CompleteLightPoint (basecolor, ent->origin, true, NULL);
- }
basecolor[0] *= colorr;
basecolor[1] *= colorg;
basecolor[2] *= colorb;
avc = colors;
if (nearlights)
{
+ GL_UseColorArray();
av = vertices;
avn = normals;
for (i = 0;i < numverts;i++)
}
}
else
- {
- for (i = 0;i < numverts;i++)
- {
- VectorCopy(basecolor, avc);
- avc[3] = a;
- avc += 4;
- }
- }
+ GL_Color(basecolor[0], basecolor[1], basecolor[2], a);
}
void R_UpdateEntLights(entity_render_t *ent)
#include "quakedef.h"
#include "r_shadow.h"
+#define SHADOWSTAGE_NONE 0
+#define SHADOWSTAGE_STENCIL 1
+#define SHADOWSTAGE_LIGHT 2
+#define SHADOWSTAGE_ERASESTENCIL 3
+
+int r_shadowstage = SHADOWSTAGE_NONE;
+
mempool_t *r_shadow_mempool;
int maxshadowelements;
rtexture_t *r_shadow_attenuation2dtexture;
rtexture_t *r_shadow_blankbumptexture;
-cvar_t r_shadow1 = {0, "r_shadow1", "16"};
-cvar_t r_shadow2 = {0, "r_shadow2", "2"};
-cvar_t r_shadow3 = {0, "r_shadow3", "65536"};
-cvar_t r_shadow4 = {0, "r_shadow4", "1"};
+cvar_t r_shadow1 = {0, "r_shadow1", "2"};
+cvar_t r_shadow2 = {0, "r_shadow2", "0"};
+cvar_t r_shadow3 = {0, "r_shadow3", "32768"};
+cvar_t r_shadow4 = {0, "r_shadow4", "0"};
cvar_t r_shadow5 = {0, "r_shadow5", "0"};
-cvar_t r_shadow6 = {0, "r_shadow6", "1"};
+cvar_t r_shadow6 = {0, "r_shadow6", "0"};
cvar_t r_light_realtime = {0, "r_light_realtime", "0"};
cvar_t r_light_quality = {0, "r_light_quality", "1"};
cvar_t r_light_gloss = {0, "r_light_gloss", "0"};
R_RegisterModule("R_Shadow", r_shadow_start, r_shadow_shutdown, r_shadow_newmap);
}
-void R_Shadow_Volume(int numverts, int numtris, float *vertex, int *elements, int *neighbors, vec3_t relativelightorigin, float lightradius, float projectdistance, int visiblevolume)
+void R_Shadow_Volume(int numverts, int numtris, float *vertex, int *elements, int *neighbors, vec3_t relativelightorigin, float lightradius, float projectdistance)
{
int i, *e, *n, *out, tris;
float *v0, *v1, *v2, temp[3], f;
}
}
}
- R_Shadow_RenderVolume(numverts * 2, tris, shadowelements, visiblevolume);
+ R_Shadow_RenderVolume(numverts * 2, tris, shadowelements);
}
-void R_Shadow_RenderVolume(int numverts, int numtris, int *elements, int visiblevolume)
+void R_Shadow_RenderVolume(int numverts, int numtris, int *elements)
{
+ if (!numverts || !numtris)
+ return;
// draw the volume
- if (visiblevolume)
- {
- //qglDisable(GL_CULL_FACE);
- R_Mesh_Draw(numverts, numtris, elements);
- //qglEnable(GL_CULL_FACE);
- }
- else
+ if (r_shadowstage == SHADOWSTAGE_STENCIL)
{
// increment stencil if backface is behind depthbuffer
qglCullFace(GL_BACK); // quake is backwards, this culls front faces
qglStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
R_Mesh_Draw(numverts, numtris, elements);
}
+ else
+ R_Mesh_Draw(numverts, numtris, elements);
}
float r_shadow_atten1, r_shadow_atten2, r_shadow_atten5;
v[0] = (x + 0.5f) * (2.0f / (float) ATTEN3DSIZE) - 1.0f;
v[1] = (y + 0.5f) * (2.0f / (float) ATTEN3DSIZE) - 1.0f;
v[2] = (z + 0.5f) * (2.0f / (float) ATTEN3DSIZE) - 1.0f;
- length = sqrt(DotProduct(v, v));
- if (DotProduct(v, v) < 1)
- intensity = (((r_shadow_atten1 / (length*length + r_shadow_atten5)) - (r_shadow_atten1 * r_shadow_atten2))) / 256.0f;
- else
- intensity = 0;
- ilen = 127.0f * bound(0, intensity, 1) / length;
+ intensity = 1.0f - sqrt(DotProduct(v, v));
+ if (intensity > 0)
+ intensity *= intensity;
+ ilen = 127.0f * bound(0, intensity * r_shadow_atten1, 1) / sqrt(DotProduct(v, v));
data[z][y][x][0] = 128.0f + ilen * v[0];
data[z][y][x][1] = 128.0f + ilen * v[1];
data[z][y][x][2] = 128.0f + ilen * v[2];
v[0] = (x + 0.5f) * (2.0f / 128.0f) - 1.0f;
v[1] = (y + 0.5f) * (2.0f / 128.0f) - 1.0f;
v[2] = 0;
- if (DotProduct(v, v) < 1)
- intensity = (((r_shadow_atten1 / (DotProduct(v, v)+r_shadow_atten5)) - (r_shadow_atten1 * r_shadow_atten2))) / 256.0f;
- else
- intensity = 0;
- d = bound(0, intensity, 255) / sqrt(DotProduct(v, v));
+ intensity = 1.0f - sqrt(DotProduct(v, v));
+ if (intensity > 0)
+ intensity *= intensity;
+ intensity = bound(0, intensity * r_shadow_atten1 * 256.0f, 255.0f);
+ d = bound(0, intensity, 255);
data[0][y][x][0] = d;
data[0][y][x][1] = d;
data[0][y][x][2] = d;
- data[0][y][x][3] = 255;
+ data[0][y][x][3] = d;
}
}
- r_shadow_attenuation2dtexture = R_LoadTexture2D(r_shadow_texturepool, "attenuation2d", 128, 128, &data[0][0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP, NULL);
+ r_shadow_attenuation2dtexture = R_LoadTexture2D(r_shadow_texturepool, "attenuation2d", 128, 128, &data[0][0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP | TEXF_ALPHA | TEXF_MIPMAP, NULL);
R_Shadow_Make3DTextures();
}
m.blendfunc2 = GL_ZERO;
R_Mesh_State(&m);
GL_Color(0, 0, 0, 1);
+ r_shadowstage = SHADOWSTAGE_NONE;
}
void R_Shadow_Stage_ShadowVolumes(void)
qglEnable(GL_STENCIL_TEST);
qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
qglStencilFunc(GL_ALWAYS, 0, 0xFF);
+ qglEnable(GL_CULL_FACE);
+ qglEnable(GL_DEPTH_TEST);
+ r_shadowstage = SHADOWSTAGE_STENCIL;
}
void R_Shadow_Stage_Light(void)
// only draw light where this geometry was already rendered AND the
// stencil is 0 (non-zero means shadow)
qglStencilFunc(GL_EQUAL, 0, 0xFF);
+ qglEnable(GL_CULL_FACE);
+ qglEnable(GL_DEPTH_TEST);
+ r_shadowstage = SHADOWSTAGE_LIGHT;
}
-void R_Shadow_Stage_End(void)
+void R_Shadow_Stage_EraseShadowVolumes(void)
{
rmeshstate_t m;
+ memset(&m, 0, sizeof(m));
+ R_Mesh_TextureState(&m);
+ GL_Color(1, 1, 1, 1);
+ qglColorMask(0, 0, 0, 0);
+ qglDisable(GL_BLEND);
+ qglDepthMask(0);
+ qglDepthFunc(GL_LESS);
+ qglClearStencil(0);
+ qglClear(GL_STENCIL_BUFFER_BIT);
+ qglEnable(GL_STENCIL_TEST);
+ qglStencilOp(GL_ZERO, GL_KEEP, GL_KEEP);
+ qglStencilFunc(GL_NOTEQUAL, 0, 0xFF);
+ qglDisable(GL_CULL_FACE);
+ qglDisable(GL_DEPTH_TEST);
+ r_shadowstage = SHADOWSTAGE_ERASESTENCIL;
+}
+
+void R_Shadow_Stage_End(void)
+{
// attempt to restore state to what Mesh_State thinks it is
qglDisable(GL_BLEND);
qglBlendFunc(GL_ONE, GL_ZERO);
qglDisable(GL_STENCIL_TEST);
qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
qglStencilFunc(GL_ALWAYS, 0, 0xFF);
+ qglEnable(GL_CULL_FACE);
+ qglEnable(GL_DEPTH_TEST);
+ r_shadowstage = SHADOWSTAGE_NONE;
}
-void R_Shadow_GenTexCoords_Attenuation2D(float *out, int numverts, const float *vertex, const float *svectors, const float *tvectors, const vec3_t relativelightorigin, float lightradius)
+void R_Shadow_GenTexCoords_Attenuation2D1D(float *out2d, float *out1d, int numverts, const float *vertex, const float *svectors, const float *tvectors, const float *normals, const vec3_t relativelightorigin, float lightradius)
{
int i;
float lightvec[3], iradius;
iradius = 0.5f / lightradius;
- for (i = 0;i < numverts;i++, vertex += 4, svectors += 4, tvectors += 4, out += 4)
+ for (i = 0;i < numverts;i++, vertex += 4, svectors += 4, tvectors += 4, normals += 4, out2d += 4, out1d += 4)
{
VectorSubtract(vertex, relativelightorigin, lightvec);
- out[0] = 0.5f + DotProduct(svectors, lightvec) * iradius;
- out[1] = 0.5f + DotProduct(tvectors, lightvec) * iradius;
- }
-}
-
-void R_Shadow_GenTexCoords_Attenuation1D(float *out, int numverts, const float *vertex, const float *normals, const vec3_t relativelightorigin, float lightradius)
-{
- int i;
- float lightvec[3], iradius;
- iradius = 0.5f / lightradius;
- for (i = 0;i < numverts;i++, vertex += 4, normals += 4, out += 4)
- {
- VectorSubtract(vertex, relativelightorigin, lightvec);
- out[0] = 0.5f + DotProduct(normals, lightvec) * iradius;
- out[1] = 0.5f;
+ out2d[0] = 0.5f + DotProduct(svectors, lightvec) * iradius;
+ out2d[1] = 0.5f + DotProduct(tvectors, lightvec) * iradius;
+ out2d[2] = 0;
+ out1d[0] = 0.5f + DotProduct(normals, lightvec) * iradius;
+ out1d[1] = 0.5f;
+ out1d[2] = 0;
}
}
for (i = 0;i < numverts;i++, vertex += 4, svectors += 4, tvectors += 4, normals += 4, out += 4)
{
VectorSubtract(vertex, relativelightorigin, lightvec);
- if (r_shadow6.integer != 0)
- {
- VectorClear(lightvec);
- if (r_shadow6.integer > 0)
- lightvec[(r_shadow6.integer - 1) % 3] = 64;
- else
- lightvec[((-r_shadow6.integer) - 1) % 3] = -64;
- }
- if (r_shadow4.integer & 8)
- lightvec[0] = -lightvec[0];
- if (r_shadow4.integer & 16)
- lightvec[1] = -lightvec[1];
- if (r_shadow4.integer & 32)
- lightvec[2] = -lightvec[2];
- if (r_shadow4.integer & 1)
- out[0] = 0.5f - DotProduct(svectors, lightvec) * iradius;
- else
- out[0] = 0.5f + DotProduct(svectors, lightvec) * iradius;
- if (r_shadow4.integer & 2)
- out[1] = 0.5f - DotProduct(tvectors, lightvec) * iradius;
- else
- out[2] = 0.5f + DotProduct(tvectors, lightvec) * iradius;
- if (r_shadow4.integer & 4)
- out[2] = 0.5f - DotProduct(normals, lightvec) * iradius;
- else
- out[2] = 0.5f + DotProduct(normals, lightvec) * iradius;
+ out[0] = 0.5f + DotProduct(svectors, lightvec) * iradius;
+ out[1] = 0.5f + DotProduct(tvectors, lightvec) * iradius;
+ out[2] = 0.5f + DotProduct(normals, lightvec) * iradius;
}
}
-void R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(float *out, int numverts, const float *vertex, const float *svectors, const float *tvectors, const float *normals, const vec3_t relativelightorigin, float lightradius)
+void R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(float *out, int numverts, const float *vertex, const float *svectors, const float *tvectors, const float *normals, const vec3_t relativelightorigin)
{
int i;
float lightdir[3], iradius;
- iradius = 0.5f / lightradius;
for (i = 0;i < numverts;i++, vertex += 4, svectors += 4, tvectors += 4, normals += 4, out += 4)
{
VectorSubtract(vertex, relativelightorigin, lightdir);
}
}
-void R_Shadow_GenTexCoords_Specular_NormalCubeMap(float *out, int numverts, const float *vertex, const float *svectors, const float *tvectors, const float *normals, const vec3_t relativelightorigin, const vec3_t relativeeyeorigin, float lightradius)
+void R_Shadow_GenTexCoords_Specular_NormalCubeMap(float *out, int numverts, const float *vertex, const float *svectors, const float *tvectors, const float *normals, const vec3_t relativelightorigin, const vec3_t relativeeyeorigin)
{
int i;
float lightdir[3], eyedir[3], halfdir[3], lightdirlen, ilen, iradius;
- iradius = 0.5f / lightradius;
for (i = 0;i < numverts;i++, vertex += 4, svectors += 4, tvectors += 4, normals += 4, out += 4)
{
VectorSubtract(vertex, relativelightorigin, lightdir);
void R_Shadow_GenTexCoords_LightCubeMap(float *out, int numverts, const float *vertex, const vec3_t relativelightorigin)
{
int i;
+ // FIXME: this needs to be written
+ // this code assumes the vertices are in worldspace (a false assumption)
for (i = 0;i < numverts;i++, vertex += 4, out += 4)
VectorSubtract(vertex, relativelightorigin, out);
}
void R_Shadow_RenderLighting(int numverts, int numtriangles, const int *elements, const float *svectors, const float *tvectors, const float *normals, const float *texcoords, const float *relativelightorigin, const float *relativeeyeorigin, float lightradius, const float *lightcolor, rtexture_t *basetexture, rtexture_t *glosstexture, rtexture_t *bumptexture, rtexture_t *lightcubemap)
{
- float f;
+ int mult;
+ float scale, colorscale;
rmeshstate_t m;
memset(&m, 0, sizeof(m));
if (!bumptexture)
bumptexture = r_shadow_blankbumptexture;
- f = 1.0f / r_shadow3.value;
+ // colorscale accounts for how much we multiply the brightness during combine
if (r_light_quality.integer == 1)
{
- // 4 texture 3D path, two pass
- GL_Color(1,1,1,1);
- //lightcolor[0] * f, lightcolor[1] * f, lightcolor[2] * f, 1);
- memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4]));
- memcpy(varray_texcoord[2], texcoords, numverts * sizeof(float[4]));
- if (r_light_gloss.integer != 2)
+ if (r_textureunits.integer >= 4)
+ colorscale = r_colorscale * 0.125f / r_shadow3.value;
+ else
+ colorscale = r_colorscale * 0.5f / r_shadow3.value;
+ }
+ else
+ colorscale = r_colorscale * 0.5f / r_shadow3.value;
+ // limit mult to 64 for sanity sake
+ for (mult = 1, scale = ixtable[mult];mult < 64 && (lightcolor[0] * scale * colorscale > 1 || lightcolor[1] * scale * colorscale > 1 || lightcolor[2] * scale * colorscale > 1);mult++, scale = ixtable[mult]);
+ colorscale *= scale;
+ for (;mult > 0;mult--)
+ {
+ if (r_light_quality.integer == 1)
{
- m.tex[0] = R_GetTexture(bumptexture);
- m.tex3d[1] = R_GetTexture(r_shadow_normalsattenuationtexture);
- m.tex[2] = R_GetTexture(basetexture);
- m.texcubemap[3] = R_GetTexture(lightcubemap);
- m.texcombinergb[0] = GL_REPLACE;
- m.texcombinergb[1] = GL_DOT3_RGB_ARB;
- m.texcombinergb[2] = GL_MODULATE;
- m.texcombinergb[3] = GL_MODULATE;
- m.texrgbscale[2] = 2;
- R_Mesh_TextureState(&m);
- R_Shadow_GenTexCoords_Diffuse_Attenuation3D(varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin, lightradius);
- if (m.texcubemap[3])
- R_Shadow_GenTexCoords_LightCubeMap(varray_texcoord[3], numverts, varray_vertex, relativelightorigin);
- R_Mesh_Draw(numverts, numtriangles, elements);
+ if (r_textureunits.integer >= 4)
+ {
+ // 4 texture 3D path, two pass
+ m.tex[0] = R_GetTexture(bumptexture);
+ m.tex3d[1] = R_GetTexture(r_shadow_normalsattenuationtexture);
+ m.tex[2] = R_GetTexture(basetexture);
+ m.texcubemap[3] = R_GetTexture(lightcubemap);
+ m.tex[3] = R_GetTexture(r_notexture);
+ m.texcombinergb[0] = GL_REPLACE;
+ m.texcombinergb[1] = GL_DOT3_RGB_ARB;
+ m.texcombinergb[2] = GL_MODULATE;
+ m.texcombinergb[3] = GL_MODULATE;
+ m.texrgbscale[1] = 2;
+ m.texrgbscale[3] = 4;
+ R_Mesh_TextureState(&m);
+ GL_Color(lightcolor[0] * colorscale, lightcolor[1] * colorscale, lightcolor[2] * colorscale, 1);
+ memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4]));
+ memcpy(varray_texcoord[2], texcoords, numverts * sizeof(float[4]));
+ if (lightcubemap)
+ R_Shadow_GenTexCoords_LightCubeMap(varray_texcoord[3], numverts, varray_vertex, relativelightorigin);
+ else
+ {
+ qglActiveTexture(GL_TEXTURE3_ARB);
+ qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR_ARB);
+ }
+ R_Shadow_GenTexCoords_Diffuse_Attenuation3D(varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin, lightradius);
+ R_Mesh_Draw(numverts, numtriangles, elements);
+ if (!lightcubemap)
+ {
+ qglActiveTexture(GL_TEXTURE3_ARB);
+ qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
+ }
+ if (r_light_gloss.integer && glosstexture)
+ {
+ m.tex[2] = R_GetTexture(glosstexture);
+ R_Mesh_TextureState(&m);
+ R_Shadow_GenTexCoords_Specular_Attenuation3D(varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin, relativeeyeorigin, lightradius);
+ if (!lightcubemap)
+ {
+ qglActiveTexture(GL_TEXTURE3_ARB);
+ qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR_ARB);
+ }
+ R_Mesh_Draw(numverts, numtriangles, elements);
+ if (!lightcubemap)
+ {
+ qglActiveTexture(GL_TEXTURE3_ARB);
+ qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
+ }
+ }
+ }
+ else
+ {
+ // 2 texture 3D path, four pass
+ m.tex[0] = R_GetTexture(bumptexture);
+ m.tex3d[1] = R_GetTexture(r_shadow_normalsattenuationtexture);
+ m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
+ m.texalphascale[1] = 2;
+ R_Mesh_TextureState(&m);
+ qglColorMask(0,0,0,1);
+ qglDisable(GL_BLEND);
+ GL_Color(1,1,1,1);
+ memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4]));
+ R_Shadow_GenTexCoords_Diffuse_Attenuation3D(varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin, lightradius);
+ R_Mesh_Draw(numverts, numtriangles, elements);
+
+ m.tex[0] = R_GetTexture(basetexture);
+ m.tex3d[1] = 0;
+ m.texcubemap[1] = R_GetTexture(lightcubemap);
+ m.texcombinergb[1] = GL_MODULATE;
+ m.texrgbscale[1] = 1;
+ m.texalphascale[1] = 1;
+ R_Mesh_TextureState(&m);
+ qglColorMask(1,1,1,1);
+ qglBlendFunc(GL_DST_ALPHA, GL_ONE);
+ qglEnable(GL_BLEND);
+ GL_Color(lightcolor[0] * colorscale, lightcolor[1] * colorscale, lightcolor[2] * colorscale, 1);
+ if (lightcubemap)
+ R_Shadow_GenTexCoords_LightCubeMap(varray_texcoord[1], numverts, varray_vertex, relativelightorigin);
+ R_Mesh_Draw(numverts, numtriangles, elements);
+ }
}
- if (r_light_gloss.integer && glosstexture)
+ else
{
+ // 2 texture no3D path, six pass
+ m.tex[0] = R_GetTexture(r_shadow_attenuation2dtexture);
+ m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture);
+ R_Mesh_TextureState(&m);
+ qglColorMask(0,0,0,1);
+ qglDisable(GL_BLEND);
+ GL_Color(1,1,1,1);
+ R_Shadow_GenTexCoords_Attenuation2D1D(varray_texcoord[0], varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin, lightradius);
+ R_Mesh_Draw(numverts, numtriangles, elements);
+
m.tex[0] = R_GetTexture(bumptexture);
- m.tex3d[1] = R_GetTexture(r_shadow_normalsattenuationtexture);
- m.tex[2] = R_GetTexture(glosstexture);
- m.texcubemap[3] = R_GetTexture(lightcubemap);
- m.texcombinergb[0] = GL_REPLACE;
- m.texcombinergb[1] = GL_DOT3_RGB_ARB;
- m.texcombinergb[2] = GL_MODULATE;
- m.texcombinergb[3] = GL_MODULATE;
- m.texrgbscale[2] = 2;
+ m.tex[1] = 0;
+ m.texcubemap[1] = R_GetTexture(r_shadow_normalscubetexture);
+ m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
+ m.texalphascale[1] = 2;
R_Mesh_TextureState(&m);
- R_Shadow_GenTexCoords_Specular_Attenuation3D(varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin, relativeeyeorigin, lightradius);
+ qglBlendFunc(GL_DST_ALPHA, GL_ZERO);
+ qglEnable(GL_BLEND);
+ memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4]));
+ R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin);
+ R_Mesh_Draw(numverts, numtriangles, elements);
+
+ m.tex[0] = R_GetTexture(basetexture);
+ m.texcubemap[1] = R_GetTexture(lightcubemap);
+ m.texcombinergb[1] = GL_MODULATE;
+ m.texrgbscale[1] = 1;
+ m.texalphascale[1] = 1;
+ R_Mesh_TextureState(&m);
+ qglColorMask(1,1,1,1);
+ qglBlendFunc(GL_DST_ALPHA, GL_ONE);
+ GL_Color(lightcolor[0] * colorscale, lightcolor[1] * colorscale, lightcolor[2] * colorscale, 1);
+ if (lightcubemap)
+ R_Shadow_GenTexCoords_LightCubeMap(varray_texcoord[1], numverts, varray_vertex, relativelightorigin);
R_Mesh_Draw(numverts, numtriangles, elements);
}
}
- else
- {
- //R_Mesh_TextureState(&m);
- }
}
extern cvar_t r_light_debuglight;
void R_Shadow_Init(void);
-void R_Shadow_Volume(int numverts, int numtris, float *vertex, int *elements, int *neighbors, vec3_t relativelightorigin, float lightradius, float projectdistance, int visiblevolume);
+void R_Shadow_Volume(int numverts, int numtris, float *vertex, int *elements, int *neighbors, vec3_t relativelightorigin, float lightradius, float projectdistance);
void R_Shadow_RenderLighting(int numverts, int numtriangles, const int *elements, const float *svectors, const float *tvectors, const float *normals, const float *texcoords, const float *relativelightorigin, const float *relativeeyeorigin, float lightradius, const float *lightcolor, rtexture_t *basetexture, rtexture_t *glosstexture, rtexture_t *bumptexture, rtexture_t *lightcubemap);
void R_Shadow_ClearStencil(void);
-void R_Shadow_RenderVolume(int numverts, int numtris, int *elements, int visiblevolume);
+void R_Shadow_RenderVolume(int numverts, int numtris, int *elements);
void R_Shadow_Stage_Begin(void);
void R_Shadow_Stage_ShadowVolumes(void);
void R_Shadow_Stage_Light(void);
+void R_Shadow_Stage_EraseShadowVolumes(void);
void R_Shadow_Stage_End(void);
#endif
void R_NewMap (void);
-void R_DrawWorld(entity_render_t *ent, int baselighting);
+void R_DrawWorld(entity_render_t *ent);
void R_DrawParticles(void);
void R_DrawExplosions(void);
//#define PARANOID 1
-int R_CullBox(const vec3_t emins, const vec3_t emaxs);
-int R_NotCulledBox(const vec3_t emins, const vec3_t emaxs);
+int R_CullBox(const vec3_t mins, const vec3_t maxs);
+int PVS_CullBox(const vec3_t mins, const vec3_t maxs);
+int R_CullSphere(const vec3_t origin, vec_t radius);
+int PVS_CullSphere(const vec3_t origin, vec_t radius);
extern qboolean fogenabled;
extern vec3_t fogcolor;
*attrib++ = GLX_BLUE_SIZE;*attrib++ = 1;
*attrib++ = GLX_DOUBLEBUFFER;
*attrib++ = GLX_DEPTH_SIZE;*attrib++ = 1;
+ // if stencil is enabled, ask for alpha too
if (stencil)
{
*attrib++ = GLX_STENCIL_SIZE;*attrib++ = 8;
+ *attrib++ = GLX_ALPHA_SIZE;*attrib++ = 1;
}
if (gamma)
{
HGLRC baseRC;
int CenterX, CenterY;
const char *gldrivername;
-
+
if (vid_initialized)
Sys_Error("VID_InitMode called when video is already initialised\n");
+ // if stencil is enabled, ask for alpha too
if (stencil)
+ {
pfd.cStencilBits = 8;
+ pfd.cAlphaBits = 8;
+ }
else
+ {
pfd.cStencilBits = 0;
+ pfd.cAlphaBits = 0;
+ }
gldrivername = "opengl32.dll";
i = COM_CheckParm("-gl_driver");