cvar_t r_testvis = {0, "r_testvis", "0"};
cvar_t r_floatbuildlightmap = {0, "r_floatbuildlightmap", "0"};
cvar_t r_detailtextures = {CVAR_SAVE, "r_detailtextures", "1"};
-cvar_t r_surfaceworldnode = {0, "r_surfaceworldnode", "0"};
+cvar_t r_surfaceworldnode = {0, "r_surfaceworldnode", "1"};
static int dlightdivtable[32768];
Combine and scale multiple lightmaps into the 8.8 format in blocklights
===============
*/
-static void R_BuildLightMap (const entity_render_t *ent, msurface_t *surf, int dlightchanged)
+static void R_BuildLightMap (const entity_render_t *ent, msurface_t *surf)
{
if (!r_floatbuildlightmap.integer)
{
// update cached lighting info
surf->cached_dlight = 0;
- surf->cached_lightmapscalebit = r_lightmapscalebit;
- surf->cached_ambient = r_ambient.value;
- surf->cached_light[0] = d_lightstylevalue[surf->styles[0]];
- surf->cached_light[1] = d_lightstylevalue[surf->styles[1]];
- surf->cached_light[2] = d_lightstylevalue[surf->styles[2]];
- surf->cached_light[3] = d_lightstylevalue[surf->styles[3]];
smax = (surf->extents[0]>>4)+1;
tmax = (surf->extents[1]>>4)+1;
surf->cached_dlight = R_IntAddDynamicLights(&ent->inversematrix, surf);
if (surf->cached_dlight)
c_light_polys++;
- else if (dlightchanged)
- return; // don't upload if only updating dlights and none mattered
}
// add all the lightmaps
// update cached lighting info
surf->cached_dlight = 0;
- surf->cached_lightmapscalebit = r_lightmapscalebit;
- surf->cached_ambient = r_ambient.value;
- surf->cached_light[0] = d_lightstylevalue[surf->styles[0]];
- surf->cached_light[1] = d_lightstylevalue[surf->styles[1]];
- surf->cached_light[2] = d_lightstylevalue[surf->styles[2]];
- surf->cached_light[3] = d_lightstylevalue[surf->styles[3]];
smax = (surf->extents[0]>>4)+1;
tmax = (surf->extents[1]>>4)+1;
surf->cached_dlight = R_FloatAddDynamicLights(&ent->inversematrix, surf);
if (surf->cached_dlight)
c_light_polys++;
- else if (dlightchanged)
- return; // don't upload if only updating dlights and none mattered
}
// add all the lightmaps
}
}
-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];
return false;
}
-static void RSurfShader_Sky(const entity_render_t *ent, const texture_t *texture, const msurface_t *firstsurf)
+static void RSurfShader_Sky(const entity_render_t *ent, const texture_t *texture, msurface_t **surfchain)
{
const msurface_t *surf;
const surfmesh_t *mesh;
}
m.depthwrite = true;
R_Mesh_State(&m);
- for (surf = firstsurf;surf;surf = surf->texturechain)
+ while((surf = *surfchain++) != NULL)
{
if (surf->visframe == r_framecount)
{
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;
}
}
-static void RSurfShader_Water(const entity_render_t *ent, const texture_t *texture, const msurface_t *firstsurf)
+static void RSurfShader_Water(const entity_render_t *ent, const texture_t *texture, msurface_t **surfchain)
{
const msurface_t *surf;
+ msurface_t **chain;
vec3_t center;
if (texture->rendertype != SURFRENDER_OPAQUE)
{
- for (surf = firstsurf;surf;surf = surf->texturechain)
+ for (chain = surfchain;(surf = *chain) != NULL;chain++)
{
if (surf->visframe == r_framecount)
{
}
}
else
- for (surf = firstsurf;surf;surf = surf->texturechain)
+ for (chain = surfchain;(surf = *chain) != NULL;chain++)
if (surf->visframe == r_framecount)
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);
}
}
-static void RSurfShader_OpaqueWall_Pass_BaseTripleTexCombine(const entity_render_t *ent, const texture_t *texture, const msurface_t *firstsurf)
+static void RSurfShader_OpaqueWall_Pass_BaseTripleTexCombine(const entity_render_t *ent, const texture_t *texture, msurface_t **surfchain)
{
const msurface_t *surf;
const surfmesh_t *mesh;
m.blendfunc1 = GL_ONE;
m.blendfunc2 = GL_ZERO;
m.tex[0] = R_GetTexture(texture->texture);
- m.tex[1] = R_GetTexture(firstsurf->lightmaptexture);
+ m.tex[1] = R_GetTexture((**surfchain).lightmaptexture);
m.tex[2] = R_GetTexture(texture->detailtexture);
m.texrgbscale[0] = 1;
m.texrgbscale[1] = 4;
R_Mesh_State(&m);
cl = (float) (1 << r_lightmapscalebit) * r_colorscale;
GL_Color(cl, cl, cl, 1);
- for (surf = firstsurf;surf;surf = surf->texturechain)
+ while((surf = *surfchain++) != NULL)
{
if (surf->visframe == r_framecount)
{
}
}
-static void RSurfShader_OpaqueWall_Pass_BaseDoubleTex(const entity_render_t *ent, const texture_t *texture, const msurface_t *firstsurf)
+static void RSurfShader_OpaqueWall_Pass_BaseDoubleTex(const entity_render_t *ent, const texture_t *texture, msurface_t **surfchain)
{
const msurface_t *surf;
const surfmesh_t *mesh;
m.blendfunc1 = GL_ONE;
m.blendfunc2 = GL_ZERO;
m.tex[0] = R_GetTexture(texture->texture);
- m.tex[1] = R_GetTexture(firstsurf->lightmaptexture);
+ m.tex[1] = R_GetTexture((**surfchain).lightmaptexture);
if (gl_combine.integer)
m.texrgbscale[1] = 4;
R_Mesh_State(&m);
GL_Color(r_colorscale, r_colorscale, r_colorscale, 1);
- for (surf = firstsurf;surf;surf = surf->texturechain)
+ while((surf = *surfchain++) != NULL)
{
if (surf->visframe == r_framecount)
{
}
}
-static void RSurfShader_OpaqueWall_Pass_BaseTexture(const entity_render_t *ent, const texture_t *texture, const msurface_t *firstsurf)
+static void RSurfShader_OpaqueWall_Pass_BaseTexture(const entity_render_t *ent, const texture_t *texture, msurface_t **surfchain)
{
const msurface_t *surf;
const surfmesh_t *mesh;
m.tex[0] = R_GetTexture(texture->texture);
R_Mesh_State(&m);
GL_Color(1, 1, 1, 1);
- for (surf = firstsurf;surf;surf = surf->texturechain)
+ while((surf = *surfchain++) != NULL)
{
if (surf->visframe == r_framecount)
{
}
}
-static void RSurfShader_OpaqueWall_Pass_BaseLightmap(const entity_render_t *ent, const texture_t *texture, const msurface_t *firstsurf)
+static void RSurfShader_OpaqueWall_Pass_BaseLightmap(const entity_render_t *ent, const texture_t *texture, msurface_t **surfchain)
{
const msurface_t *surf;
const surfmesh_t *mesh;
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_ZERO;
m.blendfunc2 = GL_SRC_COLOR;
- m.tex[0] = R_GetTexture(firstsurf->lightmaptexture);
+ m.tex[0] = R_GetTexture((**surfchain).lightmaptexture);
if (gl_combine.integer)
m.texrgbscale[0] = 4;
R_Mesh_State(&m);
GL_Color(r_colorscale, r_colorscale, r_colorscale, 1);
- for (surf = firstsurf;surf;surf = surf->texturechain)
+ while((surf = *surfchain++) != NULL)
{
if (surf->visframe == r_framecount)
{
}
}
-static void RSurfShader_OpaqueWall_Pass_Light(const entity_render_t *ent, const texture_t *texture, const msurface_t *firstsurf)
+static void RSurfShader_OpaqueWall_Pass_Light(const entity_render_t *ent, const texture_t *texture, msurface_t **surfchain)
{
const msurface_t *surf;
const surfmesh_t *mesh;
}
R_Mesh_State(&m);
GL_UseColorArray();
- for (surf = firstsurf;surf;surf = surf->texturechain)
+ while((surf = *surfchain++) != NULL)
{
if (surf->visframe == r_framecount && surf->dlightframe == r_framecount)
{
}
}
-static void RSurfShader_OpaqueWall_Pass_Fog(const entity_render_t *ent, const texture_t *texture, const msurface_t *firstsurf)
+static void RSurfShader_OpaqueWall_Pass_Fog(const entity_render_t *ent, const texture_t *texture, msurface_t **surfchain)
{
const msurface_t *surf;
const surfmesh_t *mesh;
m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
R_Mesh_State(&m);
GL_UseColorArray();
- for (surf = firstsurf;surf;surf = surf->texturechain)
+ while((surf = *surfchain++) != NULL)
{
if (surf->visframe == r_framecount)
{
}
}
-static void RSurfShader_OpaqueWall_Pass_BaseDetail(const entity_render_t *ent, const texture_t *texture, const msurface_t *firstsurf)
+static void RSurfShader_OpaqueWall_Pass_BaseDetail(const entity_render_t *ent, const texture_t *texture, msurface_t **surfchain)
{
const msurface_t *surf;
const surfmesh_t *mesh;
m.tex[0] = R_GetTexture(texture->detailtexture);
R_Mesh_State(&m);
GL_Color(1, 1, 1, 1);
- for (surf = firstsurf;surf;surf = surf->texturechain)
+ while((surf = *surfchain++) != NULL)
{
if (surf->visframe == r_framecount)
{
}
}
-static void RSurfShader_OpaqueWall_Pass_Glow(const entity_render_t *ent, const texture_t *texture, const msurface_t *firstsurf)
+static void RSurfShader_OpaqueWall_Pass_Glow(const entity_render_t *ent, const texture_t *texture, msurface_t **surfchain)
{
const msurface_t *surf;
const surfmesh_t *mesh;
m.tex[0] = R_GetTexture(texture->glowtexture);
R_Mesh_State(&m);
GL_Color(r_colorscale, r_colorscale, r_colorscale, 1);
- for (surf = firstsurf;surf;surf = surf->texturechain)
+ while((surf = *surfchain++) != NULL)
{
if (surf->visframe == r_framecount)
{
}
}
-static void RSurfShader_OpaqueWall_Pass_OpaqueGlow(const entity_render_t *ent, const texture_t *texture, const msurface_t *firstsurf)
+static void RSurfShader_OpaqueWall_Pass_OpaqueGlow(const entity_render_t *ent, const texture_t *texture, msurface_t **surfchain)
{
const msurface_t *surf;
const surfmesh_t *mesh;
GL_Color(r_colorscale, r_colorscale, r_colorscale, 1);
else
GL_Color(0, 0, 0, 1);
- for (surf = firstsurf;surf;surf = surf->texturechain)
+ while((surf = *surfchain++) != NULL)
{
if (surf->visframe == r_framecount)
{
{
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);
}
-extern cvar_t r_shadows;
-static void RSurfShader_Wall_Lightmap(const entity_render_t *ent, const texture_t *texture, const msurface_t *firstsurf)
+static void RSurfShader_Wall_Lightmap(const entity_render_t *ent, const texture_t *texture, msurface_t **surfchain)
{
const msurface_t *surf;
+ msurface_t **chain;
vec3_t center;
if (texture->rendertype != SURFRENDER_OPAQUE)
{
// transparent vertex shaded from lightmap
- for (surf = firstsurf;surf;surf = surf->texturechain)
+ for (chain = surfchain;(surf = *chain) != NULL;chain++)
{
if (surf->visframe == r_framecount)
{
}
}
}
- else if (r_shadows.integer == 3 && cl.worldmodel->numlights)
+ else if (r_shadow_lightingmode >= 2)
{
// opaque base lighting
- RSurfShader_OpaqueWall_Pass_OpaqueGlow(ent, texture, firstsurf);
+ RSurfShader_OpaqueWall_Pass_OpaqueGlow(ent, texture, surfchain);
if (fogenabled)
- RSurfShader_OpaqueWall_Pass_Fog(ent, texture, firstsurf);
+ RSurfShader_OpaqueWall_Pass_Fog(ent, texture, surfchain);
}
else if (r_vertexsurfaces.integer)
{
// opaque vertex shaded from lightmap
- for (surf = firstsurf;surf;surf = surf->texturechain)
+ for (chain = surfchain;(surf = *chain) != NULL;chain++)
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)
+ for (chain = surfchain;(surf = *chain) != NULL;chain++)
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)
+ for (chain = surfchain;(surf = *chain) != NULL;chain++)
if (surf->visframe == r_framecount)
- RSurfShader_Wall_Pass_Fog(ent, surf);
+ RSurfShader_Wall_Pass_Fog(ent, surf, texture, texture->rendertype, texture->currentalpha);
}
else
{
if (r_textureunits.integer >= 2)
{
if (r_textureunits.integer >= 3 && gl_combine.integer && r_detailtextures.integer)
- RSurfShader_OpaqueWall_Pass_BaseTripleTexCombine(ent, texture, firstsurf);
+ RSurfShader_OpaqueWall_Pass_BaseTripleTexCombine(ent, texture, surfchain);
else
{
- RSurfShader_OpaqueWall_Pass_BaseDoubleTex(ent, texture, firstsurf);
+ RSurfShader_OpaqueWall_Pass_BaseDoubleTex(ent, texture, surfchain);
if (r_detailtextures.integer)
- RSurfShader_OpaqueWall_Pass_BaseDetail(ent, texture, firstsurf);
+ RSurfShader_OpaqueWall_Pass_BaseDetail(ent, texture, surfchain);
}
}
else
{
- RSurfShader_OpaqueWall_Pass_BaseTexture(ent, texture, firstsurf);
- RSurfShader_OpaqueWall_Pass_BaseLightmap(ent, texture, firstsurf);
+ RSurfShader_OpaqueWall_Pass_BaseTexture(ent, texture, surfchain);
+ RSurfShader_OpaqueWall_Pass_BaseLightmap(ent, texture, surfchain);
if (r_detailtextures.integer)
- RSurfShader_OpaqueWall_Pass_BaseDetail(ent, texture, firstsurf);
+ RSurfShader_OpaqueWall_Pass_BaseDetail(ent, texture, surfchain);
}
if (!r_dlightmap.integer && !(ent->effects & EF_FULLBRIGHT))
- RSurfShader_OpaqueWall_Pass_Light(ent, texture, firstsurf);
+ RSurfShader_OpaqueWall_Pass_Light(ent, texture, surfchain);
if (texture->glowtexture)
- RSurfShader_OpaqueWall_Pass_Glow(ent, texture, firstsurf);
+ RSurfShader_OpaqueWall_Pass_Glow(ent, texture, surfchain);
if (fogenabled)
- RSurfShader_OpaqueWall_Pass_Fog(ent, texture, firstsurf);
+ RSurfShader_OpaqueWall_Pass_Fog(ent, texture, surfchain);
}
}
&Cshader_sky
};
-extern cvar_t r_shadows;
+void R_UpdateTextureInfo(entity_render_t *ent)
+{
+ int i, texframe, alttextures;
+ texture_t *t;
+
+ if (!ent->model)
+ return;
+
+ alttextures = ent->frame != 0;
+ texframe = (int)(cl.time * 5.0f);
+ for (i = 0;i < ent->model->numtextures;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 (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 = t->anim_frames[alttextures][(t->anim_total[alttextures] >= 2) ? (texframe % t->anim_total[alttextures]) : 0];
+ }
+}
+
void R_PrepareSurfaces(entity_render_t *ent)
{
- int i, texframe, numsurfaces, *surfacevisframes;
+ int i, numsurfaces, *surfacevisframes;
model_t *model;
- msurface_t *surf, *surfaces;
- texture_t *t;
+ msurface_t *surf, *surfaces, **surfchain;
vec3_t modelorg;
if (!ent->model)
surfaces = model->surfaces + model->firstmodelsurface;
surfacevisframes = model->surfacevisframes + model->firstmodelsurface;
- texframe = (int)(cl.time * 5.0f);
- for (i = 0;i < model->numtextures;i++)
+ R_UpdateTextureInfo(ent);
+
+ if (r_dynamic.integer && r_shadow_lightingmode < 1)
+ R_MarkLights(ent);
+
+ if (model->light_ambient != r_ambient.value || model->light_scalebit != r_lightmapscalebit)
{
- t = model->textures + i;
- 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)
- t->rendertype = SURFRENDER_ALPHA;
- else
- t->rendertype = SURFRENDER_OPAQUE;
- if (t->animated)
+ model->light_ambient = r_ambient.value;
+ model->light_scalebit = r_lightmapscalebit;
+ for (i = 0;i < model->nummodelsurfaces;i++)
+ model->surfaces[i + model->firstmodelsurface].cached_dlight = true;
+ }
+ else
+ {
+ for (i = 0;i < model->light_styles;i++)
{
- 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];
+ if (model->light_stylevalue[i] != d_lightstylevalue[model->light_style[i]])
+ {
+ model->light_stylevalue[i] = d_lightstylevalue[model->light_style[i]];
+ for (surfchain = model->light_styleupdatechains[i];*surfchain;surfchain++)
+ (**surfchain).cached_dlight = true;
+ }
}
}
- if (r_dynamic.integer && r_shadows.integer != 3)
- R_MarkLights(ent);
-
for (i = 0, surf = surfaces;i < numsurfaces;i++, surf++)
{
if (surfacevisframes[i] == r_framecount)
{
c_faces++;
surf->visframe = r_framecount;
- if (!r_vertexsurfaces.integer && surf->lightmaptexture != NULL)
- {
- if (surf->cached_dlight
- || surf->cached_ambient != r_ambient.value
- || surf->cached_lightmapscalebit != r_lightmapscalebit)
- R_BuildLightMap(ent, surf, false); // base lighting changed
- else if (r_dynamic.integer)
- {
- if (surf->styles[0] != 255 && (d_lightstylevalue[surf->styles[0]] != surf->cached_light[0]
- || (surf->styles[1] != 255 && (d_lightstylevalue[surf->styles[1]] != surf->cached_light[1]
- || (surf->styles[2] != 255 && (d_lightstylevalue[surf->styles[2]] != surf->cached_light[2]
- || (surf->styles[3] != 255 && (d_lightstylevalue[surf->styles[3]] != surf->cached_light[3]))))))))
- R_BuildLightMap(ent, surf, false); // base lighting changed
- else if (surf->dlightframe == r_framecount && r_dlightmap.integer)
- R_BuildLightMap(ent, surf, true); // only dlights
- }
- }
+ if (surf->cached_dlight && surf->lightmaptexture != NULL && !r_vertexsurfaces.integer)
+ R_BuildLightMap(ent, surf);
}
}
}
}
-void R_DrawSurfaces(entity_render_t *ent, int type)
+void R_DrawSurfaces(entity_render_t *ent, int type, msurface_t ***chains)
{
int i;
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 && chains[i] != NULL)
+ t->shader->shaderfunc[type](ent, t->currentframe, chains[i]);
}
static void R_DrawPortal_Callback(const void *calldata1, int calldata2)
int i;
mportal_t *portal, *endportal;
float temp[3], center[3], f;
-
- if (r_drawportals.integer < 1)
- return;
-
for (portal = ent->model->portals, endportal = portal + ent->model->numportals;portal < endportal;portal++)
{
- if (portal->here->pvsframe == ent->model->pvsframecount || portal->past->pvsframe == ent->model->pvsframecount)
+ if ((portal->here->pvsframe == ent->model->pvsframecount || portal->past->pvsframe == ent->model->pvsframecount) && portal->numpoints <= POLYGONELEMENTS_MAXPOINTS)
{
- if (portal->numpoints <= POLYGONELEMENTS_MAXPOINTS)
- {
- VectorClear(temp);
- for (i = 0;i < portal->numpoints;i++)
- VectorAdd(temp, portal->points[i].position, temp);
- f = ixtable[portal->numpoints];
- VectorScale(temp, f, temp);
- Matrix4x4_Transform(&ent->matrix, temp, center);
- R_MeshQueue_AddTransparent(center, R_DrawPortal_Callback, ent, portal - ent->model->portals);
- }
+ VectorClear(temp);
+ for (i = 0;i < portal->numpoints;i++)
+ VectorAdd(temp, portal->points[i].position, temp);
+ f = ixtable[portal->numpoints];
+ VectorScale(temp, f, temp);
+ Matrix4x4_Transform(&ent->matrix, temp, center);
+ R_MeshQueue_AddTransparent(center, R_DrawPortal_Callback, ent, portal - ent->model->portals);
}
}
}
if (PlaneDist(modelorg, surf->plane) < surf->plane->dist)
{
if ((surf->flags & SURF_PLANEBACK))
- {
- surfacevisframes[i] = r_framecount;
- surfacepvsframes[i] = model->pvsframecount;
- }
- }
- else
- {
- if (!(surf->flags & SURF_PLANEBACK))
- {
surfacevisframes[i] = r_framecount;
- surfacepvsframes[i] = model->pvsframecount;
- }
}
+ else if (!(surf->flags & SURF_PLANEBACK))
+ surfacevisframes[i] = r_framecount;
#else
surfacevisframes[i] = r_framecount;
- surfacepvsframes[i] = model->pvsframecount;
#endif
surf->dlightframe = -1;
}
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_CullBox (surf->poly_mins, surf->poly_maxs))
- surfacevisframes[i] = r_framecount;
- }
- else
- {
- if (!(surf->flags & SURF_PLANEBACK) && !R_CullBox (surf->poly_mins, surf->poly_maxs))
- surfacevisframes[i] = r_framecount;
- }
-#else
- if (!R_CullBox (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_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;
- 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)
{
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++)
+ surfacepvsframes[*mark] = model->pvsframecount;
}
}
}
}
+ Mod_BuildPVSTextureChains(model);
}
}
}
-/*
-=============
-R_DrawWorld
-=============
-*/
-void R_DrawWorld (entity_render_t *ent)
+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);
- R_DrawSurfaces(ent, SHADERSTAGE_NORMAL);
+ R_DrawSurfaces(ent, SHADERSTAGE_SKY, ent->model->pvstexturechains);
+ R_DrawSurfaces(ent, SHADERSTAGE_NORMAL, ent->model->pvstexturechains);
}
void R_Model_Brush_DrawSky (entity_render_t *ent)
{
if (ent != &cl_entities[0].render)
R_PrepareBrushModel(ent);
- R_DrawSurfaces(ent, SHADERSTAGE_SKY);
+ R_DrawSurfaces(ent, SHADERSTAGE_SKY, ent->model->pvstexturechains);
}
void R_Model_Brush_Draw (entity_render_t *ent)
c_bmodels++;
if (ent != &cl_entities[0].render)
R_PrepareBrushModel(ent);
- R_DrawSurfaces(ent, SHADERSTAGE_NORMAL);
+ R_DrawSurfaces(ent, SHADERSTAGE_NORMAL, ent->model->pvstexturechains);
}
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);
- }
- }
-#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);
+ 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);
+ R_UpdateTextureInfo(ent);
+ for (surfnum = 0;surfnum < numsurfaces;surfnum++)
+ {
+ surf = surflist[surfnum];
+ if (surf->visframe == r_framecount)
+ {
+ 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);
+ }
+ }
+ }
+ }
+}
+
+void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor)
+{
+ int surfnum;
+ msurface_t *surf;
+ texture_t *t;
+ float f, lightradius2, temp[3];
+ surfmesh_t *mesh;
+ R_Mesh_Matrix(&ent->matrix);
lightradius2 = lightradius * lightradius;
- for (tnum = 0;tnum < ent->model->numtextures;tnum++)
+ R_UpdateTextureInfo(ent);
+ if (ent != &cl_entities[0].render)
{
- t = ent->model->textures + tnum;
- if (ent->model->texturesurfacechains[tnum] && t->rendertype == SURFRENDER_OPAQUE && t->flags & SURF_SHADOWLIGHT)
+ // bmodel, cull crudely to view and light
+ for (surfnum = 0, surf = ent->model->surfaces + ent->model->firstmodelsurface;surfnum < ent->model->nummodelsurfaces;surfnum++, surf++)
{
- t = t->currentframe[ent->frame != 0];
- for (surf = ent->model->texturesurfacechains[tnum];surf;surf = surf->texturechain)
+ 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)
{
- if (surf->visframe == r_framecount)
+ f = PlaneDiff(relativelightorigin, surf->plane);
+ if (surf->flags & SURF_PLANEBACK)
+ f = -f;
+ if (f >= -0.1 && f < lightradius)
+ {
+ 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
+ {
+ // 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 (surf->visframe == r_framecount)
+ {
+ 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)
{
- for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ t = surf->texinfo->texture->currentframe;
+ if (t->rendertype == SURFRENDER_OPAQUE && t->flags & SURF_SHADOWLIGHT)
{
- 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);
+ 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);
+ }
}
}
}