X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=gl_textures.c;h=d244f00636bcb88dea49cda730be11351c9c191a;hb=4bfb0cbab250c020cfb990f347366f1a4eca79cd;hp=a44e3a29b948c73b536bdd660e62cade7600e7aa;hpb=2f606f773eb3e95ac0b58cbafc1c7782fc48796c;p=xonotic%2Fdarkplaces.git diff --git a/gl_textures.c b/gl_textures.c index a44e3a29..d244f006 100644 --- a/gl_textures.c +++ b/gl_textures.c @@ -31,7 +31,7 @@ cvar_t gl_texturecompression_sky = {CVAR_SAVE, "gl_texturecompression_sky", "0", 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"}; -cvar_t r_texture_dds_load_dxt1_noalpha = {0, "r_texture_dds_load_dxt1_noalpha", "0", "if set, alpha detection on DXT1 is turned off, and DXT1 textures are assumed to never have alpha"}; +cvar_t r_texture_dds_load_alphamode = {0, "r_texture_dds_load_alphamode", "1", "0: trust DDPF_ALPHAPIXELS flag, 1: texture format and brute force search if ambigous, 2: texture format only"}; qboolean gl_filter_force = false; int gl_filter_min = GL_LINEAR_MIPMAP_LINEAR; @@ -218,11 +218,11 @@ static textypeinfo_t *R_GetTexTypeInfo(textype_t textype, int flags) case TEXTYPE_PALETTE: return (flags & TEXF_ALPHA) ? &textype_palette_alpha : &textype_palette; case TEXTYPE_RGBA: - if ((flags & TEXF_COMPRESS) && gl_texturecompression.integer >= 1 && vid.support.arb_texture_compression) + if ((flags & TEXF_COMPRESS) && gl_texturecompression.integer >= 1 && vid.support.ext_texture_compression_s3tc) return (flags & TEXF_ALPHA) ? &textype_rgba_alpha_compress : &textype_rgba_compress; 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) + if ((flags & TEXF_COMPRESS) && gl_texturecompression.integer >= 1 && vid.support.ext_texture_compression_s3tc) return (flags & TEXF_ALPHA) ? &textype_bgra_alpha_compress : &textype_bgra_compress; return (flags & TEXF_ALPHA) ? &textype_bgra_alpha : &textype_bgra; case TEXTYPE_ALPHA: @@ -341,7 +341,7 @@ void R_FreeTexturePool(rtexturepool_t **rtexturepool) typedef struct glmode_s { - char *name; + const char *name; int minification, magnification; } glmode_t; @@ -359,7 +359,7 @@ static glmode_t modes[6] = #ifdef SUPPORTD3D typedef struct d3dmode_s { - char *name; + const char *name; int m1, m2; } d3dmode_t; @@ -806,7 +806,7 @@ void R_Textures_Init (void) Cvar_RegisterVariable (&gl_texturecompression_lightcubemaps); Cvar_RegisterVariable (&gl_texturecompression_reflectmask); Cvar_RegisterVariable (&gl_nopartialtextureupdates); - Cvar_RegisterVariable (&r_texture_dds_load_dxt1_noalpha); + Cvar_RegisterVariable (&r_texture_dds_load_alphamode); R_RegisterModule("R_Textures", r_textures_start, r_textures_shutdown, r_textures_newmap, r_textures_devicelost, r_textures_devicerestored); } @@ -1078,7 +1078,7 @@ static void R_Upload(gltexture_t *glt, const unsigned char *data, int fragx, int else { if (fragx || fragy || fragz || glt->inputwidth != fragwidth || glt->inputheight != fragheight || glt->inputdepth != fragdepth) - Host_Error("R_Upload: partial update not allowed on initial upload or in combination with PICMIP or MIPMAP\n"); + Sys_Error("R_Upload \"%s\": partial update not allowed on initial upload or in combination with PICMIP or MIPMAP\n", glt->identifier); // cubemaps contain multiple images and thus get processed a bit differently if (glt->texturetype != GLTEXTURETYPE_CUBEMAP) @@ -1597,7 +1597,7 @@ rtexture_t *R_LoadTextureShadowMapCube(rtexturepool_t *rtexturepool, const char return R_SetupTexture(rtexturepool, identifier, width, width, 1, 6, R_ShadowMapTextureFlags(precision, filter), -1, TEXTYPE_SHADOWMAP, GLTEXTURETYPE_CUBEMAP, NULL, NULL); } -int R_SaveTextureDDSFile(rtexture_t *rt, const char *filename, qboolean skipuncompressed) +int R_SaveTextureDDSFile(rtexture_t *rt, const char *filename, qboolean skipuncompressed, qboolean hasalpha) { gltexture_t *glt = (gltexture_t *)rt; unsigned char *dds; @@ -1672,13 +1672,15 @@ int R_SaveTextureDDSFile(rtexture_t *rt, const char *filename, qboolean skipunco else { dds_flags = 0x100F; // DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH - dds_format_flags = 0x41; // DDPF_RGB | DDPF_ALPHAPIXELS + dds_format_flags = 0x40; // DDPF_RGB } if (mipmaps) { dds_flags |= 0x20000; // DDSD_MIPMAPCOUNT dds_caps1 |= 0x400008; // DDSCAPS_MIPMAP | DDSCAPS_COMPLEX } + if(hasalpha) + dds_format_flags |= 0x1; // DDPF_ALPHAPIXELS memcpy(dds, "DDS ", 4); StoreLittleLong(dds+4, ddssize); StoreLittleLong(dds+8, dds_flags); @@ -1759,6 +1761,10 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen dds_height = BuffLittleLong(dds+12); ddspixels = dds + 128; + if(r_texture_dds_load_alphamode.integer == 0) + if(!(dds_format_flags & 0x1)) // DDPF_ALPHAPIXELS + flags &= ~TEXF_ALPHA; + //flags &= ~TEXF_ALPHA; // disabled, as we DISABLE TEXF_ALPHA in the alpha detection, not enable it! if ((dds_format_flags & 0x40) && BuffLittleLong(dds+88) == 32) { @@ -1773,15 +1779,23 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen Con_Printf("^1%s: invalid BGRA DDS image\n", filename); return NULL; } - // check alpha - for (i = 3;i < size;i += 4) - if (ddspixels[i] < 255) - break; - if (i >= size) - flags &= ~TEXF_ALPHA; + if((r_texture_dds_load_alphamode.integer == 1) && (flags & TEXF_ALPHA)) + { + // check alpha + for (i = 3;i < size;i += 4) + if (ddspixels[i] < 255) + break; + if (i >= size) + flags &= ~TEXF_ALPHA; + } } else if (!memcmp(dds+84, "DXT1", 4)) { + if(!vid.support.ext_texture_compression_s3tc) + { + Mem_Free(dds); + return NULL; + } // we need to find out if this is DXT1 (opaque) or DXT1A (transparent) // LordHavoc: it is my belief that this does not infringe on the // patent because it is not decoding pixels... @@ -1796,23 +1810,38 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen Con_Printf("^1%s: invalid DXT1 DDS image\n", filename); return NULL; } - if(r_texture_dds_load_dxt1_noalpha.integer) - { - flags &= ~TEXF_ALPHA; - } - else + if(r_texture_dds_load_alphamode.integer && (flags & TEXF_ALPHA)) { - for (i = 0;i < size;i += bytesperblock) - if (ddspixels[i+0] + ddspixels[i+1] * 256 <= ddspixels[i+2] + ddspixels[i+3] * 256) - break; - if (i < size) - textype = TEXTYPE_DXT1A; + if(r_texture_dds_load_alphamode.integer == 1) + { + // check alpha + for (i = 0;i < size;i += bytesperblock) + if (ddspixels[i+0] + ddspixels[i+1] * 256 <= ddspixels[i+2] + ddspixels[i+3] * 256) + { + // NOTE: this assumes sizeof(unsigned int) == 4 + unsigned int data = * (unsigned int *) &(ddspixels[i+4]); + // check if data, in base 4, contains a digit 3 (DXT1: transparent pixel) + if(data & (data<<1) & 0xAAAAAAAA)//rgh + break; + } + if (i < size) + textype = TEXTYPE_DXT1A; + else + flags &= ~TEXF_ALPHA; + } else + { flags &= ~TEXF_ALPHA; + } } } else if (!memcmp(dds+84, "DXT3", 4)) { + if(!vid.support.ext_texture_compression_s3tc) + { + Mem_Free(dds); + return NULL; + } textype = TEXTYPE_DXT3; bytesperblock = 16; bytesperpixel = 0; @@ -1823,9 +1852,15 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen Con_Printf("^1%s: invalid DXT3 DDS image\n", filename); return NULL; } + // we currently always assume alpha } else if (!memcmp(dds+84, "DXT5", 4)) { + if(!vid.support.ext_texture_compression_s3tc) + { + Mem_Free(dds); + return NULL; + } textype = TEXTYPE_DXT5; bytesperblock = 16; bytesperpixel = 0; @@ -1836,6 +1871,7 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen Con_Printf("^1%s: invalid DXT5 DDS image\n", filename); return NULL; } + // we currently always assume alpha } else { @@ -2125,7 +2161,7 @@ void R_UpdateTexture(rtexture_t *rt, const unsigned char *data, int x, int y, in Host_Error("R_UpdateTexture: no texture supplied"); if (!glt->texnum && !glt->d3dtexture) { - Con_Printf("R_UpdateTexture: texture %p \"%s\" in pool %p has not been uploaded yet", glt, glt->identifier, glt->pool); + Con_Printf("R_UpdateTexture: texture %p \"%s\" in pool %p has not been uploaded yet", (void *)glt, glt->identifier, (void *)glt->pool); return; } // update part of the texture