X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=gl_textures.c;h=52846b2ef46bce2f3d99ae7f4dee2691ee1ce8a3;hb=f19764dcfe28fe674266b09fe9a36c05fa847f7f;hp=b10611b7b2c9ba8f222ea347de3eaf4f4ca03f94;hpb=88a6250e7551dacddbfdbb28bb22c9dc8b6da129;p=xonotic%2Fdarkplaces.git diff --git a/gl_textures.c b/gl_textures.c index b10611b7..52846b2e 100644 --- a/gl_textures.c +++ b/gl_textures.c @@ -20,6 +20,7 @@ cvar_t gl_texturecompression_q3bsplightmaps = {CVAR_SAVE, "gl_texturecompression cvar_t gl_texturecompression_q3bspdeluxemaps = {CVAR_SAVE, "gl_texturecompression_q3bspdeluxemaps", "0", "whether to compress deluxemaps in q3bsp format levels (only levels compiled with q3map2 -deluxe have these)"}; cvar_t gl_texturecompression_sky = {CVAR_SAVE, "gl_texturecompression_sky", "0", "whether to compress sky textures"}; cvar_t gl_texturecompression_lightcubemaps = {CVAR_SAVE, "gl_texturecompression_lightcubemaps", "1", "whether to compress light cubemaps (spotlights and other light projection images)"}; +cvar_t gl_texturecompression_reflectmask = {CVAR_SAVE, "gl_texturecompression_reflectmask", "1", "whether to compress reflection cubemap masks (mask of which areas of the texture should reflect the generic shiny cubemap)"}; cvar_t gl_nopartialtextureupdates = {CVAR_SAVE, "gl_nopartialtextureupdates", "1", "use alternate path for dynamic lightmap updates that avoids a possibly slow code path in the driver"}; int gl_filter_min = GL_LINEAR_MIPMAP_LINEAR; @@ -27,6 +28,7 @@ int gl_filter_mag = GL_LINEAR; static mempool_t *texturemempool; +static memexpandablearray_t texturearray; // note: this must not conflict with TEXF_ flags in r_textures.h // bitmask for mismatch checking @@ -40,29 +42,32 @@ typedef struct textypeinfo_s int inputbytesperpixel; int internalbytesperpixel; float glinternalbytesperpixel; - int glformat; int glinternalformat; + int glformat; int gltype; } textypeinfo_t; -static textypeinfo_t textype_palette = {TEXTYPE_PALETTE, 1, 4, 4.0f, GL_BGRA , 3, GL_UNSIGNED_BYTE}; -static textypeinfo_t textype_palette_alpha = {TEXTYPE_PALETTE, 1, 4, 4.0f, GL_BGRA , 4, GL_UNSIGNED_BYTE}; -static textypeinfo_t textype_rgba = {TEXTYPE_RGBA , 4, 4, 4.0f, GL_RGBA , 3, GL_UNSIGNED_BYTE}; -static textypeinfo_t textype_rgba_alpha = {TEXTYPE_RGBA , 4, 4, 4.0f, GL_RGBA , 4, GL_UNSIGNED_BYTE}; -static textypeinfo_t textype_rgba_compress = {TEXTYPE_RGBA , 4, 4, 0.5f, GL_RGBA , GL_COMPRESSED_RGB_ARB, GL_UNSIGNED_BYTE}; -static textypeinfo_t textype_rgba_alpha_compress = {TEXTYPE_RGBA , 4, 4, 1.0f, GL_RGBA , GL_COMPRESSED_RGBA_ARB, GL_UNSIGNED_BYTE}; -static textypeinfo_t textype_bgra = {TEXTYPE_BGRA , 4, 4, 4.0f, GL_BGRA , 3, GL_UNSIGNED_BYTE}; -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_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}; -static textypeinfo_t textype_alpha = {TEXTYPE_ALPHA , 1, 4, 4.0f, GL_ALPHA , 4, GL_UNSIGNED_BYTE}; -static textypeinfo_t textype_dxt1 = {TEXTYPE_DXT1 , 4, 0, 0.5f, 0 , GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 0}; -static textypeinfo_t textype_dxt1a = {TEXTYPE_DXT1A , 4, 0, 0.5f, 0 , GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 0}; -static textypeinfo_t textype_dxt3 = {TEXTYPE_DXT3 , 4, 0, 1.0f, 0 , GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 0}; -static textypeinfo_t textype_dxt5 = {TEXTYPE_DXT5 , 4, 0, 1.0f, 0 , GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 0}; + +static textypeinfo_t textype_palette = {TEXTYPE_PALETTE , 1, 4, 4.0f, 3 , GL_BGRA , GL_UNSIGNED_BYTE }; +static textypeinfo_t textype_palette_alpha = {TEXTYPE_PALETTE , 1, 4, 4.0f, 4 , GL_BGRA , GL_UNSIGNED_BYTE }; +static textypeinfo_t textype_rgba = {TEXTYPE_RGBA , 4, 4, 4.0f, 3 , GL_RGBA , GL_UNSIGNED_BYTE }; +static textypeinfo_t textype_rgba_alpha = {TEXTYPE_RGBA , 4, 4, 4.0f, 4 , GL_RGBA , GL_UNSIGNED_BYTE }; +static textypeinfo_t textype_rgba_compress = {TEXTYPE_RGBA , 4, 4, 0.5f, GL_COMPRESSED_RGB_S3TC_DXT1_EXT , GL_RGBA , GL_UNSIGNED_BYTE }; +static textypeinfo_t textype_rgba_alpha_compress = {TEXTYPE_RGBA , 4, 4, 1.0f, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA , GL_UNSIGNED_BYTE }; +static textypeinfo_t textype_bgra = {TEXTYPE_BGRA , 4, 4, 4.0f, 3 , GL_BGRA , GL_UNSIGNED_BYTE }; +static textypeinfo_t textype_bgra_alpha = {TEXTYPE_BGRA , 4, 4, 4.0f, 4 , GL_BGRA , GL_UNSIGNED_BYTE }; +static textypeinfo_t textype_bgra_compress = {TEXTYPE_BGRA , 4, 4, 0.5f, GL_COMPRESSED_RGB_S3TC_DXT1_EXT , GL_BGRA , GL_UNSIGNED_BYTE }; +static textypeinfo_t textype_bgra_alpha_compress = {TEXTYPE_BGRA , 4, 4, 1.0f, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_BGRA , GL_UNSIGNED_BYTE }; +static textypeinfo_t textype_shadowmap16 = {TEXTYPE_SHADOWMAP , 2, 2, 2.0f, GL_DEPTH_COMPONENT16_ARB , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; +static textypeinfo_t textype_shadowmap24 = {TEXTYPE_SHADOWMAP , 4, 4, 4.0f, GL_DEPTH_COMPONENT24_ARB , GL_DEPTH_COMPONENT, GL_UNSIGNED_INT }; +static textypeinfo_t textype_alpha = {TEXTYPE_ALPHA , 1, 4, 4.0f, GL_ALPHA , GL_ALPHA , GL_UNSIGNED_BYTE }; +static textypeinfo_t textype_dxt1 = {TEXTYPE_DXT1 , 4, 0, 0.5f, GL_COMPRESSED_RGB_S3TC_DXT1_EXT , 0 , 0 }; +static textypeinfo_t textype_dxt1a = {TEXTYPE_DXT1A , 4, 0, 0.5f, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 0 , 0 }; +static textypeinfo_t textype_dxt3 = {TEXTYPE_DXT3 , 4, 0, 1.0f, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 0 , 0 }; +static textypeinfo_t textype_dxt5 = {TEXTYPE_DXT5 , 4, 0, 1.0f, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 0 , 0 }; +static textypeinfo_t textype_colorbuffer = {TEXTYPE_COLORBUFFER, 4, 4, 4.0f, 4 , GL_BGRA , GL_UNSIGNED_BYTE }; + typedef enum gltexturetype_e { @@ -156,7 +161,6 @@ static gltexturepool_t *gltexturepoolchain = NULL; static unsigned char *resizebuffer = NULL, *colorconvertbuffer; static int resizebuffersize = 0; static const unsigned char *texturebuffer; -static int texturebuffersize = 0; static textypeinfo_t *R_GetTexTypeInfo(textype_t textype, int flags) { @@ -175,24 +179,22 @@ static textypeinfo_t *R_GetTexTypeInfo(textype_t textype, int flags) case TEXTYPE_RGBA: if ((flags & TEXF_COMPRESS) && gl_texturecompression.integer >= 1 && vid.support.arb_texture_compression) return (flags & TEXF_ALPHA) ? &textype_rgba_alpha_compress : &textype_rgba_compress; - else - return (flags & TEXF_ALPHA) ? &textype_rgba_alpha : &textype_rgba; - break; + return (flags & TEXF_ALPHA) ? &textype_rgba_alpha : &textype_rgba; case TEXTYPE_BGRA: if ((flags & TEXF_COMPRESS) && gl_texturecompression.integer >= 1 && vid.support.arb_texture_compression) return (flags & TEXF_ALPHA) ? &textype_bgra_alpha_compress : &textype_bgra_compress; - else - return (flags & TEXF_ALPHA) ? &textype_bgra_alpha : &textype_bgra; - break; + return (flags & TEXF_ALPHA) ? &textype_bgra_alpha : &textype_bgra; case TEXTYPE_ALPHA: return &textype_alpha; case TEXTYPE_SHADOWMAP: return (flags & TEXF_LOWPRECISION) ? &textype_shadowmap16 : &textype_shadowmap24; + case TEXTYPE_COLORBUFFER: + return &textype_colorbuffer; default: Host_Error("R_GetTexTypeInfo: unknown texture format"); - return NULL; + break; } - return NULL; // this line only to hush compiler warnings + return NULL; } // dynamic texture code [11/22/2007 Black] @@ -257,7 +259,7 @@ void R_FreeTexture(rtexture_t *rt) if (glt->inputtexels) Mem_Free(glt->inputtexels); - Mem_Free(glt); + Mem_ExpandableArray_FreeRecord(&texturearray, glt); } rtexturepool_t *R_AllocTexturePool(void) @@ -518,6 +520,7 @@ static void r_textures_start(void) qglPixelStorei(GL_PACK_ALIGNMENT, 1);CHECKGLERROR texturemempool = Mem_AllocPool("texture management", 0, NULL); + Mem_ExpandableArray_NewArray(&texturearray, texturemempool, sizeof(gltexture_t), 512); // Disable JPEG screenshots if the DLL isn't loaded if (! JPEG_OpenLibrary ()) @@ -539,10 +542,10 @@ static void r_textures_shutdown(void) } resizebuffersize = 0; - texturebuffersize = 0; resizebuffer = NULL; colorconvertbuffer = NULL; texturebuffer = NULL; + Mem_ExpandableArray_FreeArray(&texturearray); Mem_FreePool(&texturemempool); } @@ -569,6 +572,7 @@ void R_Textures_Init (void) Cvar_RegisterVariable (&gl_texturecompression_q3bspdeluxemaps); Cvar_RegisterVariable (&gl_texturecompression_sky); Cvar_RegisterVariable (&gl_texturecompression_lightcubemaps); + Cvar_RegisterVariable (&gl_texturecompression_reflectmask); Cvar_RegisterVariable (&gl_nopartialtextureupdates); R_RegisterModule("R_Textures", r_textures_start, r_textures_shutdown, r_textures_newmap); @@ -889,7 +893,7 @@ static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *iden int i, size; gltexture_t *glt; gltexturepool_t *pool = (gltexturepool_t *)rtexturepool; - textypeinfo_t *texinfo; + textypeinfo_t *texinfo, *texinfo2; if (cls.state == ca_dedicated) return NULL; @@ -968,11 +972,20 @@ static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *iden case TEXTYPE_ALPHA: flags |= TEXF_ALPHA; break; + case TEXTYPE_COLORBUFFER: + flags |= TEXF_ALPHA; + break; default: Host_Error("R_LoadTexture: unknown texture type"); } - glt = (gltexture_t *)Mem_Alloc(texturemempool, sizeof(gltexture_t)); + texinfo2 = R_GetTexTypeInfo(textype, flags); + if(size == width * height * depth * sides * texinfo->inputbytesperpixel) + texinfo = texinfo2; + else + Con_Printf ("R_LoadTexture: input size changed after alpha fallback\n"); + + glt = (gltexture_t *)Mem_ExpandableArray_AllocRecord(&texturearray); if (identifier) strlcpy (glt->identifier, identifier, sizeof(glt->identifier)); glt->pool = pool; @@ -1181,7 +1194,9 @@ int R_SaveTextureDDSFile(rtexture_t *rt, const char *filename, qboolean skipunco rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filename, int flags, qboolean *hasalphaflag, float *avgcolor) { - int i, size, dds_flags, dds_format_flags, dds_miplevels, dds_width, dds_height, textype; + int i, size, dds_format_flags, dds_miplevels, dds_width, dds_height; + //int dds_flags; + textype_t textype; int bytesperblock, bytesperpixel; int mipcomplete; gltexture_t *glt; @@ -1202,7 +1217,10 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen ddssize = ddsfilesize; if (!dds) + { + Log_Printf("ddstexturefailures.log", "%s\n", filename); return NULL; // not found + } if (ddsfilesize <= 128 || memcmp(dds, "DDS ", 4) || ddssize < (unsigned int)BuffLittleLong(dds+4) || BuffLittleLong(dds+76) != 32) { @@ -1211,7 +1229,7 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen return NULL; } - dds_flags = BuffLittleLong(dds+8); + //dds_flags = BuffLittleLong(dds+8); dds_format_flags = BuffLittleLong(dds+80); dds_miplevels = (BuffLittleLong(dds+108) & 0x400000) ? BuffLittleLong(dds+28) : 1; dds_width = BuffLittleLong(dds+16); @@ -1236,8 +1254,8 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen for (i = 3;i < size;i += 4) if (ddspixels[i] < 255) break; - if (i < size) - flags |= TEXF_ALPHA; + if (i >= size) + flags &= ~TEXF_ALPHA; } else if (!memcmp(dds+84, "DXT1", 4)) { @@ -1259,10 +1277,9 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen if (ddspixels[i+0] + ddspixels[i+1] * 256 <= ddspixels[i+2] + ddspixels[i+3] * 256) break; if (i < size) - { textype = TEXTYPE_DXT1A; - flags |= TEXF_ALPHA; - } + else + flags &= ~TEXF_ALPHA; } else if (!memcmp(dds+84, "DXT3", 4)) { @@ -1276,7 +1293,6 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen Con_Printf("^1%s: invalid DXT3 DDS image\n", filename); return NULL; } - flags |= TEXF_ALPHA; } else if (!memcmp(dds+84, "DXT5", 4)) { @@ -1290,7 +1306,6 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen Con_Printf("^1%s: invalid DXT5 DDS image\n", filename); return NULL; } - flags |= TEXF_ALPHA; } else { @@ -1355,7 +1370,7 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen texinfo = R_GetTexTypeInfo(textype, flags); - glt = (gltexture_t *)Mem_Alloc(texturemempool, sizeof(gltexture_t)); + glt = (gltexture_t *)Mem_ExpandableArray_AllocRecord(&texturearray); strlcpy (glt->identifier, filename, sizeof(glt->identifier)); glt->pool = pool; glt->chain = pool->gltchain;