From 315098cbabb505102ea94e4d9d2bcd336b5d1d47 Mon Sep 17 00:00:00 2001 From: havoc Date: Sat, 16 Nov 2002 01:24:03 +0000 Subject: [PATCH] rewrote how texture chains are handled, they are now stored outside the surfaces, and are rebuilt as the player moves through the world (bmodel texture chains are just left untouched) good efficiency improvement I think git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2629 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_rsurf.c | 149 +++++++++++++++++++++---------------------------- model_brush.c | 71 ++++++++++++++--------- model_brush.h | 6 +- model_shared.h | 13 ++--- 4 files changed, 119 insertions(+), 120 deletions(-) diff --git a/gl_rsurf.c b/gl_rsurf.c index add2b1a2..db6c3188 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -747,7 +747,7 @@ static int RSurf_LightCheck(const matrix4x4_t *matrix, const int *dlightbits, co 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; @@ -784,7 +784,7 @@ static void RSurfShader_Sky(const entity_render_t *ent, const texture_t *texture } m.depthwrite = true; R_Mesh_State(&m); - for (surf = firstsurf;surf;surf = surf->texturechain) + while((surf = *surfchain++) != NULL) { if (surf->visframe == r_framecount) { @@ -878,13 +878,14 @@ static void RSurfShader_Water_Callback(const void *calldata1, int calldata2) } } -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) { @@ -894,7 +895,7 @@ static void RSurfShader_Water(const entity_render_t *ent, const texture_t *textu } } 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); } @@ -995,7 +996,7 @@ static void RSurfShader_Wall_Pass_Fog(const entity_render_t *ent, const msurface } } -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; @@ -1006,7 +1007,7 @@ static void RSurfShader_OpaqueWall_Pass_BaseTripleTexCombine(const entity_render 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; @@ -1014,7 +1015,7 @@ static void RSurfShader_OpaqueWall_Pass_BaseTripleTexCombine(const entity_render 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) { @@ -1037,7 +1038,7 @@ static void RSurfShader_OpaqueWall_Pass_BaseTripleTexCombine(const entity_render } } -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; @@ -1047,12 +1048,12 @@ static void RSurfShader_OpaqueWall_Pass_BaseDoubleTex(const entity_render_t *ent 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) { @@ -1074,7 +1075,7 @@ static void RSurfShader_OpaqueWall_Pass_BaseDoubleTex(const entity_render_t *ent } } -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; @@ -1085,7 +1086,7 @@ static void RSurfShader_OpaqueWall_Pass_BaseTexture(const entity_render_t *ent, 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) { @@ -1100,7 +1101,7 @@ static void RSurfShader_OpaqueWall_Pass_BaseTexture(const entity_render_t *ent, } } -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; @@ -1109,12 +1110,12 @@ static void RSurfShader_OpaqueWall_Pass_BaseLightmap(const entity_render_t *ent, 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) { @@ -1135,7 +1136,7 @@ static void RSurfShader_OpaqueWall_Pass_BaseLightmap(const entity_render_t *ent, } } -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; @@ -1154,7 +1155,7 @@ static void RSurfShader_OpaqueWall_Pass_Light(const entity_render_t *ent, const } 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) { @@ -1175,7 +1176,7 @@ static void RSurfShader_OpaqueWall_Pass_Light(const entity_render_t *ent, const } } -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; @@ -1187,7 +1188,7 @@ static void RSurfShader_OpaqueWall_Pass_Fog(const entity_render_t *ent, const te 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) { @@ -1204,7 +1205,7 @@ static void RSurfShader_OpaqueWall_Pass_Fog(const entity_render_t *ent, const te } } -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; @@ -1215,7 +1216,7 @@ static void RSurfShader_OpaqueWall_Pass_BaseDetail(const entity_render_t *ent, c 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) { @@ -1230,7 +1231,7 @@ static void RSurfShader_OpaqueWall_Pass_BaseDetail(const entity_render_t *ent, c } } -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; @@ -1241,7 +1242,7 @@ static void RSurfShader_OpaqueWall_Pass_Glow(const entity_render_t *ent, const t 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) { @@ -1256,7 +1257,7 @@ static void RSurfShader_OpaqueWall_Pass_Glow(const entity_render_t *ent, const t } } -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; @@ -1270,7 +1271,7 @@ static void RSurfShader_OpaqueWall_Pass_OpaqueGlow(const entity_render_t *ent, c 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) { @@ -1315,14 +1316,15 @@ static void RSurfShader_Wall_Vertex_Callback(const void *calldata1, int calldata 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) { @@ -1334,22 +1336,22 @@ static void RSurfShader_Wall_Lightmap(const entity_render_t *ent, const texture_ 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); } @@ -1359,27 +1361,27 @@ static void RSurfShader_Wall_Lightmap(const entity_render_t *ent, const texture_ 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); } } @@ -1488,14 +1490,14 @@ void R_PrepareSurfaces(entity_render_t *ent) } } -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) @@ -1532,24 +1534,17 @@ static void R_DrawPortals(entity_render_t *ent) 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); } } } @@ -1580,22 +1575,12 @@ void R_PrepareBrushModel(entity_render_t *ent) 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; } @@ -1757,20 +1742,12 @@ void R_PVSUpdate (entity_render_t *ent, mleaf_t *viewleaf) 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); } } } @@ -1796,15 +1773,15 @@ void R_WorldVisibility (entity_render_t *ent) 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) @@ -1812,7 +1789,7 @@ 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) diff --git a/model_brush.c b/model_brush.c index 9e805ef9..d4b1314a 100644 --- a/model_brush.c +++ b/model_brush.c @@ -236,6 +236,7 @@ static void Mod_LoadTextures (lump_t *l) // 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; @@ -2738,6 +2739,42 @@ static void Mod_BuildSurfaceNeighbors (msurface_t *surfaces, int numsurfaces, me #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 @@ -2818,11 +2855,6 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer) 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]; @@ -2841,18 +2873,22 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer) 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++) { @@ -2884,28 +2920,11 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer) 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); diff --git a/model_brush.h b/model_brush.h index a034185d..557c2ce5 100644 --- a/model_brush.h +++ b/model_brush.h @@ -82,7 +82,7 @@ struct msurface_s; // change this stuff when real shaders are added typedef struct Cshader_s { - void (*shaderfunc[SHADERSTAGE_COUNT])(const struct entity_render_s *ent, const struct texture_s *texture, const struct msurface_s *firstsurf); + void (*shaderfunc[SHADERSTAGE_COUNT])(const struct entity_render_s *ent, const struct texture_s *texture, struct msurface_s **surfchain); int flags; } Cshader_t; @@ -100,6 +100,9 @@ typedef struct texture_s // SURF_ flags unsigned int flags; + // position in the model's textures array + int number; + // type of rendering (SURFRENDER_ value) int rendertype; @@ -380,6 +383,7 @@ void Mod_FindNonSolidLocation(vec3_t pos, struct model_s *mod); mleaf_t *Mod_PointInLeaf (const float *p, struct model_s *model); int Mod_PointContents (const float *p, struct model_s *model); qbyte *Mod_LeafPVS (mleaf_t *leaf, struct model_s *model); +void Mod_BuildPVSTextureChains(struct model_s *model); #endif diff --git a/model_shared.h b/model_shared.h index 745f2ce5..1bcd0a19 100644 --- a/model_shared.h +++ b/model_shared.h @@ -188,8 +188,6 @@ typedef struct model_s int numtextures; texture_t *textures; - msurface_t **texturesurfacechains; - qbyte *visdata; qbyte *lightdata; char *entities; @@ -203,11 +201,6 @@ typedef struct model_s int numlights; mlight_t *lights; - // used only for casting dynamic shadow volumes - shadowmesh_t *shadowmesh; - vec3_t shadowmesh_mins, shadowmesh_maxs, shadowmesh_center; - float shadowmesh_radius; - // pvs visibility marking mleaf_t *pvsviewleaf; int pvsviewleafnovis; @@ -215,6 +208,12 @@ typedef struct model_s mleaf_t *pvsleafchain; int *pvssurflist; int pvssurflistlength; + // these get rebuilt as the player moves around if this is the world, + // otherwise they are left alone (no pvs for bmodels) + msurface_t ***pvstexturechains; + msurface_t **pvstexturechainsbuffer; + int *pvstexturechainslength; + // skin animation info animscene_t *skinscenes; // [numskins] -- 2.39.2