From c03ddda1e107e8483568d3d65c10df51ef556ee5 Mon Sep 17 00:00:00 2001 From: eihrul Date: Fri, 5 Feb 2010 01:09:58 +0000 Subject: [PATCH] try to cache fewer animations for entities when r_shadows is used by using cull box git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9934 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_rmain.c | 7 ++----- r_shadow.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ r_shadow.h | 2 ++ 3 files changed, 64 insertions(+), 5 deletions(-) diff --git a/gl_rmain.c b/gl_rmain.c index 74cf0cba..22c99ef1 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -6716,11 +6716,6 @@ void R_AnimCache_CacheVisibleEntities(void) for (i = 0;i < r_refdef.scene.numentities;i++) 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); } //================================================================================== @@ -8357,6 +8352,8 @@ void R_RenderScene(void) R_TimeReport("animation"); R_Shadow_PrepareLights(); + if (r_shadows.integer > 0 && r_refdef.lightmapintensity > 0) + R_Shadow_PrepareModelShadows(); if (r_timereport_active) R_TimeReport("preparelights"); diff --git a/r_shadow.c b/r_shadow.c index be7f4fab..106bcc82 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -4203,6 +4203,66 @@ extern cvar_t r_shadows_castfrombmodels; extern cvar_t r_shadows_throwdistance; extern cvar_t r_shadows_throwdirection; +void R_Shadow_PrepareModelShadows(void) +{ + int i; + float scale, size, radius, dot1, dot2; + vec3_t shadowdir, shadowforward, shadowright, shadoworigin, shadowmins, shadowmaxs; + entity_render_t *ent; + + if (!r_refdef.scene.numentities) + return; + + switch (r_shadow_shadowmode) + { + case R_SHADOW_SHADOWMODE_SHADOWMAP2D: + case R_SHADOW_SHADOWMODE_SHADOWMAPRECTANGLE: + break; + case R_SHADOW_SHADOWMODE_STENCIL; + for (i = 0;i < r_refdef.scene.numentities;i++) + { + ent = r_refdef.scene.entities[i]; + if (!ent->animcache_vertex3f && ent->model && ent->model->DrawShadowVolume != NULL && (!ent->model->brush.submodel || r_shadows_castfrombmodels.integer) && (ent->flags & RENDER_SHADOW)) + R_AnimCache_GetEntity(ent false, false); + } + return; + default: + return; + } + + size = 2*r_shadow_shadowmapmaxsize; + scale = r_shadow_shadowmapping_precision.value; + radius = 0.5f * size / scale; + Math_atov(r_shadows_throwdirection.string, shadowdir); + VectorNormalize(shadowdir); + dot1 = DotProduct(r_refdef.view.forward, shadowdir); + dot2 = DotProduct(r_refdef.view.up, shadowdir); + if (fabs(dot1) <= fabs(dot2)) + VectorMA(r_refdef.view.forward, -dot1, shadowdir, shadowforward); + else + VectorMA(r_refdef.view.up, -dot2, shadowdir, shadowforward); + VectorNormalize(shadowforward); + CrossProduct(shadowdir, shadowforward, shadowright); + VectorMA(r_refdef.view.origin, (1.0f - fabs(dot1)) * radius, shadowforward, shadoworigin); + + shadowmins[0] = shadoworigin[0] - r_shadows_throwdistance.value * fabs(shadowdir[0]) - radius * (fabs(shadowforward[0]) + fabs(shadowright[0])); + shadowmins[1] = shadoworigin[1] - r_shadows_throwdistance.value * fabs(shadowdir[1]) - radius * (fabs(shadowforward[1]) + fabs(shadowright[1])); + shadowmins[2] = shadoworigin[2] - r_shadows_throwdistance.value * fabs(shadowdir[2]) - radius * (fabs(shadowforward[2]) + fabs(shadowright[2])); + shadowmaxs[0] = shadoworigin[0] + r_shadows_throwdistance.value * fabs(shadowdir[0]) + radius * (fabs(shadowforward[0]) + fabs(shadowright[0])); + shadowmaxs[1] = shadoworigin[1] + r_shadows_throwdistance.value * fabs(shadowdir[1]) + radius * (fabs(shadowforward[1]) + fabs(shadowright[1])); + shadowmaxs[2] = shadoworigin[2] + r_shadows_throwdistance.value * fabs(shadowdir[2]) + radius * (fabs(shadowforward[2]) + fabs(shadowright[2])); + + for (i = 0;i < r_refdef.scene.numentities;i++) + { + ent = r_refdef.scene.entities[i]; + if (!BoxesOverlap(ent->mins, ent->maxs, shadowmins, shadowmaxs)) + continue; + // cast shadows from anything of the map (submodels are optional) + if (!ent->animcache_vertex3f && ent->model && ent->model->DrawShadowMap != NULL && (!ent->model->brush.submodel || r_shadows_castfrombmodels.integer) && (ent->flags & RENDER_SHADOW)) + R_AnimCache_GetEntity(ent, false, false); + } +} + void R_DrawModelShadowMaps(void) { int i; diff --git a/r_shadow.h b/r_shadow.h index 93ccb2bd..5997605e 100644 --- a/r_shadow.h +++ b/r_shadow.h @@ -90,6 +90,8 @@ extern unsigned char *shadowsides; extern int *shadowsideslist; void R_Shadow_PrepareShadowSides(int numtris); +void R_Shadow_PrepareModelShadows(void); + void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal, const vec3_t p, int dynamic); #endif -- 2.39.2