X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=gl_textures.c;h=b4649e05df094efeb75d0914f29904f677c1eb0e;hb=8a7adad3d4cde384e23f8c80d82083968a82a68e;hp=b8b904a5d27aa50f81be3c9925c5c8eb12f166ca;hpb=0ac779724c6cfa529507a2486f5af5ebe48c1356;p=xonotic%2Fdarkplaces.git diff --git a/gl_textures.c b/gl_textures.c index b8b904a5..b4649e05 100644 --- a/gl_textures.c +++ b/gl_textures.c @@ -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 = (unsigned char *)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 ); +}