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", "1"};
+cvar_t r_surfaceworldnode = {0, "r_surfaceworldnode", "0"};
cvar_t r_drawcollisionbrushes_polygonfactor = {0, "r_drawcollisionbrushes_polygonfactor", "-1"};
cvar_t r_drawcollisionbrushes_polygonoffset = {0, "r_drawcollisionbrushes_polygonoffset", "0"};
cvar_t r_q3bsp_renderskydepth = {0, "r_q3bsp_renderskydepth", "0"};
void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
{
- int i, *surfacevisframes, texturenumber, flagsmask;
+ int i, j, f, *surfacevisframes, flagsmask;
msurface_t *surface, **surfacechain;
texture_t *t, *texture;
model_t *model = ent->model;
R_UpdateTextureInfo(ent);
surfacevisframes = model->brushq1.surfacevisframes;
flagsmask = skysurfaces ? SURF_DRAWSKY : (SURF_DRAWTURB | SURF_LIGHTMAP);
- for (texturenumber = 0, t = model->brushq1.textures;texturenumber < model->brushq1.numtextures;texturenumber++, t++)
+ f = 0;
+ t = NULL;
+ numsurfacelist = 0;
+ for (i = 0, j = model->firstmodelsurface;i < model->nummodelsurfaces;i++, j++)
{
- if ((t->flags & flagsmask) && (texture = t->currentframe) && (surfacechain = model->brushq1.pvstexturechains[texturenumber]) != NULL)
+ if (surfacevisframes[j] == r_framecount)
{
- numsurfacelist = 0;
- for (i = 0;(surface = surfacechain[i]);i++)
+ surface = model->brushq1.surfaces + j;
+ if (t != surface->texinfo->texture)
{
- if (surfacevisframes[surface - model->brushq1.surfaces] == r_framecount)
+ if (numsurfacelist)
{
- // mark any backface surfaces as not visible
- if (PlaneDist(modelorg, surface->plane) < surface->plane->dist)
- {
- if (!(surface->flags & SURF_PLANEBACK))
- surfacevisframes[surface - model->brushq1.surfaces] = -1;
- }
- else
+ R_DrawSurfaceList(ent, texture, numsurfacelist, surfacelist);
+ numsurfacelist = 0;
+ }
+ t = surface->texinfo->texture;
+ f = t->flags & flagsmask;
+ texture = t->currentframe;
+ }
+ if (f)
+ {
+ // mark any backface surfaces as not visible
+ if (PlaneDist(modelorg, surface->plane) < surface->plane->dist)
+ {
+ if (!(surface->flags & SURF_PLANEBACK))
{
- if ((surface->flags & SURF_PLANEBACK))
- surfacevisframes[surface - model->brushq1.surfaces] = -1;
+ surfacevisframes[j] = -1;
+ continue;
}
- // add face to draw list and update lightmap if necessary
- c_faces++;
- surface->visframe = r_framecount;
- if (surface->cached_dlight && surface->lightmaptexture != NULL)
- R_BuildLightMap(ent, surface);
- surfacelist[numsurfacelist++] = surface;
- if (numsurfacelist >= maxsurfacelist)
+ }
+ else
+ {
+ if ((surface->flags & SURF_PLANEBACK))
{
- R_DrawSurfaceList(ent, texture, numsurfacelist, surfacelist);
- numsurfacelist = 0;
+ surfacevisframes[j] = -1;
+ continue;
}
}
+ // add face to draw list and update lightmap if necessary
+ c_faces++;
+ if (surface->cached_dlight && surface->lightmaptexture != NULL)
+ R_BuildLightMap(ent, surface);
+ surfacelist[numsurfacelist++] = surface;
+ if (numsurfacelist >= maxsurfacelist)
+ {
+ R_DrawSurfaceList(ent, texture, numsurfacelist, surfacelist);
+ numsurfacelist = 0;
+ }
}
- if (numsurfacelist)
- R_DrawSurfaceList(ent, texture, numsurfacelist, surfacelist);
}
}
+ if (numsurfacelist)
+ R_DrawSurfaceList(ent, texture, numsurfacelist, surfacelist);
}
static void R_DrawPortal_Callback(const void *calldata1, int calldata2)
for (portalnum = 0, portal = model->brushq1.portals;portalnum < model->brushq1.numportals;portalnum++, portal++)
{
if (portal->numpoints <= POLYGONELEMENTS_MAXPOINTS)
+ if (!R_CullBox(portal->mins, portal->maxs))
{
VectorClear(center);
for (i = 0;i < portal->numpoints;i++)
mleaf_t *viewleaf;
model_t *model = r_refdef.worldmodel;
int *surfacevisframes = model->brushq1.surfacevisframes;
+ int leafstackpos;
+ mportal_t *p;
+ mleaf_t *leafstack[8192];
if (!model || !model->brushq1.PointInLeaf)
return;
if (!viewleaf)
return;
- if (model->brushq1.pvsviewleaf != viewleaf || model->brushq1.pvsviewleafnovis != r_novis.integer)
- {
- int *surfacepvsframes = model->brushq1.surfacepvsframes;
- model->brushq1.pvsframecount++;
- model->brushq1.pvsviewleaf = viewleaf;
- model->brushq1.pvsviewleafnovis = r_novis.integer;
- model->brushq1.pvsleafchain = NULL;
- model->brushq1.pvssurflistlength = 0;
- for (j = 0, leaf = model->brushq1.data_leafs;j < model->brushq1.num_leafs;j++, leaf++)
- {
- if (CHECKPVSBIT(r_pvsbits, leaf->clusterindex))
- {
- leaf->pvsframe = model->brushq1.pvsframecount;
- leaf->pvschain = model->brushq1.pvsleafchain;
- model->brushq1.pvsleafchain = leaf;
- // mark surfaces bounding this leaf as visible
- for (i = 0, mark = leaf->firstmarksurface;i < leaf->nummarksurfaces;i++, mark++)
- surfacepvsframes[*mark] = model->brushq1.pvsframecount;
- }
- }
- model->brushq1.BuildPVSTextureChains(model);
- }
-
- if (r_surfaceworldnode.integer || viewleaf->contents == CONTENTS_SOLID)
+ if (viewleaf->contents == CONTENTS_SOLID || r_surfaceworldnode.integer)
{
// equivilant to quake's RecursiveWorldNode but faster and more effective
- for (leaf = model->brushq1.pvsleafchain;leaf;leaf = leaf->pvschain)
+ for (j = 0, leaf = model->brushq1.data_leafs;j < model->brushq1.num_leafs;j++, leaf++)
{
- if (!R_CullBox (leaf->mins, leaf->maxs))
+ if (CHECKPVSBIT(r_pvsbits, leaf->clusterindex) && !R_CullBox (leaf->mins, leaf->maxs))
{
c_leafs++;
leaf->visframe = r_framecount;
+ if (leaf->nummarksurfaces)
+ for (i = 0, mark = leaf->firstmarksurface;i < leaf->nummarksurfaces;i++, mark++)
+ surfacevisframes[*mark] = r_framecount;
}
}
- for (i = 0;i < model->brushq1.pvssurflistlength;i++)
- {
- int surfacenum = model->brushq1.pvssurflist[i];
- msurface_t *surface = model->brushq1.surfaces + surfacenum;
- if (!R_CullBox (surface->poly_mins, surface->poly_maxs))
- surfacevisframes[surfacenum] = r_framecount;
- }
}
else
{
- int leafstackpos;
- mportal_t *p;
- mleaf_t *leafstack[8192];
// 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
if (t->flags & SURF_LIGHTMAP && t->skin.fog == NULL)
Mod_ShadowMesh_AddMesh(r_shadow_mempool, r_shadow_compilingrtlight->static_meshchain_light, surface->texinfo->texture->skin.base, surface->texinfo->texture->skin.gloss, surface->texinfo->texture->skin.nmap, surface->mesh.data_vertex3f, surface->mesh.data_svector3f, surface->mesh.data_tvector3f, surface->mesh.data_normal3f, surface->mesh.data_texcoordtexture2f, surface->mesh.num_triangles, surface->mesh.data_element3i);
}
- else if (ent != r_refdef.worldentity || surface->visframe == r_framecount)
+ else if (ent != r_refdef.worldentity || ent->model->brushq1.surfacevisframes[surface - ent->model->brushq1.surfaces] == r_framecount)
{
t = surface->texinfo->texture->currentframe;
// FIXME: transparent surfaces need to be lit later
loadmodel->brushq1.numsurfaces = count;
loadmodel->brushq1.surfacevisframes = Mem_Alloc(loadmodel->mempool, count * sizeof(int));
- loadmodel->brushq1.surfacepvsframes = Mem_Alloc(loadmodel->mempool, count * sizeof(int));
- loadmodel->brushq1.pvssurflist = Mem_Alloc(loadmodel->mempool, count * sizeof(int));
for (surfnum = 0, surf = loadmodel->brushq1.surfaces, totalverts = 0, totaltris = 0, totalmeshes = 0;surfnum < count;surfnum++, totalverts += surf->poly_numverts, totaltris += surf->poly_numverts - 2, totalmeshes++, in++, surf++)
{
}
}
-static void Mod_Q1BSP_BuildPVSTextureChains(model_t *model)
-{
- int i, j;
- for (i = 0;i < model->brushq1.numtextures;i++)
- model->brushq1.pvstexturechainslength[i] = 0;
- for (i = 0, j = model->firstmodelsurface;i < model->nummodelsurfaces;i++, j++)
- {
- if (model->brushq1.surfacepvsframes[j] == model->brushq1.pvsframecount)
- {
- model->brushq1.pvssurflist[model->brushq1.pvssurflistlength++] = j;
- model->brushq1.pvstexturechainslength[model->brushq1.surfaces[j].texinfo->texture->number]++;
- }
- }
- for (i = 0, j = 0;i < model->brushq1.numtextures;i++)
- {
- if (model->brushq1.pvstexturechainslength[i])
- {
- model->brushq1.pvstexturechains[i] = model->brushq1.pvstexturechainsbuffer + j;
- j += model->brushq1.pvstexturechainslength[i] + 1;
- }
- else
- model->brushq1.pvstexturechains[i] = NULL;
- }
- for (i = 0, j = model->firstmodelsurface;i < model->nummodelsurfaces;i++, j++)
- if (model->brushq1.surfacepvsframes[j] == model->brushq1.pvsframecount)
- *model->brushq1.pvstexturechains[model->brushq1.surfaces[j].texinfo->texture->number]++ = model->brushq1.surfaces + j;
- for (i = 0;i < model->brushq1.numtextures;i++)
- {
- if (model->brushq1.pvstexturechainslength[i])
- {
- *model->brushq1.pvstexturechains[i] = NULL;
- model->brushq1.pvstexturechains[i] -= model->brushq1.pvstexturechainslength[i];
- }
- }
-}
-
//Returns PVS data for a given point
//(note: can return NULL)
static qbyte *Mod_Q1BSP_GetPVS(model_t *model, const vec3_t p)
mod->brush.AmbientSoundLevelsForPoint = Mod_Q1BSP_AmbientSoundLevelsForPoint;
mod->brush.RoundUpToHullSize = Mod_Q1BSP_RoundUpToHullSize;
mod->brushq1.PointInLeaf = Mod_Q1BSP_PointInLeaf;
- mod->brushq1.BuildPVSTextureChains = Mod_Q1BSP_BuildPVSTextureChains;
if (loadmodel->isworldmodel)
Cvar_SetValue("halflifebsp", mod->brush.ishlbsp);
mod->brush.LightPoint = NULL;
mod->brush.AmbientSoundLevelsForPoint = NULL;
}
- mod->brushq1.pvstexturechains = Mem_Alloc(loadmodel->mempool, mod->brushq1.numtextures * sizeof(msurface_t **));
- mod->brushq1.pvstexturechainsbuffer = Mem_Alloc(loadmodel->mempool,(mod->nummodelsurfaces + mod->brushq1.numtextures) * sizeof(msurface_t *));
- mod->brushq1.pvstexturechainslength = Mem_Alloc(loadmodel->mempool, mod->brushq1.numtextures * sizeof(int));
- Mod_Q1BSP_BuildPVSTextureChains(mod);
Mod_Q1BSP_BuildLightmapUpdateChains(loadmodel->mempool, mod);
if (mod->nummodelsurfaces)
{