From 2db250bb0c08162bf6bd0913441b7f11f81475c0 Mon Sep 17 00:00:00 2001 From: divverent Date: Mon, 21 Jun 2010 11:22:07 +0000 Subject: [PATCH] DDS picmip support (similar to JPEG one) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10243 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_rmain.c | 17 +++++++++-------- gl_textures.c | 36 ++++++++++++++++++++++++++---------- r_textures.h | 2 +- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/gl_rmain.c b/gl_rmain.c index f48771ea..834fd650 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -5538,7 +5538,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole 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) @@ -5571,7 +5571,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole 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 @@ -5614,14 +5614,15 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole 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 diff --git a/gl_textures.c b/gl_textures.c index 67301b1c..d20a0ecd 100644 --- a/gl_textures.c +++ b/gl_textures.c @@ -1208,7 +1208,7 @@ int R_SaveTextureDDSFile(rtexture_t *rt, const char *filename, qboolean skipunco 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; @@ -1371,6 +1371,24 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen } } + // 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 @@ -1391,8 +1409,8 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen 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; @@ -1404,8 +1422,8 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen 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 @@ -1418,11 +1436,9 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen 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) @@ -1446,7 +1462,7 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen 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 diff --git a/r_textures.h b/r_textures.h index c30fa727..76ad5fe2 100644 --- a/r_textures.h +++ b/r_textures.h @@ -103,7 +103,7 @@ rtexture_t *R_LoadTextureRectangle(rtexturepool_t *rtexturepool, const char *ide 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); -- 2.39.2