}
}
-void R_StainNode (mnode_t *node, model_t *model, vec3_t origin, float radius, float fcolor[8])
+void R_StainNode (mnode_t *node, model_t *model, const vec3_t origin, float radius, const float fcolor[8])
{
float ndist, a, ratio, maxdist, maxdist2, maxdist3, invradius, sdtable[256], td, dist2;
msurface_t *surf, *endsurf;
}
}
-void R_Stain (vec3_t origin, float radius, int cr1, int cg1, int cb1, int ca1, int cr2, int cg2, int cb2, int ca2)
+void R_Stain (const vec3_t origin, float radius, int cr1, int cg1, int cb1, int ca1, int cr2, int cg2, int cb2, int ca2)
{
int n;
float fcolor[8];
float f, colorscale;
const surfmesh_t *mesh;
rmeshstate_t m;
- float alpha = ent->alpha * (surf->flags & SURF_WATERALPHA ? r_wateralpha.value : 1);
+ float alpha;
float modelorg[3];
texture_t *texture;
Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
R_Mesh_Matrix(&ent->matrix);
memset(&m, 0, sizeof(m));
- texture = surf->texinfo->texture->currentframe[ent->frame != 0];
+ texture = surf->texinfo->texture->currentframe;
+ alpha = texture->currentalpha;
if (texture->rendertype == SURFRENDER_ADD)
{
m.blendfunc1 = GL_SRC_ALPHA;
RSurfShader_Water_Callback(ent, surf - ent->model->surfaces);
}
-static void RSurfShader_Wall_Pass_BaseVertex(const entity_render_t *ent, const msurface_t *surf)
+static void RSurfShader_Wall_Pass_BaseVertex(const entity_render_t *ent, const msurface_t *surf, const texture_t *texture, int rendertype, float currentalpha)
{
float base, colorscale;
const surfmesh_t *mesh;
rmeshstate_t m;
float modelorg[3];
- texture_t *texture;
Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
memset(&m, 0, sizeof(m));
- texture = surf->texinfo->texture->currentframe[ent->frame != 0];
- if (texture->rendertype == SURFRENDER_ADD)
+ if (rendertype == SURFRENDER_ADD)
{
m.blendfunc1 = GL_SRC_ALPHA;
m.blendfunc2 = GL_ONE;
}
- else if (texture->rendertype == SURFRENDER_ALPHA)
+ else if (rendertype == SURFRENDER_ALPHA)
{
m.blendfunc1 = GL_SRC_ALPHA;
m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
R_Mesh_ResizeCheck(mesh->numverts);
memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
memcpy(varray_texcoord[0], mesh->str, mesh->numverts * sizeof(float[4]));
- R_FillColors(varray_color, mesh->numverts, base, base, base, ent->alpha);
+ R_FillColors(varray_color, mesh->numverts, base, base, base, currentalpha);
if (!(ent->effects & EF_FULLBRIGHT))
{
if (surf->dlightframe == r_framecount)
}
}
-static void RSurfShader_Wall_Pass_Glow(const entity_render_t *ent, const msurface_t *surf)
+static void RSurfShader_Wall_Pass_Glow(const entity_render_t *ent, const msurface_t *surf, const texture_t *texture, int rendertype, float currentalpha)
{
const surfmesh_t *mesh;
rmeshstate_t m;
float modelorg[3];
- texture_t *texture;
- texture = surf->texinfo->texture->currentframe[ent->frame != 0];
Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_SRC_ALPHA;
R_Mesh_ResizeCheck(mesh->numverts);
memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
memcpy(varray_texcoord[0], mesh->str, mesh->numverts * sizeof(float[4]));
- RSurf_FoggedColors(varray_vertex, varray_color, 1, 1, 1, ent->alpha, r_colorscale, mesh->numverts, modelorg);
+ RSurf_FoggedColors(varray_vertex, varray_color, 1, 1, 1, currentalpha, r_colorscale, mesh->numverts, modelorg);
R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->index);
}
}
-static void RSurfShader_Wall_Pass_Fog(const entity_render_t *ent, const msurface_t *surf)
+static void RSurfShader_Wall_Pass_Fog(const entity_render_t *ent, const msurface_t *surf, const texture_t *texture, int rendertype, float currentalpha)
{
const surfmesh_t *mesh;
rmeshstate_t m;
float modelorg[3];
- texture_t *texture;
- texture = surf->texinfo->texture->currentframe[ent->frame != 0];
Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_SRC_ALPHA;
memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
if (m.tex[0])
memcpy(varray_texcoord[0], mesh->str, mesh->numverts * sizeof(float[4]));
- RSurf_FogPassColors(varray_vertex, varray_color, fogcolor[0], fogcolor[1], fogcolor[2], ent->alpha, r_colorscale, mesh->numverts, modelorg);
+ RSurf_FogPassColors(varray_vertex, varray_color, fogcolor[0], fogcolor[1], fogcolor[2], currentalpha, r_colorscale, mesh->numverts, modelorg);
R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->index);
}
}
{
const entity_render_t *ent = calldata1;
const msurface_t *surf = ent->model->surfaces + calldata2;
+ int rendertype;
+ float currentalpha;
texture_t *texture;
- texture = surf->texinfo->texture->currentframe[ent->frame != 0];
R_Mesh_Matrix(&ent->matrix);
- RSurfShader_Wall_Pass_BaseVertex(ent, surf);
+
+ texture = surf->texinfo->texture;
+ if (texture->animated)
+ texture = texture->anim_frames[ent->frame != 0][(texture->anim_total[ent->frame != 0] >= 2) ? ((int) (cl.time * 5.0f) % texture->anim_total[ent->frame != 0]) : 0];
+
+ currentalpha = ent->alpha;
+ if (texture->flags & SURF_WATERALPHA)
+ currentalpha *= r_wateralpha.value;
+ if (ent->effects & EF_ADDITIVE)
+ rendertype = SURFRENDER_ADD;
+ else if (currentalpha < 1 || texture->fogtexture != NULL)
+ rendertype = SURFRENDER_ALPHA;
+ else
+ rendertype = SURFRENDER_OPAQUE;
+
+ RSurfShader_Wall_Pass_BaseVertex(ent, surf, texture, rendertype, currentalpha);
if (texture->glowtexture)
- RSurfShader_Wall_Pass_Glow(ent, surf);
+ RSurfShader_Wall_Pass_Glow(ent, surf, texture, rendertype, currentalpha);
if (fogenabled)
- RSurfShader_Wall_Pass_Fog(ent, surf);
+ RSurfShader_Wall_Pass_Fog(ent, surf, texture, rendertype, currentalpha);
}
static void RSurfShader_Wall_Lightmap(const entity_render_t *ent, const texture_t *texture, const msurface_t *firstsurf)
}
}
}
+ else if (r_shadow_lightingmode >= 2)
+ {
+ // 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
for (surf = firstsurf;surf;surf = surf->texturechain)
if (surf->visframe == r_framecount)
- RSurfShader_Wall_Pass_BaseVertex(ent, surf);
+ RSurfShader_Wall_Pass_BaseVertex(ent, surf, texture, texture->rendertype, texture->currentalpha);
if (texture->glowtexture)
for (surf = firstsurf;surf;surf = surf->texturechain)
if (surf->visframe == r_framecount)
- RSurfShader_Wall_Pass_Glow(ent, surf);
+ RSurfShader_Wall_Pass_Glow(ent, surf, texture, texture->rendertype, texture->currentalpha);
if (fogenabled)
for (surf = firstsurf;surf;surf = surf->texturechain)
if (surf->visframe == r_framecount)
- RSurfShader_Wall_Pass_Fog(ent, surf);
+ RSurfShader_Wall_Pass_Fog(ent, surf, texture, texture->rendertype, texture->currentalpha);
}
else
{
}
}
-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
};
-void R_PrepareSurfaces(entity_render_t *ent)
+void R_UpdateTextureInfo(entity_render_t *ent)
{
- int i, texframe, numsurfaces, *surfacevisframes;
- model_t *model;
- msurface_t *surf, *surfaces;
+ int i, texframe, alttextures;
texture_t *t;
- vec3_t modelorg;
if (!ent->model)
return;
- model = ent->model;
- Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
- numsurfaces = model->nummodelsurfaces;
- surfaces = model->surfaces + model->firstmodelsurface;
- surfacevisframes = model->surfacevisframes + model->firstmodelsurface;
-
+ alttextures = ent->frame != 0;
texframe = (int)(cl.time * 5.0f);
- for (i = 0;i < model->numtextures;i++)
+ for (i = 0;i < ent->model->numtextures;i++)
{
- t = model->textures + i;
+ t = ent->model->textures + i;
+ t->currentalpha = ent->alpha;
+ if (t->flags & SURF_WATERALPHA)
+ t->currentalpha *= r_wateralpha.value;
if (ent->effects & EF_ADDITIVE)
t->rendertype = SURFRENDER_ADD;
- else if (ent->alpha < 1 || (t->flags & SURF_WATERALPHA && r_wateralpha.value < 1) || t->fogtexture != NULL)
+ else if (t->currentalpha < 1 || t->fogtexture != NULL)
t->rendertype = SURFRENDER_ALPHA;
else
t->rendertype = SURFRENDER_OPAQUE;
+ // we don't need to set currentframe if t->animated is false because
+ // it was already set up by the texture loader for non-animating
if (t->animated)
- {
- t->currentframe[0] = t->anim_frames[0][(t->anim_total[0] >= 2) ? (texframe % t->anim_total[0]) : 0];
- t->currentframe[1] = t->anim_frames[1][(t->anim_total[1] >= 2) ? (texframe % t->anim_total[1]) : 0];
- }
+ t->currentframe = t->anim_frames[alttextures][(t->anim_total[alttextures] >= 2) ? (texframe % t->anim_total[alttextures]) : 0];
}
+}
+
+void R_PrepareSurfaces(entity_render_t *ent)
+{
+ int i, numsurfaces, *surfacevisframes;
+ model_t *model;
+ msurface_t *surf, *surfaces;
+ vec3_t modelorg;
+
+ if (!ent->model)
+ return;
+
+ model = ent->model;
+ Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
+ numsurfaces = model->nummodelsurfaces;
+ surfaces = model->surfaces + model->firstmodelsurface;
+ surfacevisframes = model->surfacevisframes + model->firstmodelsurface;
+
+ R_UpdateTextureInfo(ent);
- if (r_dynamic.integer)
+ if (r_dynamic.integer && r_shadow_lightingmode < 1)
R_MarkLights(ent);
for (i = 0, surf = surfaces;i < numsurfaces;i++, surf++)
texture_t *t;
R_Mesh_Matrix(&ent->matrix);
for (i = 0, t = ent->model->textures;i < ent->model->numtextures;i++, t++)
- if (t->shader->shaderfunc[type] && ent->model->texturesurfacechains[i])
- t->shader->shaderfunc[type](ent, t, ent->model->texturesurfacechains[i]);
+ if (t->shader->shaderfunc[type] && t->currentframe && ent->model->texturesurfacechains[i])
+ t->shader->shaderfunc[type](ent, t->currentframe, ent->model->texturesurfacechains[i]);
}
static void R_DrawPortal_Callback(const void *calldata1, int calldata2)
void R_SurfaceWorldNode (entity_render_t *ent)
{
- int i, numsurfaces, *surfacevisframes, *surfacepvsframes;
- msurface_t *surfaces, *surf;
+ int i, *surfacevisframes, *surfacepvsframes, surfnum;
+ msurface_t *surf;
+ mleaf_t *leaf;
model_t *model;
vec3_t modelorg;
model = ent->model;
- numsurfaces = model->nummodelsurfaces;
- surfaces = model->surfaces + model->firstmodelsurface;
surfacevisframes = model->surfacevisframes + model->firstmodelsurface;
surfacepvsframes = model->surfacepvsframes + model->firstmodelsurface;
Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
- for (i = 0, surf = surfaces;i < numsurfaces;i++, surf++)
+ for (leaf = model->pvsleafchain;leaf;leaf = leaf->pvschain)
{
- if (surfacepvsframes[i] == model->pvsframecount)
+ if (!R_CullBox (leaf->mins, leaf->maxs))
{
-#if WORLDNODECULLBACKFACES
- if (PlaneDist(modelorg, surf->plane) < surf->plane->dist)
- {
- if ((surf->flags & SURF_PLANEBACK) && R_NotCulledBox (surf->poly_mins, surf->poly_maxs))
- surfacevisframes[i] = r_framecount;
- }
- else
- {
- if (!(surf->flags & SURF_PLANEBACK) && R_NotCulledBox (surf->poly_mins, surf->poly_maxs))
- surfacevisframes[i] = r_framecount;
- }
-#else
- if (R_NotCulledBox (surf->poly_mins, surf->poly_maxs))
- surfacevisframes[i] = r_framecount;
-#endif
+ c_leafs++;
+ leaf->visframe = r_framecount;
}
}
-}
-/*
-static void R_PortalWorldNode(entity_render_t *ent, mleaf_t *viewleaf)
-{
- int portalstack, i;
- mportal_t *p, *pstack[8192];
- msurface_t *surf, **mark, **endmark;
- mleaf_t *leaf;
- // LordHavoc: portal-passage worldnode with PVS;
- // follows portals leading outward from viewleaf, does not venture
- // offscreen or into leafs that are not visible, faster than Quake's
- // RecursiveWorldNode
- leaf = viewleaf;
- leaf->worldnodeframe = r_framecount;
- portalstack = 0;
-loc0:
- c_leafs++;
- if (leaf->nummarksurfaces)
+ for (i = 0;i < model->pvssurflistlength;i++)
{
- for (c = leaf->nummarksurfaces, mark = leaf->firstmarksurface;c;c--)
+ surfnum = model->pvssurflist[i];
+ surf = model->surfaces + surfnum;
+#if WORLDNODECULLBACKFACES
+ if (PlaneDist(modelorg, surf->plane) < surf->plane->dist)
{
- surf = *mark++;
- // make sure surfaces are only processed once
- if (surf->worldnodeframe != r_framecount)
- {
- surf->worldnodeframe = r_framecount;
- if (PlaneDist(r_origin, surf->plane) < surf->plane->dist)
- {
- if (surf->flags & SURF_PLANEBACK)
- surf->visframe = r_framecount;
- }
- else
- {
- if (!(surf->flags & SURF_PLANEBACK))
- surf->visframe = r_framecount;
- }
- }
+ if ((surf->flags & SURF_PLANEBACK) && !R_CullBox (surf->poly_mins, surf->poly_maxs))
+ surfacevisframes[surfnum] = r_framecount;
}
- }
- // follow portals into other leafs
- for (p = leaf->portals;p;p = p->next)
- {
- leaf = p->past;
- if (leaf->worldnodeframe != r_framecount)
+ else
{
- 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))
- {
- p->visframe = r_framecount;
- pstack[portalstack++] = p;
- goto loc0;
-loc1:
- p = pstack[--portalstack];
- }
+ if (!(surf->flags & SURF_PLANEBACK) && !R_CullBox (surf->poly_mins, surf->poly_maxs))
+ surfacevisframes[surfnum] = r_framecount;
}
+#else
+ if (!R_CullBox (surf->poly_mins, surf->poly_maxs))
+ surfacevisframes[surfnum] = r_framecount;
+#endif
}
- if (portalstack)
- goto loc1;
}
-*/
static void R_PortalWorldNode(entity_render_t *ent, mleaf_t *viewleaf)
{
{
c_leafs++;
leaf = leafstack[--leafstackpos];
+ leaf->visframe = r_framecount;
// draw any surfaces bounding this leaf
if (leaf->nummarksurfaces)
{
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;
}
}
model->pvsframecount++;
model->pvsviewleaf = viewleaf;
model->pvsviewleafnovis = r_novis.integer;
+ model->pvsleafchain = NULL;
+ model->pvssurflistlength = 0;
if (viewleaf)
{
surfacepvsframes = model->surfacepvsframes;
if (bits & (1 << i))
{
leaf = &model->leafs[j + i + 1];
+ leaf->pvschain = model->pvsleafchain;
+ model->pvsleafchain = leaf;
leaf->pvsframe = model->pvsframecount;
// mark surfaces bounding this leaf as visible
- for (c = leaf->nummarksurfaces, mark = leaf->firstmarksurface;c;c--)
- surfacepvsframes[*mark++] = model->pvsframecount;
+ for (c = leaf->nummarksurfaces, mark = leaf->firstmarksurface;c;c--, mark++)
+ {
+ //if (surfacepvsframes[*mark] != model->pvsframecount)
+ //{
+ surfacepvsframes[*mark] = model->pvsframecount;
+ // model->pvssurflist[model->pvssurflistlength++] = *mark;
+ //}
+ }
}
}
}
}
+ for (i = 0, j = model->firstmodelsurface;i < model->nummodelsurfaces;i++, j++)
+ if (model->surfacepvsframes[j] == model->pvsframecount)
+ model->pvssurflist[model->pvssurflistlength++] = j;
}
}
}
-/*
-=============
-R_DrawWorld
-=============
-*/
-void R_DrawWorld (entity_render_t *ent, int baselighting)
+void R_WorldVisibility (entity_render_t *ent)
{
vec3_t modelorg;
mleaf_t *viewleaf;
R_SurfaceWorldNode (ent);
else
R_PortalWorldNode (ent, viewleaf);
+}
+
+void R_DrawWorld (entity_render_t *ent)
+{
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];
- shadowmesh_t *mesh;
- VectorSubtract(relativelightorigin, ent->model->shadowmesh_center, temp);
- projectdistance = lightradius + ent->model->shadowmesh_radius - sqrt(DotProduct(temp, temp));
- if (projectdistance >= 0.1)
- {
- R_Mesh_Matrix(&ent->matrix);
- for (mesh = ent->model->shadowmesh;mesh;mesh = mesh->next)
- {
- 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);
- }
- }
-#else
int i;
msurface_t *surf;
float projectdistance, f, temp[3], lightradius2;
surfmesh_t *mesh;
R_Mesh_Matrix(&ent->matrix);
lightradius2 = lightradius * lightradius;
+ R_UpdateTextureInfo(ent);
+ projectdistance = 1000000000.0f;//lightradius + ent->model->radius;
for (i = 0, surf = ent->model->surfaces + ent->model->firstmodelsurface;i < ent->model->nummodelsurfaces;i++, surf++)
{
- if (surf->rendertype == SURFRENDER_OPAQUE && surf->flags & SURF_SHADOWCAST)
+ if (surf->texinfo->texture->rendertype == SURFRENDER_OPAQUE && surf->flags & SURF_SHADOWCAST)
{
f = PlaneDiff(relativelightorigin, surf->plane);
if (surf->flags & SURF_PLANEBACK)
f = -f;
- // draw shadows only for backfaces
- projectdistance = lightradius + f;
- if (projectdistance >= 0.1 && projectdistance < lightradius)
+ // draw shadows only for frontfaces and only if they are close
+ if (f >= 0.1 && f < lightradius)
{
- VectorSubtract(relativelightorigin, surf->poly_center, temp);
- if (DotProduct(temp, temp) < (surf->poly_radius2 + lightradius2))
+ temp[0] = bound(surf->poly_mins[0], relativelightorigin[0], surf->poly_maxs[0]) - relativelightorigin[0];
+ temp[1] = bound(surf->poly_mins[1], relativelightorigin[1], surf->poly_maxs[1]) - relativelightorigin[1];
+ temp[2] = bound(surf->poly_mins[2], relativelightorigin[2], surf->poly_maxs[2]) - relativelightorigin[2];
+ if (DotProduct(temp, temp) < lightradius2)
{
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
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, mesh->index, mesh->triangleneighbors, relativelightorigin, lightradius, projectdistance);
}
}
}
}
}
-#endif
}
-void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float lightdistbias, float lightsubtract, float *lightcolor)
+void R_Model_Brush_DrawLightForSurfaceList(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, msurface_t **surflist, int numsurfaces)
{
- int tnum;
+ int surfnum;
msurface_t *surf;
texture_t *t;
- float f, lightradius2;
surfmesh_t *mesh;
R_Mesh_Matrix(&ent->matrix);
- if (ent != &cl_entities[0].render)
- R_PrepareBrushModel(ent);
- lightradius2 = lightradius * lightradius;
- for (tnum = 0;tnum < ent->model->numtextures;tnum++)
+ R_UpdateTextureInfo(ent);
+ for (surfnum = 0;surfnum < numsurfaces;surfnum++)
{
- t = ent->model->textures + tnum;
- if (ent->model->texturesurfacechains[tnum] && t->rendertype == SURFRENDER_OPAQUE && t->flags & SURF_SHADOWLIGHT)
+ surf = surflist[surfnum];
+ if (surf->visframe == r_framecount)
{
- t = t->currentframe[ent->frame != 0];
- for (surf = ent->model->texturesurfacechains[tnum];surf;surf = surf->texturechain)
+ t = surf->texinfo->texture->currentframe;
+ if (t->rendertype == SURFRENDER_OPAQUE && t->flags & SURF_SHADOWLIGHT)
{
- if (surf->visframe == r_framecount)
+ for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
- f = PlaneDiff(relativelightorigin, surf->plane);
- if (surf->flags & SURF_PLANEBACK)
- f = -f;
- if (f >= -0.1 && f < lightradius)
- {
- for (mesh = surf->mesh;mesh;mesh = mesh->chain)
- {
- R_Mesh_ResizeCheck(mesh->numverts);
- memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
- R_Shadow_RenderLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, t->texture, t->glosstexture, t->nmaptexture, NULL);
- }
- }
+ R_Mesh_ResizeCheck(mesh->numverts);
+ memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
+ R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, lightradius, lightcolor, t->texture, t->nmaptexture, NULL);
+ R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, t->glosstexture, t->nmaptexture, NULL);
}
}
}
}
}
-/*
-extern cvar_t r_shadows;
-void R_DrawBrushModelFakeShadow (entity_render_t *ent)
+void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor)
{
- 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);
+ int surfnum;
+ msurface_t *surf;
+ texture_t *t;
+ float f, lightradius2, temp[3];
+ surfmesh_t *mesh;
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)
+ lightradius2 = lightradius * lightradius;
+ R_UpdateTextureInfo(ent);
+ if (ent != &cl_entities[0].render)
{
- for (i = 0, sl = cl.worldmodel->lights;i < cl.worldmodel->numlights;i++, sl++)
+ // bmodel, cull crudely to view and light
+ for (surfnum = 0, surf = ent->model->surfaces + ent->model->firstmodelsurface;surfnum < ent->model->nummodelsurfaces;surfnum++, surf++)
{
- if (d_lightstylevalue[sl->style] > 0 && R_NotCulledBox(sl->shadowvolumemins, sl->shadowvolumemaxs))
+ temp[0] = bound(surf->poly_mins[0], relativelightorigin[0], surf->poly_maxs[0]) - relativelightorigin[0];
+ temp[1] = bound(surf->poly_mins[1], relativelightorigin[1], surf->poly_maxs[1]) - relativelightorigin[1];
+ temp[2] = bound(surf->poly_mins[2], relativelightorigin[2], surf->poly_maxs[2]) - relativelightorigin[2];
+ if (DotProduct(temp, temp) < lightradius2)
{
- for (mesh = sl->shadowvolume;mesh;mesh = mesh->next)
+ f = PlaneDiff(relativelightorigin, surf->plane);
+ if (surf->flags & SURF_PLANEBACK)
+ f = -f;
+ if (f >= -0.1 && f < lightradius)
{
- memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
- R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->elements);
+ f = PlaneDiff(relativeeyeorigin, surf->plane);
+ if (surf->flags & SURF_PLANEBACK)
+ f = -f;
+ if (f > 0)
+ {
+ t = surf->texinfo->texture->currentframe;
+ if (t->rendertype == SURFRENDER_OPAQUE && t->flags & SURF_SHADOWLIGHT)
+ {
+ for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ {
+ R_Mesh_ResizeCheck(mesh->numverts);
+ memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
+ R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, lightradius, lightcolor, t->texture, t->nmaptexture, NULL);
+ R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, t->glosstexture, t->nmaptexture, NULL);
+ }
+ }
+ }
}
}
}
}
else
{
- for (i = 0, sl = cl.worldmodel->lights;i < cl.worldmodel->numlights;i++, sl++)
+ // world, already culled to view, just cull to light
+ for (surfnum = 0, surf = ent->model->surfaces + ent->model->firstmodelsurface;surfnum < ent->model->nummodelsurfaces;surfnum++, surf++)
{
- 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)
+ if (surf->visframe == r_framecount)
{
- Matrix4x4_Transform(&ent->inversematrix, sl->origin, relativelightorigin);
- R_DrawBrushModelShadowVolume (ent, relativelightorigin, sl->cullradius, true);
+ temp[0] = bound(surf->poly_mins[0], relativelightorigin[0], surf->poly_maxs[0]) - relativelightorigin[0];
+ temp[1] = bound(surf->poly_mins[1], relativelightorigin[1], surf->poly_maxs[1]) - relativelightorigin[1];
+ temp[2] = bound(surf->poly_mins[2], relativelightorigin[2], surf->poly_maxs[2]) - relativelightorigin[2];
+ if (DotProduct(temp, temp) < lightradius2)
+ {
+ f = PlaneDiff(relativelightorigin, surf->plane);
+ if (surf->flags & SURF_PLANEBACK)
+ f = -f;
+ if (f >= -0.1 && f < lightradius)
+ {
+ t = surf->texinfo->texture->currentframe;
+ if (t->rendertype == SURFRENDER_OPAQUE && t->flags & SURF_SHADOWLIGHT)
+ {
+ for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ {
+ R_Mesh_ResizeCheck(mesh->numverts);
+ memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
+ R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, lightradius, lightcolor, t->texture, t->nmaptexture, NULL);
+ R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, t->glosstexture, t->nmaptexture, NULL);
+ }
+ }
+ }
+ }
}
}
}
- 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)
{