]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_textures.c
new argument "force" to gl_texturemode for more augenkrebs fun (and e.g. debugging...
[xonotic/darkplaces.git] / gl_textures.c
index edc5ff197c4288ea2fe392c330451fbf7f36d87c..9fe4c4782ad395971130999084bf4399f8a2c98c 100644 (file)
@@ -20,13 +20,16 @@ cvar_t gl_texturecompression_q3bsplightmaps = {CVAR_SAVE, "gl_texturecompression
 cvar_t gl_texturecompression_q3bspdeluxemaps = {CVAR_SAVE, "gl_texturecompression_q3bspdeluxemaps", "0", "whether to compress deluxemaps in q3bsp format levels (only levels compiled with q3map2 -deluxe have these)"};
 cvar_t gl_texturecompression_sky = {CVAR_SAVE, "gl_texturecompression_sky", "0", "whether to compress sky textures"};
 cvar_t gl_texturecompression_lightcubemaps = {CVAR_SAVE, "gl_texturecompression_lightcubemaps", "1", "whether to compress light cubemaps (spotlights and other light projection images)"};
+cvar_t gl_texturecompression_reflectmask = {CVAR_SAVE, "gl_texturecompression_reflectmask", "1", "whether to compress reflection cubemap masks (mask of which areas of the texture should reflect the generic shiny cubemap)"};
 cvar_t gl_nopartialtextureupdates = {CVAR_SAVE, "gl_nopartialtextureupdates", "1", "use alternate path for dynamic lightmap updates that avoids a possibly slow code path in the driver"};
 
+qboolean       gl_filter_force = false;
 int            gl_filter_min = GL_LINEAR_MIPMAP_LINEAR;
 int            gl_filter_mag = GL_LINEAR;
 
 
 static mempool_t *texturemempool;
+static memexpandablearray_t texturearray;
 
 // note: this must not conflict with TEXF_ flags in r_textures.h
 // bitmask for mismatch checking
@@ -40,31 +43,31 @@ typedef struct textypeinfo_s
        int inputbytesperpixel;
        int internalbytesperpixel;
        float glinternalbytesperpixel;
-       int glformat;
        int glinternalformat;
+       int glformat;
        int gltype;
 }
 textypeinfo_t;
 
 
-static textypeinfo_t textype_palette                = {TEXTYPE_PALETTE, 1, 4, 4.0f, GL_BGRA   , 3, GL_UNSIGNED_BYTE};
-static textypeinfo_t textype_palette_alpha          = {TEXTYPE_PALETTE, 1, 4, 4.0f, GL_BGRA   , 4, GL_UNSIGNED_BYTE};
-static textypeinfo_t textype_rgba                   = {TEXTYPE_RGBA   , 4, 4, 4.0f, GL_RGBA   , 3, GL_UNSIGNED_BYTE};
-static textypeinfo_t textype_rgba_alpha             = {TEXTYPE_RGBA   , 4, 4, 4.0f, GL_RGBA   , 4, GL_UNSIGNED_BYTE};
-static textypeinfo_t textype_rgba_compress          = {TEXTYPE_RGBA   , 4, 4, 0.5f, GL_RGBA   , GL_COMPRESSED_RGB_ARB, GL_UNSIGNED_BYTE};
-static textypeinfo_t textype_rgba_alpha_compress    = {TEXTYPE_RGBA   , 4, 4, 1.0f, GL_RGBA   , GL_COMPRESSED_RGBA_ARB, GL_UNSIGNED_BYTE};
-static textypeinfo_t textype_bgra                   = {TEXTYPE_BGRA   , 4, 4, 4.0f, GL_BGRA   , 3, GL_UNSIGNED_BYTE};
-static textypeinfo_t textype_bgra_alpha             = {TEXTYPE_BGRA   , 4, 4, 4.0f, GL_BGRA   , 4, GL_UNSIGNED_BYTE};
-static textypeinfo_t textype_bgra_compress          = {TEXTYPE_BGRA   , 4, 4, 0.5f, GL_BGRA   , GL_COMPRESSED_RGB_ARB, GL_UNSIGNED_BYTE};
-static textypeinfo_t textype_bgra_alpha_compress    = {TEXTYPE_BGRA   , 4, 4, 1.0f, GL_BGRA   , GL_COMPRESSED_RGBA_ARB, GL_UNSIGNED_BYTE};
-static textypeinfo_t textype_shadowmap16            = {TEXTYPE_SHADOWMAP,2,2, 2.0f, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT16_ARB, GL_UNSIGNED_SHORT};
-static textypeinfo_t textype_shadowmap24            = {TEXTYPE_SHADOWMAP,4,4, 4.0f, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT24_ARB, GL_UNSIGNED_INT};
-static textypeinfo_t textype_alpha                  = {TEXTYPE_ALPHA  , 1, 4, 4.0f, GL_ALPHA  , 4, GL_UNSIGNED_BYTE};
-static textypeinfo_t textype_dxt1                   = {TEXTYPE_DXT1   , 4, 0, 0.5f, 0         , GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 0};
-static textypeinfo_t textype_dxt1a                  = {TEXTYPE_DXT1A  , 4, 0, 0.5f, 0         , GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 0};
-static textypeinfo_t textype_dxt3                   = {TEXTYPE_DXT3   , 4, 0, 1.0f, 0         , GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 0};
-static textypeinfo_t textype_dxt5                   = {TEXTYPE_DXT5   , 4, 0, 1.0f, 0         , GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 0};
-static textypeinfo_t textype_colorbuffer            = {TEXTYPE_COLORBUFFER, 4, 4, 4.0f, GL_BGRA, 4, GL_UNSIGNED_BYTE};
+static textypeinfo_t textype_palette                = {TEXTYPE_PALETTE    , 1, 4, 4.0f, 3                               , GL_BGRA           , GL_UNSIGNED_BYTE };
+static textypeinfo_t textype_palette_alpha          = {TEXTYPE_PALETTE    , 1, 4, 4.0f, 4                               , GL_BGRA           , GL_UNSIGNED_BYTE };
+static textypeinfo_t textype_rgba                   = {TEXTYPE_RGBA       , 4, 4, 4.0f, 3                               , GL_RGBA           , GL_UNSIGNED_BYTE };
+static textypeinfo_t textype_rgba_alpha             = {TEXTYPE_RGBA       , 4, 4, 4.0f, 4                               , GL_RGBA           , GL_UNSIGNED_BYTE };
+static textypeinfo_t textype_rgba_compress          = {TEXTYPE_RGBA       , 4, 4, 0.5f, GL_COMPRESSED_RGB_S3TC_DXT1_EXT , GL_RGBA           , GL_UNSIGNED_BYTE };
+static textypeinfo_t textype_rgba_alpha_compress    = {TEXTYPE_RGBA       , 4, 4, 1.0f, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA           , GL_UNSIGNED_BYTE };
+static textypeinfo_t textype_bgra                   = {TEXTYPE_BGRA       , 4, 4, 4.0f, 3                               , GL_BGRA           , GL_UNSIGNED_BYTE };
+static textypeinfo_t textype_bgra_alpha             = {TEXTYPE_BGRA       , 4, 4, 4.0f, 4                               , GL_BGRA           , GL_UNSIGNED_BYTE };
+static textypeinfo_t textype_bgra_compress          = {TEXTYPE_BGRA       , 4, 4, 0.5f, GL_COMPRESSED_RGB_S3TC_DXT1_EXT , GL_BGRA           , GL_UNSIGNED_BYTE };
+static textypeinfo_t textype_bgra_alpha_compress    = {TEXTYPE_BGRA       , 4, 4, 1.0f, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_BGRA           , GL_UNSIGNED_BYTE };
+static textypeinfo_t textype_shadowmap16            = {TEXTYPE_SHADOWMAP  , 2, 2, 2.0f, GL_DEPTH_COMPONENT16_ARB        , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT};
+static textypeinfo_t textype_shadowmap24            = {TEXTYPE_SHADOWMAP  , 4, 4, 4.0f, GL_DEPTH_COMPONENT24_ARB        , GL_DEPTH_COMPONENT, GL_UNSIGNED_INT  };
+static textypeinfo_t textype_alpha                  = {TEXTYPE_ALPHA      , 1, 4, 4.0f, GL_ALPHA                        , GL_ALPHA          , GL_UNSIGNED_BYTE };
+static textypeinfo_t textype_dxt1                   = {TEXTYPE_DXT1       , 4, 0, 0.5f, GL_COMPRESSED_RGB_S3TC_DXT1_EXT , 0                 , 0                };
+static textypeinfo_t textype_dxt1a                  = {TEXTYPE_DXT1A      , 4, 0, 0.5f, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 0                 , 0                };
+static textypeinfo_t textype_dxt3                   = {TEXTYPE_DXT3       , 4, 0, 1.0f, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 0                 , 0                };
+static textypeinfo_t textype_dxt5                   = {TEXTYPE_DXT5       , 4, 0, 1.0f, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 0                 , 0                };
+static textypeinfo_t textype_colorbuffer            = {TEXTYPE_COLORBUFFER, 4, 4, 4.0f, 4                               , GL_BGRA           , GL_UNSIGNED_BYTE };
 
 
 typedef enum gltexturetype_e
@@ -159,7 +162,6 @@ static gltexturepool_t *gltexturepoolchain = NULL;
 static unsigned char *resizebuffer = NULL, *colorconvertbuffer;
 static int resizebuffersize = 0;
 static const unsigned char *texturebuffer;
-static int texturebuffersize = 0;
 
 static textypeinfo_t *R_GetTexTypeInfo(textype_t textype, int flags)
 {
@@ -178,15 +180,11 @@ static textypeinfo_t *R_GetTexTypeInfo(textype_t textype, int flags)
        case TEXTYPE_RGBA:
                if ((flags & TEXF_COMPRESS) && gl_texturecompression.integer >= 1 && vid.support.arb_texture_compression)
                        return (flags & TEXF_ALPHA) ? &textype_rgba_alpha_compress : &textype_rgba_compress;
-               else
-                       return (flags & TEXF_ALPHA) ? &textype_rgba_alpha : &textype_rgba;
-               break;
+               return (flags & TEXF_ALPHA) ? &textype_rgba_alpha : &textype_rgba;
        case TEXTYPE_BGRA:
                if ((flags & TEXF_COMPRESS) && gl_texturecompression.integer >= 1 && vid.support.arb_texture_compression)
                        return (flags & TEXF_ALPHA) ? &textype_bgra_alpha_compress : &textype_bgra_compress;
-               else
-                       return (flags & TEXF_ALPHA) ? &textype_bgra_alpha : &textype_bgra;
-               break;
+               return (flags & TEXF_ALPHA) ? &textype_bgra_alpha : &textype_bgra;
        case TEXTYPE_ALPHA:
                return &textype_alpha;
        case TEXTYPE_SHADOWMAP:
@@ -195,9 +193,9 @@ static textypeinfo_t *R_GetTexTypeInfo(textype_t textype, int flags)
                return &textype_colorbuffer;
        default:
                Host_Error("R_GetTexTypeInfo: unknown texture format");
-               return NULL;
+               break;
        }
-       return NULL; // this line only to hush compiler warnings
+       return NULL;
 }
 
 // dynamic texture code [11/22/2007 Black]
@@ -262,7 +260,7 @@ void R_FreeTexture(rtexture_t *rt)
 
        if (glt->inputtexels)
                Mem_Free(glt->inputtexels);
-       Mem_Free(glt);
+       Mem_ExpandableArray_FreeRecord(&texturearray, glt);
 }
 
 rtexturepool_t *R_AllocTexturePool(void)
@@ -327,6 +325,7 @@ static void GL_TextureMode_f (void)
 
        if (Cmd_Argc() == 1)
        {
+               Con_Printf("Texture mode is %sforced\n", gl_filter_force ? "" : "not ");
                for (i = 0;i < 6;i++)
                {
                        if (gl_filter_min == modes[i].minification)
@@ -339,7 +338,7 @@ static void GL_TextureMode_f (void)
                return;
        }
 
-       for (i = 0;i < 6;i++)
+       for (i = 0;i < sizeof(modes)/sizeof(*modes);i++)
                if (!strcasecmp (modes[i].name, Cmd_Argv(1) ) )
                        break;
        if (i == 6)
@@ -350,6 +349,7 @@ static void GL_TextureMode_f (void)
 
        gl_filter_min = modes[i].minification;
        gl_filter_mag = modes[i].magnification;
+       gl_filter_force = ((Cmd_Argc() > 2) && !strcasecmp(Cmd_Argv(2), "force"));
 
        // change all the existing mipmap texture objects
        // FIXME: force renderer(/client/something?) restart instead?
@@ -360,7 +360,7 @@ static void GL_TextureMode_f (void)
                for (glt = pool->gltchain;glt;glt = glt->chain)
                {
                        // only update already uploaded images
-                       if (glt->texnum && !(glt->flags & (TEXF_FORCENEAREST | TEXF_FORCELINEAR)))
+                       if (glt->texnum && (gl_filter_force || !(glt->flags & (TEXF_FORCENEAREST | TEXF_FORCELINEAR))))
                        {
                                oldbindtexnum = R_Mesh_TexBound(0, gltexturetypeenums[glt->texturetype]);
                                qglBindTexture(gltexturetypeenums[glt->texturetype], glt->texnum);CHECKGLERROR
@@ -523,6 +523,7 @@ static void r_textures_start(void)
        qglPixelStorei(GL_PACK_ALIGNMENT, 1);CHECKGLERROR
 
        texturemempool = Mem_AllocPool("texture management", 0, NULL);
+       Mem_ExpandableArray_NewArray(&texturearray, texturemempool, sizeof(gltexture_t), 512);
 
        // Disable JPEG screenshots if the DLL isn't loaded
        if (! JPEG_OpenLibrary ())
@@ -544,10 +545,10 @@ static void r_textures_shutdown(void)
        }
 
        resizebuffersize = 0;
-       texturebuffersize = 0;
        resizebuffer = NULL;
        colorconvertbuffer = NULL;
        texturebuffer = NULL;
+       Mem_ExpandableArray_FreeArray(&texturearray);
        Mem_FreePool(&texturemempool);
 }
 
@@ -557,7 +558,7 @@ static void r_textures_newmap(void)
 
 void R_Textures_Init (void)
 {
-       Cmd_AddCommand("gl_texturemode", &GL_TextureMode_f, "set texture filtering mode (GL_NEAREST, GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, etc)");
+       Cmd_AddCommand("gl_texturemode", &GL_TextureMode_f, "set texture filtering mode (GL_NEAREST, GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, etc); an additional argument 'force' forces the texture mode even in cases where it may not be appropriate");
        Cmd_AddCommand("r_texturestats", R_TextureStats_f, "print information about all loaded textures and some statistics");
        Cvar_RegisterVariable (&gl_max_size);
        Cvar_RegisterVariable (&gl_picmip);
@@ -574,6 +575,7 @@ void R_Textures_Init (void)
        Cvar_RegisterVariable (&gl_texturecompression_q3bspdeluxemaps);
        Cvar_RegisterVariable (&gl_texturecompression_sky);
        Cvar_RegisterVariable (&gl_texturecompression_lightcubemaps);
+       Cvar_RegisterVariable (&gl_texturecompression_reflectmask);
        Cvar_RegisterVariable (&gl_nopartialtextureupdates);
 
        R_RegisterModule("R_Textures", r_textures_start, r_textures_shutdown, r_textures_newmap);
@@ -668,7 +670,7 @@ static void GL_SetupTextureParameters(int flags, textype_t textype, int texturet
        }
 
        CHECKGLERROR
-       if (flags & TEXF_FORCENEAREST)
+       if (!gl_filter_force && flags & TEXF_FORCENEAREST)
        {
                if (flags & TEXF_MIPMAP)
                {
@@ -680,7 +682,7 @@ static void GL_SetupTextureParameters(int flags, textype_t textype, int texturet
                }
                qglTexParameteri(textureenum, GL_TEXTURE_MAG_FILTER, GL_NEAREST);CHECKGLERROR
        }
-       else if (flags & TEXF_FORCELINEAR)
+       else if (!gl_filter_force && flags & TEXF_FORCELINEAR)
        {
                if (flags & TEXF_MIPMAP)
                {
@@ -986,7 +988,7 @@ static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *iden
        else
                Con_Printf ("R_LoadTexture: input size changed after alpha fallback\n");
 
-       glt = (gltexture_t *)Mem_Alloc(texturemempool, sizeof(gltexture_t));
+       glt = (gltexture_t *)Mem_ExpandableArray_AllocRecord(&texturearray);
        if (identifier)
                strlcpy (glt->identifier, identifier, sizeof(glt->identifier));
        glt->pool = pool;
@@ -1195,7 +1197,9 @@ int R_SaveTextureDDSFile(rtexture_t *rt, const char *filename, qboolean skipunco
 
 rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filename, int flags, qboolean *hasalphaflag, float *avgcolor)
 {
-       int i, size, dds_flags, dds_format_flags, dds_miplevels, dds_width, dds_height, textype;
+       int i, size, dds_format_flags, dds_miplevels, dds_width, dds_height;
+       //int dds_flags;
+       textype_t textype;
        int bytesperblock, bytesperpixel;
        int mipcomplete;
        gltexture_t *glt;
@@ -1216,7 +1220,10 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen
        ddssize = ddsfilesize;
 
        if (!dds)
+       {
+               Log_Printf("ddstexturefailures.log", "%s\n", filename);
                return NULL; // not found
+       }
 
        if (ddsfilesize <= 128 || memcmp(dds, "DDS ", 4) || ddssize < (unsigned int)BuffLittleLong(dds+4) || BuffLittleLong(dds+76) != 32)
        {
@@ -1225,7 +1232,7 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen
                return NULL;
        }
 
-       dds_flags = BuffLittleLong(dds+8);
+       //dds_flags = BuffLittleLong(dds+8);
        dds_format_flags = BuffLittleLong(dds+80);
        dds_miplevels = (BuffLittleLong(dds+108) & 0x400000) ? BuffLittleLong(dds+28) : 1;
        dds_width = BuffLittleLong(dds+16);
@@ -1366,7 +1373,7 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen
 
        texinfo = R_GetTexTypeInfo(textype, flags);
 
-       glt = (gltexture_t *)Mem_Alloc(texturemempool, sizeof(gltexture_t));
+       glt = (gltexture_t *)Mem_ExpandableArray_AllocRecord(&texturearray);
        strlcpy (glt->identifier, filename, sizeof(glt->identifier));
        glt->pool = pool;
        glt->chain = pool->gltchain;