]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
when r_shadow_shadowmapping is enabled, r_shadows uses shadowmaps instead of stencils
authoreihrul <eihrul@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 4 Feb 2010 00:18:13 +0000 (00:18 +0000)
committereihrul <eihrul@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 4 Feb 2010 00:18:13 +0000 (00:18 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9926 d7cf8633-e32d-0410-b094-e92efae38249

gl_rmain.c
r_shadow.c
r_shadow.h

index 68ca03a4147178af28370f15219de047c3168a72..ee2688070eaa88419170ea1125ddbd187616757b 100644 (file)
@@ -253,8 +253,6 @@ const float r_screenvertex3f[12] =
        0, 1, 0
 };
 
-extern void R_DrawModelShadows(void);
-
 void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
 {
        int i;
@@ -896,6 +894,10 @@ static const char *builtinshaderstring =
 "#endif\n"
 "uniform vec4 FogPlane;\n"
 "\n"
+"#ifdef USESHADOWMAPORTHO\n"
+"varying vec3 ShadowMapTC;\n"
+"#endif\n"
+"\n"
 "\n"
 "\n"
 "\n"
@@ -1013,7 +1015,7 @@ static const char *builtinshaderstring =
 "}\n"
 "#endif // USEOFFSETMAPPING\n"
 "\n"
-"#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE)\n"
+"#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE) || defined(USESHADOWMAPORTHO)\n"
 "uniform sampler2D Texture_Attenuation;\n"
 "uniform samplerCube Texture_Cube;\n"
 "\n"
@@ -1051,7 +1053,21 @@ static const char *builtinshaderstring =
 "#endif\n"
 "\n"
 "#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
-"# ifndef USESHADOWMAPVSDCT\n"
+"# ifdef USESHADOWMAPORTHO\n"
+"#  define GetShadowMapTC2D(dir) (min(dir, vec3(ShadowMap_Parameters.zw, 1.0)))\n"
+"# else\n"
+"#  ifdef USESHADOWMAPVSDCT\n"
+"vec3 GetShadowMapTC2D(vec3 dir)\n"
+"{\n"
+"   vec3 adir = abs(dir);\n"
+"   vec4 proj = textureCube(Texture_CubeProjection, dir);\n"
+"   float ma = max(max(adir.x, adir.y), adir.z);\n"
+"   vec3 stc = vec3(mix(dir.xy, dir.zz, proj.xy) * ShadowMap_Parameters.x, ShadowMap_Parameters.w) / ma;\n"
+"   stc.xy += proj.zw * ShadowMap_Parameters.y;\n"
+"   stc.z += ShadowMap_Parameters.z;\n"
+"   return stc;\n"
+"}\n"
+"#  else\n"
 "vec3 GetShadowMapTC2D(vec3 dir)\n"
 "{\n"
 "      vec3 adir = abs(dir);\n"
@@ -1094,17 +1110,7 @@ static const char *builtinshaderstring =
 "      stc.z += ShadowMap_Parameters.z;\n"
 "      return stc;\n"
 "}\n"
-"# else\n"
-"vec3 GetShadowMapTC2D(vec3 dir)\n"
-"{\n"
-"      vec3 adir = abs(dir);\n"
-"      vec4 proj = textureCube(Texture_CubeProjection, dir);\n"
-"      float ma = max(max(adir.x, adir.y), adir.z);\n"
-"      vec3 stc = vec3(mix(dir.xy, dir.zz, proj.xy) * ShadowMap_Parameters.x, ShadowMap_Parameters.w) / ma;\n"
-"      stc.xy += proj.zw * ShadowMap_Parameters.y;\n"
-"      stc.z += ShadowMap_Parameters.z;\n"
-"      return stc;\n"
-"}\n"
+"#  endif\n"
 "# endif\n"
 "#endif // defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
 "\n"
@@ -1156,7 +1162,11 @@ static const char *builtinshaderstring =
 "#    endif\n"
 "\n"
 "#  endif\n"
+"#  ifdef USESHADOWMAPORTHO\n"
+"      return mix(ShadowMap_Parameters.x, ShadowMap_Parameters.y, f);\n"
+"#  else\n"
 "      return f;\n"
+"#  endif\n"
 "}\n"
 "# endif\n"
 "\n"
@@ -1219,7 +1229,11 @@ static const char *builtinshaderstring =
 "      f = step(shadowmaptc.z, texture2D(Texture_ShadowMap2D, shadowmaptc.xy*ShadowMap_TextureScale).r);\n"
 "#    endif\n"
 "#  endif\n"
+"#  ifdef USESHADOWMAPORTHO\n"
+"      return mix(ShadowMap_Parameters.x, ShadowMap_Parameters.y, f);\n"
+"#  else\n"
 "      return f;\n"
+"#  endif\n"
 "}\n"
 "# endif\n"
 "\n"
@@ -1237,7 +1251,7 @@ static const char *builtinshaderstring =
 "      return f;\n"
 "}\n"
 "# endif\n"
-"#endif // !defined(MODE_LIGHTSOURCE) && !defined(MODE_DEFERREDLIGHTSOURCE)\n"
+"#endif // !defined(MODE_LIGHTSOURCE) && !defined(MODE_DEFERREDLIGHTSOURCE) && !defined(USESHADOWMAPORTHO)\n"
 "#endif // FRAGMENT_SHADER\n"
 "\n"
 "\n"
@@ -1398,6 +1412,9 @@ static const char *builtinshaderstring =
 "#ifdef MODE_LIGHTSOURCE\n"
 "uniform mat4 ModelToLight;\n"
 "#endif\n"
+"#ifdef USESHADOWMAPORTHO\n"
+"uniform mat4 ShadowMapMatrix;\n"
+"#endif\n"
 "void main(void)\n"
 "{\n"
 "#if defined(MODE_VERTEXCOLOR) || defined(USEVERTEXTEXTUREBLEND)\n"
@@ -1456,6 +1473,10 @@ static const char *builtinshaderstring =
 "      // transform vertex to camera space, using ftransform to match non-VS rendering\n"
 "      gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
 "\n"
+"#ifdef USESHADOWMAPORTHO\n"
+"      ShadowMapTC = vec3(ShadowMapMatrix * gl_Position);\n"
+"#endif\n"
+"\n"
 "#ifdef USEREFLECTION\n"
 "      ModelViewProjectionPosition = gl_Position;\n"
 "#endif\n"
@@ -1651,6 +1672,10 @@ static const char *builtinshaderstring =
 "# endif\n"
 "#endif\n"
 "\n"
+"#ifdef USESHADOWMAPORTHO\n"
+"      color.rgb *= ShadowMapCompare(ShadowMapTC);\n"
+"#endif\n"
+"\n"
 "#ifdef USEDEFERREDLIGHTMAP\n"
 "      vec2 ScreenTexCoord = gl_FragCoord.xy * PixelToScreenTexCoord;\n"
 "      color.rgb += diffusetex * myhalf3(texture2D(Texture_ScreenDiffuse, ScreenTexCoord)) * DeferredMod_Diffuse;\n"
@@ -2186,7 +2211,18 @@ const char *builtincgshaderstring =
 "\n"
 "#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE)\n"
 "#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
-"# ifndef USESHADOWMAPVSDCT\n"
+"# ifdef USESHADOWMAPVSDCT\n"
+"float3 GetShadowMapTC2D(float3 dir, float4 ShadowMap_Parameters, samplerCUBE Texture_CubeProjection)\n"
+"{\n"
+"   float3 adir = abs(dir);\n"
+"   float4 proj = texCUBE(Texture_CubeProjection, dir);\n"
+"   float ma = max(max(adir.x, adir.y), adir.z);\n"
+"   float3 stc = float3(lerp(dir.xy, dir.zz, proj.xy) * ShadowMap_Parameters.x, ShadowMap_Parameters.w) / ma;\n"
+"   stc.xy += proj.zw * ShadowMap_Parameters.y;\n"
+"   stc.z += ShadowMap_Parameters.z;\n"
+"   return stc;\n"
+"}\n"
+"# else\n"
 "float3 GetShadowMapTC2D(float3 dir, float4 ShadowMap_Parameters)\n"
 "{\n"
 "      float3 adir = abs(dir);\n"
@@ -2229,17 +2265,6 @@ const char *builtincgshaderstring =
 "      stc.z += ShadowMap_Parameters.z;\n"
 "      return stc;\n"
 "}\n"
-"# else\n"
-"float3 GetShadowMapTC2D(float3 dir, float4 ShadowMap_Parameters, samplerCUBE Texture_CubeProjection)\n"
-"{\n"
-"      float3 adir = abs(dir);\n"
-"      float4 proj = texCUBE(Texture_CubeProjection, dir);\n"
-"      float ma = max(max(adir.x, adir.y), adir.z);\n"
-"      float3 stc = float3(lerp(dir.xy, dir.zz, proj.xy) * ShadowMap_Parameters.x, ShadowMap_Parameters.w) / ma;\n"
-"      stc.xy += proj.zw * ShadowMap_Parameters.y;\n"
-"      stc.z += ShadowMap_Parameters.z;\n"
-"      return stc;\n"
-"}\n"
 "# endif\n"
 "#endif // defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
 "\n"
@@ -3214,11 +3239,12 @@ typedef enum shaderpermutation_e
        SHADERPERMUTATION_SHADOWMAPPCF2 = 1<<21, ///< (lightsource) use higher quality percentage closer filtering on shadowmap test results
        SHADERPERMUTATION_SHADOWSAMPLER = 1<<22, ///< (lightsource) use hardware shadowmap test
        SHADERPERMUTATION_SHADOWMAPVSDCT = 1<<23, ///< (lightsource) use virtual shadow depth cube texture for shadowmap indexing
-       SHADERPERMUTATION_DEFERREDLIGHTMAP = 1<<24, ///< (lightmap) read Texture_ScreenDiffuse/Specular textures and add them on top of lightmapping
-       SHADERPERMUTATION_ALPHAKILL = 1<<25, ///< (deferredgeometry) discard pixel if diffuse texture alpha below 0.5
-       SHADERPERMUTATION_REFLECTCUBE = 1<<26, ///< fake reflections using global cubemap (not HDRI light probe)
-       SHADERPERMUTATION_LIMIT = 1<<27, ///< size of permutations array
-       SHADERPERMUTATION_COUNT = 27 ///< size of shaderpermutationinfo array
+       SHADERPERMUTATION_SHADOWMAPORTHO = 1<<24, //< (lightsource) use orthographic shadowmap projection
+       SHADERPERMUTATION_DEFERREDLIGHTMAP = 1<<25, ///< (lightmap) read Texture_ScreenDiffuse/Specular textures and add them on top of lightmapping
+       SHADERPERMUTATION_ALPHAKILL = 1<<26, ///< (deferredgeometry) discard pixel if diffuse texture alpha below 0.5
+       SHADERPERMUTATION_REFLECTCUBE = 1<<27, ///< fake reflections using global cubemap (not HDRI light probe)
+       SHADERPERMUTATION_LIMIT = 1<<28, ///< size of permutations array
+       SHADERPERMUTATION_COUNT = 28 ///< size of shaderpermutationinfo array
 }
 shaderpermutation_t;
 
@@ -3249,6 +3275,7 @@ shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] =
        {"#define USESHADOWMAPPCF 2\n", " shadowmappcf2"},
        {"#define USESHADOWSAMPLER\n", " shadowsampler"},
        {"#define USESHADOWMAPVSDCT\n", " shadowmapvsdct"},
+       {"#define USESHADOWMAPORTHO\n", " shadowmaportho"},
        {"#define USEDEFERREDLIGHTMAP\n", " deferredlightmap"},
        {"#define USEALPHAKILL\n", " alphakill"},
        {"#define USEREFLECTCUBE\n", " reflectcube"},
@@ -3410,6 +3437,7 @@ typedef struct r_glsl_permutation_s
        int loc_ModelViewMatrix;
        int loc_PixelToScreenTexCoord;
        int loc_ModelToReflectCube;
+       int loc_ShadowMapMatrix;        
 }
 r_glsl_permutation_t;
 
@@ -3635,6 +3663,7 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode
                p->loc_ModelViewProjectionMatrix  = qglGetUniformLocationARB(p->program, "ModelViewProjectionMatrix");
                p->loc_PixelToScreenTexCoord      = qglGetUniformLocationARB(p->program, "PixelToScreenTexCoord");
                p->loc_ModelToReflectCube         = qglGetUniformLocationARB(p->program, "ModelToReflectCube");
+               p->loc_ShadowMapMatrix            = qglGetUniformLocationARB(p->program, "ShadowMapMatrix");            
                // initialize the samplers to refer to the texture units we use
                if (p->loc_Texture_First           >= 0) qglUniform1iARB(p->loc_Texture_First          , GL20TU_FIRST);
                if (p->loc_Texture_Second          >= 0) qglUniform1iARB(p->loc_Texture_Second         , GL20TU_SECOND);
@@ -3750,6 +3779,7 @@ typedef struct r_cg_permutation_s
        CGparameter vp_BackgroundTexMatrix;
        CGparameter vp_ModelViewProjectionMatrix;
        CGparameter vp_ModelViewMatrix;
+       CGparameter vp_ShadowMapMatrix;
 
        CGparameter fp_Texture_First;
        CGparameter fp_Texture_Second;
@@ -4041,6 +4071,7 @@ static void R_CG_CompilePermutation(r_cg_permutation_t *p, unsigned int mode, un
                p->vp_BackgroundTexMatrix        = cgGetNamedParameter(p->vprogram, "BackgroundTexMatrix");
                p->vp_ModelViewProjectionMatrix  = cgGetNamedParameter(p->vprogram, "ModelViewProjectionMatrix");
                p->vp_ModelViewMatrix            = cgGetNamedParameter(p->vprogram, "ModelViewMatrix");
+               p->vp_ShadowMapMatrix            = cgGetNamedParameter(p->vprogram, "ShadowMapMatrix");
                CHECKCGERROR
        }
        if (p->fprogram)
@@ -4402,6 +4433,7 @@ extern rtexture_t *r_shadow_attenuation3dtexture;
 extern qboolean r_shadow_usingshadowmaprect;
 extern qboolean r_shadow_usingshadowmapcube;
 extern qboolean r_shadow_usingshadowmap2d;
+extern qboolean r_shadow_usingshadowmaportho;
 extern float r_shadow_shadowmap_texturescale[2];
 extern float r_shadow_shadowmap_parameters[4];
 extern qboolean r_shadow_shadowmapvsdct;
@@ -4411,6 +4443,7 @@ extern rtexture_t *r_shadow_shadowmaprectangletexture;
 extern rtexture_t *r_shadow_shadowmap2dtexture;
 extern rtexture_t *r_shadow_shadowmapcubetexture[R_SHADOW_SHADOWMAP_NUMCUBEMAPS];
 extern rtexture_t *r_shadow_shadowmapvsdcttexture;
+extern matrix4x4_t r_shadow_shadowmapmatrix;
 extern int r_shadow_shadowmaplod; // changes for each light based on distance
 extern int r_shadow_prepass_width;
 extern int r_shadow_prepass_height;
@@ -4559,6 +4592,21 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE;
                if (rsurface.texture->colormapping)
                        permutation |= SHADERPERMUTATION_COLORMAPPING;
+               if (r_shadow_usingshadowmaportho && (r_shadow_usingshadowmaprect || r_shadow_usingshadowmap2d))
+               {
+                       permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
+                       if (r_shadow_usingshadowmaprect)
+                               permutation |= SHADERPERMUTATION_SHADOWMAPRECT;
+                       if (r_shadow_usingshadowmap2d)
+                               permutation |= SHADERPERMUTATION_SHADOWMAP2D;
+
+                       if (r_shadow_shadowmapsampler)
+                               permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
+                       if (r_shadow_shadowmappcf > 1)
+                               permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
+                       else if (r_shadow_shadowmappcf)
+                               permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
+               }
                if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
                        permutation |= SHADERPERMUTATION_REFLECTION;
                if (rsurface.texture->reflectmasktexture)
@@ -4609,6 +4657,21 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE;
                if (rsurface.texture->colormapping)
                        permutation |= SHADERPERMUTATION_COLORMAPPING;
+               if (r_shadow_usingshadowmaportho && (r_shadow_usingshadowmaprect || r_shadow_usingshadowmap2d))
+               {
+                       permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
+                       if (r_shadow_usingshadowmaprect)
+                               permutation |= SHADERPERMUTATION_SHADOWMAPRECT;
+                       if (r_shadow_usingshadowmap2d)
+                               permutation |= SHADERPERMUTATION_SHADOWMAP2D;
+
+                       if (r_shadow_shadowmapsampler)
+                               permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
+                       if (r_shadow_shadowmappcf > 1)
+                               permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
+                       else if (r_shadow_shadowmappcf)
+                               permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
+               }
                if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
                        permutation |= SHADERPERMUTATION_REFLECTION;
                if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
@@ -4651,6 +4714,21 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE;
                if (rsurface.texture->colormapping)
                        permutation |= SHADERPERMUTATION_COLORMAPPING;
+               if (r_shadow_usingshadowmaportho && (r_shadow_usingshadowmaprect || r_shadow_usingshadowmap2d))
+               {
+                       permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
+                       if (r_shadow_usingshadowmaprect)
+                               permutation |= SHADERPERMUTATION_SHADOWMAPRECT;
+                       if (r_shadow_usingshadowmap2d)
+                               permutation |= SHADERPERMUTATION_SHADOWMAP2D;
+
+                       if (r_shadow_shadowmapsampler)
+                               permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
+                       if (r_shadow_shadowmappcf > 1)
+                               permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
+                       else if (r_shadow_shadowmappcf)
+                               permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
+               }
                if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
                        permutation |= SHADERPERMUTATION_REFLECTION;
                if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
@@ -4692,6 +4770,21 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE;
                if (rsurface.texture->colormapping)
                        permutation |= SHADERPERMUTATION_COLORMAPPING;
+               if (r_shadow_usingshadowmaportho && (r_shadow_usingshadowmaprect || r_shadow_usingshadowmap2d))
+               {
+                       permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
+                       if (r_shadow_usingshadowmaprect)
+                               permutation |= SHADERPERMUTATION_SHADOWMAPRECT;
+                       if (r_shadow_usingshadowmap2d)
+                               permutation |= SHADERPERMUTATION_SHADOWMAP2D;
+
+                       if (r_shadow_shadowmapsampler)
+                               permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
+                       if (r_shadow_shadowmappcf > 1)
+                               permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
+                       else if (r_shadow_shadowmappcf)
+                               permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
+               }
                if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
                        permutation |= SHADERPERMUTATION_REFLECTION;
                if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
@@ -4785,8 +4878,6 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        // additive passes are only darkened by fog, not tinted
                        if (r_glsl_permutation->loc_FogColor >= 0)
                                qglUniform3fARB(r_glsl_permutation->loc_FogColor, 0, 0, 0);
-                       if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform2fARB(r_glsl_permutation->loc_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
-                       if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4fARB(r_glsl_permutation->loc_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
                        if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f));
                }
                else
@@ -4832,6 +4923,10 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                }
                if (r_glsl_permutation->loc_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);qglUniformMatrix4fvARB(r_glsl_permutation->loc_TexMatrix, 1, false, m16f);}
                if (r_glsl_permutation->loc_BackgroundTexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);qglUniformMatrix4fvARB(r_glsl_permutation->loc_BackgroundTexMatrix, 1, false, m16f);}
+               if (r_glsl_permutation->loc_ShadowMapMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);qglUniformMatrix4fvARB(r_glsl_permutation->loc_ShadowMapMatrix, 1, false, m16f);}
+               if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform2fARB(r_glsl_permutation->loc_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
+               if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4fARB(r_glsl_permutation->loc_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
+
                if (r_glsl_permutation->loc_Color_Glow >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
                if (r_glsl_permutation->loc_Alpha >= 0) qglUniform1fARB(r_glsl_permutation->loc_Alpha, rsurface.texture->lightmapcolor[3]);
                if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
@@ -4882,14 +4977,17 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                if (r_glsl_permutation->loc_Texture_ScreenNormalMap >= 0) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP   , r_shadow_prepassgeometrynormalmaptexture            );
                if (r_glsl_permutation->loc_Texture_ScreenDiffuse   >= 0) R_Mesh_TexBind(GL20TU_SCREENDIFFUSE     , r_shadow_prepasslightingdiffusetexture              );
                if (r_glsl_permutation->loc_Texture_ScreenSpecular  >= 0) R_Mesh_TexBind(GL20TU_SCREENSPECULAR    , r_shadow_prepasslightingspeculartexture             );
-               if (rsurface.rtlight)
+               if (rsurface.rtlight || r_shadow_usingshadowmaportho)
                {
-                       if (r_glsl_permutation->loc_Texture_Cube            >= 0) R_Mesh_TexBind(GL20TU_CUBE              , rsurface.rtlight->currentcubemap                    );
-                       if (r_glsl_permutation->loc_Texture_ShadowMapRect   >= 0) R_Mesh_TexBind(GL20TU_SHADOWMAPRECT     , r_shadow_shadowmaprectangletexture                  );
-                       if (r_shadow_usingshadowmapcube)
-                               if (r_glsl_permutation->loc_Texture_ShadowMapCube   >= 0) R_Mesh_TexBind(GL20TU_SHADOWMAPCUBE     , r_shadow_shadowmapcubetexture[r_shadow_shadowmaplod]);
                        if (r_glsl_permutation->loc_Texture_ShadowMap2D     >= 0) R_Mesh_TexBind(GL20TU_SHADOWMAP2D       , r_shadow_shadowmap2dtexture                         );
-                       if (r_glsl_permutation->loc_Texture_CubeProjection  >= 0) R_Mesh_TexBind(GL20TU_CUBEPROJECTION    , r_shadow_shadowmapvsdcttexture                      );
+                       if (r_glsl_permutation->loc_Texture_ShadowMapRect   >= 0) R_Mesh_TexBind(GL20TU_SHADOWMAPRECT     , r_shadow_shadowmaprectangletexture                  );
+                       if (rsurface.rtlight)
+                       {
+                               if (r_glsl_permutation->loc_Texture_Cube            >= 0) R_Mesh_TexBind(GL20TU_CUBE              , rsurface.rtlight->currentcubemap                    );
+                               if (r_shadow_usingshadowmapcube)
+                                       if (r_glsl_permutation->loc_Texture_ShadowMapCube   >= 0) R_Mesh_TexBind(GL20TU_SHADOWMAPCUBE     , r_shadow_shadowmapcubetexture[r_shadow_shadowmaplod]);
+                               if (r_glsl_permutation->loc_Texture_CubeProjection  >= 0) R_Mesh_TexBind(GL20TU_CUBEPROJECTION    , r_shadow_shadowmapvsdcttexture                      );
+                       }
                }
                CHECKGLERROR
                break;
@@ -4911,6 +5009,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                }
                if (r_cg_permutation->vp_TexMatrix) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->vp_TexMatrix, m16f);}CHECKCGERROR
                if (r_cg_permutation->vp_BackgroundTexMatrix) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->vp_BackgroundTexMatrix, m16f);}CHECKCGERROR
+               if (r_cg_permutation->vp_ShadowMapMatrix) {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->vp_ShadowMapMatrix, m16f);}CHECKGLERROR
                if (r_cg_permutation->vp_EyePosition) cgGLSetParameter3f(r_cg_permutation->vp_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);CHECKCGERROR
                if (r_cg_permutation->vp_FogPlane) cgGLSetParameter4f(r_cg_permutation->vp_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);CHECKCGERROR
                CHECKGLERROR
@@ -4925,8 +5024,6 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
 
                        // additive passes are only darkened by fog, not tinted
                        if (r_cg_permutation->fp_FogColor) cgGLSetParameter3f(r_cg_permutation->fp_FogColor, 0, 0, 0);CHECKCGERROR
-                       if (r_cg_permutation->fp_ShadowMap_TextureScale) cgGLSetParameter2f(r_cg_permutation->fp_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);CHECKCGERROR
-                       if (r_cg_permutation->fp_ShadowMap_Parameters) cgGLSetParameter4f(r_cg_permutation->fp_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);CHECKCGERROR
                        if (r_cg_permutation->fp_SpecularPower) cgGLSetParameter1f(r_cg_permutation->fp_SpecularPower, rsurface.texture->specularpower * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f));CHECKCGERROR
                }
                else
@@ -4971,6 +5068,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        if (r_cg_permutation->fp_ReflectOffset) cgGLSetParameter1f(r_cg_permutation->fp_ReflectOffset, rsurface.texture->reflectmin);CHECKCGERROR
                        if (r_cg_permutation->fp_SpecularPower) cgGLSetParameter1f(r_cg_permutation->fp_SpecularPower, rsurface.texture->specularpower * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f));CHECKCGERROR
                }
+               if (r_cg_permutation->fp_ShadowMap_TextureScale) cgGLSetParameter2f(r_cg_permutation->fp_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);CHECKCGERROR
+               if (r_cg_permutation->fp_ShadowMap_Parameters) cgGLSetParameter4f(r_cg_permutation->fp_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);CHECKCGERROR
                if (r_cg_permutation->fp_Color_Glow) cgGLSetParameter3f(r_cg_permutation->fp_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);CHECKCGERROR
                if (r_cg_permutation->fp_Alpha) cgGLSetParameter1f(r_cg_permutation->fp_Alpha, rsurface.texture->lightmapcolor[3]);CHECKCGERROR
                if (r_cg_permutation->fp_EyePosition) cgGLSetParameter3f(r_cg_permutation->fp_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);CHECKCGERROR
@@ -5023,14 +5122,17 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                if (r_cg_permutation->fp_Texture_ScreenNormalMap) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenNormalMap, r_shadow_prepassgeometrynormalmaptexture            );CHECKCGERROR
                if (r_cg_permutation->fp_Texture_ScreenDiffuse  ) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenDiffuse  , r_shadow_prepasslightingdiffusetexture              );CHECKCGERROR
                if (r_cg_permutation->fp_Texture_ScreenSpecular ) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenSpecular , r_shadow_prepasslightingspeculartexture             );CHECKCGERROR
-               if (rsurface.rtlight)
+               if (rsurface.rtlight || r_shadow_usingshadowmaportho)
                {
-                       if (r_cg_permutation->fp_Texture_Cube           ) CG_BindTexture(r_cg_permutation->fp_Texture_Cube           , rsurface.rtlight->currentcubemap                    );CHECKCGERROR
-                       if (r_cg_permutation->fp_Texture_ShadowMapRect  ) CG_BindTexture(r_cg_permutation->fp_Texture_ShadowMapRect  , r_shadow_shadowmaprectangletexture                  );CHECKCGERROR
-                       if (r_shadow_usingshadowmapcube)
-                               if (r_cg_permutation->fp_Texture_ShadowMapCube  ) CG_BindTexture(r_cg_permutation->fp_Texture_ShadowMapCube  , r_shadow_shadowmapcubetexture[r_shadow_shadowmaplod]);CHECKCGERROR
                        if (r_cg_permutation->fp_Texture_ShadowMap2D    ) CG_BindTexture(r_cg_permutation->fp_Texture_ShadowMap2D    , r_shadow_shadowmap2dtexture                         );CHECKCGERROR
-                       if (r_cg_permutation->fp_Texture_CubeProjection ) CG_BindTexture(r_cg_permutation->fp_Texture_CubeProjection , r_shadow_shadowmapvsdcttexture                      );CHECKCGERROR
+                       if (r_cg_permutation->fp_Texture_ShadowMapRect  ) CG_BindTexture(r_cg_permutation->fp_Texture_ShadowMapRect  , r_shadow_shadowmaprectangletexture                  );CHECKCGERROR
+                       if (rsurface.rtlight)
+                       {
+                               if (r_cg_permutation->fp_Texture_Cube           ) CG_BindTexture(r_cg_permutation->fp_Texture_Cube           , rsurface.rtlight->currentcubemap                    );CHECKCGERROR
+                               if (r_shadow_usingshadowmapcube)
+                                       if (r_cg_permutation->fp_Texture_ShadowMapCube  ) CG_BindTexture(r_cg_permutation->fp_Texture_ShadowMapCube  , r_shadow_shadowmapcubetexture[r_shadow_shadowmaplod]);CHECKCGERROR
+                               if (r_cg_permutation->fp_Texture_CubeProjection ) CG_BindTexture(r_cg_permutation->fp_Texture_CubeProjection , r_shadow_shadowmapvsdcttexture                      );CHECKCGERROR
+                       }
                }
 
                CHECKGLERROR
@@ -8159,10 +8261,14 @@ extern cvar_t cl_locs_show;
 static void R_DrawLocs(void);
 static void R_DrawEntityBBoxes(void);
 static void R_DrawModelDecals(void);
+extern void R_DrawModelShadows(void);
+extern void R_DrawModelShadowMaps(void);
 extern cvar_t cl_decals_newsystem;
 extern qboolean r_shadow_usingdeferredprepass;
 void R_RenderScene(void)
 {
+       qboolean shadowmapping = false;
+
        r_refdef.stats.renders++;
 
        R_UpdateFogColor();
@@ -8212,6 +8318,9 @@ void R_RenderScene(void)
        if (r_timereport_active)
                R_TimeReport("preparelights");
 
+       if (R_Shadow_ShadowMappingEnabled())
+               shadowmapping = true;
+
        if (r_shadow_usingdeferredprepass)
                R_Shadow_DrawPrepass();
 
@@ -8228,6 +8337,15 @@ void R_RenderScene(void)
                        R_TimeReport("modeldepth");
        }
 
+       if (r_shadows.integer > 0 && shadowmapping && r_refdef.lightmapintensity > 0)
+       {
+               R_DrawModelShadowMaps();
+               R_ResetViewRendering3D();
+               // don't let sound skip if going slow
+               if (r_refdef.scene.extraupdate)
+                       S_ExtraUpdate ();
+       }
+
        if (cl.csqc_vidvars.drawworld && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->Draw)
        {
                r_refdef.scene.worldmodel->Draw(r_refdef.scene.worldentity);
@@ -8247,7 +8365,7 @@ void R_RenderScene(void)
        if (r_refdef.scene.extraupdate)
                S_ExtraUpdate ();
 
-       if (r_shadows.integer > 0 && !r_shadows_drawafterrtlighting.integer && r_refdef.lightmapintensity > 0)
+       if (r_shadows.integer > 0 && !shadowmapping && !r_shadows_drawafterrtlighting.integer && r_refdef.lightmapintensity > 0)
        {
                R_DrawModelShadows();
                R_ResetViewRendering3D();
@@ -8267,7 +8385,7 @@ void R_RenderScene(void)
        if (r_refdef.scene.extraupdate)
                S_ExtraUpdate ();
 
-       if (r_shadows.integer > 0 && r_shadows_drawafterrtlighting.integer && r_refdef.lightmapintensity > 0)
+       if (r_shadows.integer > 0 && !shadowmapping && r_shadows_drawafterrtlighting.integer && r_refdef.lightmapintensity > 0)
        {
                R_DrawModelShadows();
                R_ResetViewRendering3D();
index 7c16c17ec3afa41b25c45ad696b093da2a4a7cd0..734c43e4e01c4cac8c9e2f53877dbd48b9fd62c5 100644 (file)
@@ -180,6 +180,7 @@ r_shadow_rendermode_t r_shadow_shadowingrendermode_zfail = R_SHADOW_RENDERMODE_N
 qboolean r_shadow_usingshadowmaprect;
 qboolean r_shadow_usingshadowmap2d;
 qboolean r_shadow_usingshadowmapcube;
+qboolean r_shadow_usingshadowmaportho;
 int r_shadow_shadowmapside;
 float r_shadow_shadowmap_texturescale[2];
 float r_shadow_shadowmap_parameters[4];
@@ -200,6 +201,7 @@ qboolean r_shadow_shadowmapvsdct;
 qboolean r_shadow_shadowmapsampler;
 int r_shadow_shadowmappcf;
 int r_shadow_shadowmapborder;
+matrix4x4_t r_shadow_shadowmapmatrix;
 int r_shadow_lightscissor[4];
 qboolean r_shadow_usingdeferredprepass;
 
@@ -449,6 +451,19 @@ void R_Shadow_SetShadowMode(void)
        }
 }
 
+qboolean R_Shadow_ShadowMappingEnabled(void)
+{
+       switch (r_shadow_shadowmode)
+       {
+       case R_SHADOW_SHADOWMODE_SHADOWMAP2D:
+       case R_SHADOW_SHADOWMODE_SHADOWMAPRECTANGLE:
+       case R_SHADOW_SHADOWMODE_SHADOWMAPCUBESIDE:
+               return true;
+       default:
+               return false;
+       }
+}
+
 void R_Shadow_FreeShadowMaps(void)
 {
        int i;
@@ -490,6 +505,8 @@ void R_Shadow_FreeShadowMaps(void)
        r_shadow_shadowmapvsdcttexture = NULL;
 
        CHECKGLERROR
+
+       r_shadow_usingshadowmaportho = false;
 }
 
 void r_shadow_start(void)
@@ -2086,6 +2103,7 @@ void R_Shadow_RenderMode_ShadowMap(int side, int clear, int size)
 {
        float nearclip, farclip, bias;
        r_viewport_t viewport;
+       int flipped;
        GLuint fbo = 0;
        CHECKGLERROR
        nearclip = r_shadow_shadowmapping_nearclip.value / rsurface.rtlight->radius;
@@ -2170,9 +2188,11 @@ void R_Shadow_RenderMode_ShadowMap(int side, int clear, int size)
 
 init_done:
        R_SetViewport(&viewport);
-       if(r_shadow_rendermode == R_SHADOW_RENDERMODE_SHADOWMAP2D || r_shadow_rendermode == R_SHADOW_RENDERMODE_SHADOWMAPRECTANGLE)
+       switch (r_shadow_rendermode)
        {
-               int flipped = (side & 1) ^ (side >> 2);
+       case R_SHADOW_RENDERMODE_SHADOWMAP2D:
+       case R_SHADOW_RENDERMODE_SHADOWMAPRECTANGLE:
+               flipped = (side & 1) ^ (side >> 2);
                r_refdef.view.cullface_front = flipped ? r_shadow_cullface_back : r_shadow_cullface_front;
                r_refdef.view.cullface_back = flipped ? r_shadow_cullface_front : r_shadow_cullface_back;
                GL_CullFace(r_refdef.view.cullface_back);
@@ -2187,13 +2207,15 @@ init_done:
                        GL_Clear(GL_DEPTH_BUFFER_BIT);
                }
                GL_Scissor(viewport.x, viewport.y, viewport.width, viewport.height);
-       }
-       else if(r_shadow_rendermode == R_SHADOW_RENDERMODE_SHADOWMAPCUBESIDE)
-       {
+               break;
+       case R_SHADOW_RENDERMODE_SHADOWMAPCUBESIDE:
                qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + side, R_GetTexture(r_shadow_shadowmapcubetexture[r_shadow_shadowmaplod]), 0);CHECKGLERROR
                GL_Scissor(viewport.x, viewport.y, viewport.width, viewport.height);
                if (clear)
                        GL_Clear(GL_DEPTH_BUFFER_BIT);
+               break;
+       default:
+               break;
        }
        CHECKGLERROR
 }
@@ -2230,12 +2252,20 @@ void R_Shadow_RenderMode_Lighting(qboolean stenciltest, qboolean transparent, qb
        }
        if (shadowmapping)
        {
-               if (r_shadow_shadowmode == R_SHADOW_SHADOWMODE_SHADOWMAP2D)
+               switch (r_shadow_shadowmode)
+               {
+               case R_SHADOW_SHADOWMODE_SHADOWMAP2D:
                        r_shadow_usingshadowmap2d = true;
-               else if (r_shadow_shadowmode == R_SHADOW_SHADOWMODE_SHADOWMAPRECTANGLE)
+                       break;
+               case R_SHADOW_SHADOWMODE_SHADOWMAPRECTANGLE:
                        r_shadow_usingshadowmaprect = true;
-               else if (r_shadow_shadowmode == R_SHADOW_SHADOWMODE_SHADOWMAPCUBESIDE)
+                       break;
+               case R_SHADOW_SHADOWMODE_SHADOWMAPCUBESIDE:
                        r_shadow_usingshadowmapcube = true;
+                       break;
+               default:
+                       break;
+               }
        }
        R_Mesh_ColorPointer(rsurface.array_color4f, 0, 0);
        CHECKGLERROR
@@ -3345,12 +3375,17 @@ void R_Shadow_DrawEntityShadow(entity_render_t *ent)
        relativeshadowmaxs[0] = relativeshadoworigin[0] + relativeshadowradius;
        relativeshadowmaxs[1] = relativeshadoworigin[1] + relativeshadowradius;
        relativeshadowmaxs[2] = relativeshadoworigin[2] + relativeshadowradius;
-       if (r_shadow_rendermode == R_SHADOW_RENDERMODE_SHADOWMAPRECTANGLE || r_shadow_rendermode == R_SHADOW_RENDERMODE_SHADOWMAPCUBESIDE || r_shadow_rendermode == R_SHADOW_RENDERMODE_SHADOWMAP2D)
+       switch (r_shadow_rendermode)
        {
+       case R_SHADOW_RENDERMODE_SHADOWMAP2D:
+       case R_SHADOW_RENDERMODE_SHADOWMAPRECTANGLE:
+       case R_SHADOW_RENDERMODE_SHADOWMAPCUBESIDE:
                ent->model->DrawShadowMap(r_shadow_shadowmapside, ent, relativeshadoworigin, NULL, relativeshadowradius, ent->model->nummodelsurfaces, ent->model->sortedmodelsurfaces, NULL, relativeshadowmins, relativeshadowmaxs);
-       }
-       else
+               break;
+       default:
                ent->model->DrawShadowVolume(ent, relativeshadoworigin, NULL, relativeshadowradius, ent->model->nummodelsurfaces, ent->model->sortedmodelsurfaces, relativeshadowmins, relativeshadowmaxs);
+               break;
+       }
        rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
 }
 
@@ -4001,6 +4036,8 @@ void R_Shadow_PrepareLights(void)
                r_shadow_shadowmapborder != bound(0, r_shadow_shadowmapping_bordersize.integer, 16))
                R_Shadow_FreeShadowMaps();
 
+       r_shadow_usingshadowmaportho = false;
+
        switch (vid.renderpath)
        {
        case RENDERPATH_GL20:
@@ -4158,6 +4195,151 @@ extern cvar_t r_shadows_drawafterrtlighting;
 extern cvar_t r_shadows_castfrombmodels;
 extern cvar_t r_shadows_throwdistance;
 extern cvar_t r_shadows_throwdirection;
+
+void R_DrawModelShadowMaps(void)
+{
+       int i;
+       float relativethrowdistance, scale, size, nearclip, farclip, dot1, dot2;
+       entity_render_t *ent;
+       vec3_t relativelightorigin;
+       vec3_t relativelightdirection;
+       vec3_t relativeshadowmins, relativeshadowmaxs;
+       vec3_t shadowdir, shadowforward;
+       float m[12];
+       matrix4x4_t shadowmatrix, cameramatrix, mvpmatrix, invmvpmatrix;
+       r_viewport_t viewport;
+       GLuint fbo = 0;
+
+       if (!r_refdef.scene.numentities)
+               return;
+
+       switch (r_shadow_shadowmode)
+       {
+       case R_SHADOW_SHADOWMODE_SHADOWMAP2D:
+       case R_SHADOW_SHADOWMODE_SHADOWMAPRECTANGLE:
+               break;
+       default:
+               return;
+       }
+
+       CHECKGLERROR
+       R_ResetViewRendering3D();
+       R_Shadow_RenderMode_Begin();
+       R_Shadow_RenderMode_ActiveLight(NULL);
+
+       switch (r_shadow_shadowmode)
+       {
+       case R_SHADOW_SHADOWMODE_SHADOWMAP2D:
+               if (!r_shadow_shadowmap2dtexture)
+                       R_Shadow_MakeShadowMap(0, r_shadow_shadowmapmaxsize);
+               fbo = r_shadow_fbo2d;
+               r_shadow_shadowmap_texturescale[0] = 1.0f / R_TextureWidth(r_shadow_shadowmap2dtexture);
+               r_shadow_shadowmap_texturescale[1] = 1.0f / R_TextureHeight(r_shadow_shadowmap2dtexture);
+               r_shadow_rendermode = R_SHADOW_RENDERMODE_SHADOWMAP2D;
+               break;
+       case R_SHADOW_SHADOWMODE_SHADOWMAPRECTANGLE:
+               if (!r_shadow_shadowmaprectangletexture)
+                       R_Shadow_MakeShadowMap(0, r_shadow_shadowmapmaxsize);
+               fbo = r_shadow_fborectangle;
+               r_shadow_shadowmap_texturescale[0] = 1.0f;
+               r_shadow_shadowmap_texturescale[1] = 1.0f;
+               r_shadow_rendermode = R_SHADOW_RENDERMODE_SHADOWMAPRECTANGLE;
+               break;
+       default:
+               break;
+       }
+
+       size = 2*r_shadow_shadowmapmaxsize;
+
+       r_shadow_shadowmap_parameters[0] = bound(0.0f, 1.0f - r_shadows_darken.value, 1.0f);
+       r_shadow_shadowmap_parameters[1] = 1.0f;
+       r_shadow_shadowmap_parameters[2] = size;
+       r_shadow_shadowmap_parameters[3] = size;
+
+       scale = r_shadow_shadowmapping_precision.value;
+       nearclip = -r_shadows_throwdistance.value;
+       farclip = r_shadows_throwdistance.value;
+       Math_atov(r_shadows_throwdirection.string, shadowdir);
+       VectorNormalize(shadowdir);
+       dot1 = DotProduct(r_refdef.view.forward, shadowdir);
+       dot2 = DotProduct(r_refdef.view.up, shadowdir);
+       if (fabs(dot1) <= fabs(dot2)) 
+               VectorMA(r_refdef.view.forward, -dot1, shadowdir, shadowforward);
+       else
+               VectorMA(r_refdef.view.up, -dot2, shadowdir, shadowforward);
+       VectorNormalize(shadowforward);
+       VectorM(scale, shadowforward, &m[0]);
+       m[3] = fabs(dot1) * 0.5f * size - DotProduct(r_refdef.view.origin, &m[0]);
+       CrossProduct(shadowdir, shadowforward, &m[4]);
+       VectorM(scale, &m[4], &m[4]);
+       m[7] = 0.5f * size - DotProduct(r_refdef.view.origin, &m[4]);
+       VectorM(1.0f / (farclip - nearclip), shadowdir, &m[8]);
+       m[11] = 0.5f - DotProduct(r_refdef.view.origin, &m[8]);
+       Matrix4x4_FromArray12FloatD3D(&shadowmatrix, m);
+       Matrix4x4_Invert_Full(&cameramatrix, &shadowmatrix);
+       R_Viewport_InitOrtho(&viewport, &cameramatrix, 0, 0, size, size, 0, size, size, 0, 0, -1, NULL); 
+
+#if 0
+       qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);CHECKGLERROR
+       R_SetupShader_ShowDepth();
+#else
+       qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);CHECKGLERROR
+       R_SetupShader_DepthOrShadow();
+#endif
+       CHECKGLERROR
+       GL_PolygonOffset(r_shadow_shadowmapping_polygonfactor.value, r_shadow_shadowmapping_polygonoffset.value);
+       GL_DepthMask(true);
+       GL_DepthTest(true);
+       R_SetViewport(&viewport);
+       GL_Scissor(viewport.x, viewport.y, viewport.width + r_shadow_shadowmapborder, viewport.height + r_shadow_shadowmapborder);
+       qglClearDepth(1);
+#if 0
+       qglClearColor(1,1,1,1);
+       GL_Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+#else
+       GL_Clear(GL_DEPTH_BUFFER_BIT);
+#endif
+       GL_Scissor(viewport.x + r_shadow_shadowmapborder, viewport.y + r_shadow_shadowmapborder, viewport.width - 2*r_shadow_shadowmapborder, viewport.height - 2*r_shadow_shadowmapborder);
+       CHECKGLERROR
+
+       for (i = 0;i < r_refdef.scene.numentities;i++)
+       {
+               ent = r_refdef.scene.entities[i];
+
+               // cast shadows from anything of the map (submodels are optional)
+               if (ent->model && ent->model->DrawShadowMap != NULL && (!ent->model->brush.submodel || r_shadows_castfrombmodels.integer) && (ent->flags & RENDER_SHADOW))
+               {
+                       relativethrowdistance = r_shadows_throwdistance.value * Matrix4x4_ScaleFromMatrix(&ent->inversematrix);
+                       VectorSet(relativeshadowmins, -relativethrowdistance, -relativethrowdistance, -relativethrowdistance);
+                       VectorSet(relativeshadowmaxs, relativethrowdistance, relativethrowdistance, relativethrowdistance);
+                       Matrix4x4_Transform3x3(&ent->inversematrix, shadowdir, relativelightdirection);
+                       VectorScale(relativelightdirection, -relativethrowdistance, relativelightorigin);
+                       RSurf_ActiveModelEntity(ent, false, false, false);
+                       ent->model->DrawShadowMap(0, ent, relativelightorigin, relativelightdirection, relativethrowdistance, ent->model->nummodelsurfaces, ent->model->sortedmodelsurfaces, NULL, relativeshadowmins, relativeshadowmaxs);
+                       rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
+               }
+       }
+
+       R_Shadow_RenderMode_End();
+
+       Matrix4x4_Concat(&mvpmatrix, &r_refdef.view.viewport.projectmatrix, &r_refdef.view.viewport.viewmatrix);
+       Matrix4x4_Invert_Full(&invmvpmatrix, &mvpmatrix);
+       Matrix4x4_Concat(&r_shadow_shadowmapmatrix, &shadowmatrix, &invmvpmatrix);
+
+       r_shadow_usingshadowmaportho = true;
+       switch (r_shadow_shadowmode)
+       {
+       case R_SHADOW_SHADOWMODE_SHADOWMAP2D:
+               r_shadow_usingshadowmap2d = true;
+               break;
+       case R_SHADOW_SHADOWMODE_SHADOWMAPRECTANGLE:
+               r_shadow_usingshadowmaprect = true;
+               break;
+       default:
+               break;
+       }
+}
+
 void R_DrawModelShadows(void)
 {
        int i;
@@ -4168,7 +4350,7 @@ void R_DrawModelShadows(void)
        vec3_t relativeshadowmins, relativeshadowmaxs;
        vec3_t tmp, shadowdir;
 
-       if (!r_refdef.scene.numentities || !vid.stencil)
+       if (!r_refdef.scene.numentities || !vid.stencil || r_shadow_shadowmode != R_SHADOW_SHADOWMODE_STENCIL)
                return;
 
        CHECKGLERROR
index ac32dc3359ac5f82ab23a4c0ca76221a96bf821c..93ccb2bd1e933409055bc1d1adeeaa8778980f09 100644 (file)
@@ -38,6 +38,7 @@ extern cvar_t gl_ext_separatestencil;
 extern cvar_t gl_ext_stenciltwoside;
 
 void R_Shadow_Init(void);
+qboolean R_Shadow_ShadowMappingEnabled(void);
 void R_Shadow_VolumeFromList(int numverts, int numtris, const float *invertex3f, const int *elements, const int *neighbors, const vec3_t projectorigin, const vec3_t projectdirection, float projectdistance, int nummarktris, const int *marktris, vec3_t trismins, vec3_t trismaxs);
 void R_Shadow_ShadowMapFromList(int numverts, int numtris, const float *vertex3f, const int *elements, int numsidetris, const int *sidetotals, const unsigned char *sides, const int *sidetris);
 void R_Shadow_MarkVolumeFromBox(int firsttriangle, int numtris, const float *invertex3f, const int *elements, const vec3_t projectorigin, const vec3_t projectdirection, const vec3_t lightmins, const vec3_t lightmaxs, const vec3_t surfacemins, const vec3_t surfacemaxs);