]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_textures.c
add DeviceLost and DeviceRestored functions to R_Modules system
[xonotic/darkplaces.git] / gl_textures.c
index 67301b1c9eb56d74b06e1eea7aee7b4dad5315e9..bcf79232cb848409f2e60b572253ac50c299226c 100644 (file)
@@ -590,7 +590,7 @@ void R_Textures_Init (void)
        Cvar_RegisterVariable (&gl_texturecompression_reflectmask);
        Cvar_RegisterVariable (&gl_nopartialtextureupdates);
 
-       R_RegisterModule("R_Textures", r_textures_start, r_textures_shutdown, r_textures_newmap);
+       R_RegisterModule("R_Textures", r_textures_start, r_textures_shutdown, r_textures_newmap, NULL, NULL);
 }
 
 void R_Textures_Frame (void)
@@ -1035,7 +1035,7 @@ static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *iden
        qglGenTextures(1, (GLuint *)&glt->texnum);CHECKGLERROR
        R_Upload(glt, data, 0, 0, 0, glt->inputwidth, glt->inputheight, glt->inputdepth);
        if ((glt->flags & TEXF_ALLOWUPDATES) && gl_nopartialtextureupdates.integer)
-               glt->bufferpixels = Mem_Alloc(texturemempool, glt->tilewidth*glt->tileheight*glt->tiledepth*glt->sides*glt->bytesperpixel);
+               glt->bufferpixels = (unsigned char *)Mem_Alloc(texturemempool, glt->tilewidth*glt->tileheight*glt->tiledepth*glt->sides*glt->bytesperpixel);
 
        // texture converting and uploading can take a while, so make sure we're sending keepalives
        CL_KeepaliveMessage(false);
@@ -1152,7 +1152,7 @@ int R_SaveTextureDDSFile(rtexture_t *rt, const char *filename, qboolean skipunco
                mipinfo[mip][3] = ddssize;
                ddssize += mipinfo[mip][2];
        }
-       dds = Mem_Alloc(tempmempool, ddssize);
+       dds = (unsigned char *)Mem_Alloc(tempmempool, ddssize);
        if (!dds)
                return -4;
        dds_caps1 = 0x1000; // DDSCAPS_TEXTURE
@@ -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