]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_textures.c
todo items went from 465 to 459 by finding items that was already done or duplicates
[xonotic/darkplaces.git] / gl_textures.c
index a57fe01295f00ef39b6e8a11085b4d377e8e8776..b4649e05df094efeb75d0914f29904f677c1eb0e 100644 (file)
@@ -38,7 +38,7 @@ static mempool_t *texturemempool;
 
 typedef struct textypeinfo_s
 {
-       int textype;
+       textype_t textype;
        int inputbytesperpixel;
        int internalbytesperpixel;
        float glinternalbytesperpixel;
@@ -47,17 +47,17 @@ typedef struct textypeinfo_s
 }
 textypeinfo_t;
 
-static textypeinfo_t textype_palette                = {TEXTYPE_PALETTE, 1, 4, 4.0f, GL_RGBA   , 3};
+static textypeinfo_t textype_palette                = {TEXTYPE_PALETTE, 1, 4, 4.0f, GL_BGRA   , 3};
+static textypeinfo_t textype_palette_alpha          = {TEXTYPE_PALETTE, 1, 4, 4.0f, GL_BGRA   , 4};
+static textypeinfo_t textype_palette_compress       = {TEXTYPE_PALETTE, 1, 4, 0.5f, GL_BGRA   , GL_COMPRESSED_RGB_ARB};
+static textypeinfo_t textype_palette_alpha_compress = {TEXTYPE_PALETTE, 1, 4, 1.0f, GL_BGRA   , GL_COMPRESSED_RGBA_ARB};
 static textypeinfo_t textype_rgba                   = {TEXTYPE_RGBA   , 4, 4, 4.0f, GL_RGBA   , 3};
-static textypeinfo_t textype_bgra                   = {TEXTYPE_BGRA   , 4, 4, 4.0f, GL_BGRA   , 3};
-static textypeinfo_t textype_palette_alpha          = {TEXTYPE_PALETTE, 1, 4, 4.0f, GL_RGBA   , 4};
 static textypeinfo_t textype_rgba_alpha             = {TEXTYPE_RGBA   , 4, 4, 4.0f, GL_RGBA   , 4};
-static textypeinfo_t textype_bgra_alpha             = {TEXTYPE_BGRA   , 4, 4, 4.0f, GL_BGRA   , 4};
-static textypeinfo_t textype_palette_compress       = {TEXTYPE_PALETTE, 1, 4, 0.5f, GL_RGBA   , GL_COMPRESSED_RGB_ARB};
 static textypeinfo_t textype_rgba_compress          = {TEXTYPE_RGBA   , 4, 4, 0.5f, GL_RGBA   , GL_COMPRESSED_RGB_ARB};
-static textypeinfo_t textype_bgra_compress          = {TEXTYPE_BGRA   , 4, 4, 0.5f, GL_BGRA   , GL_COMPRESSED_RGB_ARB};
-static textypeinfo_t textype_palette_alpha_compress = {TEXTYPE_PALETTE, 1, 4, 1.0f, GL_RGBA   , GL_COMPRESSED_RGBA_ARB};
 static textypeinfo_t textype_rgba_alpha_compress    = {TEXTYPE_RGBA   , 4, 4, 1.0f, GL_RGBA   , GL_COMPRESSED_RGBA_ARB};
+static textypeinfo_t textype_bgra                   = {TEXTYPE_BGRA   , 4, 4, 4.0f, GL_BGRA   , 3};
+static textypeinfo_t textype_bgra_alpha             = {TEXTYPE_BGRA   , 4, 4, 4.0f, GL_BGRA   , 4};
+static textypeinfo_t textype_bgra_compress          = {TEXTYPE_BGRA   , 4, 4, 0.5f, GL_BGRA   , GL_COMPRESSED_RGB_ARB};
 static textypeinfo_t textype_bgra_alpha_compress    = {TEXTYPE_BGRA   , 4, 4, 1.0f, GL_BGRA   , GL_COMPRESSED_RGBA_ARB};
 
 #define GLTEXTURETYPE_1D 0
@@ -141,10 +141,10 @@ static gltexturepool_t *gltexturepoolchain = NULL;
 
 static unsigned char *resizebuffer = NULL, *colorconvertbuffer;
 static int resizebuffersize = 0;
-static unsigned char *texturebuffer;
+static const unsigned char *texturebuffer;
 static int texturebuffersize = 0;
 
-static textypeinfo_t *R_GetTexTypeInfo(int textype, int flags)
+static textypeinfo_t *R_GetTexTypeInfo(textype_t textype, int flags)
 {
        if ((flags & TEXF_COMPRESS) && gl_texturecompression.integer >= 1 && gl_support_texture_compression)
        {
@@ -287,6 +287,13 @@ int R_RealGetTexture(rtexture_t *rt)
                return 0;
 }
 
+void R_PurgeTexture(rtexture_t *rt)
+{
+       if(rt && !(((gltexture_t*) rt)->flags & TEXF_PERSISTENT)) {
+               R_FreeTexture(rt);
+       }
+}
+
 void R_FreeTexture(rtexture_t *rt)
 {
        gltexture_t *glt, **gltpointer;
@@ -791,20 +798,16 @@ static void R_Upload(gltexture_t *glt, const unsigned char *data, int fragx, int
                for (depth  = 1;depth  < glt->inputdepth ;depth  <<= 1);
        }
 
-       R_MakeResizeBufferBigger(width * height * depth * glt->sides * glt->bytesperpixel);
-       R_MakeResizeBufferBigger(fragwidth * fragheight * fragdepth * glt->sides * glt->bytesperpixel);
-
-       if (prevbuffer == NULL)
+       if (prevbuffer != NULL)
        {
-               memset(resizebuffer, 0, fragwidth * fragheight * fragdepth * glt->bytesperpixel);
-               prevbuffer = resizebuffer;
-       }
-       else if (glt->textype->textype == TEXTYPE_PALETTE)
-       {
-               // promote paletted to RGBA, so we only have to worry about RGB and
-               // RGBA in the rest of this code
-               Image_Copy8bitRGBA(prevbuffer, colorconvertbuffer, fragwidth * fragheight * fragdepth * glt->sides, glt->palette);
-               prevbuffer = colorconvertbuffer;
+               R_MakeResizeBufferBigger(width * height * depth * glt->sides * glt->bytesperpixel);
+               R_MakeResizeBufferBigger(fragwidth * fragheight * fragdepth * glt->sides * glt->bytesperpixel);
+               if (glt->textype->textype == TEXTYPE_PALETTE)
+               {
+                       // promote paletted to BGRA, so we only have to worry about BGRA in the rest of this code
+                       Image_Copy8bitBGRA(prevbuffer, colorconvertbuffer, fragwidth * fragheight * fragdepth * glt->sides, glt->palette);
+                       prevbuffer = colorconvertbuffer;
+               }
        }
 
        if ((glt->flags & (TEXF_MIPMAP | TEXF_PICMIP | GLTEXF_UPLOAD)) == 0 && glt->inputwidth == glt->tilewidth && glt->inputheight == glt->tileheight && glt->inputdepth == glt->tiledepth)
@@ -835,7 +838,7 @@ static void R_Upload(gltexture_t *glt, const unsigned char *data, int fragx, int
                glt->flags &= ~GLTEXF_UPLOAD;
 
                // cubemaps contain multiple images and thus get processed a bit differently
-               if (glt->texturetype != GLTEXTURETYPE_CUBEMAP)
+               if ((prevbuffer != NULL) && (glt->texturetype != GLTEXTURETYPE_CUBEMAP))
                {
                        if (glt->inputwidth != width || glt->inputheight != height || glt->inputdepth != depth)
                        {
@@ -866,8 +869,17 @@ static void R_Upload(gltexture_t *glt, const unsigned char *data, int fragx, int
                        {
                                while (width > 1 || height > 1 || depth > 1)
                                {
-                                       Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1);
-                                       prevbuffer = resizebuffer;
+                                       if (prevbuffer != NULL)
+                                       {
+                                               Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1);
+                                               prevbuffer = resizebuffer;
+                                       }
+                                       else
+                                       {
+                                               if (width > 1) width >>= 1;
+                                               if (height > 1) height >>= 1;
+                                               if (depth > 1) depth >>= 1;
+                                       }
                                        qglTexImage1D(GL_TEXTURE_1D, mip++, glt->glinternalformat, width, 0, glt->glformat, GL_UNSIGNED_BYTE, prevbuffer);CHECKGLERROR
                                }
                        }
@@ -878,8 +890,17 @@ static void R_Upload(gltexture_t *glt, const unsigned char *data, int fragx, int
                        {
                                while (width > 1 || height > 1 || depth > 1)
                                {
-                                       Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1);
-                                       prevbuffer = resizebuffer;
+                                       if (prevbuffer != NULL)
+                                       {
+                                               Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1);
+                                               prevbuffer = resizebuffer;
+                                       }
+                                       else
+                                       {
+                                               if (width > 1) width >>= 1;
+                                               if (height > 1) height >>= 1;
+                                               if (depth > 1) depth >>= 1;
+                                       }
                                        qglTexImage2D(GL_TEXTURE_2D, mip++, glt->glinternalformat, width, height, 0, glt->glformat, GL_UNSIGNED_BYTE, prevbuffer);CHECKGLERROR
                                }
                        }
@@ -890,8 +911,17 @@ static void R_Upload(gltexture_t *glt, const unsigned char *data, int fragx, int
                        {
                                while (width > 1 || height > 1 || depth > 1)
                                {
-                                       Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1);
-                                       prevbuffer = resizebuffer;
+                                       if (prevbuffer != NULL)
+                                       {
+                                               Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1);
+                                               prevbuffer = resizebuffer;
+                                       }
+                                       else
+                                       {
+                                               if (width > 1) width >>= 1;
+                                               if (height > 1) height >>= 1;
+                                               if (depth > 1) depth >>= 1;
+                                       }
                                        qglTexImage3D(GL_TEXTURE_3D, mip++, glt->glinternalformat, width, height, depth, 0, glt->glformat, GL_UNSIGNED_BYTE, prevbuffer);CHECKGLERROR
                                }
                        }
@@ -899,21 +929,24 @@ static void R_Upload(gltexture_t *glt, const unsigned char *data, int fragx, int
                case GLTEXTURETYPE_CUBEMAP:
                        // convert and upload each side in turn,
                        // from a continuous block of input texels
-                       texturebuffer = prevbuffer;
+                       texturebuffer = prevbuffer ? (unsigned char *)prevbuffer : NULL;
                        for (i = 0;i < 6;i++)
                        {
                                prevbuffer = texturebuffer;
-                               texturebuffer += glt->inputwidth * glt->inputheight * glt->inputdepth * glt->textype->inputbytesperpixel;
-                               if (glt->inputwidth != width || glt->inputheight != height || glt->inputdepth != depth)
-                               {
-                                       Image_Resample32(prevbuffer, glt->inputwidth, glt->inputheight, glt->inputdepth, resizebuffer, width, height, depth, r_lerpimages.integer);
-                                       prevbuffer = resizebuffer;
-                               }
-                               // picmip/max_size
-                               while (width > glt->tilewidth || height > glt->tileheight || depth > glt->tiledepth)
+                               if (prevbuffer != NULL)
                                {
-                                       Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, glt->tilewidth, glt->tileheight, glt->tiledepth);
-                                       prevbuffer = resizebuffer;
+                                       texturebuffer += glt->inputwidth * glt->inputheight * glt->inputdepth * glt->textype->inputbytesperpixel;
+                                       if (glt->inputwidth != width || glt->inputheight != height || glt->inputdepth != depth)
+                                       {
+                                               Image_Resample32(prevbuffer, glt->inputwidth, glt->inputheight, glt->inputdepth, resizebuffer, width, height, depth, r_lerpimages.integer);
+                                               prevbuffer = resizebuffer;
+                                       }
+                                       // picmip/max_size
+                                       while (width > glt->tilewidth || height > glt->tileheight || depth > glt->tiledepth)
+                                       {
+                                               Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, glt->tilewidth, glt->tileheight, glt->tiledepth);
+                                               prevbuffer = resizebuffer;
+                                       }
                                }
                                mip = 0;
                                qglTexImage2D(cubemapside[i], mip++, glt->glinternalformat, width, height, 0, glt->glformat, GL_UNSIGNED_BYTE, prevbuffer);CHECKGLERROR
@@ -921,8 +954,17 @@ static void R_Upload(gltexture_t *glt, const unsigned char *data, int fragx, int
                                {
                                        while (width > 1 || height > 1 || depth > 1)
                                        {
-                                               Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1);
-                                               prevbuffer = resizebuffer;
+                                               if (prevbuffer != NULL)
+                                               {
+                                                       Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1);
+                                                       prevbuffer = resizebuffer;
+                                               }
+                                               else
+                                               {
+                                                       if (width > 1) width >>= 1;
+                                                       if (height > 1) height >>= 1;
+                                                       if (depth > 1) depth >>= 1;
+                                               }
                                                qglTexImage2D(cubemapside[i], mip++, glt->glinternalformat, width, height, 0, glt->glformat, GL_UNSIGNED_BYTE, prevbuffer);CHECKGLERROR
                                        }
                                }
@@ -952,7 +994,7 @@ static void R_UploadTexture (gltexture_t *glt)
                Con_Printf("R_UploadTexture: Texture %s already uploaded and destroyed.  Can not upload original image again.  Uploaded blank texture.\n", glt->identifier);
 }
 
-static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int depth, int sides, int flags, int textype, int texturetype, const unsigned char *data, const unsigned int *palette)
+static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int depth, int sides, int flags, textype_t textype, int texturetype, const unsigned char *data, const unsigned int *palette)
 {
        int i, size;
        gltexture_t *glt;
@@ -1061,22 +1103,22 @@ static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *iden
        return (rtexture_t *)glt;
 }
 
-rtexture_t *R_LoadTexture1D(rtexturepool_t *rtexturepool, const char *identifier, int width, const unsigned char *data, int textype, int flags, const unsigned int *palette)
+rtexture_t *R_LoadTexture1D(rtexturepool_t *rtexturepool, const char *identifier, int width, const unsigned char *data, textype_t textype, int flags, const unsigned int *palette)
 {
        return R_SetupTexture(rtexturepool, identifier, width, 1, 1, 1, flags, textype, GLTEXTURETYPE_1D, data, palette);
 }
 
-rtexture_t *R_LoadTexture2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, const unsigned char *data, int textype, int flags, const unsigned int *palette)
+rtexture_t *R_LoadTexture2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, const unsigned char *data, textype_t textype, int flags, const unsigned int *palette)
 {
        return R_SetupTexture(rtexturepool, identifier, width, height, 1, 1, flags, textype, GLTEXTURETYPE_2D, data, palette);
 }
 
-rtexture_t *R_LoadTexture3D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int depth, const unsigned char *data, int textype, int flags, const unsigned int *palette)
+rtexture_t *R_LoadTexture3D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int depth, const unsigned char *data, textype_t textype, int flags, const unsigned int *palette)
 {
        return R_SetupTexture(rtexturepool, identifier, width, height, depth, 1, flags, textype, GLTEXTURETYPE_3D, data, palette);
 }
 
-rtexture_t *R_LoadTextureCubeMap(rtexturepool_t *rtexturepool, const char *identifier, int width, const unsigned char *data, int textype, int flags, const unsigned int *palette)
+rtexture_t *R_LoadTextureCubeMap(rtexturepool_t *rtexturepool, const char *identifier, int width, const unsigned char *data, textype_t textype, int flags, const unsigned int *palette)
 {
        return R_SetupTexture(rtexturepool, identifier, width, width, 1, 6, flags, textype, GLTEXTURETYPE_CUBEMAP, data, palette);
 }
@@ -1113,3 +1155,9 @@ void R_UpdateTexture(rtexture_t *rt, const unsigned char *data, int x, int y, in
        R_Upload(glt, data, x, y, 0, width, height, 1);
 }
 
+void R_ClearTexture (rtexture_t *rt)
+{
+       gltexture_t *glt = (gltexture_t *)rt;
+
+       R_Upload( glt, NULL, 0, 0, 0, glt->tilewidth, glt->tileheight, glt->tiledepth );
+}