X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=gl_textures.c;h=6bcd55a8a4b51b3665d088b106c5ef16588c0e26;hb=e13119a0c2d45c917d429dda262803208fee95a9;hp=558b1f59cb457bfab6721dec5a539c06e0e5c99e;hpb=fabdca42b48cc4acf214c06adda9814e5cce8577;p=xonotic%2Fdarkplaces.git diff --git a/gl_textures.c b/gl_textures.c index 558b1f59..6bcd55a8 100644 --- a/gl_textures.c +++ b/gl_textures.c @@ -1,6 +1,7 @@ #include "quakedef.h" #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"}; @@ -120,7 +121,7 @@ gltexture_t; typedef struct gltexturepool_s { - int sentinel; + unsigned int sentinel; struct gltextureimage_s *imagechain; struct gltexture_s *gltchain; struct gltexturepool_s *next; @@ -222,20 +223,23 @@ void R_FreeTexture(rtexture_t *rt) // note: if freeing a fragment texture, this will not make the claimed // space available for new textures unless all other fragments in the // image are also freed - image = glt->image; - image->texturecount--; - if (image->texturecount < 1) + if (glt->image) { - for (gltimagepointer = &glt->pool->imagechain;*gltimagepointer && *gltimagepointer != image;gltimagepointer = &(*gltimagepointer)->imagechain); - if (*gltimagepointer == image) - *gltimagepointer = image->imagechain; - else - Host_Error("R_FreeTexture: image not linked in pool\n"); - if (image->texnum) - qglDeleteTextures(1, &image->texnum); - if (image->blockallocation) - Mem_Free(image->blockallocation); - Mem_Free(image); + image = glt->image; + image->texturecount--; + if (image->texturecount < 1) + { + for (gltimagepointer = &glt->pool->imagechain;*gltimagepointer && *gltimagepointer != image;gltimagepointer = &(*gltimagepointer)->imagechain); + if (*gltimagepointer == image) + *gltimagepointer = image->imagechain; + else + Host_Error("R_FreeTexture: image not linked in pool\n"); + if (image->texnum) + qglDeleteTextures(1, &image->texnum); + if (image->blockallocation) + Mem_Free(image->blockallocation); + Mem_Free(image); + } } if (glt->identifier) @@ -339,7 +343,7 @@ static void GL_TextureMode_f (void) } for (i = 0;i < 6;i++) - if (!Q_strcasecmp (modes[i].name, Cmd_Argv(1) ) ) + if (!strcasecmp (modes[i].name, Cmd_Argv(1) ) ) break; if (i == 6) { @@ -473,11 +477,18 @@ static void r_textures_start(void) texturemempool = Mem_AllocPool("Texture Info"); texturedatamempool = Mem_AllocPool("Texture Storage (not yet uploaded)"); textureprocessingmempool = Mem_AllocPool("Texture Processing Buffers"); + + // Disable JPEG screenshots if the DLL isn't loaded + if (! JPEG_OpenLibrary ()) + Cvar_SetValueQuick (&scr_screenshot_jpeg, 0); } static void r_textures_shutdown(void) { rtexturepool_t *temp; + + JPEG_CloseLibrary (); + while(gltexturepoolchain) { temp = (rtexturepool_t *) gltexturepoolchain; @@ -549,7 +560,7 @@ void R_MakeResizeBufferBigger(int size) static void GL_SetupTextureParameters(int flags, int texturetype) { int textureenum = gltexturetypeenums[texturetype]; - int wrapmode = (flags & TEXF_CLAMP) ? GL_CLAMP : GL_REPEAT; + int wrapmode = ((flags & TEXF_CLAMP) && gl_support_clamptoedge) ? GL_CLAMP_TO_EDGE : GL_REPEAT; CHECKGLERROR @@ -558,11 +569,35 @@ static void GL_SetupTextureParameters(int flags, int texturetype) if (gltexturetypedimensions[texturetype] >= 3) qglTexParameteri(textureenum, GL_TEXTURE_WRAP_R, wrapmode); - if (flags & TEXF_MIPMAP) - qglTexParameteri(textureenum, GL_TEXTURE_MIN_FILTER, gl_filter_min); + if (flags & TEXF_FORCENEAREST) + { + if (flags & TEXF_MIPMAP) + qglTexParameteri(textureenum, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + else + qglTexParameteri(textureenum, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + qglTexParameteri(textureenum, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + 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); + else + qglTexParameteri(textureenum, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + } + else + qglTexParameteri(textureenum, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameteri(textureenum, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } else - qglTexParameteri(textureenum, GL_TEXTURE_MIN_FILTER, gl_filter_mag); - qglTexParameteri(textureenum, GL_TEXTURE_MAG_FILTER, gl_filter_mag); + { + if (flags & TEXF_MIPMAP) + qglTexParameteri(textureenum, GL_TEXTURE_MIN_FILTER, gl_filter_min); + else + qglTexParameteri(textureenum, GL_TEXTURE_MIN_FILTER, gl_filter_mag); + qglTexParameteri(textureenum, GL_TEXTURE_MAG_FILTER, gl_filter_mag); + } CHECKGLERROR } @@ -950,6 +985,8 @@ static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *iden texinfo = R_GetTexTypeInfo(textype, flags); size = width * height * depth * sides * texinfo->inputbytesperpixel; + if (size < 1) + Sys_Error("R_LoadTexture: bogus texture size (%dx%dx%dx%dbppx%dsides = %d bytes)\n", width, height, depth, texinfo->inputbytesperpixel * 8, sides); // clear the alpha flag if the texture has no transparent pixels switch(textype) @@ -962,7 +999,7 @@ static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *iden { for (i = 0;i < size;i++) { - if (((qbyte *)&palette[data[i]])[3] == 255) + if (((qbyte *)&palette[data[i]])[3] < 255) { flags |= TEXF_ALPHA; break; @@ -1020,7 +1057,7 @@ static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *iden { glt->inputtexels = Mem_Alloc(texturedatamempool, size); if (glt->inputtexels == NULL) - Sys_Error("R_SetupTexture: out of memory\n"); + Sys_Error("R_LoadTexture: out of memory\n"); memcpy(glt->inputtexels, data, size); } else