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)
{
}
}
-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_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)
{
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)
+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_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, 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, 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, texture, texture->rendertype, texture->currentalpha);
}
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);
}
}
}
}
-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] && t->currentframe && ent->model->texturesurfacechains[i])
- t->shader->shaderfunc[type](ent, t->currentframe, 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;
}
leaf->pvsframe = model->pvsframecount;
// mark surfaces bounding this leaf as visible
for (c = leaf->nummarksurfaces, mark = leaf->firstmarksurface;c;c--, mark++)
- {
- //if (surfacepvsframes[*mark] != model->pvsframecount)
- //{
- surfacepvsframes[*mark] = model->pvsframecount;
- // model->pvssurflist[model->pvssurflistlength++] = *mark;
- //}
- }
+ surfacepvsframes[*mark] = model->pvsframecount;
}
}
}
}
- for (i = 0, j = model->firstmodelsurface;i < model->nummodelsurfaces;i++, j++)
- if (model->surfacepvsframes[j] == model->pvsframecount)
- model->pvssurflist[model->pvssurflistlength++] = j;
+ Mod_BuildPVSTextureChains(model);
}
}
}
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)
// fill out all slots with notexture
for (i = 0, tx = loadmodel->textures;i < loadmodel->numtextures;i++, tx++)
{
+ tx->number = i;
tx->width = 16;
tx->height = 16;
tx->texture = r_notexture;
#endif
}
+void Mod_BuildPVSTextureChains(model_t *model)
+{
+ int i, j;
+ for (i = 0;i < model->numtextures;i++)
+ model->pvstexturechainslength[i] = 0;
+ for (i = 0, j = model->firstmodelsurface;i < model->nummodelsurfaces;i++, j++)
+ {
+ if (model->surfacepvsframes[j] == model->pvsframecount)
+ {
+ model->pvssurflist[model->pvssurflistlength++] = j;
+ model->pvstexturechainslength[model->surfaces[j].texinfo->texture->number]++;
+ }
+ }
+ for (i = 0, j = 0;i < model->numtextures;i++)
+ {
+ if (model->pvstexturechainslength[i])
+ {
+ model->pvstexturechains[i] = model->pvstexturechainsbuffer + j;
+ j += model->pvstexturechainslength[i] + 1;
+ }
+ else
+ model->pvstexturechains[i] = NULL;
+ }
+ for (i = 0, j = model->firstmodelsurface;i < model->nummodelsurfaces;i++, j++)
+ if (model->surfacepvsframes[j] == model->pvsframecount)
+ *model->pvstexturechains[model->surfaces[j].texinfo->texture->number]++ = model->surfaces + j;
+ for (i = 0;i < model->numtextures;i++)
+ {
+ if (model->pvstexturechainslength[i])
+ {
+ *model->pvstexturechains[i] = NULL;
+ model->pvstexturechains[i] -= model->pvstexturechainslength[i];
+ }
+ }
+}
+
/*
=================
Mod_LoadBrushModel
float dist, modelyawradius, modelradius, *vec;
msurface_t *surf;
- mod->normalmins[0] = mod->normalmins[1] = mod->normalmins[2] = 1000000000.0f;
- mod->normalmaxs[0] = mod->normalmaxs[1] = mod->normalmaxs[2] = -1000000000.0f;
- modelyawradius = 0;
- modelradius = 0;
-
bm = &mod->submodels[i];
mod->hulls[0].firstclipnode = bm->headnode[0];
mod->DrawFakeShadow = NULL;
mod->DrawShadowVolume = R_Model_Brush_DrawShadowVolume;
mod->DrawLight = R_Model_Brush_DrawLight;
- mod->texturesurfacechains = Mem_Alloc(originalloadmodel->mempool, mod->numtextures * sizeof(msurface_t *));
+ mod->pvstexturechains = Mem_Alloc(originalloadmodel->mempool, mod->numtextures * sizeof(msurface_t **));
+ mod->pvstexturechainsbuffer = Mem_Alloc(originalloadmodel->mempool, (mod->nummodelsurfaces + mod->numtextures) * sizeof(msurface_t *));
+ mod->pvstexturechainslength = Mem_Alloc(originalloadmodel->mempool, mod->numtextures * sizeof(int));
+ Mod_BuildPVSTextureChains(mod);
if (mod->nummodelsurfaces)
{
// LordHavoc: calculate bmodel bounding box rather than trusting what it says
+ mod->normalmins[0] = mod->normalmins[1] = mod->normalmins[2] = 1000000000.0f;
+ mod->normalmaxs[0] = mod->normalmaxs[1] = mod->normalmaxs[2] = -1000000000.0f;
+ modelyawradius = 0;
+ modelradius = 0;
for (j = 0, surf = &mod->surfaces[mod->firstmodelsurface];j < mod->nummodelsurfaces;j++, surf++)
{
// we only need to have a drawsky function if it is used (usually only on world model)
if (surf->texinfo->texture->shader == &Cshader_sky)
mod->DrawSky = R_Model_Brush_DrawSky;
- // link into texture chain
- surf->texturechain = mod->texturesurfacechains[surf->texinfo->texture - mod->textures];
- mod->texturesurfacechains[surf->texinfo->texture - mod->textures] = surf;
// calculate bounding shapes
for (k = 0;k < surf->numedges;k++)
{
mod->rotatedmaxs[0] = mod->rotatedmaxs[1] = mod->rotatedmaxs[2] = modelradius;
mod->radius = modelradius;
mod->radius2 = modelradius * modelradius;
- // LordHavoc: build triangle meshs for entire model's geometry
- // (only used for shadow volumes)
- mod->shadowmesh = Mod_ShadowMesh_Begin(originalloadmodel->mempool, 1024);
- for (j = 0, surf = &mod->surfaces[mod->firstmodelsurface];j < mod->nummodelsurfaces;j++, surf++)
- if (surf->flags & SURF_SHADOWCAST)
- Mod_ShadowMesh_AddPolygon(originalloadmodel->mempool, mod->shadowmesh, surf->poly_numverts, surf->poly_verts);
- mod->shadowmesh = Mod_ShadowMesh_Finish(originalloadmodel->mempool, mod->shadowmesh);
- Mod_ShadowMesh_CalcBBox(mod->shadowmesh, mod->shadowmesh_mins, mod->shadowmesh_maxs, mod->shadowmesh_center, &mod->shadowmesh_radius);
}
else
{
// LordHavoc: empty submodel (lacrima.bsp has such a glitch)
Con_Printf("warning: empty submodel *%i in %s\n", i+1, loadname);
- VectorClear(mod->normalmins);
- VectorClear(mod->normalmaxs);
- VectorClear(mod->yawmins);
- VectorClear(mod->yawmaxs);
- VectorClear(mod->rotatedmins);
- VectorClear(mod->rotatedmaxs);
- mod->radius = 0;
- mod->radius2 = 0;
- mod->shadowmesh = NULL;
}
Mod_BuildSurfaceNeighbors(mod->surfaces + mod->firstmodelsurface, mod->nummodelsurfaces, originalloadmodel->mempool);