From 8663634a9ee1b8392f1edf9dd5e2861af9a80443 Mon Sep 17 00:00:00 2001 From: havoc Date: Fri, 23 Feb 2007 13:07:36 +0000 Subject: [PATCH] audited R_Mesh_Matrix calls and RSurf_ActiveEntity calls and moved them to more appropriate locations in some cases 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 | 172 ++++++++++++++++++++++++++++++++++++----------------- gl_rsurf.c | 13 ++-- r_shadow.c | 14 ++--- render.h | 6 +- todo | 2 + 5 files changed, 141 insertions(+), 66 deletions(-) diff --git a/gl_rmain.c b/gl_rmain.c index aec70567..d4b26cb8 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -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; @@ -4067,6 +4056,83 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces) r_refdef.stats.entities_triangles += counttriangles; 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); diff --git a/gl_rsurf.c b/gl_rsurf.c index 5b9cff9f..5bdd7faf 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -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 diff --git a/r_shadow.c b/r_shadow.c index 38973ab3..c22c90be 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -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); } } diff --git a/render.h b/render.h index d28c8118..5010a752 100644 --- 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 61397120..3be18238 100644 --- 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) -- 2.39.2