]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - r_shadow.c
CSQC entity networking: if a frame BEFORE the last packetlog reset got lost, this...
[xonotic/darkplaces.git] / r_shadow.c
index 83a7517c07cd6a8062171f00184966279921d7d0..ba4ca14a63c15d98df01b355aa05701b6f166aed 100644 (file)
@@ -298,7 +298,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 (slower than compileportalculling but more exact)"};
-cvar_t r_shadow_realtime_world_compileportalculling = {0, "r_shadow_realtime_world_compileportalculling", "0", "enables portal-based culling optimization during compilation (overrides compilesvbsp)"};
+cvar_t r_shadow_realtime_world_compileportalculling = {0, "r_shadow_realtime_world_compileportalculling", "1", "enables portal-based culling optimization during compilation (overrides compilesvbsp)"};
 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_shadowmapping = {CVAR_SAVE, "r_shadow_shadowmapping", "0", "enables use of shadowmapping (depth texture sampling) instead of stencil shadow volumes, requires gl_fbo 1"};
 cvar_t r_shadow_shadowmapping_filterquality = {CVAR_SAVE, "r_shadow_shadowmapping_filterquality", "-1", "shadowmap filter modes: -1 = auto-select, 0 = no filtering, 1 = bilinear, 2 = bilinear 2x2 blur (fast), 3 = 3x3 blur (moderate), 4 = 4x4 blur (slow)"};
@@ -420,11 +420,7 @@ void R_Shadow_SetShadowMode(void)
                                }
                        }
                        r_shadow_shadowmode = R_SHADOW_SHADOWMODE_SHADOWMAP2D;
-                       // Cg has very little choice in depth texture sampling
-                       if (vid.cgcontext)
-                               r_shadow_shadowmapsampler = false;
                        break;
-               case RENDERPATH_CGGL:
                case RENDERPATH_D3D9:
                case RENDERPATH_D3D10:
                case RENDERPATH_D3D11:
@@ -437,6 +433,8 @@ void R_Shadow_SetShadowMode(void)
                        break;
                case RENDERPATH_GL11:
                        break;
+               case RENDERPATH_GLES2:
+                       break;
                }
        }
 }
@@ -1895,11 +1893,11 @@ void R_Shadow_RenderMode_Begin(void)
        switch(vid.renderpath)
        {
        case RENDERPATH_GL20:
-       case RENDERPATH_CGGL:
        case RENDERPATH_D3D9:
        case RENDERPATH_D3D10:
        case RENDERPATH_D3D11:
        case RENDERPATH_SOFT:
+       case RENDERPATH_GLES2:
                r_shadow_lightingrendermode = R_SHADOW_RENDERMODE_LIGHT_GLSL;
                break;
        case RENDERPATH_GL13:
@@ -2103,8 +2101,8 @@ init_done:
        case RENDERPATH_GL11:
        case RENDERPATH_GL13:
        case RENDERPATH_GL20:
-       case RENDERPATH_CGGL:
        case RENDERPATH_SOFT:
+       case RENDERPATH_GLES2:
                GL_CullFace(r_refdef.view.cullface_back);
                // OpenGL lets us scissor larger than the viewport, so go ahead and clear all views at once
                if ((clear & ((2 << side) - 1)) == (1 << side)) // only clear if the side is the first in the mask
@@ -2676,7 +2674,7 @@ void R_Shadow_RenderLighting(int texturenumsurfaces, const msurface_t **textures
                case RENDERPATH_GL11:
                case RENDERPATH_GL13:
                case RENDERPATH_GL20:
-               case RENDERPATH_CGGL:
+               case RENDERPATH_GLES2:
                        qglBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT);
                        break;
                case RENDERPATH_D3D9:
@@ -2722,7 +2720,7 @@ void R_Shadow_RenderLighting(int texturenumsurfaces, const msurface_t **textures
                case RENDERPATH_GL11:
                case RENDERPATH_GL13:
                case RENDERPATH_GL20:
-               case RENDERPATH_CGGL:
+               case RENDERPATH_GLES2:
                        qglBlendEquationEXT(GL_FUNC_ADD_EXT);
                        break;
                case RENDERPATH_D3D9:
@@ -3238,7 +3236,6 @@ void R_Shadow_SetupEntityLight(const entity_render_t *ent)
 {
        // set up properties for rendering light onto this entity
        RSurf_ActiveModelEntity(ent, true, true, false);
-       GL_AlphaTest(false);
        Matrix4x4_Concat(&rsurface.entitytolight, &rsurface.rtlight->matrix_worldtolight, &ent->matrix);
        Matrix4x4_Concat(&rsurface.entitytoattenuationxyz, &matrix_attenuationxyz, &rsurface.entitytolight);
        Matrix4x4_Concat(&rsurface.entitytoattenuationz, &matrix_attenuationz, &rsurface.entitytolight);
@@ -3252,7 +3249,6 @@ void R_Shadow_DrawWorldLight(int numsurfaces, int *surfacelist, const unsigned c
 
        // set up properties for rendering light onto this entity
        RSurf_ActiveWorldEntity();
-       GL_AlphaTest(false);
        rsurface.entitytolight = rsurface.rtlight->matrix_worldtolight;
        Matrix4x4_Concat(&rsurface.entitytoattenuationxyz, &matrix_attenuationxyz, &rsurface.entitytolight);
        Matrix4x4_Concat(&rsurface.entitytoattenuationz, &matrix_attenuationz, &rsurface.entitytolight);
@@ -3788,7 +3784,6 @@ void R_Shadow_DrawPrepass(void)
        entity_render_t *ent;
        float clearcolor[4];
 
-       GL_AlphaTest(false);
        R_Mesh_ResetTextureState();
        GL_DepthMask(true);
        GL_ColorMask(1,1,1,1);
@@ -3885,11 +3880,11 @@ void R_Shadow_PrepareLights(void)
        switch (vid.renderpath)
        {
        case RENDERPATH_GL20:
-       case RENDERPATH_CGGL:
        case RENDERPATH_D3D9:
        case RENDERPATH_D3D10:
        case RENDERPATH_D3D11:
        case RENDERPATH_SOFT:
+       case RENDERPATH_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;
@@ -4281,8 +4276,8 @@ void R_DrawModelShadowMaps(void)
        case RENDERPATH_GL11:
        case RENDERPATH_GL13:
        case RENDERPATH_GL20:
-       case RENDERPATH_CGGL:
        case RENDERPATH_SOFT:
+       case RENDERPATH_GLES2:
                break;
        case RENDERPATH_D3D9:
        case RENDERPATH_D3D10:
@@ -4458,7 +4453,7 @@ void R_BeginCoronaQuery(rtlight_t *rtlight, float scale, qboolean usequery)
                case RENDERPATH_GL20:
                case RENDERPATH_GL13:
                case RENDERPATH_GL11:
-               case RENDERPATH_CGGL:
+               case RENDERPATH_GLES2:
                        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);
@@ -4506,7 +4501,7 @@ void R_DrawCorona(rtlight_t *rtlight, float cscale, float scale)
                case RENDERPATH_GL20:
                case RENDERPATH_GL13:
                case RENDERPATH_GL11:
-               case RENDERPATH_CGGL:
+               case RENDERPATH_GLES2:
                        CHECKGLERROR
                        qglGetQueryObjectivARB(rtlight->corona_queryindex_visiblepixels, GL_QUERY_RESULT_ARB, &visiblepixels);
                        qglGetQueryObjectivARB(rtlight->corona_queryindex_allpixels, GL_QUERY_RESULT_ARB, &allpixels);
@@ -4550,7 +4545,7 @@ void R_DrawCorona(rtlight_t *rtlight, float cscale, float scale)
                        case RENDERPATH_GL11:
                        case RENDERPATH_GL13:
                        case RENDERPATH_GL20:
-                       case RENDERPATH_CGGL:
+                       case RENDERPATH_GLES2:
                                qglBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT);
                                break;
                        case RENDERPATH_D3D9:
@@ -4579,7 +4574,7 @@ void R_DrawCorona(rtlight_t *rtlight, float cscale, float scale)
                        case RENDERPATH_GL11:
                        case RENDERPATH_GL13:
                        case RENDERPATH_GL20:
-                       case RENDERPATH_CGGL:
+                       case RENDERPATH_GLES2:
                                qglBlendEquationEXT(GL_FUNC_ADD_EXT);
                                break;
                        case RENDERPATH_D3D9:
@@ -4627,7 +4622,7 @@ void R_Shadow_DrawCoronas(void)
        case RENDERPATH_GL11:
        case RENDERPATH_GL13:
        case RENDERPATH_GL20:
-       case RENDERPATH_CGGL:
+       case RENDERPATH_GLES2:
                usequery = vid.support.arb_occlusion_query && r_coronas_occlusionquery.integer;
                if (usequery)
                {
@@ -4664,6 +4659,7 @@ void R_Shadow_DrawCoronas(void)
                Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
                break;
        case RENDERPATH_SOFT:
+               usequery = false;
                //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
                break;
        }
@@ -6036,26 +6032,60 @@ LIGHT SAMPLING
 =============================================================================
 */
 
-void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal, const vec3_t p, const int flags)
+void R_CompleteLightPoint(vec3_t ambient, vec3_t diffuse, vec3_t lightdir, const vec3_t p, const int flags)
 {
        int i, numlights, flag;
-       float f, relativepoint[3], dist, dist2, lightradius2;
        rtlight_t *light;
        dlight_t *dlight;
+       float relativepoint[3];
+       float color[3];
+       float dir[3];
+       float dist;
+       float dist2;
+       float intensity;
+       float sample[5*3];
+       float lightradius2;
 
-       VectorClear(diffusecolor);
-       VectorClear(diffusenormal);
+       if (r_fullbright.integer)
+       {
+               VectorSet(ambient, 1, 1, 1);
+               VectorClear(diffuse);
+               VectorClear(lightdir);
+               return;
+       }
 
        if (flags & LP_LIGHTMAP)
        {
-               if (!r_fullbright.integer && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.LightPoint)
-               {
-                       ambientcolor[0] = ambientcolor[1] = ambientcolor[2] = r_refdef.scene.ambient;
-                       r_refdef.scene.worldmodel->brush.LightPoint(r_refdef.scene.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
-               }
-               else
-                       VectorSet(ambientcolor, 1, 1, 1);
+               VectorSet(ambient, r_refdef.scene.ambient, r_refdef.scene.ambient, r_refdef.scene.ambient);
+               VectorClear(diffuse);
+               VectorClear(lightdir);
+               if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.LightPoint)
+                       r_refdef.scene.worldmodel->brush.LightPoint(r_refdef.scene.worldmodel, p, ambient, diffuse, lightdir);
+               return;
        }
+
+       memset(sample, 0, sizeof(sample));
+       VectorSet(sample, r_refdef.scene.ambient, r_refdef.scene.ambient, r_refdef.scene.ambient);
+
+       if ((flags & LP_LIGHTMAP) && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.LightPoint)
+       {
+               vec3_t tempambient;
+               VectorClear(tempambient);
+               VectorClear(color);
+               VectorClear(relativepoint);
+               r_refdef.scene.worldmodel->brush.LightPoint(r_refdef.scene.worldmodel, p, tempambient, color, relativepoint);
+               VectorScale(tempambient, r_refdef.lightmapintensity, tempambient);
+               VectorScale(color, r_refdef.lightmapintensity, color);
+               VectorAdd(sample, tempambient, sample);
+               VectorMA(sample    , 0.5f            , color, sample    );
+               VectorMA(sample + 3, relativepoint[0], color, sample + 3);
+               VectorMA(sample + 6, relativepoint[1], color, sample + 6);
+               VectorMA(sample + 9, relativepoint[2], color, sample + 9);
+               // calculate a weighted average light direction as well
+               intensity = VectorLength(color);
+               VectorMA(sample + 12, intensity, relativepoint, sample + 12);
+       }
+
        if (flags & LP_RTWORLD)
        {
                flag = r_refdef.scene.rtworld ? LIGHTFLAG_REALTIMEMODE : LIGHTFLAG_NORMALMODE;
@@ -6075,14 +6105,25 @@ void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffu
                        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)
+                       intensity = min(1.0f, (1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist)) * r_shadow_lightintensityscale.value;
+                       if (intensity <= 0.0f)
                                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).fraction == 1)
-                               VectorMA(ambientcolor, f, light->currentcolor, ambientcolor);
+                       if (light->shadow && CL_TraceLine(p, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction < 1)
+                               continue;
+                       // scale down intensity to add to both ambient and diffuse
+                       //intensity *= 0.5f;
+                       VectorNormalize(relativepoint);
+                       VectorScale(light->currentcolor, intensity, color);
+                       VectorMA(sample    , 0.5f            , color, sample    );
+                       VectorMA(sample + 3, relativepoint[0], color, sample + 3);
+                       VectorMA(sample + 6, relativepoint[1], color, sample + 6);
+                       VectorMA(sample + 9, relativepoint[2], color, sample + 9);
+                       // calculate a weighted average light direction as well
+                       intensity *= VectorLength(color);
+                       VectorMA(sample + 12, intensity, relativepoint, sample + 12);
                }
        }
+
        if (flags & LP_DYNLIGHT)
        {
                // sample dlights
@@ -6096,12 +6137,35 @@ void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffu
                        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)
+                       intensity = (1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist) * r_shadow_lightintensityscale.value;
+                       if (intensity <= 0.0f)
                                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).fraction == 1)
-                               VectorMA(ambientcolor, f, light->color, ambientcolor);
+                       if (light->shadow && CL_TraceLine(p, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction < 1)
+                               continue;
+                       // scale down intensity to add to both ambient and diffuse
+                       //intensity *= 0.5f;
+                       VectorNormalize(relativepoint);
+                       VectorScale(light->currentcolor, intensity, color);
+                       VectorMA(sample    , 0.5f            , color, sample    );
+                       VectorMA(sample + 3, relativepoint[0], color, sample + 3);
+                       VectorMA(sample + 6, relativepoint[1], color, sample + 6);
+                       VectorMA(sample + 9, relativepoint[2], color, sample + 9);
+                       // calculate a weighted average light direction as well
+                       intensity *= VectorLength(color);
+                       VectorMA(sample + 12, intensity, relativepoint, sample + 12);
                }
        }
+
+       // calculate the direction we'll use to reduce the sample to a directional light source
+       VectorCopy(sample + 12, dir);
+       //VectorSet(dir, sample[3] + sample[4] + sample[5], sample[6] + sample[7] + sample[8], sample[9] + sample[10] + sample[11]);
+       VectorNormalize(dir);
+       // extract the diffuse color along the chosen direction and scale it
+       diffuse[0] = (dir[0]*sample[3] + dir[1]*sample[6] + dir[2]*sample[ 9] + sample[ 0]);
+       diffuse[1] = (dir[0]*sample[4] + dir[1]*sample[7] + dir[2]*sample[10] + sample[ 1]);
+       diffuse[2] = (dir[0]*sample[5] + dir[1]*sample[8] + dir[2]*sample[11] + sample[ 2]);
+       // subtract some of diffuse from ambient
+       VectorMA(sample, -0.333f, diffuse, ambient);
+       // store the normalized lightdir
+       VectorCopy(dir, lightdir);
 }