rtexture_t *r_shadow_prepasslightingdiffusetexture;
rtexture_t *r_shadow_prepasslightingspeculartexture;
-// keep track of the provided framebuffer info
-static int r_shadow_fb_fbo;
-static rtexture_t *r_shadow_fb_depthtexture;
-static rtexture_t *r_shadow_fb_colortexture;
+int r_shadow_viewfbo;
+rtexture_t *r_shadow_viewdepthtexture;
+rtexture_t *r_shadow_viewcolortexture;
+int r_shadow_viewx;
+int r_shadow_viewy;
+int r_shadow_viewwidth;
+int r_shadow_viewheight;
// lights are reloaded when this changes
char r_shadow_mapname[MAX_QPATH];
cvar_t r_shadow_culllights_pvs = {CVAR_SAVE, "r_shadow_culllights_pvs", "1", "check if light overlaps any visible bsp leafs when determining if the light is visible"};
cvar_t r_shadow_culllights_trace = {CVAR_SAVE, "r_shadow_culllights_trace", "1", "use raytraces from the eye to random places within light bounds to determine if the light is visible"};
cvar_t r_shadow_culllights_trace_eyejitter = {CVAR_SAVE, "r_shadow_culllights_trace_eyejitter", "16", "offset eye location randomly by this much"};
-cvar_t r_shadow_culllights_trace_enlarge = {CVAR_SAVE, "r_shadow_culllights_trace_enlarge", "0.1", "make light bounds bigger by *1.0+enlarge"};
+cvar_t r_shadow_culllights_trace_enlarge = {CVAR_SAVE, "r_shadow_culllights_trace_enlarge", "0", "make light bounds bigger by *(1.0+enlarge)"};
+cvar_t r_shadow_culllights_trace_expand = {CVAR_SAVE, "r_shadow_culllights_trace_expand", "8", "make light bounds bigger by this many units"};
+cvar_t r_shadow_culllights_trace_pad = {CVAR_SAVE, "r_shadow_culllights_trace_expand", "8", "accept traces that hit within this many units of the light bounds"};
cvar_t r_shadow_culllights_trace_samples = {CVAR_SAVE, "r_shadow_culllights_trace_samples", "16", "use this many traces to random positions (in addition to center trace)"};
cvar_t r_shadow_culllights_trace_tempsamples = {CVAR_SAVE, "r_shadow_culllights_trace_tempsamples", "16", "use this many traces if the light was created by csqc (no inter-frame caching), -1 disables the check (to avoid flicker entirely)"};
cvar_t r_shadow_culllights_trace_delay = {CVAR_SAVE, "r_shadow_culllights_trace_delay", "1", "light will be considered visible for this many seconds after any trace connects"};
Cvar_RegisterVariable(&r_shadow_culllights_trace);
Cvar_RegisterVariable(&r_shadow_culllights_trace_eyejitter);
Cvar_RegisterVariable(&r_shadow_culllights_trace_enlarge);
+ Cvar_RegisterVariable(&r_shadow_culllights_trace_expand);
+ Cvar_RegisterVariable(&r_shadow_culllights_trace_pad);
Cvar_RegisterVariable(&r_shadow_culllights_trace_samples);
Cvar_RegisterVariable(&r_shadow_culllights_trace_tempsamples);
Cvar_RegisterVariable(&r_shadow_culllights_trace_delay);
void R_Shadow_RenderMode_Reset(void)
{
R_Mesh_ResetTextureState();
- R_Mesh_SetRenderTargets(r_shadow_fb_fbo, r_shadow_fb_depthtexture, r_shadow_fb_colortexture, NULL, NULL, NULL);
+ R_Mesh_SetRenderTargets(r_shadow_viewfbo, r_shadow_viewdepthtexture, r_shadow_viewcolortexture, NULL, NULL, NULL);
R_SetViewport(&r_refdef.view.viewport);
GL_Scissor(r_shadow_lightscissor[0], r_shadow_lightscissor[1], r_shadow_lightscissor[2], r_shadow_lightscissor[3]);
GL_DepthRange(0, 1);
// is probably fine (and they use the same timer)
if (r_shadow_culllights_trace.integer)
{
- if (rtlight->trace_timer != realtime && R_CanSeeBox(rtlight->trace_timer == 0 ? r_shadow_culllights_trace_tempsamples.integer : r_shadow_culllights_trace_samples.integer, r_shadow_culllights_trace_eyejitter.value, r_shadow_culllights_trace_enlarge.value, r_refdef.view.origin, rtlight->cullmins, rtlight->cullmaxs))
+ if (rtlight->trace_timer != realtime && R_CanSeeBox(rtlight->trace_timer == 0 ? r_shadow_culllights_trace_tempsamples.integer : r_shadow_culllights_trace_samples.integer, r_shadow_culllights_trace_eyejitter.value, r_shadow_culllights_trace_enlarge.value, r_shadow_culllights_trace_expand.value, r_shadow_culllights_trace_pad.value, r_refdef.view.origin, rtlight->cullmins, rtlight->cullmaxs))
rtlight->trace_timer = realtime;
if (realtime - rtlight->trace_timer > r_shadow_culllights_trace_delay.value)
return;
// skip if the light box is not visible to traceline
if (r_shadow_culllights_trace.integer)
{
- if (rtlight->trace_timer != realtime && R_CanSeeBox(rtlight->trace_timer == 0 ? r_shadow_culllights_trace_tempsamples.integer : r_shadow_culllights_trace_samples.integer, r_shadow_culllights_trace_eyejitter.value, r_shadow_culllights_trace_enlarge.value, r_refdef.view.origin, rtlight->cullmins, rtlight->cullmaxs))
+ if (rtlight->trace_timer != realtime && R_CanSeeBox(rtlight->trace_timer == 0 ? r_shadow_culllights_trace_tempsamples.integer : r_shadow_culllights_trace_samples.integer, r_shadow_culllights_trace_eyejitter.value, r_shadow_culllights_trace_enlarge.value, r_shadow_culllights_trace_expand.value, r_shadow_culllights_trace_pad.value, r_refdef.view.origin, rtlight->cullmins, rtlight->cullmaxs))
rtlight->trace_timer = realtime;
if (realtime - rtlight->trace_timer > r_shadow_culllights_trace_delay.value)
return;
}
void R_Shadow_DrawLightSprites(void);
-void R_Shadow_PrepareLights(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture)
+void R_Shadow_PrepareLights(void)
{
int flag;
int lnum;
r_shadow_shadowmapdepthtexture != r_fb.usedepthtextures)
R_Shadow_FreeShadowMaps();
- r_shadow_fb_fbo = fbo;
- r_shadow_fb_depthtexture = depthtexture;
- r_shadow_fb_colortexture = colortexture;
-
r_shadow_usingshadowmaportho = false;
switch (vid.renderpath)
if (!r_shadow_nummodelshadows || (r_shadow_shadowmode != R_SHADOW_SHADOWMODE_STENCIL && r_shadows.integer != 1))
return;
- R_ResetViewRendering3D(r_shadow_fb_fbo, r_shadow_fb_depthtexture, r_shadow_fb_colortexture);
+ R_ResetViewRendering3D(r_shadow_viewfbo, r_shadow_viewdepthtexture, r_shadow_viewcolortexture, r_shadow_viewx, r_shadow_viewy, r_shadow_viewwidth, r_shadow_viewheight);
//GL_Scissor(r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height);
//GL_Scissor(r_refdef.view.x, vid.height - r_refdef.view.height - r_refdef.view.y, r_refdef.view.width, r_refdef.view.height);
R_Shadow_RenderMode_Begin();
R_Shadow_RenderMode_ActiveLight(NULL);
- r_shadow_lightscissor[0] = r_refdef.view.x;
- r_shadow_lightscissor[1] = vid.height - r_refdef.view.y - r_refdef.view.height;
- r_shadow_lightscissor[2] = r_refdef.view.width;
- r_shadow_lightscissor[3] = r_refdef.view.height;
+ r_shadow_lightscissor[0] = r_shadow_viewx;
+ r_shadow_lightscissor[1] = (r_shadow_viewfbo ? r_shadow_viewheight : vid.height) - r_shadow_viewy - r_shadow_viewheight;
+ r_shadow_lightscissor[2] = r_shadow_viewwidth;
+ r_shadow_lightscissor[3] = r_shadow_viewheight;
R_Shadow_RenderMode_StencilShadowVolumes(false);
// get shadow dir
//GL_ScissorTest(true);
//R_EntityMatrix(&identitymatrix);
//R_Mesh_ResetTextureState();
- R_ResetViewRendering2D(r_shadow_fb_fbo, r_shadow_fb_depthtexture, r_shadow_fb_colortexture);
+ R_ResetViewRendering2D(r_shadow_viewfbo, r_shadow_viewdepthtexture, r_shadow_viewcolortexture, r_shadow_viewx, r_shadow_viewy, r_shadow_viewwidth, r_shadow_viewheight);
// set up a darkening blend on shadowed areas
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);