]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
added cvar r_shadow_shadowmapping_precision to control minimum shadowmap depth precision
authoreihrul <eihrul@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 2 Oct 2009 04:47:56 +0000 (04:47 +0000)
committereihrul <eihrul@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 2 Oct 2009 04:47:56 +0000 (04:47 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9277 d7cf8633-e32d-0410-b094-e92efae38249

gl_textures.c
r_shadow.c
r_textures.h

index e0c9720c526896211272f85448de153ad89c08d6..a9a8de183c107e673db0983151375fad8efe6789 100644 (file)
@@ -60,7 +60,8 @@ static textypeinfo_t textype_bgra                   = {TEXTYPE_BGRA   , 4, 4, 4.
 static textypeinfo_t textype_bgra_alpha             = {TEXTYPE_BGRA   , 4, 4, 4.0f, GL_BGRA   , 4, GL_UNSIGNED_BYTE};
 static textypeinfo_t textype_bgra_compress          = {TEXTYPE_BGRA   , 4, 4, 0.5f, GL_BGRA   , GL_COMPRESSED_RGB_ARB, GL_UNSIGNED_BYTE};
 static textypeinfo_t textype_bgra_alpha_compress    = {TEXTYPE_BGRA   , 4, 4, 1.0f, GL_BGRA   , GL_COMPRESSED_RGBA_ARB, GL_UNSIGNED_BYTE};
-static textypeinfo_t textype_shadowmap              = {TEXTYPE_SHADOWMAP,4,4, 4.0f, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT24_ARB, GL_UNSIGNED_INT};
+static textypeinfo_t textype_shadowmap16            = {TEXTYPE_SHADOWMAP,2,2, 2.0f, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT16_ARB, GL_UNSIGNED_SHORT};
+static textypeinfo_t textype_shadowmap24            = {TEXTYPE_SHADOWMAP,4,4, 4.0f, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT24_ARB, GL_UNSIGNED_INT};
 
 typedef enum gltexturetype_e
 {
@@ -217,7 +218,7 @@ static textypeinfo_t *R_GetTexTypeInfo(textype_t textype, int flags)
                        case TEXTYPE_BGRA:
                                return &textype_bgra;
                        case TEXTYPE_SHADOWMAP:
-                               return &textype_shadowmap;
+                               return (flags & TEXF_LOWPRECISION) ? &textype_shadowmap16 : &textype_shadowmap24;
                        default:
                                Host_Error("R_GetTexTypeInfo: unknown texture format");
                                return NULL;
@@ -1130,19 +1131,31 @@ rtexture_t *R_LoadTextureCubeMap(rtexturepool_t *rtexturepool, const char *ident
        return R_SetupTexture(rtexturepool, identifier, width, width, 1, 6, flags, textype, GLTEXTURETYPE_CUBEMAP, data, palette);
 }
 
-rtexture_t *R_LoadTextureShadowMapRectangle(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, qboolean filter)
+static int R_ShadowMapTextureFlags(int precision, qboolean filter)
 {
-       return R_SetupTexture(rtexturepool, identifier, width, height, 1, 1, TEXF_ALWAYSPRECACHE | TEXF_CLAMP | (filter ? TEXF_FORCELINEAR | TEXF_COMPARE : TEXF_FORCENEAREST), TEXTYPE_SHADOWMAP, GLTEXTURETYPE_RECTANGLE, NULL, NULL);
+       int flags = TEXF_ALWAYSPRECACHE | TEXF_CLAMP;
+       if (filter)
+               flags |= TEXF_FORCELINEAR | TEXF_COMPARE;
+       else
+               flags |= TEXF_FORCENEAREST;
+       if (precision <= 16)
+               flags |= TEXF_LOWPRECISION;
+       return flags;
+}
+
+rtexture_t *R_LoadTextureShadowMapRectangle(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int precision, qboolean filter)
+{
+       return R_SetupTexture(rtexturepool, identifier, width, height, 1, 1, R_ShadowMapTextureFlags(precision, filter), TEXTYPE_SHADOWMAP, GLTEXTURETYPE_RECTANGLE, NULL, NULL);
 }
 
-rtexture_t *R_LoadTextureShadowMap2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, qboolean filter)
+rtexture_t *R_LoadTextureShadowMap2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int precision, qboolean filter)
 {
-       return R_SetupTexture(rtexturepool, identifier, width, height, 1, 1, TEXF_ALWAYSPRECACHE | TEXF_CLAMP | (filter ? TEXF_FORCELINEAR | TEXF_COMPARE : TEXF_FORCENEAREST), TEXTYPE_SHADOWMAP, GLTEXTURETYPE_2D, NULL, NULL);
+       return R_SetupTexture(rtexturepool, identifier, width, height, 1, 1, R_ShadowMapTextureFlags(precision, filter), TEXTYPE_SHADOWMAP, GLTEXTURETYPE_2D, NULL, NULL);
 }
 
-rtexture_t *R_LoadTextureShadowMapCube(rtexturepool_t *rtexturepool, const char *identifier, int width, qboolean filter)
+rtexture_t *R_LoadTextureShadowMapCube(rtexturepool_t *rtexturepool, const char *identifier, int width, int precision, qboolean filter)
 {
-    return R_SetupTexture(rtexturepool, identifier, width, width, 1, 6, TEXF_ALWAYSPRECACHE | TEXF_CLAMP | (filter ? TEXF_FORCELINEAR | TEXF_COMPARE : TEXF_FORCENEAREST), TEXTYPE_SHADOWMAP, GLTEXTURETYPE_CUBEMAP, NULL, NULL);
+    return R_SetupTexture(rtexturepool, identifier, width, width, 1, 6, R_ShadowMapTextureFlags(precision, filter), TEXTYPE_SHADOWMAP, GLTEXTURETYPE_CUBEMAP, NULL, NULL);
 }
 
 int R_TextureHasAlpha(rtexture_t *rt)
index 16528cb75d763b0c7aa9c7e013c682d8b8e7f007..3f09a41e35ecec15aa98aff2727936d6062e4b9c 100644 (file)
@@ -181,6 +181,7 @@ GLuint r_shadow_fbo2d;
 int r_shadow_shadowmode;
 int r_shadow_shadowmapfilterquality;
 int r_shadow_shadowmaptexturetype;
+int r_shadow_shadowmapprecision;
 int r_shadow_shadowmapmaxsize;
 qboolean r_shadow_shadowmapvsdct;
 qboolean r_shadow_shadowmapsampler;
@@ -268,6 +269,7 @@ cvar_t r_shadow_scissor = {0, "r_shadow_scissor", "1", "use scissor optimization
 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_texturetype = {CVAR_SAVE, "r_shadow_shadowmapping_texturetype", "0", "shadowmap texture types: 0 = auto-select, 1 = 2D, 2 = rectangle, 3 = cubemap"};
 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)"};
+cvar_t r_shadow_shadowmapping_precision = {CVAR_SAVE, "r_shadow_shadowmapping_precision", "24", "requested minimum shadowmap texture precision"};
 cvar_t r_shadow_shadowmapping_vsdct = {CVAR_SAVE, "r_shadow_shadowmapping_vsdct", "1", "enables use of virtual shadow depth cube texture"};
 cvar_t r_shadow_shadowmapping_minsize = {CVAR_SAVE, "r_shadow_shadowmapping_minsize", "32", "shadowmap size limit"};
 cvar_t r_shadow_shadowmapping_maxsize = {CVAR_SAVE, "r_shadow_shadowmapping_maxsize", "512", "shadowmap size limit"};
@@ -348,6 +350,7 @@ void R_Shadow_SetShadowMode(void)
        r_shadow_shadowmapvsdct = r_shadow_shadowmapping_vsdct.integer != 0;
        r_shadow_shadowmapfilterquality = r_shadow_shadowmapping_filterquality.integer;
        r_shadow_shadowmaptexturetype = r_shadow_shadowmapping_texturetype.integer;
+       r_shadow_shadowmapprecision = r_shadow_shadowmapping_precision.integer;
        r_shadow_shadowmapborder = bound(0, r_shadow_shadowmapping_bordersize.integer, 16);
        r_shadow_shadowmaplod = -1;
        r_shadow_shadowmapsampler = false;
@@ -459,6 +462,7 @@ void r_shadow_start(void)
        r_shadow_shadowmaplod = 0;
        r_shadow_shadowmapfilterquality = 0;
        r_shadow_shadowmaptexturetype = 0;
+       r_shadow_shadowmapprecision = 0;
        r_shadow_shadowmapvsdct = false;
        r_shadow_shadowmapsampler = false;
        r_shadow_shadowmappcf = 0;
@@ -636,6 +640,7 @@ void R_Shadow_Init(void)
        Cvar_RegisterVariable(&r_shadow_shadowmapping_vsdct);
        Cvar_RegisterVariable(&r_shadow_shadowmapping_texturetype);
        Cvar_RegisterVariable(&r_shadow_shadowmapping_filterquality);
+       Cvar_RegisterVariable(&r_shadow_shadowmapping_precision);
        Cvar_RegisterVariable(&r_shadow_shadowmapping_maxsize);
        Cvar_RegisterVariable(&r_shadow_shadowmapping_minsize);
        Cvar_RegisterVariable(&r_shadow_shadowmapping_lod_bias);
@@ -1578,7 +1583,7 @@ void R_Shadow_RenderMode_ShadowMap(int side, qboolean clear, int size)
                {
 #if 1
                        int w = maxsize*2, h = gl_support_arb_texture_non_power_of_two ? maxsize*3 : maxsize*4;
-                       r_shadow_shadowmap2dtexture = R_LoadTextureShadowMap2D(r_shadow_texturepool, "shadowmap", w, h, r_shadow_shadowmapsampler);
+                       r_shadow_shadowmap2dtexture = R_LoadTextureShadowMap2D(r_shadow_texturepool, "shadowmap", w, h, r_shadow_shadowmapprecision, r_shadow_shadowmapsampler);
                        qglGenFramebuffersEXT(1, &r_shadow_fbo2d);CHECKGLERROR
                        qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, r_shadow_fbo2d);CHECKGLERROR
                        qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, R_GetTexture(r_shadow_shadowmap2dtexture), 0);CHECKGLERROR
@@ -1620,7 +1625,7 @@ void R_Shadow_RenderMode_ShadowMap(int side, qboolean clear, int size)
                if (!r_shadow_shadowmaprectangletexture)
                {
 #if 1
-                       r_shadow_shadowmaprectangletexture = R_LoadTextureShadowMapRectangle(r_shadow_texturepool, "shadowmap", maxsize*2, maxsize*3, r_shadow_shadowmapsampler);
+                       r_shadow_shadowmaprectangletexture = R_LoadTextureShadowMapRectangle(r_shadow_texturepool, "shadowmap", maxsize*2, maxsize*3, r_shadow_shadowmapprecision, r_shadow_shadowmapsampler);
                        qglGenFramebuffersEXT(1, &r_shadow_fborectangle);CHECKGLERROR
                        qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, r_shadow_fborectangle);CHECKGLERROR
                        qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, R_GetTexture(r_shadow_shadowmaprectangletexture), 0);CHECKGLERROR
@@ -1660,7 +1665,7 @@ void R_Shadow_RenderMode_ShadowMap(int side, qboolean clear, int size)
                if (!r_shadow_shadowmapcubetexture[r_shadow_shadowmaplod])
                {
  #if 1
-                       r_shadow_shadowmapcubetexture[r_shadow_shadowmaplod] = R_LoadTextureShadowMapCube(r_shadow_texturepool, "shadowmapcube", bound(1, maxsize >> r_shadow_shadowmaplod, 2048), r_shadow_shadowmapsampler);
+                       r_shadow_shadowmapcubetexture[r_shadow_shadowmaplod] = R_LoadTextureShadowMapCube(r_shadow_texturepool, "shadowmapcube", size, r_shadow_shadowmapprecision, r_shadow_shadowmapsampler);
                        qglGenFramebuffersEXT(6, r_shadow_fbocubeside[r_shadow_shadowmaplod]);CHECKGLERROR
                        for (i = 0;i < 6;i++)
                        {
@@ -3915,6 +3920,7 @@ void R_ShadowVolumeLighting(qboolean visible)
                r_shadow_shadowmapvsdct != (r_shadow_shadowmapping_vsdct.integer != 0) || 
                r_shadow_shadowmaptexturetype != r_shadow_shadowmapping_texturetype.integer ||
                r_shadow_shadowmapfilterquality != r_shadow_shadowmapping_filterquality.integer || 
+               r_shadow_shadowmapprecision != r_shadow_shadowmapping_precision.integer || 
                r_shadow_shadowmapborder != bound(0, r_shadow_shadowmapping_bordersize.integer, 16))
                R_Shadow_FreeShadowMaps();
 
index d43be40403209f9efe9231ee5107f601ee039c4d..ec2da990d004db2040aadd88d69612b2a2c68a3e 100644 (file)
 #define TEXF_PERSISTENT 0x00000400
 // indicates texture should use GL_COMPARE_R_TO_TEXTURE mode
 #define TEXF_COMPARE 0x00000800
+// indicates texture should use lower precision where supported
+#define TEXF_LOWPRECISION 0x00001000
 // used for checking if textures mismatch
-#define TEXF_IMPORTANTBITS (TEXF_ALPHA | TEXF_MIPMAP | TEXF_CLAMP | TEXF_FORCENEAREST | TEXF_FORCELINEAR | TEXF_PICMIP | TEXF_COMPRESS | TEXF_COMPARE)
+#define TEXF_IMPORTANTBITS (TEXF_ALPHA | TEXF_MIPMAP | TEXF_CLAMP | TEXF_FORCENEAREST | TEXF_FORCELINEAR | TEXF_PICMIP | TEXF_COMPRESS | TEXF_COMPARE | TEXF_LOWPRECISION)
 
 typedef enum textype_e
 {
@@ -35,7 +37,7 @@ typedef enum textype_e
        TEXTYPE_RGBA,
        // 32bit BGRA (preferred format due to faster uploads on most hardware)
        TEXTYPE_BGRA,
-       // 32bit S8D24 (24bit depth, 8bit stencil unused)
+       // 16bit D16 (16bit depth) or 32bit S8D24 (24bit depth, 8bit stencil unused)
        TEXTYPE_SHADOWMAP,
 }
 textype_t;
@@ -81,9 +83,9 @@ rtexture_t *R_LoadTexture1D(rtexturepool_t *rtexturepool, const char *identifier
 rtexture_t *R_LoadTexture2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, const unsigned char *data, textype_t textype, int flags, const unsigned int *palette);
 rtexture_t *R_LoadTexture3D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int depth, const unsigned char *data, textype_t textype, int flags, const unsigned int *palette);
 rtexture_t *R_LoadTextureCubeMap(rtexturepool_t *rtexturepool, const char *identifier, int width, const unsigned char *data, textype_t textype, int flags, const unsigned int *palette);
-rtexture_t *R_LoadTextureShadowMapRectangle(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, qboolean filter);
-rtexture_t *R_LoadTextureShadowMap2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, qboolean filter);
-rtexture_t *R_LoadTextureShadowMapCube(rtexturepool_t *rtexturepool, const char *identifier, int width, qboolean filter);
+rtexture_t *R_LoadTextureShadowMapRectangle(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int precision, qboolean filter);
+rtexture_t *R_LoadTextureShadowMap2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int precision, qboolean filter);
+rtexture_t *R_LoadTextureShadowMapCube(rtexturepool_t *rtexturepool, const char *identifier, int width, int precision, qboolean filter);
 
 // free a texture
 void R_FreeTexture(rtexture_t *rt);