]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_textures.c
Fix shader compile log again. Print error in any case, warnings only if developer...
[xonotic/darkplaces.git] / gl_textures.c
index 37c135edc45807fd14b62908a691e65ae55fe7c4..57c7633a349c5e737368b1da3466df5e0da64241 100644 (file)
@@ -38,7 +38,7 @@ cvar_t gl_texturecompression_reflectmask = {CVAR_SAVE, "gl_texturecompression_re
 cvar_t gl_texturecompression_sprites = {CVAR_SAVE, "gl_texturecompression_sprites", "1", "whether to compress sprites"};
 cvar_t gl_nopartialtextureupdates = {CVAR_SAVE, "gl_nopartialtextureupdates", "0", "use alternate path for dynamic lightmap updates that avoids a possibly slow code path in the driver"};
 cvar_t r_texture_dds_load_alphamode = {0, "r_texture_dds_load_alphamode", "1", "0: trust DDPF_ALPHAPIXELS flag, 1: texture format and brute force search if ambiguous, 2: texture format only"};
-cvar_t r_texture_dds_load_logfailure = {0, "r_texture_dds_load_logfailure", "0", "log missing DDS textures to ddstexturefailures.log"};
+cvar_t r_texture_dds_load_logfailure = {0, "r_texture_dds_load_logfailure", "0", "log missing DDS textures to ddstexturefailures.log, 0: done log, 1: log with no optional textures (_norm, glow etc.). 2: log all"};
 cvar_t r_texture_dds_swdecode = {0, "r_texture_dds_swdecode", "0", "0: don't software decode DDS, 1: software decode DDS if unsupported, 2: always software decode DDS"};
 
 qboolean       gl_filter_force = false;
@@ -175,6 +175,7 @@ typedef struct gltexture_s
        int texnum; // GL texture slot number
        int renderbuffernum; // GL renderbuffer slot number
        qboolean dirty; // indicates that R_RealGetTexture should be called
+       qboolean glisdepthstencil; // indicates that FBO attachment has to be GL_DEPTH_STENCIL_ATTACHMENT
        int gltexturetypeenum; // used by R_Mesh_TexBind
        // d3d stuff the backend needs
        void *d3dtexture;
@@ -370,7 +371,7 @@ void R_FreeTexture(rtexture_t *rt)
                if (glt->renderbuffernum)
                {
                        CHECKGLERROR
-                       qglDeleteRenderbuffersEXT(1, (GLuint *)&glt->renderbuffernum);CHECKGLERROR
+                       qglDeleteRenderbuffers(1, (GLuint *)&glt->renderbuffernum);CHECKGLERROR
                }
                break;
        case RENDERPATH_D3D9:
@@ -1758,6 +1759,7 @@ static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *iden
        glt->sides = glt->texturetype == GLTEXTURETYPE_CUBEMAP ? 6 : 1;
        glt->texnum = 0;
        glt->dirty = false;
+       glt->glisdepthstencil = false;
        glt->gltexturetypeenum = gltexturetypeenums[glt->texturetype];
        // init the dynamic texture attributes, too [11/22/2007 Black]
        glt->updatecallback = NULL;
@@ -1929,6 +1931,7 @@ rtexture_t *R_LoadTextureRenderBuffer(rtexturepool_t *rtexturepool, const char *
        glt->sides = glt->texturetype == GLTEXTURETYPE_CUBEMAP ? 6 : 1;
        glt->texnum = 0;
        glt->dirty = false;
+       glt->glisdepthstencil = glt->texturetype == TEXTYPE_DEPTHBUFFER24STENCIL8;
        glt->gltexturetypeenum = gltexturetypeenums[glt->texturetype];
        // init the dynamic texture attributes, too [11/22/2007 Black]
        glt->updatecallback = NULL;
@@ -1946,11 +1949,11 @@ rtexture_t *R_LoadTextureRenderBuffer(rtexturepool_t *rtexturepool, const char *
        case RENDERPATH_GLES1:
        case RENDERPATH_GLES2:
                CHECKGLERROR
-               qglGenRenderbuffersEXT(1, (GLuint *)&glt->renderbuffernum);CHECKGLERROR
-               qglBindRenderbufferEXT(GL_RENDERBUFFER, glt->renderbuffernum);CHECKGLERROR
-               qglRenderbufferStorageEXT(GL_RENDERBUFFER, glt->glinternalformat, glt->tilewidth, glt->tileheight);CHECKGLERROR
+               qglGenRenderbuffers(1, (GLuint *)&glt->renderbuffernum);CHECKGLERROR
+               qglBindRenderbuffer(GL_RENDERBUFFER, glt->renderbuffernum);CHECKGLERROR
+               qglRenderbufferStorage(GL_RENDERBUFFER, glt->glinternalformat, glt->tilewidth, glt->tileheight);CHECKGLERROR
                // note we can query the renderbuffer for info with glGetRenderbufferParameteriv for GL_WIDTH, GL_HEIGHt, GL_RED_SIZE, GL_GREEN_SIZE, GL_BLUE_SIZE, GL_GL_ALPHA_SIZE, GL_DEPTH_SIZE, GL_STENCIL_SIZE, GL_INTERNAL_FORMAT
-               qglBindRenderbufferEXT(GL_RENDERBUFFER, 0);CHECKGLERROR
+               qglBindRenderbuffer(GL_RENDERBUFFER, 0);CHECKGLERROR
                break;
        case RENDERPATH_D3D9:
 #ifdef SUPPORTD3D
@@ -2145,7 +2148,7 @@ int R_SaveTextureDDSFile(rtexture_t *rt, const char *filename, qboolean skipunco
 #endif
 }
 
-rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filename, qboolean srgb, int flags, qboolean *hasalphaflag, float *avgcolor, int miplevel) // DDS textures are opaque, so miplevel isn't a pointer but just seen as a hint
+rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filename, qboolean srgb, int flags, qboolean *hasalphaflag, float *avgcolor, int miplevel, qboolean optionaltexture) // DDS textures are opaque, so miplevel isn't a pointer but just seen as a hint
 {
        int i, size, dds_format_flags, dds_miplevels, dds_width, dds_height;
        //int dds_flags;
@@ -2164,7 +2167,7 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen
        unsigned char *dds;
        fs_offset_t ddsfilesize;
        unsigned int ddssize;
-       qboolean force_swdecode = (r_texture_dds_swdecode.integer > 1);
+       qboolean force_swdecode, npothack;
 
        if (cls.state == ca_dedicated)
                return NULL;
@@ -2174,7 +2177,7 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen
 
        if (!dds)
        {
-               if(r_texture_dds_load_logfailure.integer)
+               if (r_texture_dds_load_logfailure.integer && (r_texture_dds_load_logfailure.integer >= 2 || !optionaltexture))
                        Log_Printf("ddstexturefailures.log", "%s\n", filename);
                return NULL; // not found
        }
@@ -2238,9 +2241,9 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen
                        Con_Printf("^1%s: invalid DXT1 DDS image\n", filename);
                        return NULL;
                }
-               if(r_texture_dds_load_alphamode.integer && (flags & TEXF_ALPHA))
+               if (flags & TEXF_ALPHA)
                {
-                       if(r_texture_dds_load_alphamode.integer == 1)
+                       if (r_texture_dds_load_alphamode.integer == 1)
                        {
                                // check alpha
                                for (i = 0;i < size;i += bytesperblock)
@@ -2257,6 +2260,8 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen
                                else
                                        flags &= ~TEXF_ALPHA;
                        }
+                       else if (r_texture_dds_load_alphamode.integer == 0)
+                               textype = TEXTYPE_DXT1A;
                        else
                        {
                                flags &= ~TEXF_ALPHA;
@@ -2339,9 +2344,17 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen
        }
 
        force_swdecode = false;
+       npothack = 
+               (!vid.support.arb_texture_non_power_of_two &&
+                       (
+                               (dds_width & (dds_width - 1))
+                               ||
+                               (dds_height & (dds_height - 1))
+                       )
+               );
        if(bytesperblock)
        {
-               if(vid.support.arb_texture_compression && vid.support.ext_texture_compression_s3tc)
+               if(vid.support.arb_texture_compression && vid.support.ext_texture_compression_s3tc && !npothack)
                {
                        if(r_texture_dds_swdecode.integer > 1)
                                force_swdecode = true;
@@ -2452,7 +2465,7 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen
                                avgcolor[1] += ((c >>  5) & 0x3F) + ((c >> 21) & 0x3F);
                                avgcolor[2] += ((c      ) & 0x1F) + ((c >> 16) & 0x1F);
                                if(textype == TEXTYPE_DXT5)
-                                       avgcolor[3] += (0.5 * mippixels[i-8] + 0.5 * mippixels[i-7]);
+                                       avgcolor[3] += (mippixels[i-8] + (int) mippixels[i-7]) * (0.5f / 255.0f);
                                else if(textype == TEXTYPE_DXT3)
                                        avgcolor[3] += (
                                                  (mippixels_start[i-8] & 0x0F)
@@ -2463,11 +2476,11 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen
                                                + (mippixels_start[i-6] >> 4)
                                                + (mippixels_start[i-5] & 0x0F)
                                                + (mippixels_start[i-5] >> 4)
-                                              ) * (0.125f / 15.0f * 255.0f);
+                                              ) * (0.125f / 15.0f);
                                else
-                                       avgcolor[3] += 255;
+                                       avgcolor[3] += 1.0f;
                        }
-                       f = (float)bytesperblock / size;
+                       f = (float)bytesperblock / mipsize;
                        avgcolor[0] *= (0.5f / 31.0f) * f;
                        avgcolor[1] *= (0.5f / 63.0f) * f;
                        avgcolor[2] *= (0.5f / 31.0f) * f;
@@ -2482,7 +2495,7 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen
                                avgcolor[2] += mippixels[i];
                                avgcolor[3] += mippixels[i+3];
                        }
-                       f = (1.0f / 255.0f) * bytesperpixel / size;
+                       f = (1.0f / 255.0f) * bytesperpixel / mipsize;
                        avgcolor[0] *= f;
                        avgcolor[1] *= f;
                        avgcolor[2] *= f;
@@ -2619,6 +2632,12 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen
        glt->tiledepth = 1;
        glt->miplevels = dds_miplevels;
 
+       if(npothack)
+       {
+               for (glt->tilewidth = 1;glt->tilewidth < mipwidth;glt->tilewidth <<= 1);
+               for (glt->tileheight = 1;glt->tileheight < mipheight;glt->tileheight <<= 1);
+       }
+
        // texture uploading can take a while, so make sure we're sending keepalives
        CL_KeepaliveMessage(false);
 
@@ -2673,9 +2692,25 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen
 
        for (mip = 0;mip <= dds_miplevels;mip++) // <= to include the not-counted "largest" miplevel
        {
+               unsigned char *upload_mippixels = mippixels;
+               int upload_mipwidth = mipwidth;
+               int upload_mipheight = mipheight;
                mipsize = bytesperblock ? ((mipwidth+3)/4)*((mipheight+3)/4)*bytesperblock : mipwidth*mipheight*bytesperpixel;
                if (mippixels + mipsize > mippixels_start + mipsize_total)
                        break;
+               if(npothack)
+               {
+                       upload_mipwidth = (glt->tilewidth >> mip);
+                       upload_mipheight = (glt->tileheight >> mip);
+                       if(upload_mipwidth != mipwidth || upload_mipheight != mipheight)
+                       // I _think_ they always mismatch, but I was too lazy
+                       // to properly check, and this test here is really
+                       // harmless
+                       {
+                               upload_mippixels = (unsigned char *) Mem_Alloc(tempmempool, 4 * upload_mipwidth * upload_mipheight);
+                               Image_Resample32(mippixels, mipwidth, mipheight, 1, upload_mippixels, upload_mipwidth, upload_mipheight, 1, r_lerpimages.integer);
+                       }
+               }
                switch(vid.renderpath)
                {
                case RENDERPATH_GL11:
@@ -2685,11 +2720,11 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen
                case RENDERPATH_GLES2:
                        if (bytesperblock)
                        {
-                               qglCompressedTexImage2DARB(GL_TEXTURE_2D, mip, glt->glinternalformat, mipwidth, mipheight, 0, mipsize, mippixels);CHECKGLERROR
+                               qglCompressedTexImage2DARB(GL_TEXTURE_2D, mip, glt->glinternalformat, upload_mipwidth, upload_mipheight, 0, mipsize, upload_mippixels);CHECKGLERROR
                        }
                        else
                        {
-                               qglTexImage2D(GL_TEXTURE_2D, mip, glt->glinternalformat, mipwidth, mipheight, 0, glt->glformat, glt->gltype, mippixels);CHECKGLERROR
+                               qglTexImage2D(GL_TEXTURE_2D, mip, glt->glinternalformat, upload_mipwidth, upload_mipheight, 0, glt->glformat, glt->gltype, upload_mippixels);CHECKGLERROR
                        }
                        break;
                case RENDERPATH_D3D9:
@@ -2698,7 +2733,7 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen
                                D3DLOCKED_RECT d3dlockedrect;
                                if (IDirect3DTexture9_LockRect((IDirect3DTexture9*)glt->d3dtexture, mip, &d3dlockedrect, NULL, 0) == D3D_OK && d3dlockedrect.pBits)
                                {
-                                       memcpy(d3dlockedrect.pBits, mippixels, mipsize);
+                                       memcpy(d3dlockedrect.pBits, upload_mippixels, mipsize);
                                        IDirect3DTexture9_UnlockRect((IDirect3DTexture9*)glt->d3dtexture, mip);
                                }
                                break;
@@ -2715,11 +2750,13 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen
                        if (bytesperblock)
                                Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
                        else
-                               DPSOFTRAST_Texture_UpdateFull(glt->texnum, mippixels);
+                               DPSOFTRAST_Texture_UpdateFull(glt->texnum, upload_mippixels);
                        // DPSOFTRAST calculates its own mipmaps
                        mip = dds_miplevels;
                        break;
                }
+               if(upload_mippixels != mippixels)
+                       Mem_Free(upload_mippixels);
                mippixels += mipsize;
                if (mipwidth <= 1 && mipheight <= 1)
                {