From f7412a0c49465d916da5920d1132eeda9c3a4a3d Mon Sep 17 00:00:00 2001 From: havoc Date: Thu, 5 Sep 2002 12:07:55 +0000 Subject: [PATCH] added r_surfaceworldnode and r_cullsurface cvars (it is recommended that these both be on, or both be off) shuffled around WorldNode, DrawSurfaces, PrepareSurfaces, SurfMarkLights, and other related code a great deal, it is now somewhat cleaner git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2330 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_rmain.c | 85 ++++++++------------- gl_rsurf.c | 207 +++++++++++++++++++++++++------------------------- model_brush.h | 8 +- render.h | 4 - 4 files changed, 139 insertions(+), 165 deletions(-) diff --git a/gl_rmain.c b/gl_rmain.c index b16a2bda..684e2248 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -121,8 +121,6 @@ static void R_TimeRefresh_f (void) Con_Printf ("%f seconds (%f fps)\n", time, 128/time); } -extern cvar_t r_drawportals; - vec3_t fogcolor; vec_t fogdensity; float fog_density, fog_red, fog_green, fog_blue; @@ -401,6 +399,28 @@ int R_DrawBrushModelsSky (void) return sky; } +/* +============= +R_DrawViewModel +============= +*/ +void R_DrawViewModel (void) +{ + entity_render_t *ent; + + // FIXME: move these checks to client + if (!r_drawviewmodel.integer || chase_active.integer || envmap || !r_drawentities.integer || cl.items & IT_INVISIBILITY || cl.stats[STAT_HEALTH] <= 0 || !cl.viewent.render.model) + return; + + ent = &cl.viewent.render; + Mod_CheckLoaded(ent->model); + R_LerpAnimation(ent); + Matrix4x4_CreateFromQuakeEntity(&ent->matrix, ent->origin[0], ent->origin[1], ent->origin[2], -ent->angles[0], ent->angles[1], ent->angles[2], ent->scale); + Matrix4x4_Invert_Simple(&ent->inversematrix, &ent->matrix); + R_UpdateEntLights(ent); + ent->model->Draw(ent); +} + void R_DrawNoModel(entity_render_t *ent); void R_DrawModels (void) { @@ -410,6 +430,7 @@ void R_DrawModels (void) if (!r_drawentities.integer) return; + R_DrawViewModel(); for (i = 0;i < r_refdef.numentities;i++) { ent = r_refdef.entities[i]; @@ -426,28 +447,6 @@ void R_DrawModels (void) } } -/* -============= -R_DrawViewModel -============= -*/ -void R_DrawViewModel (void) -{ - entity_render_t *ent; - - // FIXME: move these checks to client - if (!r_drawviewmodel.integer || chase_active.integer || envmap || !r_drawentities.integer || cl.items & IT_INVISIBILITY || cl.stats[STAT_HEALTH] <= 0 || !cl.viewent.render.model) - return; - - ent = &cl.viewent.render; - Mod_CheckLoaded(ent->model); - R_LerpAnimation(ent); - Matrix4x4_CreateFromQuakeEntity(&ent->matrix, ent->origin[0], ent->origin[1], ent->origin[2], -ent->angles[0], ent->angles[1], ent->angles[2], ent->scale); - Matrix4x4_Invert_Simple(&ent->inversematrix, &ent->matrix); - R_UpdateEntLights(ent); - ent->model->Draw(ent); -} - static void R_SetFrustum (void) { int i; @@ -576,35 +575,6 @@ void R_RenderView (void) if (R_DrawBrushModelsSky()) R_TimeReport("bmodelsky"); - if (world->model) - { - R_DrawWorld(world); - R_TimeReport("worldnode"); - - R_SurfMarkLights(world); - R_TimeReport("marklights"); - - R_PrepareSurfaces(world); - R_TimeReport("surfprep"); - - R_DrawSurfaces(world, SHADERSTAGE_SKY); - R_DrawSurfaces(world, SHADERSTAGE_NORMAL); - R_TimeReport("surfdraw"); - - if (r_drawportals.integer) - { - R_DrawPortals(world); - R_TimeReport("portals"); - } - } - - // don't let sound skip if going slow - if (!intimerefresh && !r_speeds.integer) - S_ExtraUpdate (); - - R_DrawViewModel(); - R_TimeReport("viewmodel"); - R_DrawModels(); R_TimeReport("models"); @@ -614,8 +584,15 @@ void R_RenderView (void) R_DrawExplosions(); R_TimeReport("explosions"); + // don't let sound skip if going slow + if (!intimerefresh && !r_speeds.integer) + S_ExtraUpdate (); + + R_DrawWorld(world); + R_TimeReport("world"); + R_MeshQueue_RenderTransparent(); - R_TimeReport("addtrans"); + R_TimeReport("drawtrans"); R_DrawCoronas(); R_TimeReport("coronas"); diff --git a/gl_rsurf.c b/gl_rsurf.c index 35701067..48440d94 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -31,7 +31,7 @@ static qbyte templight[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE*4]; cvar_t r_ambient = {0, "r_ambient", "0"}; cvar_t r_vertexsurfaces = {0, "r_vertexsurfaces", "0"}; cvar_t r_dlightmap = {CVAR_SAVE, "r_dlightmap", "1"}; -cvar_t r_drawportals = {0, "r_drawportals", "0"}; +//cvar_t r_drawportals = {0, "r_drawportals", "0"}; 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"}; @@ -42,8 +42,9 @@ static int dlightdivtable[32768]; // variables used by R_PVSUpdate int r_pvsframecount = 0; -mleaf_t *r_viewleaf = NULL; -int r_viewleafnovis = 0; +mleaf_t *r_pvsviewleaf = NULL; +int r_pvsviewleafnovis = 0; +msurface_t *r_pvsfirstsurface = NULL; static int R_IntAddDynamicLights (const matrix4x4_t *matrix, msurface_t *surf) { @@ -1543,13 +1544,17 @@ Cshader_t *Cshaders[5] = &Cshader_sky }; -void R_PrepareSurfaces(entity_render_t *ent) +void R_DrawSurfaces(entity_render_t *ent, int sky, int normal) { int i, alttextures, texframe, framecount; texture_t *t; model_t *model; msurface_t *surf; vec3_t modelorg; + Cshader_t *shader; + + if (!ent->model) + return; for (i = 0;i < Cshader_count;i++) Cshaders[i]->chain = NULL; @@ -1577,39 +1582,78 @@ void R_PrepareSurfaces(entity_render_t *ent) } if (surf->visframe == r_framecount) { - c_faces++; - t = surf->texinfo->texture; - if (t->animated) + if (r_cullsurface.integer && R_CullBox (surf->poly_mins, surf->poly_maxs)) + surf->visframe = -1; + else { - framecount = t->anim_total[alttextures]; - if (framecount >= 2) - surf->currenttexture = t->anim_frames[alttextures][texframe % framecount]; + c_faces++; + t = surf->texinfo->texture; + if (t->animated) + { + framecount = t->anim_total[alttextures]; + if (framecount >= 2) + surf->currenttexture = t->anim_frames[alttextures][texframe % framecount]; + else + surf->currenttexture = t->anim_frames[alttextures][0]; + } else - surf->currenttexture = t->anim_frames[alttextures][0]; + surf->currenttexture = t; + surf->chain = surf->shader->chain; + surf->shader->chain = surf; } - else - surf->currenttexture = t; - - surf->chain = surf->shader->chain; - surf->shader->chain = surf; } } } -} -void R_DrawSurfaces (entity_render_t *ent, int type) -{ - int i; - Cshader_t *shader; + if (sky) + { + for (i = 0;i < Cshader_count;i++) + { + shader = Cshaders[i]; + if (shader->chain && shader->shaderfunc[SHADERSTAGE_SKY]) + shader->shaderfunc[SHADERSTAGE_SKY](ent, shader->chain); + } + } - for (i = 0;i < Cshader_count;i++) + if (normal) { - shader = Cshaders[i]; - if (shader->chain && shader->shaderfunc[type]) - shader->shaderfunc[type](ent, shader->chain); + if (r_dynamic.integer) + R_MarkLights(ent); + + if (!r_vertexsurfaces.integer) + { + for (i = 0, surf = ent->model->surfaces + ent->model->firstmodelsurface;i < ent->model->nummodelsurfaces;i++, surf++) + { + if (surf->visframe == r_framecount && surf->lightmaptexture != NULL) + { + if (surf->cached_dlight + || surf->cached_ambient != r_ambient.value + || surf->cached_lightscalebit != lightscalebit) + 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 + } + } + } + } + + for (i = 0;i < Cshader_count;i++) + { + shader = Cshaders[i]; + if (shader->chain && shader->shaderfunc[SHADERSTAGE_NORMAL]) + shader->shaderfunc[SHADERSTAGE_NORMAL](ent, shader->chain); + } } } +/* static void R_DrawPortal_Callback(const void *calldata1, int calldata2) { int i; @@ -1649,7 +1693,7 @@ static void R_DrawPortal_Callback(const void *calldata1, int calldata2) } } -void R_DrawPortals(entity_render_t *ent) +static void R_DrawPortals(entity_render_t *ent) { int i; mportal_t *portal, *endportal; @@ -1672,8 +1716,9 @@ void R_DrawPortals(entity_render_t *ent) } } } +*/ -void R_SetupForBrushModelRendering(entity_render_t *ent) +void R_DrawBrushModel(entity_render_t *ent, int sky, int normal) { int i; msurface_t *surf; @@ -1693,55 +1738,14 @@ void R_SetupForBrushModelRendering(entity_render_t *ent) surf->lightframe = -1; surf->dlightframe = -1; } - R_PrepareSurfaces(ent); + R_DrawSurfaces(ent, sky, normal); } -void R_SurfMarkLights (entity_render_t *ent) +void R_SurfaceWorldNode (void) { - int i; msurface_t *surf; - - if (!ent->model) - return; - - if (r_dynamic.integer) - R_MarkLights(ent); - - if (!r_vertexsurfaces.integer) - { - for (i = 0, surf = ent->model->surfaces + ent->model->firstmodelsurface;i < ent->model->nummodelsurfaces;i++, surf++) - { - if (surf->visframe == r_framecount && surf->lightmaptexture != NULL) - { - if (surf->cached_dlight - || surf->cached_ambient != r_ambient.value - || surf->cached_lightscalebit != lightscalebit) - 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 - } - } - } - } -} - -void R_SurfaceWorldNode (entity_render_t *ent) -{ - int i; - msurface_t *surf; - model_t *model; - model = ent->model; - // FIXME: R_NotCulledBox is absolute, should be done relative - for (i = 0, surf = model->surfaces + model->firstmodelsurface;i < model->nummodelsurfaces;i++, surf++) - if (surf->pvsframe == r_pvsframecount && (!r_cullsurface.integer || R_NotCulledBox (surf->poly_mins, surf->poly_maxs))) - surf->visframe = r_framecount; + for (surf = r_pvsfirstsurface;surf;surf = surf->pvschain) + surf->visframe = r_framecount; } /* @@ -1810,7 +1814,7 @@ static void R_PortalWorldNode(entity_render_t *ent, mleaf_t *viewleaf) int c, leafstackpos; mleaf_t *leaf, *leafstack[8192]; mportal_t *p; - msurface_t *surf, **mark; + msurface_t **mark; vec3_t modelorg; // LordHavoc: portal-passage worldnode with PVS; // follows portals leading outward from viewleaf, does not venture @@ -1828,14 +1832,8 @@ static void R_PortalWorldNode(entity_render_t *ent, mleaf_t *viewleaf) //leaf->visframe = r_framecount; // draw any surfaces bounding this leaf if (leaf->nummarksurfaces) - { for (c = leaf->nummarksurfaces, mark = leaf->firstmarksurface;c;c--) - { - surf = *mark++; - if (!r_cullsurface.integer || R_NotCulledBox (surf->poly_mins, surf->poly_maxs)) - surf->visframe = r_framecount; - } - } + (*mark++)->visframe = r_framecount; // follow portals into other leafs for (p = leaf->portals;p;p = p->next) { @@ -1849,23 +1847,24 @@ static void R_PortalWorldNode(entity_render_t *ent, mleaf_t *viewleaf) } } } + //if (r_drawportals.integer) + // R_DrawPortals(ent); } void R_PVSUpdate (mleaf_t *viewleaf) { int i, j, l, c, bits; - mnode_t *node; mleaf_t *leaf; qbyte *vis; - msurface_t **mark; + msurface_t **mark, *surf; - if (r_viewleaf == viewleaf && r_viewleafnovis == r_novis.integer) + if (r_pvsviewleaf == viewleaf && r_pvsviewleafnovis == r_novis.integer) return; r_pvsframecount++; - r_viewleaf = viewleaf; - r_viewleafnovis = r_novis.integer; + r_pvsviewleaf = viewleaf; + r_pvsviewleafnovis = r_novis.integer; if (viewleaf) { @@ -1883,17 +1882,26 @@ void R_PVSUpdate (mleaf_t *viewleaf) if (bits & (1 << i)) { leaf = &cl.worldmodel->leafs[j + i + 1]; + leaf->pvsframe = r_pvsframecount; // mark surfaces bounding this leaf as visible for (c = leaf->nummarksurfaces, mark = leaf->firstmarksurface;c;c--) (*mark++)->pvsframe = r_pvsframecount; - // mark parents as visible until we hit an already - // marked parent (which is usually very soon) - for (node = (mnode_t *)leaf;node && node->pvsframe != r_pvsframecount;node = node->parent) - node->pvsframe = r_pvsframecount; } } } } + // build pvs surfacechain + r_pvsfirstsurface = NULL; + mark = &r_pvsfirstsurface; + for (c = cl.worldmodel->nummodelsurfaces, surf = cl.worldmodel->surfaces + cl.worldmodel->firstmodelsurface;c;c--, surf++) + { + if (surf->pvsframe == r_pvsframecount) + { + *mark = surf; + mark = &surf->pvschain; + } + } + *mark = NULL; } } @@ -1904,17 +1912,16 @@ R_DrawWorld */ void R_DrawWorld (entity_render_t *ent) { - // there is only one instance of the world, but it can be rendered in - // multiple stages mleaf_t *viewleaf; viewleaf = Mod_PointInLeaf (r_origin, cl.worldmodel); R_PVSUpdate(viewleaf); if (!viewleaf) return; if (r_surfaceworldnode.integer || viewleaf->contents == CONTENTS_SOLID) - R_SurfaceWorldNode (ent); + R_SurfaceWorldNode (); else R_PortalWorldNode (ent, viewleaf); + R_DrawSurfaces(ent, true, true); } /* @@ -1924,18 +1931,13 @@ R_DrawBrushModel */ void R_DrawBrushModelSky (entity_render_t *ent) { - R_SetupForBrushModelRendering(ent); - R_DrawSurfaces(ent, SHADERSTAGE_SKY); + R_DrawBrushModel(ent, true, false); } void R_DrawBrushModelNormal (entity_render_t *ent) { c_bmodels++; - // have to flush queue because of possible lightmap reuse - R_Mesh_Render(); - R_SetupForBrushModelRendering(ent); - R_SurfMarkLights(ent); - R_DrawSurfaces(ent, SHADERSTAGE_NORMAL); + R_DrawBrushModel(ent, false, true); } static void gl_surf_start(void) @@ -1950,8 +1952,9 @@ static void gl_surf_newmap(void) { // reset pvs visibility variables so it will update on first frame r_pvsframecount = 1; - r_viewleaf = NULL; - r_viewleafnovis = false; + r_pvsviewleaf = NULL; + r_pvsviewleafnovis = false; + r_pvsfirstsurface = NULL; } void GL_Surf_Init(void) @@ -1964,7 +1967,7 @@ void GL_Surf_Init(void) Cvar_RegisterVariable(&r_ambient); Cvar_RegisterVariable(&r_vertexsurfaces); Cvar_RegisterVariable(&r_dlightmap); - Cvar_RegisterVariable(&r_drawportals); + //Cvar_RegisterVariable(&r_drawportals); Cvar_RegisterVariable(&r_testvis); Cvar_RegisterVariable(&r_floatbuildlightmap); Cvar_RegisterVariable(&r_detailtextures); diff --git a/model_brush.h b/model_brush.h index 6f24b259..cd53901d 100644 --- a/model_brush.h +++ b/model_brush.h @@ -141,6 +141,8 @@ typedef struct msurface_s int visframe; // should be drawn if onscreen and not a backface (used for setting visframe) int pvsframe; + // chain of surfaces marked visible by pvs + struct msurface_s *pvschain; // the node plane this is on, backwards if SURF_PLANEBACK flag set mplane_t *plane; @@ -235,8 +237,6 @@ typedef struct mnode_s vec3_t mins; vec3_t maxs; - int pvsframe; // potentially visible if current (r_pvsframecount) - // node specific mplane_t *plane; struct mnode_s *children[2]; @@ -258,10 +258,8 @@ typedef struct mleaf_s vec3_t mins; vec3_t maxs; - int pvsframe; // potentially visible if current (r_pvsframecount) - // leaf specific - int visframe; // visible if current (r_framecount) + int pvsframe; // potentially visible if current (r_pvsframecount) int worldnodeframe; // used by certain worldnode variants to avoid processing the same leaf twice in a frame int portalmarkid; // used by polygon-through-portals visibility checker diff --git a/render.h b/render.h index 195c0cac..7aa31b7a 100644 --- a/render.h +++ b/render.h @@ -110,10 +110,6 @@ void R_InitSky (qbyte *src, int bytesperpixel); // called at level load void R_NewMap (void); void R_DrawWorld(entity_render_t *ent); -void R_SurfMarkLights (entity_render_t *ent); -void R_PrepareSurfaces(entity_render_t *ent); -void R_DrawSurfaces(entity_render_t *ent, int type); -void R_DrawPortals(entity_render_t *ent); void R_DrawParticles(void); void R_DrawExplosions(void); void R_DrawBrushModelSky (entity_render_t *ent); -- 2.39.2