]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - r_shadow.c
MOVETYPE_FLY_WORLDONLY (movetype 33)
[xonotic/darkplaces.git] / r_shadow.c
index bbdf84032478c5414f60aa3cfe7df5bb47d16761..76dd1fabb0a8eba63bd281b21b5199be14d955db 100644 (file)
@@ -267,7 +267,9 @@ char r_shadow_mapname[MAX_QPATH];
 // used only for light filters (cubemaps)
 rtexturepool_t *r_shadow_filters_texturepool;
 
-static const GLenum r_shadow_prepasslightingdrawbuffers[2] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT};
+#ifndef USE_GLES2
+static const GLenum r_shadow_prepasslightingdrawbuffers[2] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
+#endif
 
 cvar_t r_shadow_bumpscale_basetexture = {0, "r_shadow_bumpscale_basetexture", "0", "generate fake bumpmaps from diffuse textures at this bumpyness, try 4 to match tenebrae, higher values increase depth, requires r_restart to take effect"};
 cvar_t r_shadow_bumpscale_bumpmap = {0, "r_shadow_bumpscale_bumpmap", "4", "what magnitude to interpret _bump.tga textures as, higher values increase depth, requires r_restart to take effect"};
@@ -326,15 +328,17 @@ cvar_t r_shadow_bouncegrid_dlightparticlemultiplier = {CVAR_SAVE, "r_shadow_boun
 cvar_t r_shadow_bouncegrid_hitmodels = {CVAR_SAVE, "r_shadow_bouncegrid_hitmodels", "0", "enables hitting character model geometry (SLOW)"};
 cvar_t r_shadow_bouncegrid_includedirectlighting = {CVAR_SAVE, "r_shadow_bouncegrid_includedirectlighting", "0", "allows direct lighting to be recorded, not just indirect (gives an effect somewhat like r_shadow_realtime_world_lightmaps)"};
 cvar_t r_shadow_bouncegrid_intensity = {CVAR_SAVE, "r_shadow_bouncegrid_intensity", "4", "overall brightness of bouncegrid texture"};
-cvar_t r_shadow_bouncegrid_lightradiusscale = {CVAR_SAVE, "r_shadow_bouncegrid_lightradiusscale", "10", "particles stop at this fraction of light radius (can be more than 1)"};
-cvar_t r_shadow_bouncegrid_maxbounce = {CVAR_SAVE, "r_shadow_bouncegrid_maxbounce", "5", "maximum number of bounces for a particle (minimum is 1)"};
-cvar_t r_shadow_bouncegrid_particlebounceintensity = {CVAR_SAVE, "r_shadow_bouncegrid_particlebounceintensity", "4", "amount of energy carried over after each bounce, this is a multiplier of texture color and the result is clamped to 1 or less, to prevent adding energy on each bounce"};
+cvar_t r_shadow_bouncegrid_lightradiusscale = {CVAR_SAVE, "r_shadow_bouncegrid_lightradiusscale", "4", "particles stop at this fraction of light radius (can be more than 1)"};
+cvar_t r_shadow_bouncegrid_maxbounce = {CVAR_SAVE, "r_shadow_bouncegrid_maxbounce", "2", "maximum number of bounces for a particle (minimum is 0)"};
+cvar_t r_shadow_bouncegrid_particlebounceintensity = {CVAR_SAVE, "r_shadow_bouncegrid_particlebounceintensity", "1", "amount of energy carried over after each bounce, this is a multiplier of texture color and the result is clamped to 1 or less, to prevent adding energy on each bounce"};
 cvar_t r_shadow_bouncegrid_particleintensity = {CVAR_SAVE, "r_shadow_bouncegrid_particleintensity", "1", "brightness of particles contributing to bouncegrid texture"};
 cvar_t r_shadow_bouncegrid_photons = {CVAR_SAVE, "r_shadow_bouncegrid_photons", "2000", "total photons to shoot per update, divided proportionately between lights"};
 cvar_t r_shadow_bouncegrid_spacing = {CVAR_SAVE, "r_shadow_bouncegrid_spacing", "64", "unit size of bouncegrid pixel"};
 cvar_t r_shadow_bouncegrid_stablerandom = {CVAR_SAVE, "r_shadow_bouncegrid_stablerandom", "1", "make particle distribution consistent from frame to frame"};
 cvar_t r_shadow_bouncegrid_static = {CVAR_SAVE, "r_shadow_bouncegrid_static", "1", "use static radiosity solution (high quality) rather than dynamic (splotchy)"};
 cvar_t r_shadow_bouncegrid_static_directionalshading = {CVAR_SAVE, "r_shadow_bouncegrid_static_directionalshading", "1", "whether to use directionalshading when in static mode"};
+cvar_t r_shadow_bouncegrid_static_lightradiusscale = {CVAR_SAVE, "r_shadow_bouncegrid_static_lightradiusscale", "10", "particles stop at this fraction of light radius (can be more than 1) when in static mode"};
+cvar_t r_shadow_bouncegrid_static_maxbounce = {CVAR_SAVE, "r_shadow_bouncegrid_static_maxbounce", "5", "maximum number of bounces for a particle (minimum is 0) in static mode"};
 cvar_t r_shadow_bouncegrid_static_photons = {CVAR_SAVE, "r_shadow_bouncegrid_static_photons", "25000", "photons value to use when in static mode"};
 cvar_t r_shadow_bouncegrid_updateinterval = {CVAR_SAVE, "r_shadow_bouncegrid_updateinterval", "0", "update bouncegrid texture once per this many seconds, useful values are 0, 0.05, or 1000000"};
 cvar_t r_shadow_bouncegrid_x = {CVAR_SAVE, "r_shadow_bouncegrid_x", "64", "maximum texture size of bouncegrid on X axis"};
@@ -752,6 +756,8 @@ void R_Shadow_Init(void)
        Cvar_RegisterVariable(&r_shadow_bouncegrid_stablerandom);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_static);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_static_directionalshading);
+       Cvar_RegisterVariable(&r_shadow_bouncegrid_static_lightradiusscale);
+       Cvar_RegisterVariable(&r_shadow_bouncegrid_static_maxbounce);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_static_photons);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_updateinterval);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_x);
@@ -2024,7 +2030,7 @@ void R_Shadow_RenderMode_Reset(void)
        GL_Color(1, 1, 1, 1);
        GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1);
        GL_BlendFunc(GL_ONE, GL_ZERO);
-       R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, false);
+       R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, false, false);
        r_shadow_usingshadowmap2d = false;
        r_shadow_usingshadowmaportho = false;
        R_SetStencil(false, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_ALWAYS, 128, 255);
@@ -2108,6 +2114,7 @@ static void R_Shadow_MakeShadowMap(int side, int size)
                return;
        }
 
+#ifndef USE_GLES2
        // render depth into the fbo, do not render color at all
        // validate the fbo now
        if (qglDrawBuffer)
@@ -2115,14 +2122,15 @@ static void R_Shadow_MakeShadowMap(int side, int size)
                int status;
                qglDrawBuffer(GL_NONE);CHECKGLERROR
                qglReadBuffer(GL_NONE);CHECKGLERROR
-               status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);CHECKGLERROR
-               if (status != GL_FRAMEBUFFER_COMPLETE_EXT && (r_shadow_shadowmapping.integer || r_shadow_deferred.integer))
+               status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER);CHECKGLERROR
+               if (status != GL_FRAMEBUFFER_COMPLETE && (r_shadow_shadowmapping.integer || r_shadow_deferred.integer))
                {
                        Con_Printf("R_Shadow_MakeShadowMap: glCheckFramebufferStatusEXT returned %i\n", status);
                        Cvar_SetValueQuick(&r_shadow_shadowmapping, 0);
                        Cvar_SetValueQuick(&r_shadow_deferred, 0);
                }
        }
+#endif
 }
 
 void R_Shadow_RenderMode_ShadowMap(int side, int clear, int size)
@@ -2343,6 +2351,7 @@ void R_Shadow_UpdateBounceGridTexture(void)
        vec3_t lightcolor;
        vec3_t steppos;
        vec3_t stepdelta;
+       vec3_t cullmins, cullmaxs;
        vec_t radius;
        vec_t s;
        vec_t lightintensity;
@@ -2439,8 +2448,8 @@ void R_Shadow_UpdateBounceGridTexture(void)
        settings.dlightparticlemultiplier      = r_shadow_bouncegrid_dlightparticlemultiplier.value;
        settings.hitmodels                     = r_shadow_bouncegrid_hitmodels.integer != 0;
        settings.includedirectlighting         = r_shadow_bouncegrid_includedirectlighting.integer != 0 || r_shadow_bouncegrid.integer == 2;
-       settings.lightradiusscale              = r_shadow_bouncegrid_lightradiusscale.value;
-       settings.maxbounce                     = r_shadow_bouncegrid_maxbounce.integer;
+       settings.lightradiusscale              = (r_shadow_bouncegrid_static.integer != 0 ? r_shadow_bouncegrid_static_lightradiusscale.value : r_shadow_bouncegrid_lightradiusscale.value);
+       settings.maxbounce                     = (r_shadow_bouncegrid_static.integer != 0 ? r_shadow_bouncegrid_static_maxbounce.integer : r_shadow_bouncegrid_maxbounce.integer);
        settings.particlebounceintensity       = r_shadow_bouncegrid_particlebounceintensity.value;
        settings.particleintensity             = r_shadow_bouncegrid_particleintensity.value * 16384.0f * (settings.directionalshading ? 4.0f : 1.0f) / (r_shadow_bouncegrid_spacing.value * r_shadow_bouncegrid_spacing.value);
        settings.photons                       = r_shadow_bouncegrid_static.integer ? r_shadow_bouncegrid_static_photons.integer : r_shadow_bouncegrid_photons.integer;
@@ -2604,22 +2613,27 @@ void R_Shadow_UpdateBounceGridTexture(void)
                                if (rtlight->style > 0 && r_shadow_bouncegrid.integer != 2)
                                        continue;
                        }
-                       else
-                       {
-                               // draw only visible lights (major speedup)
-                               //if (!rtlight->draw)
-                               //      continue;
-                       }
                }
                else
                {
                        rtlight = r_refdef.scene.lights[lightindex - range];
                        VectorClear(rtlight->photoncolor);
                        rtlight->photons = 0;
-                       // draw only visible lights (major speedup)
-                       //if (!rtlight->draw)
-                       //      continue;
                }
+               // draw only visible lights (major speedup)
+               radius = rtlight->radius * settings.lightradiusscale;
+               cullmins[0] = rtlight->shadoworigin[0] - radius;
+               cullmins[1] = rtlight->shadoworigin[1] - radius;
+               cullmins[2] = rtlight->shadoworigin[2] - radius;
+               cullmaxs[0] = rtlight->shadoworigin[0] + radius;
+               cullmaxs[1] = rtlight->shadoworigin[1] + radius;
+               cullmaxs[2] = rtlight->shadoworigin[2] + radius;
+               if (R_CullBox(cullmins, cullmaxs))
+                       continue;
+               if (r_refdef.scene.worldmodel
+                && r_refdef.scene.worldmodel->brush.BoxTouchingVisibleLeafs
+                && !r_refdef.scene.worldmodel->brush.BoxTouchingVisibleLeafs(r_refdef.scene.worldmodel, r_refdef.viewcache.world_leafvisible, cullmins, cullmaxs))
+                       continue;
                w = r_shadow_lightintensityscale.value * (rtlight->ambientscale + rtlight->diffusescale + rtlight->specularscale);
                if (w * VectorLength2(rtlight->color) == 0.0f)
                        continue;
@@ -2632,7 +2646,6 @@ void R_Shadow_UpdateBounceGridTexture(void)
                // vary with lightstyle, otherwise we get randomized particle
                // distribution, the seeded random is only consistent for a
                // consistent number of particles on this light...
-               radius = rtlight->radius * settings.lightradiusscale;
                s = rtlight->radius;
                lightintensity = VectorLength(rtlight->color) * (rtlight->ambientscale + rtlight->diffusescale + rtlight->specularscale);
                if (lightindex >= range)
@@ -3312,8 +3325,8 @@ void R_Shadow_RenderLighting(int texturenumsurfaces, const msurface_t **textures
        qboolean negated;
        float lightcolor[3];
        VectorCopy(rsurface.rtlight->currentcolor, lightcolor);
-       ambientscale = rsurface.rtlight->ambientscale;
-       diffusescale = rsurface.rtlight->diffusescale;
+       ambientscale = rsurface.rtlight->ambientscale + rsurface.texture->rtlightambient;
+       diffusescale = rsurface.rtlight->diffusescale * max(0, 1.0 - rsurface.texture->rtlightambient);
        specularscale = rsurface.rtlight->specularscale * rsurface.texture->specularscale;
        if (!r_shadow_usenormalmap.integer)
        {
@@ -4502,7 +4515,7 @@ void R_Shadow_PrepareLights(void)
        case RENDERPATH_D3D10:
        case RENDERPATH_D3D11:
        case RENDERPATH_SOFT:
-       case RENDERPATH_GLES2:
+#ifndef USE_GLES2
                if (!r_shadow_deferred.integer || r_shadow_shadowmode == R_SHADOW_SHADOWMODE_STENCIL || !vid.support.ext_framebuffer_object || vid.maxdrawbuffers < 2)
                {
                        r_shadow_usingdeferredprepass = false;
@@ -4538,10 +4551,10 @@ void R_Shadow_PrepareLights(void)
                        // render depth into one texture and normalmap into the other
                        if (qglDrawBuffersARB)
                        {
-                               qglDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);CHECKGLERROR
+                               qglDrawBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR
                                qglReadBuffer(GL_NONE);CHECKGLERROR
-                               status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);CHECKGLERROR
-                               if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
+                               status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER);CHECKGLERROR
+                               if (status != GL_FRAMEBUFFER_COMPLETE)
                                {
                                        Con_Printf("R_PrepareRTLights: glCheckFramebufferStatusEXT returned %i\n", status);
                                        Cvar_SetValueQuick(&r_shadow_deferred, 0);
@@ -4559,8 +4572,8 @@ void R_Shadow_PrepareLights(void)
                        {
                                qglDrawBuffersARB(2, r_shadow_prepasslightingdrawbuffers);CHECKGLERROR
                                qglReadBuffer(GL_NONE);CHECKGLERROR
-                               status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);CHECKGLERROR
-                               if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
+                               status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER);CHECKGLERROR
+                               if (status != GL_FRAMEBUFFER_COMPLETE)
                                {
                                        Con_Printf("R_PrepareRTLights: glCheckFramebufferStatusEXT returned %i\n", status);
                                        Cvar_SetValueQuick(&r_shadow_deferred, 0);
@@ -4576,10 +4589,10 @@ void R_Shadow_PrepareLights(void)
                        // with depth bound as attachment as well
                        if (qglDrawBuffersARB)
                        {
-                               qglDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);CHECKGLERROR
+                               qglDrawBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR
                                qglReadBuffer(GL_NONE);CHECKGLERROR
-                               status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);CHECKGLERROR
-                               if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
+                               status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER);CHECKGLERROR
+                               if (status != GL_FRAMEBUFFER_COMPLETE)
                                {
                                        Con_Printf("R_PrepareRTLights: glCheckFramebufferStatusEXT returned %i\n", status);
                                        Cvar_SetValueQuick(&r_shadow_deferred, 0);
@@ -4587,10 +4600,12 @@ void R_Shadow_PrepareLights(void)
                                }
                        }
                }
+#endif
                break;
        case RENDERPATH_GL11:
        case RENDERPATH_GL13:
        case RENDERPATH_GLES1:
+       case RENDERPATH_GLES2:
                r_shadow_usingdeferredprepass = false;
                break;
        }
@@ -5065,7 +5080,7 @@ void R_DrawModelShadows(void)
 
        // apply the blend to the shadowed areas
        R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, NULL);
-       R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, true);
+       R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, false, true);
        R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
 
        // restore the viewport
@@ -5100,6 +5115,7 @@ void R_BeginCoronaQuery(rtlight_t *rtlight, float scale, qboolean usequery)
                case RENDERPATH_GL20:
                case RENDERPATH_GLES1:
                case RENDERPATH_GLES2:
+#ifdef GL_SAMPLES_PASSED_ARB
                        CHECKGLERROR
                        // NOTE: GL_DEPTH_TEST must be enabled or ATI won't count samples, so use GL_DepthFunc instead
                        qglBeginQueryARB(GL_SAMPLES_PASSED_ARB, rtlight->corona_queryindex_allpixels);
@@ -5115,6 +5131,7 @@ void R_BeginCoronaQuery(rtlight_t *rtlight, float scale, qboolean usequery)
                        R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
                        qglEndQueryARB(GL_SAMPLES_PASSED_ARB);
                        CHECKGLERROR
+#endif
                        break;
                case RENDERPATH_D3D9:
                        Con_DPrintf("FIXME D3D9 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
@@ -5149,10 +5166,12 @@ void R_DrawCorona(rtlight_t *rtlight, float cscale, float scale)
                case RENDERPATH_GL20:
                case RENDERPATH_GLES1:
                case RENDERPATH_GLES2:
+#ifdef GL_SAMPLES_PASSED_ARB
                        CHECKGLERROR
                        qglGetQueryObjectivARB(rtlight->corona_queryindex_visiblepixels, GL_QUERY_RESULT_ARB, &visiblepixels);
                        qglGetQueryObjectivARB(rtlight->corona_queryindex_allpixels, GL_QUERY_RESULT_ARB, &allpixels);
                        CHECKGLERROR
+#endif
                        break;
                case RENDERPATH_D3D9:
                        Con_DPrintf("FIXME D3D9 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
@@ -5226,6 +5245,7 @@ void R_Shadow_DrawCoronas(void)
        case RENDERPATH_GLES1:
        case RENDERPATH_GLES2:
                usequery = vid.support.arb_occlusion_query && r_coronas_occlusionquery.integer;
+#ifdef GL_SAMPLES_PASSED_ARB
                if (usequery)
                {
                        GL_ColorMask(0,0,0,0);
@@ -5247,8 +5267,9 @@ void R_Shadow_DrawCoronas(void)
                        GL_PolygonOffset(0, 0);
                        GL_DepthTest(true);
                        R_Mesh_ResetTextureState();
-                       R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, false);
+                       R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, false, false);
                }
+#endif
                break;
        case RENDERPATH_D3D9:
                usequery = false;
@@ -6819,6 +6840,7 @@ void R_CompleteLightPoint(vec3_t ambient, vec3_t diffuse, vec3_t lightdir, const
                        intensity *= VectorLength(color);
                        VectorMA(sample + 12, intensity, relativepoint, sample + 12);
                }
+               // FIXME: sample bouncegrid too!
        }
 
        if (flags & LP_DYNLIGHT)