]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - r_shadow.c
default gl_lockarrays to 0, I'm not aware of any cards that actually benefit from it
[xonotic/darkplaces.git] / r_shadow.c
index 3f570a5d0b3da8d4f543cb457450eeebe3ede192..1ed8fe70461306239c491de974b469e8e14ff23e 100644 (file)
@@ -204,7 +204,7 @@ cvar_t r_shadow_bumpscale_bumpmap = {0, "r_shadow_bumpscale_bumpmap", "4", "what
 cvar_t r_shadow_debuglight = {0, "r_shadow_debuglight", "-1", "renders only one light, for level design purposes or debugging"};
 cvar_t r_shadow_gloss = {CVAR_SAVE, "r_shadow_gloss", "1", "0 disables gloss (specularity) rendering, 1 uses gloss if textures are found, 2 forces a flat metallic specular effect on everything without textures (similar to tenebrae)"};
 cvar_t r_shadow_gloss2intensity = {0, "r_shadow_gloss2intensity", "0.125", "how bright the forced flat gloss should look if r_shadow_gloss is 2"};
-cvar_t r_shadow_glossintensity = {0, "r_shadow_glossintensity", "2", "how bright textured glossmaps should look if r_shadow_gloss is 1 or 2"};
+cvar_t r_shadow_glossintensity = {0, "r_shadow_glossintensity", "1", "how bright textured glossmaps should look if r_shadow_gloss is 1 or 2"};
 cvar_t r_shadow_glossexponent = {0, "r_shadow_glossexponent", "32", "how 'sharp' the gloss should appear (specular power)"};
 cvar_t r_shadow_lightattenuationpower = {0, "r_shadow_lightattenuationpower", "0.5", "changes attenuation texture generation (does not affect r_glsl lighting)"};
 cvar_t r_shadow_lightattenuationscale = {0, "r_shadow_lightattenuationscale", "1", "changes attenuation texture generation (does not affect r_glsl lighting)"};
@@ -215,6 +215,7 @@ cvar_t r_shadow_frontsidecasting = {0, "r_shadow_frontsidecasting", "1", "whethe
 cvar_t r_shadow_realtime_dlight = {CVAR_SAVE, "r_shadow_realtime_dlight", "1", "enables rendering of dynamic lights such as explosions and rocket light"};
 cvar_t r_shadow_realtime_dlight_shadows = {CVAR_SAVE, "r_shadow_realtime_dlight_shadows", "1", "enables rendering of shadows from dynamic lights"};
 cvar_t r_shadow_realtime_dlight_svbspculling = {0, "r_shadow_realtime_dlight_svbspculling", "0", "enables svbsp optimization on dynamic lights (very slow!)"};
+cvar_t r_shadow_realtime_dlight_portalculling = {0, "r_shadow_realtime_dlight_portalculling", "0", "enables portal optimization on dynamic lights (slow!)"};
 cvar_t r_shadow_realtime_world = {CVAR_SAVE, "r_shadow_realtime_world", "0", "enables rendering of full world lighting (whether loaded from the map, or a .rtlights file, or a .ent file, or a .lights file produced by hlight)"};
 cvar_t r_shadow_realtime_world_dlightshadows = {CVAR_SAVE, "r_shadow_realtime_world_dlightshadows", "1", "enables shadows from dynamic lights when using full world lighting"};
 cvar_t r_shadow_realtime_world_lightmaps = {CVAR_SAVE, "r_shadow_realtime_world_lightmaps", "0", "brightness to render lightmaps when using full world lighting, try 0.5 for a tenebrae-like appearance"};
@@ -222,6 +223,7 @@ cvar_t r_shadow_realtime_world_shadows = {CVAR_SAVE, "r_shadow_realtime_world_sh
 cvar_t r_shadow_realtime_world_compile = {0, "r_shadow_realtime_world_compile", "1", "enables compilation of world lights for higher performance rendering"};
 cvar_t r_shadow_realtime_world_compileshadow = {0, "r_shadow_realtime_world_compileshadow", "1", "enables compilation of shadows from world lights for higher performance rendering"};
 cvar_t r_shadow_realtime_world_compilesvbsp = {0, "r_shadow_realtime_world_compilesvbsp", "1", "enables svbsp optimization during compilation"};
+cvar_t r_shadow_realtime_world_compileportalculling = {0, "r_shadow_realtime_world_compileportalculling", "1", "enables portal-based culling optimization during compilation"};
 cvar_t r_shadow_scissor = {0, "r_shadow_scissor", "1", "use scissor optimization of light rendering (restricts rendering to the portion of the screen affected by the light)"};
 cvar_t r_shadow_shadow_polygonfactor = {0, "r_shadow_shadow_polygonfactor", "0", "how much to enlarge shadow volume polygons when rendering (should be 0!)"};
 cvar_t r_shadow_shadow_polygonoffset = {0, "r_shadow_shadow_polygonoffset", "1", "how much to push shadow volumes into the distance when rendering, to reduce chances of zfighting artifacts (should not be less than 0)"};
@@ -403,6 +405,7 @@ void R_Shadow_Init(void)
        Cvar_RegisterVariable(&r_shadow_realtime_dlight);
        Cvar_RegisterVariable(&r_shadow_realtime_dlight_shadows);
        Cvar_RegisterVariable(&r_shadow_realtime_dlight_svbspculling);
+       Cvar_RegisterVariable(&r_shadow_realtime_dlight_portalculling);
        Cvar_RegisterVariable(&r_shadow_realtime_world);
        Cvar_RegisterVariable(&r_shadow_realtime_world_dlightshadows);
        Cvar_RegisterVariable(&r_shadow_realtime_world_lightmaps);
@@ -410,6 +413,7 @@ void R_Shadow_Init(void)
        Cvar_RegisterVariable(&r_shadow_realtime_world_compile);
        Cvar_RegisterVariable(&r_shadow_realtime_world_compileshadow);
        Cvar_RegisterVariable(&r_shadow_realtime_world_compilesvbsp);
+       Cvar_RegisterVariable(&r_shadow_realtime_world_compileportalculling);
        Cvar_RegisterVariable(&r_shadow_scissor);
        Cvar_RegisterVariable(&r_shadow_shadow_polygonfactor);
        Cvar_RegisterVariable(&r_shadow_shadow_polygonoffset);
@@ -2135,16 +2139,33 @@ void R_Shadow_RenderSurfacesLighting(int numsurfaces, msurface_t **surfacelist)
        }
 }
 
-void R_RTLight_Update(dlight_t *light, int isstatic)
+void R_RTLight_Update(rtlight_t *rtlight, int isstatic, matrix4x4_t *matrix, vec3_t color, int style, const char *cubemapname, qboolean shadow, vec_t corona, vec_t coronasizescale, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int flags)
 {
-       double scale;
-       rtlight_t *rtlight = &light->rtlight;
+       // if this light has been compiled before, free the associated data
        R_RTLight_Uncompile(rtlight);
+
+       // clear it completely to avoid any lingering data
        memset(rtlight, 0, sizeof(*rtlight));
 
-       VectorCopy(light->origin, rtlight->shadoworigin);
-       VectorCopy(light->color, rtlight->color);
-       rtlight->radius = light->radius;
+       // copy the properties
+       Matrix4x4_Invert_Simple(&rtlight->matrix_worldtolight, matrix);
+       Matrix4x4_OriginFromMatrix(matrix, rtlight->shadoworigin);
+       rtlight->radius = Matrix4x4_ScaleFromMatrix(matrix);
+       VectorCopy(color, rtlight->color);
+       rtlight->cubemapname[0] = 0;
+       if (cubemapname && cubemapname[0])
+               strlcpy(rtlight->cubemapname, cubemapname, sizeof(rtlight->cubemapname));
+       rtlight->shadow = shadow;
+       rtlight->corona = corona;
+       rtlight->style = style;
+       rtlight->isstatic = isstatic;
+       rtlight->coronasizescale = coronasizescale;
+       rtlight->ambientscale = ambientscale;
+       rtlight->diffusescale = diffusescale;
+       rtlight->specularscale = specularscale;
+       rtlight->flags = flags;
+
+       // compute derived data
        //rtlight->cullradius = rtlight->radius;
        //rtlight->cullradius2 = rtlight->radius * rtlight->radius;
        rtlight->cullmins[0] = rtlight->shadoworigin[0] - rtlight->radius;
@@ -2153,26 +2174,6 @@ void R_RTLight_Update(dlight_t *light, int isstatic)
        rtlight->cullmaxs[0] = rtlight->shadoworigin[0] + rtlight->radius;
        rtlight->cullmaxs[1] = rtlight->shadoworigin[1] + rtlight->radius;
        rtlight->cullmaxs[2] = rtlight->shadoworigin[2] + rtlight->radius;
-       rtlight->cubemapname[0] = 0;
-       if (light->cubemapname[0])
-               strlcpy(rtlight->cubemapname, light->cubemapname, sizeof(rtlight->cubemapname));
-       else if (light->cubemapnum > 0)
-               sprintf(rtlight->cubemapname, "cubemaps/%i", light->cubemapnum);
-       rtlight->shadow = light->shadow;
-       rtlight->corona = light->corona;
-       rtlight->style = light->style;
-       rtlight->isstatic = isstatic;
-       rtlight->coronasizescale = light->coronasizescale;
-       rtlight->ambientscale = light->ambientscale;
-       rtlight->diffusescale = light->diffusescale;
-       rtlight->specularscale = light->specularscale;
-       rtlight->flags = light->flags;
-       Matrix4x4_Invert_Simple(&rtlight->matrix_worldtolight, &light->matrix);
-       // this has to scale both rotate and translate because this is an already
-       // inverted matrix (it transforms from world to light space, not the other
-       // way around)
-       scale = 1.0 / rtlight->radius;
-       Matrix4x4_Scale(&rtlight->matrix_worldtolight, scale, scale);
 }
 
 // compiles rtlight geometry
@@ -2552,7 +2553,7 @@ void R_ShadowVolumeLighting(qboolean visible)
                                R_DrawRTLight(&light->rtlight, visible);
        if (r_refdef.rtdlight)
                for (lnum = 0;lnum < r_refdef.numlights;lnum++)
-                       R_DrawRTLight(&r_refdef.lights[lnum]->rtlight, visible);
+                       R_DrawRTLight(&r_refdef.lights[lnum], visible);
 
        R_Shadow_RenderMode_End();
 }
@@ -2776,6 +2777,17 @@ dlight_t *R_Shadow_NewWorldLight(void)
 
 void R_Shadow_UpdateWorldLight(dlight_t *light, vec3_t origin, vec3_t angles, vec3_t color, vec_t radius, vec_t corona, int style, int shadowenable, const char *cubemapname, vec_t coronasizescale, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int flags)
 {
+       matrix4x4_t matrix;
+       // validate parameters
+       if (style < 0 || style >= MAX_LIGHTSTYLES)
+       {
+               Con_Printf("R_Shadow_NewWorldLight: invalid light style number %i, must be >= 0 and < %i\n", light->style, MAX_LIGHTSTYLES);
+               style = 0;
+       }
+       if (!cubemapname)
+               cubemapname = "";
+
+       // copy to light properties
        VectorCopy(origin, light->origin);
        light->angles[0] = angles[0] - 360 * floor(angles[0] / 360);
        light->angles[1] = angles[1] - 360 * floor(angles[1] / 360);
@@ -2785,24 +2797,18 @@ void R_Shadow_UpdateWorldLight(dlight_t *light, vec3_t origin, vec3_t angles, ve
        light->color[2] = max(color[2], 0);
        light->radius = max(radius, 0);
        light->style = style;
-       if (light->style < 0 || light->style >= MAX_LIGHTSTYLES)
-       {
-               Con_Printf("R_Shadow_NewWorldLight: invalid light style number %i, must be >= 0 and < %i\n", light->style, MAX_LIGHTSTYLES);
-               light->style = 0;
-       }
        light->shadow = shadowenable;
        light->corona = corona;
-       if (!cubemapname)
-               cubemapname = "";
        strlcpy(light->cubemapname, cubemapname, sizeof(light->cubemapname));
        light->coronasizescale = coronasizescale;
        light->ambientscale = ambientscale;
        light->diffusescale = diffusescale;
        light->specularscale = specularscale;
        light->flags = flags;
-       Matrix4x4_CreateFromQuakeEntity(&light->matrix, light->origin[0], light->origin[1], light->origin[2], light->angles[0], light->angles[1], light->angles[2], 1);
 
-       R_RTLight_Update(light, true);
+       // update renderable light data
+       Matrix4x4_CreateFromQuakeEntity(&matrix, light->origin[0], light->origin[1], light->origin[2], light->angles[0], light->angles[1], light->angles[2], light->radius);
+       R_RTLight_Update(&light->rtlight, true, &matrix, light->color, light->style, light->cubemapname[0] ? light->cubemapname : NULL, light->shadow, light->corona, light->coronasizescale, light->ambientscale, light->diffusescale, light->specularscale, light->flags);
 }
 
 void R_Shadow_FreeWorldLight(dlight_t *light)
@@ -2877,7 +2883,7 @@ void R_Shadow_SelectLightInView(void)
                if (rating >= 0.95)
                {
                        rating /= (1 + 0.0625f * sqrt(DotProduct(temp, temp)));
-                       if (bestrating < rating && CL_TraceBox(light->origin, vec3_origin, vec3_origin, r_view.origin, true, NULL, SUPERCONTENTS_SOLID, false).fraction == 1.0f)
+                       if (bestrating < rating && CL_Move(light->origin, vec3_origin, vec3_origin, r_view.origin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction == 1.0f)
                        {
                                bestrating = rating;
                                best = light;
@@ -3306,7 +3312,7 @@ void R_Shadow_SetCursorLocationForView(void)
        vec3_t dest, endpos;
        trace_t trace;
        VectorMA(r_view.origin, r_editlights_cursordistance.value, r_view.forward, dest);
-       trace = CL_TraceBox(r_view.origin, vec3_origin, vec3_origin, dest, true, NULL, SUPERCONTENTS_SOLID, false);
+       trace = CL_Move(r_view.origin, vec3_origin, vec3_origin, dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false);
        if (trace.fraction < 1)
        {
                dist = trace.fraction * r_editlights_cursordistance.value;