From 5faa9f314b5c676160899535e7bc60c342e2915e Mon Sep 17 00:00:00 2001 From: eihrul Date: Fri, 2 Oct 2009 04:47:56 +0000 Subject: [PATCH] added cvar r_shadow_shadowmapping_precision to control minimum shadowmap depth precision git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9277 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_textures.c | 29 +++++++++++++++++++++-------- r_shadow.c | 12 +++++++++--- r_textures.h | 12 +++++++----- 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/gl_textures.c b/gl_textures.c index e0c9720c..a9a8de18 100644 --- a/gl_textures.c +++ b/gl_textures.c @@ -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) diff --git a/r_shadow.c b/r_shadow.c index 16528cb7..3f09a41e 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -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(); diff --git a/r_textures.h b/r_textures.h index d43be404..ec2da990 100644 --- a/r_textures.h +++ b/r_textures.h @@ -24,8 +24,10 @@ #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); -- 2.39.2