static qbyte templight[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE*4];
-static mempool_t *r_surf_mempool = NULL;
-static int r_surf_surfacevisiblelimit = 0;
-static qbyte *r_surf_surfacevisible = NULL;
-
cvar_t r_ambient = {0, "r_ambient", "0"};
cvar_t r_drawportals = {0, "r_drawportals", "0"};
cvar_t r_testvis = {0, "r_testvis", "0"};
cvar_t r_q3bsp_renderskydepth = {0, "r_q3bsp_renderskydepth", "0"};
cvar_t gl_lightmaps = {0, "gl_lightmaps", "0"};
-/*
-// FIXME: these arrays are huge!
-int r_q1bsp_maxmarkleafs;
-int r_q1bsp_nummarkleafs;
-mleaf_t *r_q1bsp_maxleaflist[65536];
-int r_q1bsp_maxmarksurfaces;
-int r_q1bsp_nummarksurfaces;
-msurface_t *r_q1bsp_maxsurfacelist[65536];
-
-// FIXME: these arrays are huge!
-int r_q3bsp_maxmarkleafs;
-int r_q3bsp_nummarkleafs;
-q3mleaf_t *r_q3bsp_maxleaflist[65536];
-int r_q3bsp_maxmarksurfaces;
-int r_q3bsp_nummarksurfaces;
-q3msurface_t *r_q3bsp_maxsurfacelist[65536];
-*/
-
-void R_Surf_ClearSurfaceVisible(int num)
-{
- if (r_surf_surfacevisiblelimit < num)
- {
- Mem_Free(r_surf_surfacevisible);
- r_surf_surfacevisiblelimit = num;
- r_surf_surfacevisible = Mem_Alloc(r_surf_mempool, r_surf_surfacevisiblelimit);
- }
- memset(r_surf_surfacevisible, 0, num);
-}
-
static int dlightdivtable[32768];
static int R_IntAddDynamicLights (const matrix4x4_t *matrix, msurface_t *surf)
invradius = 1.0f / radius;
loc0:
- if (node->contents < 0)
+ if (!node->plane)
return;
ndist = PlaneDiff(origin, node->plane);
if (ndist > radius)
}
}
- if (node->children[0]->contents >= 0)
+ if (node->children[0]->plane)
{
- if (node->children[1]->contents >= 0)
+ if (node->children[1]->plane)
{
R_StainNode(node->children[0], model, origin, radius, fcolor);
node = node->children[1];
goto loc0;
}
}
- else if (node->children[1]->contents >= 0)
+ else if (node->children[1]->plane)
{
node = node->children[1];
goto loc0;
entity_render_t *ent;
model_t *model;
vec3_t org;
- if (r_refdef.worldmodel == NULL || !r_refdef.worldmodel->brushq1.nodes)
+ if (r_refdef.worldmodel == NULL || !r_refdef.worldmodel->brush.data_nodes)
return;
fcolor[0] = cr1;
fcolor[1] = cg1;
fcolor[6] = cb2 - cb1;
fcolor[7] = (ca2 - ca1) * (1.0f / 64.0f);
- R_StainNode(r_refdef.worldmodel->brushq1.nodes + r_refdef.worldmodel->brushq1.hulls[0].firstclipnode, r_refdef.worldmodel, origin, radius, fcolor);
+ R_StainNode(r_refdef.worldmodel->brush.data_nodes + r_refdef.worldmodel->brushq1.hulls[0].firstclipnode, r_refdef.worldmodel, origin, radius, fcolor);
// look for embedded bmodels
for (n = 0;n < cl_num_brushmodel_entities;n++)
if (model && model->name[0] == '*')
{
Mod_CheckLoaded(model);
- if (model->brushq1.nodes)
+ if (model->brush.data_nodes)
{
Matrix4x4_Transform(&ent->inversematrix, origin, org);
- R_StainNode(model->brushq1.nodes + model->brushq1.hulls[0].firstclipnode, model, org, radius, fcolor);
+ R_StainNode(model->brush.data_nodes + model->brushq1.hulls[0].firstclipnode, model, org, radius, fcolor);
}
}
}
void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
{
- int i, j, f, *surfacevisframes, flagsmask;
+ int i, j, f, flagsmask;
msurface_t *surface, **surfacechain;
texture_t *t, *texture;
model_t *model = ent->model;
if (ent != r_refdef.worldentity)
{
- // because bmodels can be reused, we have to decide which things to render
- // from scratch every time
- int *mark = model->brushq1.surfacevisframes + model->firstmodelsurface;
+ // because bmodels can be reused, we have to clear dlightframe every time
surface = model->brushq1.surfaces + model->firstmodelsurface;
- for (i = 0;i < model->nummodelsurfaces;i++, mark++, surface++)
- {
- *mark = r_framecount;
+ for (i = 0;i < model->nummodelsurfaces;i++, surface++)
surface->dlightframe = -1;
- }
}
// update light styles
}
R_UpdateTextureInfo(ent);
- surfacevisframes = model->brushq1.surfacevisframes;
flagsmask = skysurfaces ? SURF_DRAWSKY : (SURF_DRAWTURB | SURF_LIGHTMAP);
f = 0;
t = NULL;
numsurfacelist = 0;
for (i = 0, j = model->firstmodelsurface;i < model->nummodelsurfaces;i++, j++)
{
- if (surfacevisframes[j] == r_framecount)
+ if (ent != r_refdef.worldentity || r_worldsurfacevisible[j])
{
surface = model->brushq1.surfaces + j;
if (t != surface->texinfo->texture)
}
if (f)
{
- // mark any backface surfaces as not visible
- if (PlaneDist(modelorg, surface->plane) < surface->plane->dist)
- {
- if (!(surface->flags & SURF_PLANEBACK))
- {
- surfacevisframes[j] = -1;
- continue;
- }
- }
- else
- {
- if ((surface->flags & SURF_PLANEBACK))
- {
- surfacevisframes[j] = -1;
- continue;
- }
- }
// add face to draw list and update lightmap if necessary
c_faces++;
if (surface->cached_dlight && surface->lightmaptexture != NULL)
model_t *model = r_refdef.worldmodel;
if (model == NULL)
return;
- for (portalnum = 0, portal = model->brushq1.portals;portalnum < model->brushq1.numportals;portalnum++, portal++)
+ for (portalnum = 0, portal = model->brush.data_portals;portalnum < model->brush.num_portals;portalnum++, portal++)
{
if (portal->numpoints <= POLYGONELEMENTS_MAXPOINTS)
if (!R_CullBox(portal->mins, portal->maxs))
void R_WorldVisibility(void)
{
- int i, j, *mark;
- mleaf_t *leaf;
- 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)
+ if (!model)
return;
- viewleaf = model->brushq1.PointInLeaf(model, r_vieworigin);
- if (!viewleaf)
- return;
-
- if (viewleaf->contents == CONTENTS_SOLID || r_surfaceworldnode.integer)
+ if (model->type == mod_brushq3)
{
- // equivilant to quake's RecursiveWorldNode but faster and more effective
- for (j = 0, leaf = model->brushq1.data_leafs;j < model->brushq1.num_leafs;j++, leaf++)
+ int i, j;
+ mleaf_t *leaf;
+ memset(r_worldsurfacevisible, 0, r_refdef.worldmodel->brushq3.num_faces);
+ for (j = 0, leaf = r_refdef.worldmodel->brush.data_leafs;j < r_refdef.worldmodel->brush.num_leafs;j++, leaf++)
{
- if (CHECKPVSBIT(r_pvsbits, leaf->clusterindex) && !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 < leaf->numleaffaces;i++)
+ r_worldsurfacevisible[leaf->firstleafface[i]] = 1;
}
}
}
- else
+ else if (model->type == mod_brushq1)
{
- // 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
- leafstack[0] = viewleaf;
- leafstackpos = 1;
- while (leafstackpos)
- {
- c_leafs++;
- leaf = leafstack[--leafstackpos];
- leaf->visframe = r_framecount;
- // draw any surfaces bounding this leaf
- if (leaf->nummarksurfaces)
- for (i = 0, mark = leaf->firstmarksurface;i < leaf->nummarksurfaces;i++, mark++)
- surfacevisframes[*mark] = r_framecount;
- // follow portals into other leafs
- for (p = leaf->portals;p;p = p->next)
- if (DotProduct(r_vieworigin, p->plane.normal) < (p->plane.dist + 1) && p->past->visframe != r_framecount && CHECKPVSBIT(r_pvsbits, p->past->clusterindex) && !R_CullBox(p->mins, p->maxs))
- leafstack[leafstackpos++] = p->past;
+ int i, j, *mark;
+ mleaf_t *leaf;
+ mleaf_t *viewleaf;
+ int leafstackpos;
+ mportal_t *p;
+ mleaf_t *leafstack[8192];
+ qbyte leafvisited[32768];
+
+ viewleaf = model->brushq1.PointInLeaf(model, r_vieworigin);
+ if (!viewleaf)
+ return;
+
+ memset(r_worldsurfacevisible, 0, r_refdef.worldmodel->brushq1.numsurfaces);
+ if (viewleaf->clusterindex < 0 || r_surfaceworldnode.integer)
+ {
+ // equivilant to quake's RecursiveWorldNode but faster and more effective
+ for (j = 0, leaf = model->brush.data_leafs;j < model->brush.num_leafs;j++, leaf++)
+ {
+ if (CHECKPVSBIT(r_pvsbits, leaf->clusterindex) && !R_CullBox (leaf->mins, leaf->maxs))
+ {
+ c_leafs++;
+ if (leaf->numleaffaces)
+ for (i = 0, mark = leaf->firstleafface;i < leaf->numleaffaces;i++, mark++)
+ r_worldsurfacevisible[*mark] = true;
+ }
+ }
+ }
+ else
+ {
+ // 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
+ leafstack[0] = viewleaf;
+ leafstackpos = 1;
+ memset(leafvisited, 0, r_refdef.worldmodel->brush.num_leafs);
+ while (leafstackpos)
+ {
+ c_leafs++;
+ leaf = leafstack[--leafstackpos];
+ leafvisited[leaf - r_refdef.worldmodel->brush.data_leafs] = 1;
+ // draw any surfaces bounding this leaf
+ if (leaf->numleaffaces)
+ for (i = 0, mark = leaf->firstleafface;i < leaf->numleaffaces;i++, mark++)
+ r_worldsurfacevisible[*mark] = true;
+ // follow portals into other leafs
+ for (p = leaf->portals;p;p = p->next)
+ if (DotProduct(r_vieworigin, p->plane.normal) < (p->plane.dist + 1) && !leafvisited[p->past - r_refdef.worldmodel->brush.data_leafs] && CHECKPVSBIT(r_pvsbits, p->past->clusterindex) && !R_CullBox(p->mins, p->maxs))
+ leafstack[leafstackpos++] = p->past;
+ }
}
- }
- if (r_drawportals.integer)
- R_DrawPortals();
+ if (r_drawportals.integer)
+ R_DrawPortals();
+ }
}
void R_Q1BSP_DrawSky(entity_render_t *ent)
{
model_t *model = ent->model;
vec3_t lightmins, lightmaxs;
- int t, leafindex, marksurfaceindex, surfaceindex, triangleindex, outnumclusters = 0, outnumsurfaces = 0;
+ int t, leafindex, leaffaceindex, surfaceindex, triangleindex, outnumclusters = 0, outnumsurfaces = 0;
const int *e;
const float *v[3];
msurface_t *surface;
else
pvs = NULL;
// FIXME: use BSP recursion as lights are often small
- for (leafindex = 0, leaf = model->brushq1.data_leafs;leafindex < model->brushq1.num_leafs;leafindex++, leaf++)
+ for (leafindex = 0, leaf = model->brush.data_leafs;leafindex < model->brush.num_leafs;leafindex++, leaf++)
{
if (BoxesOverlap(lightmins, lightmaxs, leaf->mins, leaf->maxs) && (pvs == NULL || CHECKPVSBIT(pvs, leaf->clusterindex)))
{
}
if (outsurfacepvs)
{
- for (marksurfaceindex = 0;marksurfaceindex < leaf->nummarksurfaces;marksurfaceindex++)
+ for (leaffaceindex = 0;leaffaceindex < leaf->numleaffaces;leaffaceindex++)
{
- surfaceindex = leaf->firstmarksurface[marksurfaceindex];
+ surfaceindex = leaf->firstleafface[leaffaceindex];
if (!CHECKPVSBIT(outsurfacepvs, surfaceindex))
{
surface = model->brushq1.surfaces + surfaceindex;
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 || ent->model->brushq1.surfacevisframes[surface - ent->model->brushq1.surfaces] == r_framecount)
+ else if (ent != r_refdef.worldentity || r_worldsurfacevisible[surface - ent->model->brushq1.surfaces])
{
t = surface->texinfo->texture->currentframe;
// FIXME: transparent surfaces need to be lit later
void R_Q3BSP_DrawFaceList(entity_render_t *ent, q3mtexture_t *t, int texturenumfaces, q3msurface_t **texturefacelist)
{
int i, texturefaceindex;
+ qboolean dolightmap;
+ qboolean dobase;
+ qboolean doambient;
+ qboolean doglow;
+ qboolean dofog;
rmeshstate_t m;
if (!texturenumfaces)
return;
return;
}
// anything else is a typical wall, lightmap * texture + glow
- qboolean dolightmap = (ent->flags & RENDER_LIGHT);
- qboolean dobase = true;
- qboolean doambient = r_ambient.value > 0;
- qboolean doglow = t->skin.glow != NULL;
- qboolean dofog = fogenabled;
+ dolightmap = (ent->flags & RENDER_LIGHT);
+ dobase = true;
+ doambient = r_ambient.value > 0;
+ doglow = t->skin.glow != NULL;
+ dofog = fogenabled;
if (t->textureflags & Q3TEXTUREFLAG_TWOSIDED)
qglDisable(GL_CULL_FACE);
if (!dolightmap && dobase)
void R_Q3BSP_DrawFaces(entity_render_t *ent, int skyfaces)
{
- int i, ti, flagsmask, flags;
+ int i, j, f, flagsmask, flags;
q3msurface_t *face;
- model_t *model;
+ model_t *model = ent->model;
q3mtexture_t *t;
const int maxfaces = 1024;
int numfaces = 0;
q3msurface_t *facelist[1024];
R_Mesh_Matrix(&ent->matrix);
- model = ent->model;
flagsmask = Q3SURFACEFLAG_NODRAW | Q3SURFACEFLAG_SKY;
if (skyfaces)
flags = Q3SURFACEFLAG_SKY;
else
flags = 0;
- if (ent == r_refdef.worldentity)
+ t = NULL;
+ f = 0;
+ numfaces = 0;
+ for (i = 0, j = model->firstmodelsurface;i < model->nummodelsurfaces;i++, j++)
{
- int j;
- q3mleaf_t *leaf;
- R_Surf_ClearSurfaceVisible(r_refdef.worldmodel->brushq3.num_faces);
- for (j = 0, leaf = r_refdef.worldmodel->brushq3.data_leafs;j < r_refdef.worldmodel->brushq3.num_leafs;j++, leaf++)
+ if (ent != r_refdef.worldentity || r_worldsurfacevisible[j])
{
- if (CHECKPVSBIT(r_pvsbits, leaf->clusterindex) && !R_CullBox(leaf->mins, leaf->maxs))
+ face = model->brushq3.data_faces + j;
+ if (t != face->texture)
{
- c_leafs++;
- for (i = 0;i < leaf->numleaffaces;i++)
- r_surf_surfacevisible[leaf->firstleaffacenum[i]] = 1;
- }
- }
- for (ti = 0, t = model->brushq3.data_textures;ti < model->brushq3.num_textures;ti++, t++)
- {
- if ((t->surfaceflags & flagsmask) == flags)
- {
- numfaces = 0;
- for (i = 0;i < t->numfaces;i++)
- {
- if (r_surf_surfacevisible[t->facenumlist[i]])
- {
- face = t->facelist[i];
- //if (!R_CullBox(face->mins, face->maxs))
- if (face->mesh.num_triangles)
- {
- if (numfaces >= maxfaces)
- {
- if (numfaces)
- R_Q3BSP_DrawFaceList(ent, t, numfaces, facelist);
- numfaces = 0;
- }
- facelist[numfaces++] = face;
- }
- }
- }
if (numfaces)
+ {
R_Q3BSP_DrawFaceList(ent, t, numfaces, facelist);
+ numfaces = 0;
+ }
+ t = face->texture;
+ f = t->surfaceflags & flagsmask;
}
- }
- }
- else
- {
- t = NULL;
- numfaces = 0;
- for (i = 0, face = model->brushq3.data_thismodel->firstface;i < model->brushq3.data_thismodel->numfaces;i++, face++)
- {
- if ((face->texture->surfaceflags & flagsmask) == flags && face->mesh.num_triangles)
+ if (f == flags)
{
- if (t != face->texture || numfaces >= maxfaces)
+ if (!face->mesh.num_triangles)
+ continue;
+ facelist[numfaces++] = face;
+ if (numfaces >= maxfaces)
{
- if (numfaces)
- R_Q3BSP_DrawFaceList(ent, t, numfaces, facelist);
+ R_Q3BSP_DrawFaceList(ent, t, numfaces, facelist);
numfaces = 0;
- t = face->texture;
}
- facelist[numfaces++] = face;
}
}
- if (numfaces)
- R_Q3BSP_DrawFaceList(ent, t, numfaces, facelist);
}
+ if (numfaces)
+ R_Q3BSP_DrawFaceList(ent, t, numfaces, facelist);
}
void R_Q3BSP_DrawSky(entity_render_t *ent)
GL_DepthMask(false);
GL_DepthTest(true);
qglPolygonOffset(r_drawcollisionbrushes_polygonfactor.value, r_drawcollisionbrushes_polygonoffset.value);
- for (i = 0;i < model->brushq3.data_thismodel->numbrushes;i++)
- if (model->brushq3.data_thismodel->firstbrush[i].colbrushf && model->brushq3.data_thismodel->firstbrush[i].colbrushf->numtriangles)
- R_DrawCollisionBrush(model->brushq3.data_thismodel->firstbrush[i].colbrushf);
- for (i = 0, face = model->brushq3.data_thismodel->firstface;i < model->brushq3.data_thismodel->numfaces;i++, face++)
+ for (i = 0;i < model->brushq3.data_models[model->brush.submodel].numbrushes;i++)
+ if (model->brushq3.data_models[model->brush.submodel].firstbrush[i].colbrushf && model->brushq3.data_models[model->brush.submodel].firstbrush[i].colbrushf->numtriangles)
+ R_DrawCollisionBrush(model->brushq3.data_models[model->brush.submodel].firstbrush[i].colbrushf);
+ for (i = 0, face = model->brushq3.data_models[model->brush.submodel].firstface;i < model->brushq3.data_models[model->brush.submodel].numfaces;i++, face++)
if (face->mesh.num_collisiontriangles)
R_Q3BSP_DrawCollisionFace(ent, face);
qglPolygonOffset(0, 0);
{
model_t *model = ent->model;
vec3_t lightmins, lightmaxs;
- int t, leafindex, marksurfaceindex, surfaceindex, triangleindex, outnumclusters = 0, outnumsurfaces = 0;
+ int t, leafindex, leaffaceindex, surfaceindex, triangleindex, outnumclusters = 0, outnumsurfaces = 0;
const int *e;
const float *v[3];
q3msurface_t *surface;
- q3mleaf_t *leaf;
+ mleaf_t *leaf;
const qbyte *pvs;
lightmins[0] = relativelightorigin[0] - lightradius;
lightmins[1] = relativelightorigin[1] - lightradius;
else
pvs = NULL;
// FIXME: use BSP recursion as lights are often small
- for (leafindex = 0, leaf = model->brushq3.data_leafs;leafindex < model->brushq3.num_leafs;leafindex++, leaf++)
+ for (leafindex = 0, leaf = model->brush.data_leafs;leafindex < model->brush.num_leafs;leafindex++, leaf++)
{
if (BoxesOverlap(lightmins, lightmaxs, leaf->mins, leaf->maxs) && (pvs == NULL || CHECKPVSBIT(pvs, leaf->clusterindex)))
{
}
if (outsurfacepvs)
{
- for (marksurfaceindex = 0;marksurfaceindex < leaf->numleaffaces;marksurfaceindex++)
+ for (leaffaceindex = 0;leaffaceindex < leaf->numleaffaces;leaffaceindex++)
{
- surface = leaf->firstleafface[marksurfaceindex];
- surfaceindex = surface - model->brushq3.data_faces;
+ surfaceindex = leaf->firstleafface[leaffaceindex];
+ surface = model->brushq3.data_faces + surfaceindex;
if (!CHECKPVSBIT(outsurfacepvs, surfaceindex))
{
if (BoxesOverlap(lightmins, lightmaxs, surface->mins, surface->maxs) && !(surface->texture->surfaceparms & Q3SURFACEPARM_TRANS) && !(surface->texture->surfaceflags & (Q3SURFACEFLAG_SKY | Q3SURFACEFLAG_NODRAW)) && surface->mesh.num_triangles)
}
}
+#if 0
static void gl_surf_start(void)
{
- r_surf_mempool = Mem_AllocPool("gl_rsurf", 0, NULL);
- r_surf_surfacevisiblelimit = 65536;
- r_surf_surfacevisible = Mem_Alloc(r_surf_mempool, r_surf_surfacevisiblelimit);
}
static void gl_surf_shutdown(void)
{
- r_surf_surfacevisiblelimit = 0;
- r_surf_surfacevisible = NULL;
- Mem_FreePool(&r_surf_mempool);
}
static void gl_surf_newmap(void)
{
}
+#endif
void GL_Surf_Init(void)
{
Cvar_RegisterVariable(&r_q3bsp_renderskydepth);
Cvar_RegisterVariable(&gl_lightmaps);
- R_RegisterModule("GL_Surf", gl_surf_start, gl_surf_shutdown, gl_surf_newmap);
+ //R_RegisterModule("GL_Surf", gl_surf_start, gl_surf_shutdown, gl_surf_newmap);
}