audited R_Mesh_Matrix calls and RSurf_ActiveEntity calls and moved them to more appro...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 23 Feb 2007 13:07:36 +0000 (13:07 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 23 Feb 2007 13:07:36 +0000 (13:07 +0000)
split R_DrawSurfaces into R_DrawWorldSurfaces and R_DrawModelSurfaces to make profile reports more useful
split RSurf_ActiveEntity into RSurf_ActiveWorldEntity and RSurf_ActiveModelEntity to make profile reports more useful, and very slightly improve performance

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@6911 d7cf8633-e32d-0410-b094-e92efae38249

gl_rmain.c
gl_rsurf.c
r_shadow.c
render.h
todo

index aec7056..d4b26cb 100644 (file)
@@ -2851,10 +2851,29 @@ void RSurf_CleanUp(void)
        rsurface_texture = NULL;
 }
 
-void RSurf_ActiveEntity(const entity_render_t *ent, qboolean wantnormals, qboolean wanttangents)
+void RSurf_ActiveWorldEntity(void)
+{
+       RSurf_CleanUp();
+       rsurface_entity = r_refdef.worldentity;
+       rsurface_model = r_refdef.worldmodel;
+       if (rsurface_array_size < rsurface_model->surfmesh.num_vertices)
+               R_Mesh_ResizeArrays(rsurface_model->surfmesh.num_vertices);
+       R_Mesh_Matrix(&identitymatrix);
+       VectorCopy(r_view.origin, rsurface_modelorg);
+       rsurface_modelvertex3f  = rsurface_model->surfmesh.data_vertex3f;
+       rsurface_modelsvector3f = rsurface_model->surfmesh.data_svector3f;
+       rsurface_modeltvector3f = rsurface_model->surfmesh.data_tvector3f;
+       rsurface_modelnormal3f  = rsurface_model->surfmesh.data_normal3f;
+       rsurface_generatedvertex = false;
+       rsurface_vertex3f  = rsurface_modelvertex3f;
+       rsurface_svector3f = rsurface_modelsvector3f;
+       rsurface_tvector3f = rsurface_modeltvector3f;
+       rsurface_normal3f  = rsurface_modelnormal3f;
+}
+
+void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, qboolean wanttangents)
 {
        RSurf_CleanUp();
-       Matrix4x4_Transform(&ent->inversematrix, r_view.origin, rsurface_modelorg);
        rsurface_entity = ent;
        rsurface_model = ent->model;
        if (rsurface_array_size < rsurface_model->surfmesh.num_vertices)
@@ -3791,10 +3810,12 @@ static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, const
        // if the model is static it doesn't matter what value we give for
        // wantnormals and wanttangents, so this logic uses only rules applicable
        // to a model, knowing that they are meaningless otherwise
-       if ((ent->effects & EF_FULLBRIGHT) || r_showsurfaces.integer || VectorLength2(ent->modellight_diffuse) < (1.0f / 256.0f))
-               RSurf_ActiveEntity(ent, false, false);
+       if (ent == r_refdef.worldentity)
+               RSurf_ActiveWorldEntity();
+       else if ((ent->effects & EF_FULLBRIGHT) || r_showsurfaces.integer || VectorLength2(ent->modellight_diffuse) < (1.0f / 256.0f))
+               RSurf_ActiveModelEntity(ent, false, false);
        else
-               RSurf_ActiveEntity(ent, true, r_glsl.integer && gl_support_fragment_shader);
+               RSurf_ActiveModelEntity(ent, true, r_glsl.integer && gl_support_fragment_shader);
 
        for (i = 0;i < numsurfaces;i = j)
        {
@@ -3964,26 +3985,20 @@ void R_DrawTrianglesAndNormals(entity_render_t *ent, qboolean drawtris, qboolean
 }
 
 extern void R_BuildLightMap(const entity_render_t *ent, msurface_t *surface);
-void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
+void R_DrawWorldSurfaces(qboolean skysurfaces)
 {
        int i, j, endj, f, flagsmask;
        int counttriangles = 0;
-       msurface_t *surface, *endsurface, **surfacechain;
+       msurface_t *surface, **surfacechain;
        texture_t *t;
-       model_t *model = ent->model;
+       model_t *model = r_refdef.worldmodel;
        const int maxsurfacelist = 1024;
        int numsurfacelist = 0;
        msurface_t *surfacelist[1024];
        if (model == NULL)
                return;
 
-       // if the model is static it doesn't matter what value we give for
-       // wantnormals and wanttangents, so this logic uses only rules applicable
-       // to a model, knowing that they are meaningless otherwise
-       if ((ent->effects & EF_FULLBRIGHT) || r_showsurfaces.integer || VectorLength2(ent->modellight_diffuse) < (1.0f / 256.0f))
-               RSurf_ActiveEntity(ent, false, false);
-       else
-               RSurf_ActiveEntity(ent, true, r_glsl.integer && gl_support_fragment_shader);
+       RSurf_ActiveWorldEntity();
 
        // update light styles
        if (!skysurfaces && model->brushq1.light_styleupdatechains)
@@ -4000,57 +4015,31 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
                }
        }
 
-       R_UpdateAllTextureInfo(ent);
+       R_UpdateAllTextureInfo(r_refdef.worldentity);
        flagsmask = skysurfaces ? MATERIALFLAG_SKY : (MATERIALFLAG_WATER | MATERIALFLAG_WALL);
        f = 0;
        t = NULL;
        rsurface_uselightmaptexture = false;
        rsurface_texture = NULL;
        numsurfacelist = 0;
-       if (ent == r_refdef.worldentity)
-       {
-               j = model->firstmodelsurface;
-               endj = j + model->nummodelsurfaces;
-               while (j < endj)
-               {
-                       // quickly skip over non-visible surfaces
-                       for (;j < endj && !r_viewcache.world_surfacevisible[j];j++)
-                               ;
-                       // quickly iterate over visible surfaces
-                       for (;j < endj && r_viewcache.world_surfacevisible[j];j++)
-                       {
-                               // process this surface
-                               surface = model->data_surfaces + j;
-                               // if this surface fits the criteria, add it to the list
-                               if (surface->texture->basematerialflags & flagsmask && surface->num_triangles)
-                               {
-                                       // if lightmap parameters changed, rebuild lightmap texture
-                                       if (surface->cached_dlight)
-                                               R_BuildLightMap(ent, surface);
-                                       // add face to draw list
-                                       surfacelist[numsurfacelist++] = surface;
-                                       counttriangles += surface->num_triangles;
-                                       if (numsurfacelist >= maxsurfacelist)
-                                       {
-                                               R_QueueSurfaceList(numsurfacelist, surfacelist);
-                                               numsurfacelist = 0;
-                                       }
-                               }
-                       }
-               }
-       }
-       else
+       j = model->firstmodelsurface;
+       endj = j + model->nummodelsurfaces;
+       while (j < endj)
        {
-               surface = model->data_surfaces + model->firstmodelsurface;
-               endsurface = surface + model->nummodelsurfaces;
-               for (;surface < endsurface;surface++)
+               // quickly skip over non-visible surfaces
+               for (;j < endj && !r_viewcache.world_surfacevisible[j];j++)
+                       ;
+               // quickly iterate over visible surfaces
+               for (;j < endj && r_viewcache.world_surfacevisible[j];j++)
                {
+                       // process this surface
+                       surface = model->data_surfaces + j;
                        // if this surface fits the criteria, add it to the list
                        if (surface->texture->basematerialflags & flagsmask && surface->num_triangles)
                        {
                                // if lightmap parameters changed, rebuild lightmap texture
                                if (surface->cached_dlight)
-                                       R_BuildLightMap(ent, surface);
+                                       R_BuildLightMap(r_refdef.worldentity, surface);
                                // add face to draw list
                                surfacelist[numsurfacelist++] = surface;
                                counttriangles += surface->num_triangles;
@@ -4068,6 +4057,83 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
        RSurf_CleanUp();
 
        if (r_showcollisionbrushes.integer && !skysurfaces)
+               R_DrawCollisionBrushes(r_refdef.worldentity);
+
+       if (r_showtris.integer || r_shownormals.integer)
+               R_DrawTrianglesAndNormals(r_refdef.worldentity, r_showtris.integer, r_shownormals.integer, flagsmask);
+}
+
+void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces)
+{
+       int i, f, flagsmask;
+       int counttriangles = 0;
+       msurface_t *surface, *endsurface, **surfacechain;
+       texture_t *t;
+       model_t *model = ent->model;
+       const int maxsurfacelist = 1024;
+       int numsurfacelist = 0;
+       msurface_t *surfacelist[1024];
+       if (model == NULL)
+               return;
+
+       // if the model is static it doesn't matter what value we give for
+       // wantnormals and wanttangents, so this logic uses only rules applicable
+       // to a model, knowing that they are meaningless otherwise
+       if (ent == r_refdef.worldentity)
+               RSurf_ActiveWorldEntity();
+       else if ((ent->effects & EF_FULLBRIGHT) || r_showsurfaces.integer || VectorLength2(ent->modellight_diffuse) < (1.0f / 256.0f))
+               RSurf_ActiveModelEntity(ent, false, false);
+       else
+               RSurf_ActiveModelEntity(ent, true, r_glsl.integer && gl_support_fragment_shader);
+
+       // update light styles
+       if (!skysurfaces && model->brushq1.light_styleupdatechains)
+       {
+               for (i = 0;i < model->brushq1.light_styles;i++)
+               {
+                       if (model->brushq1.light_stylevalue[i] != r_refdef.lightstylevalue[model->brushq1.light_style[i]])
+                       {
+                               model->brushq1.light_stylevalue[i] = r_refdef.lightstylevalue[model->brushq1.light_style[i]];
+                               if ((surfacechain = model->brushq1.light_styleupdatechains[i]))
+                                       for (;(surface = *surfacechain);surfacechain++)
+                                               surface->cached_dlight = true;
+                       }
+               }
+       }
+
+       R_UpdateAllTextureInfo(ent);
+       flagsmask = skysurfaces ? MATERIALFLAG_SKY : (MATERIALFLAG_WATER | MATERIALFLAG_WALL);
+       f = 0;
+       t = NULL;
+       rsurface_uselightmaptexture = false;
+       rsurface_texture = NULL;
+       numsurfacelist = 0;
+       surface = model->data_surfaces + model->firstmodelsurface;
+       endsurface = surface + model->nummodelsurfaces;
+       for (;surface < endsurface;surface++)
+       {
+               // if this surface fits the criteria, add it to the list
+               if (surface->texture->basematerialflags & flagsmask && surface->num_triangles)
+               {
+                       // if lightmap parameters changed, rebuild lightmap texture
+                       if (surface->cached_dlight)
+                               R_BuildLightMap(ent, surface);
+                       // add face to draw list
+                       surfacelist[numsurfacelist++] = surface;
+                       counttriangles += surface->num_triangles;
+                       if (numsurfacelist >= maxsurfacelist)
+                       {
+                               R_QueueSurfaceList(numsurfacelist, surfacelist);
+                               numsurfacelist = 0;
+                       }
+               }
+       }
+       if (numsurfacelist)
+               R_QueueSurfaceList(numsurfacelist, surfacelist);
+       r_refdef.stats.entities_triangles += counttriangles;
+       RSurf_CleanUp();
+
+       if (r_showcollisionbrushes.integer && !skysurfaces)
                R_DrawCollisionBrushes(ent);
 
        if (r_showtris.integer || r_shownormals.integer)
index 5b9cff9..5bdd7fa 100644 (file)
@@ -505,7 +505,10 @@ void R_Q1BSP_DrawSky(entity_render_t *ent)
 {
        if (ent->model == NULL)
                return;
-       R_DrawSurfaces(ent, true);
+       if (ent == r_refdef.worldentity)
+               R_DrawWorldSurfaces(true);
+       else
+               R_DrawModelSurfaces(ent, true);
 }
 
 void R_Q1BSP_Draw(entity_render_t *ent)
@@ -513,7 +516,10 @@ void R_Q1BSP_Draw(entity_render_t *ent)
        model_t *model = ent->model;
        if (model == NULL)
                return;
-       R_DrawSurfaces(ent, false);
+       if (ent == r_refdef.worldentity)
+               R_DrawWorldSurfaces(false);
+       else
+               R_DrawModelSurfaces(ent, false);
 }
 
 typedef struct r_q1bsp_getlightinfo_s
@@ -849,7 +855,6 @@ void R_Q1BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin,
        else
        {
                projectdistance = lightradius + model->radius*2;
-               RSurf_ActiveEntity(ent, false, false);
                R_Shadow_PrepareShadowMark(model->surfmesh.num_triangles);
                // identify lit faces within the bounding box
                for (modelsurfacelistindex = 0;modelsurfacelistindex < modelnumsurfaces;modelsurfacelistindex++)
@@ -926,7 +931,7 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, int numsurfaces, const int *surface
        msurface_t *batchsurfacelist[RSURF_MAX_BATCHSURFACES];
        texture_t *tex;
        CHECKGLERROR
-       RSurf_ActiveEntity(ent, true, true);
+       RSurf_ActiveModelEntity(ent, true, true);
        R_UpdateAllTextureInfo(ent);
        CHECKGLERROR
        // this is a double loop because non-visible surface skipping has to be
index 38973ab..c22c90b 100644 (file)
@@ -2287,10 +2287,10 @@ void R_Shadow_DrawEntityShadow(entity_render_t *ent, int numsurfaces, int *surfa
        vec_t relativeshadowradius;
        if (ent == r_refdef.worldentity)
        {
+               RSurf_ActiveWorldEntity();
                if (r_shadow_rtlight->compiled && r_shadow_realtime_world_compile.integer && r_shadow_realtime_world_compileshadow.integer)
                {
                        shadowmesh_t *mesh;
-                       R_Mesh_Matrix(&ent->matrix);
                        CHECKGLERROR
                        for (mesh = r_shadow_rtlight->static_meshchain_shadow;mesh;mesh = mesh->next)
                        {
@@ -2313,13 +2313,11 @@ void R_Shadow_DrawEntityShadow(entity_render_t *ent, int numsurfaces, int *surfa
                        CHECKGLERROR
                }
                else if (numsurfaces)
-               {
-                       R_Mesh_Matrix(&ent->matrix);
                        model->DrawShadowVolume(ent, r_shadow_rtlight->shadoworigin, NULL, r_shadow_rtlight->radius, numsurfaces, surfacelist, r_shadow_rtlight_cullmins, r_shadow_rtlight_cullmaxs);
-               }
        }
        else
        {
+               RSurf_ActiveModelEntity(ent, false, false);
                Matrix4x4_Transform(&ent->inversematrix, r_shadow_rtlight->shadoworigin, relativeshadoworigin);
                relativeshadowradius = r_shadow_rtlight->radius / ent->scale;
                relativeshadowmins[0] = relativeshadoworigin[0] - relativeshadowradius;
@@ -2328,7 +2326,6 @@ void R_Shadow_DrawEntityShadow(entity_render_t *ent, int numsurfaces, int *surfa
                relativeshadowmaxs[0] = relativeshadoworigin[0] + relativeshadowradius;
                relativeshadowmaxs[1] = relativeshadoworigin[1] + relativeshadowradius;
                relativeshadowmaxs[2] = relativeshadoworigin[2] + relativeshadowradius;
-               R_Mesh_Matrix(&ent->matrix);
                model->DrawShadowVolume(ent, relativeshadoworigin, NULL, relativeshadowradius, model->nummodelsurfaces, model->surfacelist, relativeshadowmins, relativeshadowmaxs);
        }
 }
@@ -2336,7 +2333,10 @@ void R_Shadow_DrawEntityShadow(entity_render_t *ent, int numsurfaces, int *surfa
 void R_Shadow_SetupEntityLight(const entity_render_t *ent)
 {
        // set up properties for rendering light onto this entity
-       RSurf_ActiveEntity(ent, true, true);
+       if (ent == r_refdef.worldentity)
+               RSurf_ActiveWorldEntity();
+       else
+               RSurf_ActiveModelEntity(ent, true, true);
        Matrix4x4_Concat(&r_shadow_entitytolight, &r_shadow_rtlight->matrix_worldtolight, &ent->matrix);
        Matrix4x4_Concat(&r_shadow_entitytoattenuationxyz, &matrix_attenuationxyz, &r_shadow_entitytolight);
        Matrix4x4_Concat(&r_shadow_entitytoattenuationz, &matrix_attenuationz, &r_shadow_entitytolight);
@@ -2604,7 +2604,7 @@ void R_DrawModelShadows(void)
                        VectorSet(relativeshadowmaxs, relativethrowdistance, relativethrowdistance, relativethrowdistance);
                        VectorNegate(ent->modellight_lightdir, relativelightdirection);
                        VectorScale(relativelightdirection, -relativethrowdistance, relativelightorigin);
-                       R_Mesh_Matrix(&ent->matrix);
+                       RSurf_ActiveModelEntity(ent, false, false);
                        ent->model->DrawShadowVolume(ent, relativelightorigin, relativelightdirection, relativethrowdistance, ent->model->nummodelsurfaces, ent->model->surfacelist, relativeshadowmins, relativeshadowmaxs);
                }
        }
index d28c811..5010a75 100644 (file)
--- a/render.h
+++ b/render.h
@@ -218,7 +218,8 @@ extern texture_t *rsurface_texture;
 extern qboolean rsurface_uselightmaptexture;
 extern rsurfmode_t rsurface_mode;
 
-void RSurf_ActiveEntity(const entity_render_t *ent, qboolean wantnormals, qboolean wanttangents);
+void RSurf_ActiveWorldEntity(void);
+void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, qboolean wanttangents);
 void RSurf_CleanUp(void);
 
 void R_Mesh_ResizeArrays(int newvertices);
@@ -229,7 +230,8 @@ struct msurface_s;
 void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t);
 void R_UpdateAllTextureInfo(entity_render_t *ent);
 void R_QueueTextureSurfaceList(int texturenumsurfaces, msurface_t **texturesurfacelist);
-void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces);
+void R_DrawWorldSurfaces(qboolean skysurfaces);
+void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces);
 
 void RSurf_PrepareVerticesForBatch(qboolean generatenormals, qboolean generatetangents, int texturenumsurfaces, msurface_t **texturesurfacelist);
 void RSurf_DrawBatch_Simple(int texturenumsurfaces, msurface_t **texturesurfacelist);
diff --git a/todo b/todo
index 6139712..3be1823 100644 (file)
--- a/todo
+++ b/todo
@@ -1283,6 +1283,8 @@ f bug darkplaces renderer: modify r_showtris_polygonoffset to push back all fill
 f bug darkplaces renderer: r_editlights 1 causes crashes on level change 40% of the time? (romi)
 f bug darkplaces renderer: rtlight "style" values are broken, e1m6 trap hall for example (romi)
 f bug darkplaces renderer: the quake logo shadow is missing in e1m5 rtlights, too much vis optimization... (romi)
+0 bug darkplaces renderer: if an animated model is entirely transparent, the RSurf_ActiveModelEntity call updating vertices is completely wasted
+0 bug darkplaces renderer: if an animated model has transparent surfaces, each one calls RSurf_ActiveModelEntity, recomputing all vertices
 f bug darkplaces server: items still falling through the floor in nexuiz, and they seem to fall through more often at smaller sys_ticrate values such as 0.02 rather than 0.05 (GreEn`mArine)
 f change darkplaces client: hardcode sbar image sizes so they can be replaced with higher quality images
 f darkplaces client: add chase_pitch cvar to control pitch angle of chase camera, and chase_angle cvar to control yaw angle of chase camera, and add back chase_right cvar (Electro)