Image_StripImageExtension(name, basename, sizeof(basename));
// check for DDS texture file first
- if (!r_loaddds || !(ddsbase = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s.dds", basename), textureflags, &ddshasalpha, ddsavgcolor)))
+ if (!r_loaddds || !(ddsbase = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s.dds", basename), textureflags, &ddshasalpha, ddsavgcolor, miplevel)))
{
basepixels = loadimagepixelsbgra(name, complain, true, r_texture_convertsRGB_skin.integer, &miplevel);
if (basepixels == NULL)
skinframe->hasalpha = ddshasalpha;
VectorCopy(ddsavgcolor, skinframe->avgcolor);
if (r_loadfog && skinframe->hasalpha)
- skinframe->fog = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_mask.dds", skinframe->basename), textureflags | TEXF_ALPHA, NULL, NULL);
+ skinframe->fog = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_mask.dds", skinframe->basename), textureflags | TEXF_ALPHA, NULL, NULL, miplevel);
//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]);
}
else
if (r_loaddds)
{
+ mymiplevel = savemiplevel;
if (r_loadnormalmap)
- skinframe->nmap = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_norm.dds", skinframe->basename), textureflags | TEXF_ALPHA, NULL, NULL);
- skinframe->glow = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_glow.dds", skinframe->basename), textureflags, NULL, NULL);
+ skinframe->nmap = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_norm.dds", skinframe->basename), textureflags | TEXF_ALPHA, NULL, NULL, mymiplevel);
+ skinframe->glow = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_glow.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
if (r_loadgloss)
- skinframe->gloss = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_gloss.dds", skinframe->basename), textureflags, NULL, NULL);
- skinframe->pants = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_pants.dds", skinframe->basename), textureflags, NULL, NULL);
- skinframe->shirt = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_shirt.dds", skinframe->basename), textureflags, NULL, NULL);
- skinframe->reflect = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_reflect.dds", skinframe->basename), textureflags, NULL, NULL);
+ skinframe->gloss = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_gloss.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
+ skinframe->pants = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_pants.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
+ skinframe->shirt = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_shirt.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
+ skinframe->reflect = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_reflect.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
}
// _norm is the name used by tenebrae and has been adopted as standard
return ret ? ddssize : -5;
}
-rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filename, int flags, qboolean *hasalphaflag, float *avgcolor)
+rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filename, int flags, qboolean *hasalphaflag, float *avgcolor, int miplevel) // DDS textures are opaque, so miplevel isn't a pointer but just seen as a hint
{
int i, size, dds_format_flags, dds_miplevels, dds_width, dds_height;
//int dds_flags;
}
}
+ // this is where we apply gl_picmip
+ mippixels = ddspixels;
+ mipwidth = dds_width;
+ mipheight = dds_height;
+ while(miplevel >= 1 && dds_miplevels >= 1)
+ {
+ if (mipwidth <= 1 && mipheight <= 1)
+ break;
+ mipsize = bytesperblock ? ((mipwidth+3)/4)*((mipheight+3)/4)*bytesperblock : mipwidth*mipheight*bytesperpixel;
+ mippixels += mipsize; // just skip
+ --dds_miplevels;
+ --miplevel;
+ if (mipwidth > 1)
+ mipwidth >>= 1;
+ if (mipheight > 1)
+ mipheight >>= 1;
+ }
+
if (dds_miplevels > 1)
flags |= TEXF_MIPMAP;
else
glt->pool = pool;
glt->chain = pool->gltchain;
pool->gltchain = glt;
- glt->inputwidth = dds_width;
- glt->inputheight = dds_height;
+ glt->inputwidth = mipwidth;
+ glt->inputheight = mipheight;
glt->inputdepth = 1;
glt->flags = flags;
glt->textype = texinfo;
glt->bytesperpixel = texinfo->internalbytesperpixel;
glt->sides = 1;
glt->gltexturetypeenum = gltexturetypeenums[glt->texturetype];
- glt->tilewidth = dds_width;
- glt->tileheight = dds_height;
+ glt->tilewidth = mipwidth;
+ glt->tileheight = mipheight;
glt->tiledepth = 1;
// texture uploading can take a while, so make sure we're sending keepalives
oldbindtexnum = R_Mesh_TexBound(0, gltexturetypeenums[glt->texturetype]);
qglGenTextures(1, (GLuint *)&glt->texnum);CHECKGLERROR
qglBindTexture(gltexturetypeenums[glt->texturetype], glt->texnum);CHECKGLERROR
- mippixels = ddspixels;
- mipwidth = dds_width;
- mipheight = dds_height;
mipcomplete = false;
- for (mip = 0;mip < dds_miplevels+1;mip++)
+
+ for (mip = 0;mip <= dds_miplevels;mip++) // <= to include the not-counted "largest" miplevel
{
mipsize = bytesperblock ? ((mipwidth+3)/4)*((mipheight+3)/4)*bytesperblock : mipwidth*mipheight*bytesperpixel;
if (mippixels + mipsize > dds + ddssize)
if (mipheight > 1)
mipheight >>= 1;
}
- if (dds_miplevels > 1 && !mipcomplete)
+ if (dds_miplevels >= 1 && !mipcomplete)
{
// need to set GL_TEXTURE_MAX_LEVEL
qglTexParameteri(gltexturetypeenums[glt->texturetype], GL_TEXTURE_MAX_LEVEL, dds_miplevels - 1);CHECKGLERROR
rtexture_t *R_LoadTextureShadowMapRectangle(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int precision, qboolean filter);
rtexture_t *R_LoadTextureShadowMap2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int precision, qboolean filter);
rtexture_t *R_LoadTextureShadowMapCube(rtexturepool_t *rtexturepool, const char *identifier, int width, int precision, qboolean filter);
-rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filename, int flags, qboolean *hasalphaflag, float *avgcolor);
+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);