From bc69fba592f3f55d69447a7d64b7a9fc384b02e6 Mon Sep 17 00:00:00 2001 From: divverent Date: Fri, 6 Aug 2010 19:22:21 +0000 Subject: [PATCH] use the DDPF_ALPHAPIXELS flag for DDS reading, at least works for ATI Compressonator git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10376 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_rmain.c | 16 +++++++-------- gl_textures.c | 55 ++++++++++++++++++++++++++++++++------------------- r_textures.h | 2 +- 3 files changed, 44 insertions(+), 29 deletions(-) diff --git a/gl_rmain.c b/gl_rmain.c index 219e04c9..032ff51a 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -6588,9 +6588,9 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole R_SKINFRAME_LOAD_AVERAGE_COLORS(basepixels_width * basepixels_height, basepixels[4 * pix + comp]); //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]); if (r_savedds && qglGetCompressedTexImageARB && skinframe->base) - R_SaveTextureDDSFile(skinframe->base, va("dds/%s.dds", skinframe->basename), true); + R_SaveTextureDDSFile(skinframe->base, va("dds/%s.dds", skinframe->basename), true, skinframe->hasalpha); if (r_savedds && qglGetCompressedTexImageARB && skinframe->fog) - R_SaveTextureDDSFile(skinframe->fog, va("dds/%s_mask.dds", skinframe->basename), true); + R_SaveTextureDDSFile(skinframe->fog, va("dds/%s_mask.dds", skinframe->basename), true, true); } if (r_loaddds) @@ -6632,7 +6632,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole Mem_Free(pixels); } if (r_savedds && qglGetCompressedTexImageARB && skinframe->nmap) - R_SaveTextureDDSFile(skinframe->nmap, va("dds/%s_norm.dds", skinframe->basename), true); + R_SaveTextureDDSFile(skinframe->nmap, va("dds/%s_norm.dds", skinframe->basename), true, true); } // _luma is supported only for tenebrae compatibility @@ -6642,7 +6642,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole { skinframe->glow = R_LoadTexture2D (r_main_texturepool, va("%s_glow", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_glow.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL); if (r_savedds && qglGetCompressedTexImageARB && skinframe->glow) - R_SaveTextureDDSFile(skinframe->glow, va("dds/%s_glow.dds", skinframe->basename), true); + R_SaveTextureDDSFile(skinframe->glow, va("dds/%s_glow.dds", skinframe->basename), true, true); Mem_Free(pixels);pixels = NULL; } @@ -6651,7 +6651,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole { skinframe->gloss = R_LoadTexture2D (r_main_texturepool, va("%s_gloss", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_gloss.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL); if (r_savedds && qglGetCompressedTexImageARB && skinframe->gloss) - R_SaveTextureDDSFile(skinframe->gloss, va("dds/%s_gloss.dds", skinframe->basename), true); + R_SaveTextureDDSFile(skinframe->gloss, va("dds/%s_gloss.dds", skinframe->basename), true, true); Mem_Free(pixels); pixels = NULL; } @@ -6661,7 +6661,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole { skinframe->pants = R_LoadTexture2D (r_main_texturepool, va("%s_pants", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL); if (r_savedds && qglGetCompressedTexImageARB && skinframe->pants) - R_SaveTextureDDSFile(skinframe->pants, va("dds/%s_pants.dds", skinframe->basename), true); + R_SaveTextureDDSFile(skinframe->pants, va("dds/%s_pants.dds", skinframe->basename), true, false); Mem_Free(pixels); pixels = NULL; } @@ -6671,7 +6671,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole { skinframe->shirt = R_LoadTexture2D (r_main_texturepool, va("%s_shirt", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL); if (r_savedds && qglGetCompressedTexImageARB && skinframe->shirt) - R_SaveTextureDDSFile(skinframe->shirt, va("dds/%s_shirt.dds", skinframe->basename), true); + R_SaveTextureDDSFile(skinframe->shirt, va("dds/%s_shirt.dds", skinframe->basename), true, false); Mem_Free(pixels); pixels = NULL; } @@ -6681,7 +6681,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole { skinframe->reflect = R_LoadTexture2D (r_main_texturepool, va("%s_reflect", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_reflectmask.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL); if (r_savedds && qglGetCompressedTexImageARB && skinframe->reflect) - R_SaveTextureDDSFile(skinframe->reflect, va("dds/%s_reflect.dds", skinframe->basename), true); + R_SaveTextureDDSFile(skinframe->reflect, va("dds/%s_reflect.dds", skinframe->basename), true, true); Mem_Free(pixels); pixels = NULL; } diff --git a/gl_textures.c b/gl_textures.c index a44e3a29..527ec31b 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", "0", "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; @@ -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); } @@ -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,12 +1779,15 @@ 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)) { @@ -1796,19 +1805,23 @@ 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) + if(r_texture_dds_load_alphamode.integer && (flags & TEXF_ALPHA)) { - flags &= ~TEXF_ALPHA; - } - else - { - 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) + break; + if (i < size) + textype = TEXTYPE_DXT1A; + else + flags &= ~TEXF_ALPHA; + } else + { flags &= ~TEXF_ALPHA; + } } } else if (!memcmp(dds+84, "DXT3", 4)) @@ -1823,6 +1836,7 @@ 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)) { @@ -1836,6 +1850,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 { diff --git a/r_textures.h b/r_textures.h index 0d7ca047..c433a04b 100644 --- a/r_textures.h +++ b/r_textures.h @@ -134,7 +134,7 @@ rtexture_t *R_LoadTextureShadowMapCube(rtexturepool_t *rtexturepool, const char rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filename, int flags, qboolean *hasalphaflag, float *avgcolor, int miplevel); // saves a texture to a DDS file -int R_SaveTextureDDSFile(rtexture_t *rt, const char *filename, qboolean skipuncompressed); +int R_SaveTextureDDSFile(rtexture_t *rt, const char *filename, qboolean skipuncompressed, qboolean hasalpha); // free a texture void R_FreeTexture(rtexture_t *rt); -- 2.39.2