From b4f27ddf07c8b4e6a4116c8334336f8d8ebe78d2 Mon Sep 17 00:00:00 2001 From: havoc Date: Mon, 14 Dec 2009 06:35:00 +0000 Subject: [PATCH] reworked animcache code to store information in ent->animcache_vertex3f and similar fields rather than having a separate info array git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9585 d7cf8633-e32d-0410-b094-e92efae38249 --- client.h | 8 +++-- gl_rmain.c | 102 +++++++++++++++++++++-------------------------------- r_shadow.c | 4 +-- 3 files changed, 48 insertions(+), 66 deletions(-) diff --git a/client.h b/client.h index 96b8de31..53e31e32 100644 --- a/client.h +++ b/client.h @@ -362,8 +362,12 @@ typedef struct entity_render_s // skeletal animation data (if skeleton.relativetransforms is not NULL, it overrides frameblend) skeleton_t *skeleton; - // animation cache index - int animcacheindex; + // animation cache (pointers allocated using R_FrameData_Alloc) + // ONLY valid during R_RenderView! may be NULL (not cached) + float *animcache_vertex3f; + float *animcache_normal3f; + float *animcache_svector3f; + float *animcache_tvector3f; // current lighting from map (updated ONLY by client code, not renderer) vec3_t modellight_ambient; diff --git a/gl_rmain.c b/gl_rmain.c index 3f39feab..f818b9b3 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -3428,36 +3428,15 @@ void *R_FrameData_Store(size_t size, void *data) //================================================================================== -// LordHavoc: animcache written by Echon, refactored and reformatted by me +// LordHavoc: animcache originally written by Echon, rewritten since then /** - * Animation cache helps save re-animating a player mesh if it's re-rendered again in a given frame - * (reflections, lighting, etc). All animation cache becomes invalid on the next frame and is flushed - * (well, over-wrote). The memory for each cache is kept around to save on allocation thrashing. + * Animation cache prevents re-generating mesh data for an animated model + * multiple times in one frame for lighting, shadowing, reflections, etc. */ -typedef struct r_animcache_entity_s -{ - float *vertex3f; - float *normal3f; - float *svector3f; - float *tvector3f; -} -r_animcache_entity_t; - -typedef struct r_animcache_s -{ - r_animcache_entity_t entity[MAX_EDICTS]; - int maxindex; - int currentindex; -} -r_animcache_t; - -static r_animcache_t r_animcachestate; - void R_AnimCache_Free(void) { - memset(&r_animcachestate, 0, sizeof(r_animcachestate)); } void R_AnimCache_ClearCache(void) @@ -3465,69 +3444,62 @@ void R_AnimCache_ClearCache(void) int i; entity_render_t *ent; - r_animcachestate.maxindex = sizeof(r_animcachestate.entity) / sizeof(r_animcachestate.entity[0]); - r_animcachestate.currentindex = 0; - for (i = 0;i < r_refdef.scene.numentities;i++) { ent = r_refdef.scene.entities[i]; - ent->animcacheindex = -1; + ent->animcache_vertex3f = NULL; + ent->animcache_normal3f = NULL; + ent->animcache_svector3f = NULL; + ent->animcache_tvector3f = NULL; } } qboolean R_AnimCache_GetEntity(entity_render_t *ent, qboolean wantnormals, qboolean wanttangents) { dp_model_t *model = ent->model; - r_animcache_entity_t *c; int numvertices; // see if it's already cached this frame - if (ent->animcacheindex >= 0) + if (ent->animcache_vertex3f) { // add normals/tangents if needed if (wantnormals || wanttangents) { - c = r_animcachestate.entity + ent->animcacheindex; - if (c->normal3f) + if (ent->animcache_normal3f) wantnormals = false; - if (c->svector3f) + if (ent->animcache_svector3f) wanttangents = false; if (wantnormals || wanttangents) { numvertices = model->surfmesh.num_vertices; if (wantnormals) - c->normal3f = R_FrameData_Alloc(sizeof(float[3])*numvertices); + ent->animcache_normal3f = R_FrameData_Alloc(sizeof(float[3])*numvertices); if (wanttangents) { - c->svector3f = R_FrameData_Alloc(sizeof(float[3])*numvertices); - c->tvector3f = R_FrameData_Alloc(sizeof(float[3])*numvertices); + ent->animcache_svector3f = R_FrameData_Alloc(sizeof(float[3])*numvertices); + ent->animcache_tvector3f = R_FrameData_Alloc(sizeof(float[3])*numvertices); } if (!r_framedata_failed) - model->AnimateVertices(model, ent->frameblend, ent->skeleton, NULL, wantnormals ? c->normal3f : NULL, wanttangents ? c->svector3f : NULL, wanttangents ? c->tvector3f : NULL); + model->AnimateVertices(model, ent->frameblend, ent->skeleton, NULL, wantnormals ? ent->animcache_normal3f : NULL, wanttangents ? ent->animcache_svector3f : NULL, wanttangents ? ent->animcache_tvector3f : NULL); } } } else { // see if this ent is worth caching - if (r_animcachestate.maxindex <= r_animcachestate.currentindex) - return false; if (!model || !model->Draw || !model->surfmesh.isanimated || !model->AnimateVertices || (ent->frameblend[0].lerp == 1 && ent->frameblend[0].subframe == 0 && !ent->skeleton)) return false; - // assign it a cache entry and get some temp memory - ent->animcacheindex = r_animcachestate.currentindex++; - c = r_animcachestate.entity + ent->animcacheindex; + // get some memory for this entity and generate mesh data numvertices = model->surfmesh.num_vertices; - memset(c, 0, sizeof(*c)); - c->vertex3f = R_FrameData_Alloc(sizeof(float[3])*numvertices); + ent->animcache_vertex3f = R_FrameData_Alloc(sizeof(float[3])*numvertices); if (wantnormals) - c->normal3f = R_FrameData_Alloc(sizeof(float[3])*numvertices); + ent->animcache_normal3f = R_FrameData_Alloc(sizeof(float[3])*numvertices); if (wanttangents) { - c->svector3f = R_FrameData_Alloc(sizeof(float[3])*numvertices); - c->tvector3f = R_FrameData_Alloc(sizeof(float[3])*numvertices); + ent->animcache_svector3f = R_FrameData_Alloc(sizeof(float[3])*numvertices); + ent->animcache_tvector3f = R_FrameData_Alloc(sizeof(float[3])*numvertices); } if (!r_framedata_failed) - model->AnimateVertices(model, ent->frameblend, ent->skeleton, c->vertex3f, c->normal3f, c->svector3f, c->tvector3f); + model->AnimateVertices(model, ent->frameblend, ent->skeleton, ent->animcache_vertex3f, ent->animcache_normal3f, ent->animcache_svector3f, ent->animcache_tvector3f); } return !r_framedata_failed; } @@ -3535,7 +3507,6 @@ qboolean R_AnimCache_GetEntity(entity_render_t *ent, qboolean wantnormals, qbool void R_AnimCache_CacheVisibleEntities(void) { int i; - entity_render_t *ent; qboolean wantnormals = !r_showsurfaces.integer; qboolean wanttangents = !r_showsurfaces.integer; @@ -3550,16 +3521,16 @@ void R_AnimCache_CacheVisibleEntities(void) } // TODO: thread this + // NOTE: R_PrepareRTLights() also caches entities for (i = 0;i < r_refdef.scene.numentities;i++) - { - if (!r_refdef.viewcache.entityvisible[i]) - continue; - ent = r_refdef.scene.entities[i]; - if (ent->animcacheindex >= 0) - continue; - R_AnimCache_GetEntity(ent, wantnormals, wanttangents); - } + if (r_refdef.viewcache.entityvisible[i]) + R_AnimCache_GetEntity(r_refdef.scene.entities[i], wantnormals, wanttangents); + + if (r_shadows.integer) + for (i = 0;i < r_refdef.scene.numentities;i++) + if (!r_refdef.viewcache.entityvisible[i]) + R_AnimCache_GetEntity(r_refdef.scene.entities[i], false, false); } //================================================================================== @@ -5154,11 +5125,18 @@ void R_RenderScene(void) R_SetupView(false); R_Sky(); R_SetupView(true); + if (r_timereport_active) + R_TimeReport("sky"); } } R_AnimCache_CacheVisibleEntities(); + if (r_timereport_active) + R_TimeReport("animation"); + R_PrepareRTLights(); + if (r_timereport_active) + R_TimeReport("preplights"); if (r_depthfirst.integer >= 1 && cl.csqc_vidvars.drawworld && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->DrawDepth) { @@ -6212,12 +6190,12 @@ void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, q } if (model->surfmesh.isanimated && model->AnimateVertices && (rsurface.frameblend[0].lerp != 1 || rsurface.frameblend[0].subframe != 0)) { - if (R_AnimCache_GetEntity((entity_render_t *)ent, wantnormals, wanttangents)) + if (ent->animcache_vertex3f && !r_framedata_failed) { - rsurface.modelvertex3f = r_animcachestate.entity[ent->animcacheindex].vertex3f; - rsurface.modelsvector3f = wanttangents ? r_animcachestate.entity[ent->animcacheindex].svector3f : NULL; - rsurface.modeltvector3f = wanttangents ? r_animcachestate.entity[ent->animcacheindex].tvector3f : NULL; - rsurface.modelnormal3f = wantnormals ? r_animcachestate.entity[ent->animcacheindex].normal3f : NULL; + rsurface.modelvertex3f = ent->animcache_vertex3f; + rsurface.modelsvector3f = wanttangents ? ent->animcache_svector3f : NULL; + rsurface.modeltvector3f = wanttangents ? ent->animcache_tvector3f : NULL; + rsurface.modelnormal3f = wantnormals ? ent->animcache_normal3f : NULL; } else if (wanttangents) { diff --git a/r_shadow.c b/r_shadow.c index 7674fb50..47f1a1bc 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -3648,10 +3648,10 @@ void R_CacheRTLight(rtlight_t *rtlight) // cache all the animated entities that cast a shadow but are not visible for (i = 0;i < numshadowentities;i++) - if (shadowentities[i]->animcacheindex < 0) + if (!shadowentities[i]->animcache_vertex3f) R_AnimCache_GetEntity(shadowentities[i], false, false); for (i = 0;i < numshadowentities_noselfshadow;i++) - if (shadowentities_noselfshadow[i]->animcacheindex < 0) + if (!shadowentities_noselfshadow[i]->animcache_vertex3f) R_AnimCache_GetEntity(shadowentities_noselfshadow[i], false, false); // allocate some temporary memory for rendering this light later in the frame -- 2.39.2