added r_surfaceworldnode and r_cullsurface cvars (it is recommended that these both...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 5 Sep 2002 12:07:55 +0000 (12:07 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 5 Sep 2002 12:07:55 +0000 (12:07 +0000)
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
gl_rsurf.c
model_brush.h
render.h

index b16a2bd..684e224 100644 (file)
@@ -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");
index 3570106..48440d9 100644 (file)
@@ -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);
index 6f24b25..cd53901 100644 (file)
@@ -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
 
index 195c0ca..7aa31b7 100644 (file)
--- 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);