From 174b8bcffc1b69f555e9a978046240a4b072b1ab Mon Sep 17 00:00:00 2001 From: vortex Date: Thu, 24 Mar 2011 23:13:40 +0000 Subject: [PATCH] Add R_LightPoint which is fast version of R_CompleteLightPoint that only grabs ambient color to use with litsprites and particles. Fix bug in R_CompleteLightPoint (RTWORLD and DYNLIGHT wasnt processed if LP_LIGHTMAP flag is there). New trick for SPR_OVERHEAD (a bit of additional rotation). git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10963 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_particles.c | 7 +---- gl_rmain.c | 2 +- r_shadow.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++- r_shadow.h | 7 +++-- r_sprites.c | 4 +++ 5 files changed, 89 insertions(+), 11 deletions(-) diff --git a/cl_particles.c b/cl_particles.c index 328ab48a..12ab2bb5 100644 --- a/cl_particles.c +++ b/cl_particles.c @@ -2537,12 +2537,7 @@ void R_DrawParticle_TransparentCallback(const entity_render_t *ent, const rtligh c4f[3] = alpha; // note: lighting is not cheap! if (particletype[p->typeindex].lighting) - { - R_CompleteLightPoint(ambient, diffuse, diffusenormal, p->org, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT); - c4f[0] *= (ambient[0] + 0.5 * diffuse[0]); - c4f[1] *= (ambient[1] + 0.5 * diffuse[1]); - c4f[2] *= (ambient[2] + 0.5 * diffuse[2]); - } + R_LightPoint(c4f, p->org, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT); // mix in the fog color if (r_refdef.fogenabled) { diff --git a/gl_rmain.c b/gl_rmain.c index f60e7e2b..3cda3276 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -4614,7 +4614,7 @@ static void R_View_UpdateEntityLighting (void) { if (ent->model->sprite.sprnum_type == SPR_OVERHEAD) // apply offset for overhead sprites org[2] = org[2] + r_overheadsprites_pushback.value; - R_CompleteLightPoint(ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal, org, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT); + R_LightPoint(ent->modellight_ambient, org, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT); } else R_CompleteLightPoint(ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal, org, LP_LIGHTMAP); diff --git a/r_shadow.c b/r_shadow.c index 52a2357d..c3286a20 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -6598,6 +6598,84 @@ LIGHT SAMPLING ============================================================================= */ +void R_LightPoint(vec3_t color, const vec3_t p, const int flags) +{ + int i, numlights, flag; + float f, relativepoint[3], dist, dist2, lightradius2; + vec3_t diffuse, n; + rtlight_t *light; + dlight_t *dlight; + + VectorClear(color); + + if (r_fullbright.integer) + { + VectorSet(color, 1, 1, 1); + return; + } + + if (flags & LP_LIGHTMAP) + { + if (!r_fullbright.integer && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.LightPoint) + { + r_refdef.scene.worldmodel->brush.LightPoint(r_refdef.scene.worldmodel, p, color, diffuse, n); + color[0] += r_refdef.scene.ambient + diffuse[0]; + color[1] += r_refdef.scene.ambient + diffuse[1]; + color[2] += r_refdef.scene.ambient + diffuse[2]; + } + else + VectorSet(color, 1, 1, 1); + } + if (flags & LP_RTWORLD) + { + flag = r_refdef.scene.rtworld ? LIGHTFLAG_REALTIMEMODE : LIGHTFLAG_NORMALMODE; + numlights = Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray); + for (i = 0; i < numlights; i++) + { + dlight = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, i); + if (!dlight) + continue; + light = &dlight->rtlight; + if (!(light->flags & flag)) + continue; + // sample + lightradius2 = light->radius * light->radius; + VectorSubtract(light->shadoworigin, p, relativepoint); + dist2 = VectorLength2(relativepoint); + if (dist2 >= lightradius2) + continue; + dist = sqrt(dist2) / light->radius; + f = dist < 1 ? (r_shadow_lightintensityscale.value * ((1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist))) : 0; + if (f <= 0) + continue; + // todo: add to both ambient and diffuse + if (!light->shadow || CL_TraceLine(p, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false, true).fraction == 1) + VectorMA(color, f, light->currentcolor, color); + } + } + if (flags & LP_DYNLIGHT) + { + // sample dlights + for (i = 0;i < r_refdef.scene.numlights;i++) + { + light = r_refdef.scene.lights[i]; + // sample + lightradius2 = light->radius * light->radius; + VectorSubtract(light->shadoworigin, p, relativepoint); + dist2 = VectorLength2(relativepoint); + if (dist2 >= lightradius2) + continue; + dist = sqrt(dist2) / light->radius; + f = dist < 1 ? (r_shadow_lightintensityscale.value * ((1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist))) : 0; + if (f <= 0) + continue; + // todo: add to both ambient and diffuse + if (!light->shadow || CL_TraceLine(p, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false, true).fraction == 1) + VectorMA(color, f, light->color, color); + } + } +} + void R_CompleteLightPoint(vec3_t ambient, vec3_t diffuse, vec3_t lightdir, const vec3_t p, const int flags) { int i, numlights, flag; @@ -6620,7 +6698,7 @@ void R_CompleteLightPoint(vec3_t ambient, vec3_t diffuse, vec3_t lightdir, const return; } - if (flags & LP_LIGHTMAP) + if (flags == LP_LIGHTMAP) { VectorSet(ambient, r_refdef.scene.ambient, r_refdef.scene.ambient, r_refdef.scene.ambient); VectorClear(diffuse); diff --git a/r_shadow.h b/r_shadow.h index b2dab2dd..c595fbe9 100644 --- a/r_shadow.h +++ b/r_shadow.h @@ -98,9 +98,10 @@ void R_Shadow_PrepareShadowSides(int numtris); void R_Shadow_PrepareModelShadows(void); -#define LP_LIGHTMAP 1 -#define LP_RTWORLD 2 -#define LP_DYNLIGHT 4 +#define LP_LIGHTMAP 1 +#define LP_RTWORLD 2 +#define LP_DYNLIGHT 4 +void R_LightPoint(vec3_t color, const vec3_t p, const int flags); void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal, const vec3_t p, const int flags); #endif diff --git a/r_sprites.c b/r_sprites.c index 8f416b47..486b119f 100644 --- a/r_sprites.c +++ b/r_sprites.c @@ -374,6 +374,10 @@ void R_Model_Sprite_Draw_TransparentCallback(const entity_render_t *ent, const r org[2] = org[2] - middle[2]*r_overheadsprites_pushback.value; // little perspective effect up[2] = up[2] + dir_angle * 0.3; + // a bit of counter-camera rotation + up[0] = up[0] + r_refdef.view.forward[0] * 0.07; + up[1] = up[1] + r_refdef.view.forward[1] * 0.07; + up[2] = up[2] + r_refdef.view.forward[2] * 0.07; break; } -- 2.39.2