]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_textures.c
changed array pointer state to const float * instead of const void *
[xonotic/darkplaces.git] / gl_textures.c
index cc43c8d37085be3dff3d14bf0f38d30b604f10dc..e2a49dd35fa9609142674fbef2ebc2a971879cd8 100644 (file)
@@ -3,12 +3,12 @@
 #include "image.h"
 #include "jpeg.h"
 
-cvar_t r_max_size = {CVAR_SAVE, "r_max_size", "2048"};
-cvar_t r_max_scrapsize = {CVAR_SAVE, "r_max_scrapsize", "256"};
-cvar_t r_picmip = {CVAR_SAVE, "r_picmip", "0"};
+cvar_t gl_max_size = {CVAR_SAVE, "gl_max_size", "2048"};
+cvar_t gl_max_scrapsize = {CVAR_SAVE, "gl_max_scrapsize", "256"};
+cvar_t gl_picmip = {CVAR_SAVE, "gl_picmip", "0"};
 cvar_t r_lerpimages = {CVAR_SAVE, "r_lerpimages", "1"};
 cvar_t r_precachetextures = {CVAR_SAVE, "r_precachetextures", "1"};
-cvar_t  gl_texture_anisotropy = {CVAR_SAVE, "gl_texture_anisotropy", "0"};
+cvar_t  gl_texture_anisotropy = {CVAR_SAVE, "gl_texture_anisotropy", "1"};
 
 int            gl_filter_min = GL_LINEAR_MIPMAP_LINEAR;
 int            gl_filter_mag = GL_LINEAR;
@@ -338,11 +338,11 @@ static void GL_TextureMode_f (void)
                {
                        if (gl_filter_min == modes[i].minification)
                        {
-                               Con_Printf ("%s\n", modes[i].name);
+                               Con_Printf("%s\n", modes[i].name);
                                return;
                        }
                }
-               Con_Print("current filter is unknown???\n");
+               Con_Print("current filter is unknown???\n");
                return;
        }
 
@@ -351,7 +351,7 @@ static void GL_TextureMode_f (void)
                        break;
        if (i == 6)
        {
-               Con_Print("bad filter name\n");
+               Con_Print("bad filter name\n");
                return;
        }
 
@@ -382,20 +382,23 @@ static void GL_TextureMode_f (void)
 
 static int R_CalcTexelDataSize (gltexture_t *glt)
 {
-       int width2, height2, depth2, size;
+       int width2, height2, depth2, size, picmip;
        if (glt->flags & TEXF_FRAGMENT)
                size = glt->width * glt->height * glt->depth;
        else
        {
-               if (r_max_size.integer > realmaxsize)
-                       Cvar_SetValue("r_max_size", realmaxsize);
+               picmip = 0;
+               if (glt->flags & TEXF_PICMIP)
+                       picmip = gl_picmip.integer;
+               if (gl_max_size.integer > realmaxsize)
+                       Cvar_SetValue("gl_max_size", realmaxsize);
                // calculate final size
                for (width2 = 1;width2 < glt->width;width2 <<= 1);
                for (height2 = 1;height2 < glt->height;height2 <<= 1);
                for (depth2 = 1;depth2 < glt->depth;depth2 <<= 1);
-               for (width2 >>= r_picmip.integer;width2 > r_max_size.integer;width2 >>= 1);
-               for (height2 >>= r_picmip.integer;height2 > r_max_size.integer;height2 >>= 1);
-               for (depth2 >>= r_picmip.integer;depth2 > r_max_size.integer;depth2 >>= 1);
+               for (width2 >>= picmip;width2 > gl_max_size.integer;width2 >>= 1);
+               for (height2 >>= picmip;height2 > gl_max_size.integer;height2 >>= 1);
+               for (depth2 >>= picmip;depth2 > gl_max_size.integer;depth2 >>= 1);
                if (width2 < 1) width2 = 1;
                if (height2 < 1) height2 = 1;
                if (depth2 < 1) depth2 = 1;
@@ -423,46 +426,56 @@ static int R_CalcTexelDataSize (gltexture_t *glt)
        return size;
 }
 
-void R_TextureStats_PrintTotal(void)
+void R_TextureStats_Print(qboolean printeach, qboolean printpool, qboolean printtotal)
 {
-       int glsize, total = 0, totalt = 0, totalp = 0, loaded = 0, loadedt = 0, loadedp = 0;
+       int glsize;
+       int isloaded;
+       int pooltotal = 0, pooltotalt = 0, pooltotalp = 0, poolloaded = 0, poolloadedt = 0, poolloadedp = 0;
+       int sumtotal = 0, sumtotalt = 0, sumtotalp = 0, sumloaded = 0, sumloadedt = 0, sumloadedp = 0;
        gltexture_t *glt;
        gltexturepool_t *pool;
+       if (printeach)
+               Con_Print("glsize input loaded mip alpha name\n");
        for (pool = gltexturepoolchain;pool;pool = pool->next)
        {
+               pooltotal = 0;
+               pooltotalt = 0;
+               pooltotalp = 0;
+               poolloaded = 0;
+               poolloadedt = 0;
+               poolloadedp = 0;
                for (glt = pool->gltchain;glt;glt = glt->chain)
                {
                        glsize = R_CalcTexelDataSize(glt);
-                       total++;
-                       totalt += glsize;
-                       totalp += glt->inputdatasize;
-                       if (!(glt->flags & GLTEXF_UPLOAD))
+                       isloaded = !(glt->flags & GLTEXF_UPLOAD);
+                       pooltotal++;
+                       pooltotalt += glsize;
+                       pooltotalp += glt->inputdatasize;
+                       if (isloaded)
                        {
-                               loaded++;
-                               loadedt += glsize;
-                               loadedp += glt->inputdatasize;
+                               poolloaded++;
+                               poolloadedt += glsize;
+                               poolloadedp += glt->inputdatasize;
                        }
+                       if (printeach)
+                               Con_Printf("%c%4i%c%c%4i%c %s %s %s %s\n", isloaded ? '[' : ' ', (glsize + 1023) / 1024, isloaded ? ']' : ' ', glt->inputtexels ? '[' : ' ', (glt->inputdatasize + 1023) / 1024, glt->inputtexels ? ']' : ' ', isloaded ? "loaded" : "      ", (glt->flags & TEXF_MIPMAP) ? "mip" : "   ", (glt->flags & TEXF_ALPHA) ? "alpha" : "     ", glt->identifier ? glt->identifier : "<unnamed>");
                }
+               if (printpool)
+                       Con_Printf("texturepool %10p total: %i (%.3fMB, %.3fMB original), uploaded %i (%.3fMB, %.3fMB original), upload on demand %i (%.3fMB, %.3fMB original)\n", pool, pooltotal, pooltotalt / 1048576.0, pooltotalp / 1048576.0, poolloaded, poolloadedt / 1048576.0, poolloadedp / 1048576.0, pooltotal - poolloaded, (pooltotalt - poolloadedt) / 1048576.0, (pooltotalp - poolloadedp) / 1048576.0);
+               sumtotal += pooltotal;
+               sumtotalt += pooltotalt;
+               sumtotalp += pooltotalp;
+               sumloaded += poolloaded;
+               sumloadedt += poolloadedt;
+               sumloadedp += poolloadedp;
        }
-       Con_Printf("total: %i (%.3fMB, %.3fMB original), uploaded %i (%.3fMB, %.3fMB original), upload on demand %i (%.3fMB, %.3fMB original)\n", total, totalt / 1048576.0, totalp / 1048576.0, loaded, loadedt / 1048576.0, loadedp / 1048576.0, total - loaded, (totalt - loadedt) / 1048576.0, (totalp - loadedp) / 1048576.0);
+       if (printtotal)
+               Con_Printf("textures total: %i (%.3fMB, %.3fMB original), uploaded %i (%.3fMB, %.3fMB original), upload on demand %i (%.3fMB, %.3fMB original)\n", sumtotal, sumtotalt / 1048576.0, sumtotalp / 1048576.0, sumloaded, sumloadedt / 1048576.0, sumloadedp / 1048576.0, sumtotal - sumloaded, (sumtotalt - sumloadedt) / 1048576.0, (sumtotalp - sumloadedp) / 1048576.0);
 }
 
 static void R_TextureStats_f(void)
 {
-       int loaded;
-       gltexture_t *glt;
-       gltexturepool_t *pool;
-       Con_Printf("glsize input loaded mip alpha name\n");
-       for (pool = gltexturepoolchain;pool;pool = pool->next)
-       {
-               for (glt = pool->gltchain;glt;glt = glt->chain)
-               {
-                       loaded = !(glt->flags & GLTEXF_UPLOAD);
-                       Con_Printf("%c%4i%c%c%4i%c %s %s %s %s\n", loaded ? '[' : ' ', (R_CalcTexelDataSize(glt) + 1023) / 1024, loaded ? ']' : ' ', glt->inputtexels ? '[' : ' ', (glt->inputdatasize + 1023) / 1024, glt->inputtexels ? ']' : ' ', loaded ? "loaded" : "      ", (glt->flags & TEXF_MIPMAP) ? "mip" : "   ", (glt->flags & TEXF_ALPHA) ? "alpha" : "     ", glt->identifier ? glt->identifier : "<unnamed>");
-               }
-               Con_Printf("pool %10p\n", pool);
-       }
-       R_TextureStats_PrintTotal();
+       R_TextureStats_Print(true, true, true);
 }
 
 char engineversion[40];
@@ -477,11 +490,11 @@ static void r_textures_start(void)
        CHECKGLERROR
 
        // use the largest scrap texture size we can (not sure if this is really a good idea)
-       for (block_size = 1;block_size < realmaxsize && block_size < r_max_scrapsize.integer;block_size <<= 1);
+       for (block_size = 1;block_size < realmaxsize && block_size < gl_max_scrapsize.integer;block_size <<= 1);
 
-       texturemempool = Mem_AllocPool("Texture Info");
-       texturedatamempool = Mem_AllocPool("Texture Storage (not yet uploaded)");
-       textureprocessingmempool = Mem_AllocPool("Texture Processing Buffers");
+       texturemempool = Mem_AllocPool("Texture Info", 0, NULL);
+       texturedatamempool = Mem_AllocPool("Texture Storage (not yet uploaded)", 0, NULL);
+       textureprocessingmempool = Mem_AllocPool("Texture Processing Buffers", 0, NULL);
 
        // Disable JPEG screenshots if the DLL isn't loaded
        if (! JPEG_OpenLibrary ())
@@ -518,9 +531,9 @@ void R_Textures_Init (void)
 {
        Cmd_AddCommand("gl_texturemode", &GL_TextureMode_f);
        Cmd_AddCommand("r_texturestats", R_TextureStats_f);
-       Cvar_RegisterVariable (&r_max_scrapsize);
-       Cvar_RegisterVariable (&r_max_size);
-       Cvar_RegisterVariable (&r_picmip);
+       Cvar_RegisterVariable (&gl_max_scrapsize);
+       Cvar_RegisterVariable (&gl_max_size);
+       Cvar_RegisterVariable (&gl_picmip);
        Cvar_RegisterVariable (&r_lerpimages);
        Cvar_RegisterVariable (&r_precachetextures);
        Cvar_RegisterVariable (&gl_texture_anisotropy);
@@ -530,6 +543,8 @@ void R_Textures_Init (void)
 
 void R_Textures_Frame (void)
 {
+       static int old_aniso = 0;
+
        // could do procedural texture animation here, if we keep track of which
        // textures were accessed this frame...
 
@@ -545,6 +560,34 @@ void R_Textures_Frame (void)
                Mem_Free(colorconvertbuffer);
                colorconvertbuffer = NULL;
        }
+
+       if (old_aniso != gl_texture_anisotropy.integer)
+       {
+               gltextureimage_t *image;
+               gltexturepool_t *pool;
+               GLint oldbindtexnum;
+
+               old_aniso = bound(1, gl_texture_anisotropy.integer, gl_max_anisotropy);
+
+               Cvar_SetValueQuick(&gl_texture_anisotropy, old_aniso);
+
+               for (pool = gltexturepoolchain;pool;pool = pool->next)
+               {
+                       for (image = pool->imagechain;image;image = image->imagechain)
+                       {
+                               // only update already uploaded images
+                               if (!(image->flags & GLTEXF_UPLOAD))
+                               {
+                                       qglGetIntegerv(gltexturetypebindingenums[image->texturetype], &oldbindtexnum);
+
+                                       qglBindTexture(gltexturetypeenums[image->texturetype], image->texnum);
+                                       qglTexParameteri(gltexturetypeenums[image->texturetype], GL_TEXTURE_MAX_ANISOTROPY_EXT, old_aniso);CHECKGLERROR
+
+                                       qglBindTexture(gltexturetypeenums[image->texturetype], oldbindtexnum);
+                               }
+                       }
+               }
+       }
 }
 
 void R_MakeResizeBufferBigger(int size)
@@ -571,40 +614,62 @@ static void GL_SetupTextureParameters(int flags, int texturetype)
        CHECKGLERROR
 
        if (gl_support_anisotropy)
-               qglTexParameterf(textureenum, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_texture_anisotropy.value);
-       qglTexParameteri(textureenum, GL_TEXTURE_WRAP_S, wrapmode);
-       qglTexParameteri(textureenum, GL_TEXTURE_WRAP_T, wrapmode);
+       {
+               int aniso = bound(1, gl_texture_anisotropy.integer, gl_max_anisotropy);
+               if (gl_texture_anisotropy.integer != aniso)
+                       Cvar_SetValueQuick(&gl_texture_anisotropy, aniso);
+               qglTexParameteri(textureenum, GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso);CHECKGLERROR
+       }
+       qglTexParameteri(textureenum, GL_TEXTURE_WRAP_S, wrapmode);CHECKGLERROR
+       qglTexParameteri(textureenum, GL_TEXTURE_WRAP_T, wrapmode);CHECKGLERROR
        if (gltexturetypedimensions[texturetype] >= 3)
-               qglTexParameteri(textureenum, GL_TEXTURE_WRAP_R, wrapmode);
+       {
+               qglTexParameteri(textureenum, GL_TEXTURE_WRAP_R, wrapmode);CHECKGLERROR
+       }
 
+       CHECKGLERROR
        if (flags & TEXF_FORCENEAREST)
        {
                if (flags & TEXF_MIPMAP)
-                       qglTexParameteri(textureenum, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
+               {
+                       qglTexParameteri(textureenum, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);CHECKGLERROR
+               }
                else
-                       qglTexParameteri(textureenum, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-               qglTexParameteri(textureenum, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+               {
+                       qglTexParameteri(textureenum, GL_TEXTURE_MIN_FILTER, GL_NEAREST);CHECKGLERROR
+               }
+               qglTexParameteri(textureenum, GL_TEXTURE_MAG_FILTER, GL_NEAREST);CHECKGLERROR
        }
        else if (flags & TEXF_FORCELINEAR)
        {
                if (flags & TEXF_MIPMAP)
                {
                        if (gl_filter_min == GL_NEAREST_MIPMAP_LINEAR || gl_filter_min == GL_LINEAR_MIPMAP_LINEAR)
-                               qglTexParameteri(textureenum, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+                       {
+                               qglTexParameteri(textureenum, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);CHECKGLERROR
+                       }
                        else
-                               qglTexParameteri(textureenum, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+                       {
+                               qglTexParameteri(textureenum, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);CHECKGLERROR
+                       }
                }
                else
-                       qglTexParameteri(textureenum, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-               qglTexParameteri(textureenum, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+               {
+                       qglTexParameteri(textureenum, GL_TEXTURE_MIN_FILTER, GL_LINEAR);CHECKGLERROR
+               }
+               qglTexParameteri(textureenum, GL_TEXTURE_MAG_FILTER, GL_LINEAR);CHECKGLERROR
        }
        else
        {
                if (flags & TEXF_MIPMAP)
-                       qglTexParameteri(textureenum, GL_TEXTURE_MIN_FILTER, gl_filter_min);
+               {
+                       qglTexParameteri(textureenum, GL_TEXTURE_MIN_FILTER, gl_filter_min);CHECKGLERROR
+               }
                else
-                       qglTexParameteri(textureenum, GL_TEXTURE_MIN_FILTER, gl_filter_mag);
-               qglTexParameteri(textureenum, GL_TEXTURE_MAG_FILTER, gl_filter_mag);
+               {
+                       qglTexParameteri(textureenum, GL_TEXTURE_MIN_FILTER, gl_filter_mag);CHECKGLERROR
+               }
+               qglTexParameteri(textureenum, GL_TEXTURE_MAG_FILTER, gl_filter_mag);CHECKGLERROR
        }
 
        CHECKGLERROR
@@ -631,7 +696,7 @@ static void R_Upload(gltexture_t *glt, qbyte *data)
                if (glt->image->flags & GLTEXF_UPLOAD)
                {
                        glt->image->flags &= ~GLTEXF_UPLOAD;
-                       Con_DPrintf("uploaded new fragments image\n");
+                       Con_DPrint("uploaded new fragments image\n");
                        R_MakeResizeBufferBigger(glt->image->width * glt->image->height * glt->image->depth * glt->image->bytesperpixel);
                        memset(resizebuffer, 255, glt->image->width * glt->image->height * glt->image->depth * glt->image->bytesperpixel);
                        switch(glt->image->texturetype)
@@ -658,7 +723,7 @@ static void R_Upload(gltexture_t *glt, qbyte *data)
                if (prevbuffer == NULL)
                {
                        R_MakeResizeBufferBigger(glt->image->width * glt->image->height * glt->image->depth * glt->image->bytesperpixel);
-                       memset(resizebuffer, 255, glt->width * glt->height * glt->image->depth * glt->image->bytesperpixel);
+                       memset(resizebuffer, 0, glt->width * glt->height * glt->image->depth * glt->image->bytesperpixel);
                        prevbuffer = resizebuffer;
                }
                else if (glt->textype->textype == TEXTYPE_PALETTE)
@@ -705,7 +770,7 @@ static void R_Upload(gltexture_t *glt, qbyte *data)
                        width = glt->image->width;
                        height = glt->image->height;
                        depth = glt->image->depth;
-                       memset(resizebuffer, 255, width * height * depth * glt->image->bytesperpixel);
+                       memset(resizebuffer, 0, width * height * depth * glt->image->bytesperpixel);
                        prevbuffer = resizebuffer;
                }
                else
@@ -821,7 +886,7 @@ static void R_Upload(gltexture_t *glt, qbyte *data)
 
 static void R_FindImageForTexture(gltexture_t *glt)
 {
-       int i, j, best, best2, x, y, z, w, h, d;
+       int i, j, best, best2, x, y, z, w, h, d, picmip;
        textypeinfo_t *texinfo;
        gltexturepool_t *pool;
        gltextureimage_t *image, **imagechainpointer;
@@ -916,15 +981,18 @@ static void R_FindImageForTexture(gltexture_t *glt)
                image->type = GLIMAGETYPE_TILE;
                image->blockallocation = NULL;
 
+               picmip = 0;
+               if (glt->flags & TEXF_PICMIP)
+                       picmip = gl_picmip.integer;
                // calculate final size
-               if (r_max_size.integer > realmaxsize)
-                       Cvar_SetValue("r_max_size", realmaxsize);
+               if (gl_max_size.integer > realmaxsize)
+                       Cvar_SetValue("gl_max_size", realmaxsize);
                for (image->width = 1;image->width < glt->width;image->width <<= 1);
                for (image->height = 1;image->height < glt->height;image->height <<= 1);
                for (image->depth = 1;image->depth < glt->depth;image->depth <<= 1);
-               for (image->width >>= r_picmip.integer;image->width > r_max_size.integer;image->width >>= 1);
-               for (image->height >>= r_picmip.integer;image->height > r_max_size.integer;image->height >>= 1);
-               for (image->depth >>= r_picmip.integer;image->depth > r_max_size.integer;image->depth >>= 1);
+               for (image->width >>= picmip;image->width > gl_max_size.integer;image->width >>= 1);
+               for (image->height >>= picmip;image->height > gl_max_size.integer;image->height >>= 1);
+               for (image->depth >>= picmip;image->depth > gl_max_size.integer;image->depth >>= 1);
                if (image->width < 1) image->width = 1;
                if (image->height < 1) image->height = 1;
                if (image->depth < 1) image->depth = 1;
@@ -932,7 +1000,7 @@ static void R_FindImageForTexture(gltexture_t *glt)
        image->texturetype = glt->texturetype;
        image->glinternalformat = texinfo->glinternalformat;
        image->glformat = texinfo->glformat;
-       image->flags = (glt->flags & (TEXF_MIPMAP | TEXF_ALPHA | TEXF_CLAMP)) | GLTEXF_UPLOAD;
+       image->flags = (glt->flags & (TEXF_MIPMAP | TEXF_ALPHA | TEXF_CLAMP | TEXF_PICMIP)) | GLTEXF_UPLOAD;
        image->bytesperpixel = texinfo->internalbytesperpixel;
        image->sides = image->texturetype == GLTEXTURETYPE_CUBEMAP ? 6 : 1;
        // get a texture number to use