use the DDPF_ALPHAPIXELS flag for DDS reading, at least works for ATI Compressonator
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 6 Aug 2010 19:22:21 +0000 (19:22 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 6 Aug 2010 19:22:21 +0000 (19:22 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10376 d7cf8633-e32d-0410-b094-e92efae38249

gl_rmain.c
gl_textures.c
r_textures.h

index 219e04c..032ff51 100644 (file)
@@ -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;
        }
index a44e3a2..527ec31 100644 (file)
@@ -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
        {
index 0d7ca04..c433a04 100644 (file)
@@ -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);