From 3190d8a82f7eae2fab0baaa38e5353a5e6909bf4 Mon Sep 17 00:00:00 2001 From: havoc Date: Thu, 17 Nov 2005 15:17:14 +0000 Subject: [PATCH] made gl_max_size cvar only affect TEXF_PICMIP textures, this prevents it from breaking bloom like it did previously, and bloom now disables itself if the hardware doesn't support big enough textures (such as 3Dfx Voodoo1/2/3/Rush/Banshee) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@5810 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_rmain.c | 25 ++++++---- gl_textures.c | 128 +++++++++++++++++++++++++++----------------------- glquake.h | 4 ++ r_textures.h | 2 +- vid_shared.c | 15 +++++- 5 files changed, 104 insertions(+), 70 deletions(-) diff --git a/gl_rmain.c b/gl_rmain.c index 9373aa1a..0b719b97 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -746,9 +746,21 @@ static void R_SetFrustum(void) static void R_BlendView(void) { + int screenwidth, screenheight; + qboolean dobloom; + qboolean doblend; rmeshstate_t m; - if (r_refdef.viewblend[3] < 0.01f && !r_bloom.integer) + // set the (poorly named) screenwidth and screenheight variables to + // a power of 2 at least as large as the screen, these will define the + // size of the texture to allocate + for (screenwidth = 1;screenwidth < vid.width;screenwidth *= 2); + for (screenheight = 1;screenheight < vid.height;screenheight *= 2); + + doblend = r_refdef.viewblend[3] >= 0.01f; + dobloom = r_bloom.integer && screenwidth <= gl_max_texture_size && screenheight <= gl_max_texture_size && r_bloom_resolution.value >= 32 && r_bloom_power.integer >= 1 && r_bloom_power.integer < 100 && r_bloom_blur.value >= 0 && r_bloom_blur.value < 512; + + if (!dobloom && !doblend) return; GL_SetupView_Mode_Ortho(0, 0, 1, 1, -10, 100); @@ -760,16 +772,11 @@ static void R_BlendView(void) varray_vertex3f[3] = 1;varray_vertex3f[4] = 0;varray_vertex3f[5] = 0; varray_vertex3f[6] = 1;varray_vertex3f[7] = 1;varray_vertex3f[8] = 0; varray_vertex3f[9] = 0;varray_vertex3f[10] = 1;varray_vertex3f[11] = 0; - if (r_bloom.integer && r_bloom_resolution.value >= 32 && r_bloom_power.integer >= 1 && r_bloom_power.integer < 100 && r_bloom_blur.value >= 0 && r_bloom_blur.value < 512) + if (dobloom) { - int screenwidth, screenheight, bloomwidth, bloomheight, x, dobloomblend, range; + int bloomwidth, bloomheight, x, dobloomblend, range; float xoffset, yoffset, r; renderstats.bloom++; - // set the (poorly named) screenwidth and screenheight variables to - // a power of 2 at least as large as the screen, these will define the - // size of the texture to allocate - for (screenwidth = 1;screenwidth < vid.width;screenwidth *= 2); - for (screenheight = 1;screenheight < vid.height;screenheight *= 2); // allocate textures as needed if (!r_bloom_texture_screen) r_bloom_texture_screen = R_LoadTexture2D(r_main_texturepool, "screen", screenwidth, screenheight, NULL, TEXTYPE_RGBA, TEXF_FORCENEAREST | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL); @@ -940,7 +947,7 @@ static void R_BlendView(void) renderstats.bloom_drawpixels += r_view_width * r_view_height; } } - if (r_refdef.viewblend[3] >= 0.01f) + if (doblend) { // apply a color tint to the whole view memset(&m, 0, sizeof(m)); diff --git a/gl_textures.c b/gl_textures.c index 537438fa..9fe27447 100644 --- a/gl_textures.c +++ b/gl_textures.c @@ -136,8 +136,6 @@ static int resizebuffersize = 0; static unsigned char *texturebuffer; static int texturebuffersize = 0; -static int realmaxsize = 0; - static textypeinfo_t *R_GetTexTypeInfo(int textype, int flags) { if ((flags & (TEXF_PICMIP | TEXF_FRAGMENT)) == (TEXF_PICMIP | TEXF_FRAGMENT)) @@ -365,50 +363,81 @@ static void GL_TextureMode_f (void) } } +static void GL_Texture_CalcImageSize(int texturetype, int flags, int inwidth, int inheight, int indepth, int *outwidth, int *outheight, int *outdepth) +{ + int picmip = 0, maxsize = 0, width2 = 1, height2 = 1, depth2 = 1; + + if (gl_max_size.integer > gl_max_texture_size) + Cvar_SetValue("gl_max_size", gl_max_texture_size); + + switch (texturetype) + { + default: + case GLTEXTURETYPE_1D: + case GLTEXTURETYPE_2D: + maxsize = gl_max_texture_size; + break; + case GLTEXTURETYPE_3D: + maxsize = gl_max_3d_texture_size; + break; + case GLTEXTURETYPE_CUBEMAP: + maxsize = gl_max_cube_map_texture_size; + break; + } + + if (flags & TEXF_PICMIP) + { + maxsize = min(maxsize, gl_max_size.integer); + picmip = gl_picmip.integer; + } + + if (outwidth) + { + for (width2 = 1;width2 < inwidth;width2 <<= 1); + for (width2 >>= picmip;width2 > maxsize;width2 >>= 1); + *outwidth = max(1, width2); + } + if (outheight) + { + for (height2 = 1;height2 < inheight;height2 <<= 1); + for (height2 >>= picmip;height2 > maxsize;height2 >>= 1); + *outheight = max(1, height2); + } + if (outdepth) + { + for (depth2 = 1;depth2 < indepth;depth2 <<= 1); + for (depth2 >>= picmip;depth2 > maxsize;depth2 >>= 1); + *outdepth = max(1, depth2); + } +} + + static int R_CalcTexelDataSize (gltexture_t *glt) { - int width2, height2, depth2, size, picmip; + int width2, height2, depth2, size; + if (glt->flags & TEXF_FRAGMENT) - size = glt->width * glt->height * glt->depth; - else + return glt->width * glt->height * glt->depth * glt->textype->internalbytesperpixel * glt->image->sides; + + GL_Texture_CalcImageSize(glt->texturetype, glt->flags, glt->width, glt->height, glt->depth, &width2, &height2, &depth2); + + size = width2 * height2 * depth2; + + if (glt->flags & TEXF_MIPMAP) { - picmip = 0; - if (glt->flags & TEXF_PICMIP) - picmip = gl_picmip.integer; - if (gl_max_size.integer > realmaxsize) - Cvar_SetValue("gl_max_size", realmaxsize); - // calculate final size - for (width2 = 1;width2 < glt->width;width2 <<= 1); - for (height2 = 1;height2 < glt->height;height2 <<= 1); - for (depth2 = 1;depth2 < glt->depth;depth2 <<= 1); - for (width2 >>= picmip;width2 > gl_max_size.integer;width2 >>= 1); - for (height2 >>= picmip;height2 > gl_max_size.integer;height2 >>= 1); - for (depth2 >>= picmip;depth2 > gl_max_size.integer;depth2 >>= 1); - if (width2 < 1) width2 = 1; - if (height2 < 1) height2 = 1; - if (depth2 < 1) depth2 = 1; - - size = 0; - if (glt->flags & TEXF_MIPMAP) + while (width2 > 1 || height2 > 1 || depth2 > 1) { - while (width2 > 1 || height2 > 1 || depth2 > 1) - { - size += width2 * height2 * depth2; - if (width2 > 1) - width2 >>= 1; - if (height2 > 1) - height2 >>= 1; - if (depth2 > 1) - depth2 >>= 1; - } - size++; // count the last 1x1 mipmap + if (width2 > 1) + width2 >>= 1; + if (height2 > 1) + height2 >>= 1; + if (depth2 > 1) + depth2 >>= 1; + size += width2 * height2 * depth2; } - else - size = width2 * height2 * depth2; } - size *= glt->textype->internalbytesperpixel * glt->image->sides; - return size; + return size * glt->textype->internalbytesperpixel * glt->image->sides; } void R_TextureStats_Print(qboolean printeach, qboolean printpool, qboolean printtotal) @@ -465,15 +494,12 @@ static void R_TextureStats_f(void) static void r_textures_start(void) { - // deal with size limits of various drivers (3dfx in particular) - qglGetIntegerv(GL_MAX_TEXTURE_SIZE, &realmaxsize); - CHECKGLERROR // LordHavoc: allow any alignment qglPixelStorei(GL_UNPACK_ALIGNMENT, 1); CHECKGLERROR // use the largest scrap texture size we can (not sure if this is really a good idea) - for (block_size = 1;block_size < realmaxsize && block_size < gl_max_scrapsize.integer;block_size <<= 1); + for (block_size = 1;block_size * 2 <= gl_max_texture_size && block_size * 2 <= gl_max_scrapsize.integer;block_size *= 2); texturemempool = Mem_AllocPool("texture management", 0, NULL); @@ -865,7 +891,7 @@ static void R_Upload(gltexture_t *glt, unsigned char *data) static void R_FindImageForTexture(gltexture_t *glt) { - int i, j, best, best2, x, y, z, w, h, d, picmip; + int i, j, best, best2, x, y, z, w, h, d; textypeinfo_t *texinfo; gltexturepool_t *pool; gltextureimage_t *image, **imagechainpointer; @@ -966,21 +992,7 @@ static void R_FindImageForTexture(gltexture_t *glt) image->type = GLIMAGETYPE_TILE; image->blockallocation = NULL; - picmip = 0; - if (glt->flags & TEXF_PICMIP) - picmip = gl_picmip.integer; - // calculate final size - if (gl_max_size.integer > realmaxsize) - Cvar_SetValue("gl_max_size", realmaxsize); - for (image->width = 1;image->width < glt->width;image->width <<= 1); - for (image->height = 1;image->height < glt->height;image->height <<= 1); - for (image->depth = 1;image->depth < glt->depth;image->depth <<= 1); - for (image->width >>= picmip;image->width > gl_max_size.integer;image->width >>= 1); - for (image->height >>= picmip;image->height > gl_max_size.integer;image->height >>= 1); - for (image->depth >>= picmip;image->depth > gl_max_size.integer;image->depth >>= 1); - if (image->width < 1) image->width = 1; - if (image->height < 1) image->height = 1; - if (image->depth < 1) image->depth = 1; + GL_Texture_CalcImageSize(glt->texturetype, glt->flags, glt->width, glt->height, glt->depth, &image->width, &image->height, &image->depth); } image->texturetype = glt->texturetype; image->glinternalformat = texinfo->glinternalformat; diff --git a/glquake.h b/glquake.h index 20f2b6d0..764fe465 100644 --- a/glquake.h +++ b/glquake.h @@ -224,6 +224,8 @@ extern int gl_max_anisotropy; #define GL_POLYGON_SMOOTH 0x0B41 #endif +extern int gl_max_texture_size; + // GL_ARB_multitexture extern int gl_textureunits; extern void (GLAPIENTRY *qglMultiTexCoord1f) (GLenum, GLfloat); @@ -322,6 +324,7 @@ extern int gl_textureshader; #endif extern int gl_texture3d; +extern int gl_max_3d_texture_size; #ifndef GL_TEXTURE_3D #define GL_PACK_SKIP_IMAGES 0x806B #define GL_PACK_IMAGE_HEIGHT 0x806C @@ -339,6 +342,7 @@ extern void (GLAPIENTRY *qglCopyTexSubImage3D)(GLenum target, GLint level, GLint #endif extern int gl_texturecubemap; +extern int gl_max_cube_map_texture_size; #ifndef GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB #define GL_NORMAL_MAP_ARB 0x8511 #define GL_REFLECTION_MAP_ARB 0x8512 diff --git a/r_textures.h b/r_textures.h index 44d574ea..6a0c46bf 100644 --- a/r_textures.h +++ b/r_textures.h @@ -19,7 +19,7 @@ #define TEXF_FORCENEAREST 0x00000040 // indicates texture should be uploaded using GL_LINEAR or GL_LINEAR_MIPMAP_NEAREST or GL_LINEAR_MIPMAP_LINEAR mode #define TEXF_FORCELINEAR 0x00000080 -// indicates texture should be affected by gl_picmip +// indicates texture should be affected by gl_picmip and gl_max_size cvar #define TEXF_PICMIP 0x00000100 // used for checking if textures mismatch #define TEXF_IMPORTANTBITS (TEXF_ALPHA | TEXF_MIPMAP | TEXF_FRAGMENT | TEXF_CLAMP | TEXF_FORCENEAREST | TEXF_FORCELINEAR | TEXF_PICMIP) diff --git a/vid_shared.c b/vid_shared.c index f9621dc3..75c7c2cc 100644 --- a/vid_shared.c +++ b/vid_shared.c @@ -15,6 +15,10 @@ qboolean in_client_mouse = true; // AK where should it be placed ? float in_mouse_x, in_mouse_y; +// value of GL_MAX_TEXTURE__SIZE +int gl_max_texture_size = 0; +int gl_max_3d_texture_size = 0; +int gl_max_cube_map_texture_size = 0; // GL_ARB_multitexture int gl_textureunits = 1; // GL_ARB_texture_env_combine or GL_EXT_texture_env_combine @@ -608,6 +612,9 @@ void VID_CheckExtensions(void) // reset all the gl extension variables here // this should match the declarations + gl_max_texture_size = 0; + gl_max_3d_texture_size = 0; + gl_max_cube_map_texture_size = 0; gl_textureunits = 1; gl_combine_extension = false; gl_supportslockarrays = false; @@ -633,6 +640,8 @@ void VID_CheckExtensions(void) Con_Printf("GL_EXTENSIONS: %s\n", gl_extensions); Con_Printf("%s_EXTENSIONS: %s\n", gl_platform, gl_platformextensions); + qglGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max_texture_size); + Con_Print("Checking OpenGL extensions...\n"); // COMMANDLINEOPTION: GL: -nodrawrangeelements disables GL_EXT_draw_range_elements (renders faster) @@ -651,9 +660,11 @@ void VID_CheckExtensions(void) } // COMMANDLINEOPTION: GL: -notexture3d disables GL_EXT_texture3D (required for spherical lights, otherwise they render as a column) - gl_texture3d = GL_CheckExtension("GL_EXT_texture3D", texture3dextfuncs, "-notexture3d", false); + if ((gl_texture3d = GL_CheckExtension("GL_EXT_texture3D", texture3dextfuncs, "-notexture3d", false))) + qglGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &gl_max_3d_texture_size); // COMMANDLINEOPTION: GL: -nocubemap disables GL_ARB_texture_cube_map (required for bumpmapping) - gl_texturecubemap = GL_CheckExtension("GL_ARB_texture_cube_map", NULL, "-nocubemap", false); + if ((gl_texturecubemap = GL_CheckExtension("GL_ARB_texture_cube_map", NULL, "-nocubemap", false))) + qglGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB, &gl_max_cube_map_texture_size); // COMMANDLINEOPTION: GL: -nocva disables GL_EXT_compiled_vertex_array (renders faster) gl_supportslockarrays = GL_CheckExtension("GL_EXT_compiled_vertex_array", compiledvertexarrayfuncs, "-nocva", false); // COMMANDLINEOPTION: GL: -noedgeclamp disables GL_EXT_texture_edge_clamp or GL_SGIS_texture_edge_clamp (recommended, some cards do not support the other texture clamp method) -- 2.39.2