From 417727143082992c3b4c9469f0c5683005c949fd Mon Sep 17 00:00:00 2001 From: vortex Date: Tue, 15 Sep 2009 19:18:26 +0000 Subject: [PATCH] improved r_shadows mode, new cvars for better use with overhead camera mods: - r_shadows_darken : how much shadowed areas will be darkened (was constant 0.5) - r_shadows_throwdirection : override shadow direction for r_shadows 2 (was constant 0 0 -1) - r_shadows_drawafterrtlightning : this change fake shadows to draw AFTER realtime lightning is drawn, may be useful for simulating faster sunlight on large outdoor maps with only one noshadow rtlight. The price is less realistic appearance of dynamic light shadows. - r_shadows_castfrombmodels : allow to cast fake shadows from bmodels git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9201 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_rmain.c | 23 +++++++++++++++++++---- r_shadow.c | 31 +++++++++++++++++++------------ 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/gl_rmain.c b/gl_rmain.c index 6463c805..e2f38cde 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -71,8 +71,12 @@ cvar_t r_fullbright = {0, "r_fullbright","0", "makes map very bright and renders cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1", "opacity of water polygons"}; cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1", "enables dynamic lights (rocket glow and such)"}; cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1", "enables glowing pixels in quake textures (changes need r_restart to take effect)"}; -cvar_t r_shadows = {CVAR_SAVE, "r_shadows", "0", "casts fake stencil shadows from models onto the world (rtlights are unaffected by this); when set to 2, always cast the shadows DOWN, otherwise use the model lighting"}; +cvar_t r_shadows = {CVAR_SAVE, "r_shadows", "0", "casts fake stencil shadows from models onto the world (rtlights are unaffected by this); when set to 2, always cast the shadows in the direction set by r_shadows_throwdirection, otherwise use the model lighting."}; +cvar_t r_shadows_darken = {CVAR_SAVE, "r_shadows_darken", "0.5", "how much shadowed areas will be darkened"}; cvar_t r_shadows_throwdistance = {CVAR_SAVE, "r_shadows_throwdistance", "500", "how far to cast shadows from models"}; +cvar_t r_shadows_throwdirection = {CVAR_SAVE, "r_shadows_throwdirection", "0 0 -1", "override throwing direction for r_shadows 2"}; +cvar_t r_shadows_drawafterrtlightning = {CVAR_SAVE, "r_shadows_drawafterrtlightning", "0", "draw fake shadows AFTER realtime lightning is drawn. May be useful for simulating fast sunlight on large outdoor maps with only one noshadow rtlight. The price is less realistic appearance of dynamic light shadows."}; +cvar_t r_shadows_castfrombmodels = {CVAR_SAVE, "r_shadows_castfrombmodels", "0", "do cast shadows from bmodels"}; cvar_t r_q1bsp_skymasking = {0, "r_q1bsp_skymasking", "1", "allows sky polygons in quake1 maps to obscure other geometry"}; cvar_t r_polygonoffset_submodel_factor = {0, "r_polygonoffset_submodel_factor", "0", "biases depth values of world submodels such as doors, to prevent z-fighting artifacts in Quake maps"}; cvar_t r_polygonoffset_submodel_offset = {0, "r_polygonoffset_submodel_offset", "2", "biases depth values of world submodels such as doors, to prevent z-fighting artifacts in Quake maps"}; @@ -2433,7 +2437,11 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_dynamic); Cvar_RegisterVariable(&r_fullbright); Cvar_RegisterVariable(&r_shadows); + Cvar_RegisterVariable(&r_shadows_darken); + Cvar_RegisterVariable(&r_shadows_drawafterrtlightning); + Cvar_RegisterVariable(&r_shadows_castfrombmodels); Cvar_RegisterVariable(&r_shadows_throwdistance); + Cvar_RegisterVariable(&r_shadows_throwdirection); Cvar_RegisterVariable(&r_q1bsp_skymasking); Cvar_RegisterVariable(&r_polygonoffset_submodel_factor); Cvar_RegisterVariable(&r_polygonoffset_submodel_offset); @@ -4318,12 +4326,10 @@ void R_RenderScene(void) if (r_refdef.scene.extraupdate) S_ExtraUpdate (); - if (r_shadows.integer > 0 && r_refdef.lightmapintensity > 0) + if (r_shadows.integer > 0 && !r_shadows_drawafterrtlightning.integer && r_refdef.lightmapintensity > 0) { R_DrawModelShadows(); - R_ResetViewRendering3D(); - // don't let sound skip if going slow if (r_refdef.scene.extraupdate) S_ExtraUpdate (); @@ -4337,6 +4343,15 @@ void R_RenderScene(void) if (r_refdef.scene.extraupdate) S_ExtraUpdate (); + if (r_shadows.integer > 0 && r_shadows_drawafterrtlightning.integer && r_refdef.lightmapintensity > 0) + { + R_DrawModelShadows(); + R_ResetViewRendering3D(); + // don't let sound skip if going slow + if (r_refdef.scene.extraupdate) + S_ExtraUpdate (); + } + if (cl.csqc_vidvars.drawworld) { R_DrawLightningBeams(); diff --git a/r_shadow.c b/r_shadow.c index b96264fe..49fc4738 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -3385,7 +3385,11 @@ void R_ShadowVolumeLighting(qboolean visible) extern void R_SetupView(qboolean allowwaterclippingplane); extern cvar_t r_shadows; +extern cvar_t r_shadows_darken; +extern cvar_t r_shadows_drawafterrtlightning; +extern cvar_t r_shadows_castfrombmodels; extern cvar_t r_shadows_throwdistance; +extern cvar_t r_shadows_throwdirection; void R_DrawModelShadows(void) { int i; @@ -3394,7 +3398,7 @@ void R_DrawModelShadows(void) vec3_t relativelightorigin; vec3_t relativelightdirection; vec3_t relativeshadowmins, relativeshadowmaxs; - vec3_t tmp; + vec3_t tmp, shadowdir; float vertex3f[12]; if (!r_drawentities.integer || !gl_stencil) @@ -3421,24 +3425,27 @@ void R_DrawModelShadows(void) r_shadow_shadowingrendermode_zfail = R_SHADOW_RENDERMODE_ZFAIL_STENCIL; } + // get shadow dir + if (r_shadows.integer == 2) + { + Math_atov(r_shadows_throwdirection.string, shadowdir); + VectorNormalize(shadowdir); + } + R_Shadow_ClearStencil(); for (i = 0;i < r_refdef.scene.numentities;i++) { ent = r_refdef.scene.entities[i]; - // cast shadows from anything that is not a submodel of the map - if (ent->model && ent->model->DrawShadowVolume != NULL && !ent->model->brush.submodel && (ent->flags & RENDER_SHADOW)) + + // cast shadows from anything of the map (submodels are optional) + if (ent->model && ent->model->DrawShadowVolume != NULL && (!ent->model->brush.submodel || r_shadows_castfrombmodels.integer) && (ent->flags & RENDER_SHADOW)) { relativethrowdistance = r_shadows_throwdistance.value * Matrix4x4_ScaleFromMatrix(&ent->inversematrix); VectorSet(relativeshadowmins, -relativethrowdistance, -relativethrowdistance, -relativethrowdistance); VectorSet(relativeshadowmaxs, relativethrowdistance, relativethrowdistance, relativethrowdistance); - - if(r_shadows.integer == 2) - { - // 2: simpler mode, throw shadows always DOWN - VectorSet(tmp, 0, 0, -1); - Matrix4x4_Transform3x3(&ent->inversematrix, tmp, relativelightdirection); - } + if (r_shadows.integer == 2) // 2: simpler mode, throw shadows always in same direction + Matrix4x4_Transform3x3(&ent->inversematrix, shadowdir, relativelightdirection); else { if(ent->entitynumber != 0) @@ -3494,13 +3501,13 @@ void R_DrawModelShadows(void) R_Mesh_VertexPointer(vertex3f, 0, 0); R_Mesh_ColorPointer(NULL, 0, 0); - // set up a 50% darkening blend on shadowed areas + // set up a darkening blend on shadowed areas GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GL_DepthRange(0, 1); GL_DepthTest(false); GL_DepthMask(false); GL_PolygonOffset(0, 0);CHECKGLERROR - GL_Color(0, 0, 0, 0.5); + GL_Color(0, 0, 0, r_shadows_darken.value); GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1); qglDepthFunc(GL_ALWAYS);CHECKGLERROR qglEnable(GL_STENCIL_TEST);CHECKGLERROR -- 2.39.2