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)
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
{
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;
}
{
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;
}
{
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;
}
{
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;
}
{
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;
}
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;
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, NULL, NULL);
}
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;
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);
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)
{
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))
{
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))
Con_Printf("^1%s: invalid DXT3 DDS image\n", filename);
return NULL;
}
+ // we currently always assume alpha
}
else if (!memcmp(dds+84, "DXT5", 4))
{
Con_Printf("^1%s: invalid DXT5 DDS image\n", filename);
return NULL;
}
+ // we currently always assume alpha
}
else
{
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);