X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=gl_textures.c;h=3ce6755b0071c075abc5a39ae3b862da2ee69a2a;hb=7938a89abdf37e9452182f64bc9aec0293f493a3;hp=180447ff6f74856896a0782ba4f816ad24ea721f;hpb=f8363704e91dfe99ee1596e926183a86184c57cf;p=xonotic%2Fdarkplaces.git diff --git a/gl_textures.c b/gl_textures.c index 180447ff..3ce6755b 100644 --- a/gl_textures.c +++ b/gl_textures.c @@ -83,11 +83,16 @@ textypeinfo_t; #ifdef USE_GLES2 // framebuffer texture formats // GLES2 devices rarely support depth textures, so we actually use a renderbuffer there -static textypeinfo_t textype_shadowmap16 = {"shadowmap16", TEXTYPE_SHADOWMAP , 2, 2, 2.0f, GL_DEPTH_COMPONENT16 , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; -static textypeinfo_t textype_shadowmap24 = {"shadowmap24", TEXTYPE_SHADOWMAP , 2, 2, 2.0f, GL_DEPTH_COMPONENT16 , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; -static textypeinfo_t textype_colorbuffer = {"colorbuffer", TEXTYPE_COLORBUFFER , 4, 4, 4.0f, GL_RGBA , GL_BGRA , GL_UNSIGNED_BYTE }; -static textypeinfo_t textype_colorbuffer16f = {"colorbuffer16f", TEXTYPE_COLORBUFFER16F, 8, 8, 8.0f, GL_RGBA , GL_RGBA , GL_FLOAT }; -static textypeinfo_t textype_colorbuffer32f = {"colorbuffer32f", TEXTYPE_COLORBUFFER32F, 16, 16, 16.0f, GL_RGBA , GL_RGBA , GL_FLOAT }; +static textypeinfo_t textype_shadowmap16_comp = {"shadowmap16_comp", TEXTYPE_SHADOWMAP16_COMP , 2, 2, 2.0f, GL_DEPTH_COMPONENT16 , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; +static textypeinfo_t textype_shadowmap16_raw = {"shadowmap16_raw", TEXTYPE_SHADOWMAP16_RAW , 2, 2, 2.0f, GL_DEPTH_COMPONENT16 , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; +static textypeinfo_t textype_shadowmap24_comp = {"shadowmap24_comp", TEXTYPE_SHADOWMAP24_COMP , 2, 2, 2.0f, GL_DEPTH_COMPONENT16 , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; +static textypeinfo_t textype_shadowmap24_raw = {"shadowmap24_raw", TEXTYPE_SHADOWMAP24_RAW , 2, 2, 2.0f, GL_DEPTH_COMPONENT16 , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; +static textypeinfo_t textype_depth16 = {"depth16", TEXTYPE_DEPTHBUFFER16 , 2, 2, 2.0f, GL_DEPTH_COMPONENT16 , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; +static textypeinfo_t textype_depth24 = {"depth24", TEXTYPE_DEPTHBUFFER24 , 2, 2, 2.0f, GL_DEPTH_COMPONENT16 , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; +static textypeinfo_t textype_depth24stencil8 = {"depth24stencil8", TEXTYPE_DEPTHBUFFER24STENCIL8, 2, 2, 2.0f, GL_DEPTH_COMPONENT16 , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; +static textypeinfo_t textype_colorbuffer = {"colorbuffer", TEXTYPE_COLORBUFFER , 2, 2, 2.0f, GL_RGB565 , GL_RGBA , GL_UNSIGNED_SHORT_5_6_5}; +static textypeinfo_t textype_colorbuffer16f = {"colorbuffer16f", TEXTYPE_COLORBUFFER16F , 2, 2, 2.0f, GL_RGB565 , GL_RGBA , GL_UNSIGNED_SHORT_5_6_5}; +static textypeinfo_t textype_colorbuffer32f = {"colorbuffer32f", TEXTYPE_COLORBUFFER32F , 2, 2, 2.0f, GL_RGB565 , GL_RGBA , GL_UNSIGNED_SHORT_5_6_5}; // image formats: static textypeinfo_t textype_alpha = {"alpha", TEXTYPE_ALPHA , 1, 4, 4.0f, GL_ALPHA , GL_ALPHA , GL_UNSIGNED_BYTE }; @@ -99,11 +104,16 @@ static textypeinfo_t textype_bgra = {"bgra", static textypeinfo_t textype_bgra_alpha = {"bgra_alpha", TEXTYPE_BGRA , 4, 4, 4.0f, GL_RGBA , GL_BGRA , GL_UNSIGNED_BYTE }; #else // framebuffer texture formats -static textypeinfo_t textype_shadowmap16 = {"shadowmap16", TEXTYPE_SHADOWMAP , 2, 2, 2.0f, GL_DEPTH_COMPONENT16_ARB , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; -static textypeinfo_t textype_shadowmap24 = {"shadowmap24", TEXTYPE_SHADOWMAP , 4, 4, 4.0f, GL_DEPTH_COMPONENT24_ARB , GL_DEPTH_COMPONENT, GL_UNSIGNED_INT }; -static textypeinfo_t textype_colorbuffer = {"colorbuffer", TEXTYPE_COLORBUFFER , 4, 4, 4.0f, GL_RGBA , GL_BGRA , GL_UNSIGNED_BYTE }; -static textypeinfo_t textype_colorbuffer16f = {"colorbuffer16f", TEXTYPE_COLORBUFFER16F, 8, 8, 8.0f, GL_RGBA16F_ARB , GL_RGBA , GL_FLOAT }; -static textypeinfo_t textype_colorbuffer32f = {"colorbuffer32f", TEXTYPE_COLORBUFFER32F, 16, 16, 16.0f, GL_RGBA32F_ARB , GL_RGBA , GL_FLOAT }; +static textypeinfo_t textype_shadowmap16_comp = {"shadowmap16_comp", TEXTYPE_SHADOWMAP16_COMP , 2, 2, 2.0f, GL_DEPTH_COMPONENT16_ARB , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; +static textypeinfo_t textype_shadowmap16_raw = {"shadowmap16_raw", TEXTYPE_SHADOWMAP16_RAW , 2, 2, 2.0f, GL_DEPTH_COMPONENT16_ARB , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; +static textypeinfo_t textype_shadowmap24_comp = {"shadowmap24_comp", TEXTYPE_SHADOWMAP24_COMP , 4, 4, 4.0f, GL_DEPTH_COMPONENT24_ARB , GL_DEPTH_COMPONENT, GL_UNSIGNED_INT }; +static textypeinfo_t textype_shadowmap24_raw = {"shadowmap24_raw", TEXTYPE_SHADOWMAP24_RAW , 4, 4, 4.0f, GL_DEPTH_COMPONENT24_ARB , GL_DEPTH_COMPONENT, GL_UNSIGNED_INT }; +static textypeinfo_t textype_depth16 = {"depth16", TEXTYPE_DEPTHBUFFER16 , 2, 2, 2.0f, GL_DEPTH_COMPONENT16_ARB , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; +static textypeinfo_t textype_depth24 = {"depth24", TEXTYPE_DEPTHBUFFER24 , 4, 4, 4.0f, GL_DEPTH_COMPONENT24_ARB , GL_DEPTH_COMPONENT, GL_UNSIGNED_INT }; +static textypeinfo_t textype_depth24stencil8 = {"depth24stencil8", TEXTYPE_DEPTHBUFFER24STENCIL8, 4, 4, 4.0f, GL_DEPTH24_STENCIL8_EXT , GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT}; +static textypeinfo_t textype_colorbuffer = {"colorbuffer", TEXTYPE_COLORBUFFER , 4, 4, 4.0f, GL_RGBA , GL_BGRA , GL_UNSIGNED_BYTE }; +static textypeinfo_t textype_colorbuffer16f = {"colorbuffer16f", TEXTYPE_COLORBUFFER16F , 8, 8, 8.0f, GL_RGBA16F_ARB , GL_RGBA , GL_FLOAT }; +static textypeinfo_t textype_colorbuffer32f = {"colorbuffer32f", TEXTYPE_COLORBUFFER32F , 16, 16, 16.0f, GL_RGBA32F_ARB , GL_RGBA , GL_FLOAT }; // image formats: static textypeinfo_t textype_alpha = {"alpha", TEXTYPE_ALPHA , 1, 4, 4.0f, GL_ALPHA , GL_ALPHA , GL_UNSIGNED_BYTE }; @@ -163,12 +173,16 @@ typedef struct gltexture_s // this portion of the struct is exposed to the R_GetTexture macro for // speed reasons, must be identical in rtexture_t! 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; + void *d3dsurface; #ifdef SUPPORTD3D - qboolean d3disdepthsurface; // for depth/stencil surfaces + qboolean d3disrendertargetsurface; + qboolean d3disdepthstencilsurface; int d3dformat; int d3dusage; int d3dpool; @@ -252,22 +266,6 @@ static const unsigned char *texturebuffer; static textypeinfo_t *R_GetTexTypeInfo(textype_t textype, int flags) { -#ifdef USE_GLES2 - switch(textype) - { - case TEXTYPE_PALETTE: return (flags & TEXF_ALPHA) ? &textype_palette_alpha : &textype_palette; - case TEXTYPE_RGBA: return ((flags & TEXF_ALPHA) ? &textype_rgba_alpha : &textype_rgba); - case TEXTYPE_BGRA: return ((flags & TEXF_ALPHA) ? &textype_bgra_alpha : &textype_bgra); - case TEXTYPE_ALPHA: return &textype_alpha; - case TEXTYPE_SHADOWMAP: return (flags & TEXF_LOWPRECISION) ? &textype_shadowmap16 : &textype_shadowmap24; - case TEXTYPE_COLORBUFFER: return &textype_colorbuffer; - case TEXTYPE_COLORBUFFER16F: return &textype_colorbuffer16f; - case TEXTYPE_COLORBUFFER32F: return &textype_colorbuffer32f; - default: - Host_Error("R_GetTexTypeInfo: unknown texture format"); - break; - } -#else switch(textype) { case TEXTYPE_DXT1: return &textype_dxt1; @@ -278,10 +276,16 @@ static textypeinfo_t *R_GetTexTypeInfo(textype_t textype, int flags) case TEXTYPE_RGBA: return ((flags & TEXF_COMPRESS) && vid.support.ext_texture_compression_s3tc) ? ((flags & TEXF_ALPHA) ? &textype_rgba_alpha_compress : &textype_rgba_compress) : ((flags & TEXF_ALPHA) ? &textype_rgba_alpha : &textype_rgba); case TEXTYPE_BGRA: return ((flags & TEXF_COMPRESS) && vid.support.ext_texture_compression_s3tc) ? ((flags & TEXF_ALPHA) ? &textype_bgra_alpha_compress : &textype_bgra_compress) : ((flags & TEXF_ALPHA) ? &textype_bgra_alpha : &textype_bgra); case TEXTYPE_ALPHA: return &textype_alpha; - case TEXTYPE_SHADOWMAP: return (flags & TEXF_LOWPRECISION) ? &textype_shadowmap16 : &textype_shadowmap24; case TEXTYPE_COLORBUFFER: return &textype_colorbuffer; case TEXTYPE_COLORBUFFER16F: return &textype_colorbuffer16f; case TEXTYPE_COLORBUFFER32F: return &textype_colorbuffer32f; + case TEXTYPE_DEPTHBUFFER16: return &textype_depth16; + case TEXTYPE_DEPTHBUFFER24: return &textype_depth24; + case TEXTYPE_DEPTHBUFFER24STENCIL8: return &textype_depth24stencil8; + case TEXTYPE_SHADOWMAP16_COMP: return &textype_shadowmap16_comp; + case TEXTYPE_SHADOWMAP16_RAW: return &textype_shadowmap16_raw; + case TEXTYPE_SHADOWMAP24_COMP: return &textype_shadowmap24_comp; + case TEXTYPE_SHADOWMAP24_RAW: return &textype_shadowmap24_raw; case TEXTYPE_SRGB_DXT1: return &textype_sRGB_dxt1; case TEXTYPE_SRGB_DXT1A: return &textype_sRGB_dxt1a; case TEXTYPE_SRGB_DXT3: return &textype_sRGB_dxt3; @@ -293,7 +297,6 @@ static textypeinfo_t *R_GetTexTypeInfo(textype_t textype, int flags) Host_Error("R_GetTexTypeInfo: unknown texture format"); break; } -#endif return NULL; } @@ -365,11 +368,16 @@ void R_FreeTexture(rtexture_t *rt) CHECKGLERROR qglDeleteTextures(1, (GLuint *)&glt->texnum);CHECKGLERROR } + if (glt->renderbuffernum) + { + CHECKGLERROR + qglDeleteRenderbuffers(1, (GLuint *)&glt->renderbuffernum);CHECKGLERROR + } break; case RENDERPATH_D3D9: #ifdef SUPPORTD3D - if (glt->d3disdepthsurface) - IDirect3DSurface9_Release((IDirect3DSurface9 *)glt->d3dtexture); + if (glt->d3dsurface) + IDirect3DSurface9_Release((IDirect3DSurface9 *)glt->d3dsurface); else if (glt->tiledepth > 1) IDirect3DVolumeTexture9_Release((IDirect3DVolumeTexture9 *)glt->d3dtexture); else if (glt->sides == 6) @@ -377,6 +385,7 @@ void R_FreeTexture(rtexture_t *rt) else IDirect3DTexture9_Release((IDirect3DTexture9 *)glt->d3dtexture); glt->d3dtexture = NULL; + glt->d3dsurface = NULL; #endif break; case RENDERPATH_D3D10: @@ -557,7 +566,7 @@ static void GL_TextureMode_f (void) for (glt = pool->gltchain;glt;glt = glt->chain) { // only update already uploaded images - if (glt->d3dtexture && !glt->d3disdepthsurface && (gl_filter_force || !(glt->flags & (TEXF_FORCENEAREST | TEXF_FORCELINEAR)))) + if (glt->d3dtexture && !glt->d3dsurface && (gl_filter_force || !(glt->flags & (TEXF_FORCENEAREST | TEXF_FORCELINEAR)))) { if (glt->flags & TEXF_MIPMAP) { @@ -721,7 +730,7 @@ void R_TextureStats_Print(qboolean printeach, qboolean printpool, qboolean print for (glt = pool->gltchain;glt;glt = glt->chain) { glsize = R_CalcTexelDataSize(glt); - isloaded = glt->texnum != 0; + isloaded = glt->texnum != 0 || glt->renderbuffernum != 0 || glt->d3dtexture || glt->d3dsurface; pooltotal++; pooltotalt += glsize; pooltotalp += glt->inputdatasize; @@ -832,8 +841,8 @@ static void r_textures_devicelost(void) break; case RENDERPATH_D3D9: #ifdef SUPPORTD3D - if (glt->d3disdepthsurface) - IDirect3DSurface9_Release((IDirect3DSurface9 *)glt->d3dtexture); + if (glt->d3dsurface) + IDirect3DSurface9_Release((IDirect3DSurface9 *)glt->d3dsurface); else if (glt->tiledepth > 1) IDirect3DVolumeTexture9_Release((IDirect3DVolumeTexture9 *)glt->d3dtexture); else if (glt->sides == 6) @@ -841,6 +850,7 @@ static void r_textures_devicelost(void) else IDirect3DTexture9_Release((IDirect3DTexture9 *)glt->d3dtexture); glt->d3dtexture = NULL; + glt->d3dsurface = NULL; #endif break; case RENDERPATH_D3D10: @@ -877,9 +887,14 @@ static void r_textures_devicerestored(void) #ifdef SUPPORTD3D { HRESULT d3dresult; - if (glt->d3disdepthsurface) + if (glt->d3disrendertargetsurface) + { + if (FAILED(d3dresult = IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, glt->tilewidth, glt->tileheight, (D3DFORMAT)glt->d3dformat, D3DMULTISAMPLE_NONE, 0, false, (IDirect3DSurface9 **)&glt->d3dsurface, NULL))) + Sys_Error("IDirect3DDevice9_CreateRenderTarget failed!"); + } + else if (glt->d3disdepthstencilsurface) { - if (FAILED(d3dresult = IDirect3DDevice9_CreateDepthStencilSurface(vid_d3d9dev, glt->tilewidth, glt->tileheight, (D3DFORMAT)glt->d3dformat, D3DMULTISAMPLE_NONE, 0, false, (IDirect3DSurface9 **)&glt->d3dtexture, NULL))) + if (FAILED(d3dresult = IDirect3DDevice9_CreateDepthStencilSurface(vid_d3d9dev, glt->tilewidth, glt->tileheight, (D3DFORMAT)glt->d3dformat, D3DMULTISAMPLE_NONE, 0, false, (IDirect3DSurface9 **)&glt->d3dsurface, NULL))) Sys_Error("IDirect3DDevice9_CreateDepthStencilSurface failed!"); } else if (glt->tiledepth > 1) @@ -1012,7 +1027,7 @@ void R_Textures_Frame (void) } } -void R_MakeResizeBufferBigger(int size) +static void R_MakeResizeBufferBigger(int size) { if (resizebuffersize < size) { @@ -1096,24 +1111,23 @@ static void GL_SetupTextureParameters(int flags, textype_t textype, int texturet qglTexParameteri(textureenum, GL_TEXTURE_MAG_FILTER, gl_filter_mag);CHECKGLERROR } -#ifndef USE_GLES2 - if (textype == TEXTYPE_SHADOWMAP) + switch(textype) { - if (vid.support.arb_shadow) - { - if (flags & TEXF_COMPARE) - { - qglTexParameteri(textureenum, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);CHECKGLERROR - } - else - { - qglTexParameteri(textureenum, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);CHECKGLERROR - } - qglTexParameteri(textureenum, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);CHECKGLERROR - } + case TEXTYPE_SHADOWMAP16_COMP: + case TEXTYPE_SHADOWMAP24_COMP: + qglTexParameteri(textureenum, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);CHECKGLERROR + qglTexParameteri(textureenum, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);CHECKGLERROR + qglTexParameteri(textureenum, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);CHECKGLERROR + break; + case TEXTYPE_SHADOWMAP16_RAW: + case TEXTYPE_SHADOWMAP24_RAW: + qglTexParameteri(textureenum, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);CHECKGLERROR + qglTexParameteri(textureenum, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);CHECKGLERROR qglTexParameteri(textureenum, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);CHECKGLERROR + break; + default: + break; } -#endif CHECKGLERROR } @@ -1258,90 +1272,93 @@ static void R_UploadFullTexture(gltexture_t *glt, const unsigned char *data) case RENDERPATH_GL20: case RENDERPATH_GLES1: case RENDERPATH_GLES2: - CHECKGLERROR + if (glt->texnum) // not renderbuffers + { + CHECKGLERROR - // we need to restore the texture binding after finishing the upload - GL_ActiveTexture(0); - oldbindtexnum = R_Mesh_TexBound(0, gltexturetypeenums[glt->texturetype]); - qglBindTexture(gltexturetypeenums[glt->texturetype], glt->texnum);CHECKGLERROR + // we need to restore the texture binding after finishing the upload + GL_ActiveTexture(0); + oldbindtexnum = R_Mesh_TexBound(0, gltexturetypeenums[glt->texturetype]); + qglBindTexture(gltexturetypeenums[glt->texturetype], glt->texnum);CHECKGLERROR #ifdef GL_TEXTURE_COMPRESSION_HINT_ARB - if (qglGetCompressedTexImageARB) - { - if (gl_texturecompression.integer >= 2) - qglHint(GL_TEXTURE_COMPRESSION_HINT_ARB, GL_NICEST); - else - qglHint(GL_TEXTURE_COMPRESSION_HINT_ARB, GL_FASTEST); - CHECKGLERROR - } -#endif - switch(glt->texturetype) - { - case GLTEXTURETYPE_2D: - qglTexImage2D(GL_TEXTURE_2D, mip++, glt->glinternalformat, width, height, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR - if (glt->flags & TEXF_MIPMAP) - { - while (width > 1 || height > 1 || depth > 1) - { - Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1); - prevbuffer = resizebuffer; - qglTexImage2D(GL_TEXTURE_2D, mip++, glt->glinternalformat, width, height, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR - } - } - break; - case GLTEXTURETYPE_3D: -#ifndef USE_GLES2 - qglTexImage3D(GL_TEXTURE_3D, mip++, glt->glinternalformat, width, height, depth, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR - if (glt->flags & TEXF_MIPMAP) + if (qglGetCompressedTexImageARB) { - while (width > 1 || height > 1 || depth > 1) - { - Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1); - prevbuffer = resizebuffer; - qglTexImage3D(GL_TEXTURE_3D, mip++, glt->glinternalformat, width, height, depth, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR - } + if (gl_texturecompression.integer >= 2) + qglHint(GL_TEXTURE_COMPRESSION_HINT_ARB, GL_NICEST); + else + qglHint(GL_TEXTURE_COMPRESSION_HINT_ARB, GL_FASTEST); + CHECKGLERROR } #endif - break; - case GLTEXTURETYPE_CUBEMAP: - // convert and upload each side in turn, - // from a continuous block of input texels - texturebuffer = (unsigned char *)prevbuffer; - for (i = 0;i < 6;i++) + switch(glt->texturetype) { - 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) + case GLTEXTURETYPE_2D: + qglTexImage2D(GL_TEXTURE_2D, mip++, glt->glinternalformat, width, height, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR + if (glt->flags & TEXF_MIPMAP) { - Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, glt->tilewidth, glt->tileheight, glt->tiledepth); - prevbuffer = resizebuffer; + while (width > 1 || height > 1 || depth > 1) + { + Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1); + prevbuffer = resizebuffer; + qglTexImage2D(GL_TEXTURE_2D, mip++, glt->glinternalformat, width, height, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR + } } - mip = 0; - qglTexImage2D(cubemapside[i], mip++, glt->glinternalformat, width, height, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR + break; + case GLTEXTURETYPE_3D: +#ifndef USE_GLES2 + qglTexImage3D(GL_TEXTURE_3D, mip++, glt->glinternalformat, width, height, depth, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR if (glt->flags & TEXF_MIPMAP) { while (width > 1 || height > 1 || depth > 1) { Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1); prevbuffer = resizebuffer; - qglTexImage2D(cubemapside[i], mip++, glt->glinternalformat, width, height, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR + qglTexImage3D(GL_TEXTURE_3D, mip++, glt->glinternalformat, width, height, depth, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR } } +#endif + break; + case GLTEXTURETYPE_CUBEMAP: + // convert and upload each side in turn, + // from a continuous block of input texels + texturebuffer = (unsigned char *)prevbuffer; + 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) + { + 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, glt->gltype, prevbuffer);CHECKGLERROR + if (glt->flags & TEXF_MIPMAP) + { + while (width > 1 || height > 1 || depth > 1) + { + Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1); + prevbuffer = resizebuffer; + qglTexImage2D(cubemapside[i], mip++, glt->glinternalformat, width, height, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR + } + } + } + break; } - break; + GL_SetupTextureParameters(glt->flags, glt->textype->textype, glt->texturetype); + qglBindTexture(gltexturetypeenums[glt->texturetype], oldbindtexnum);CHECKGLERROR } - GL_SetupTextureParameters(glt->flags, glt->textype->textype, glt->texturetype); - qglBindTexture(gltexturetypeenums[glt->texturetype], oldbindtexnum);CHECKGLERROR break; case RENDERPATH_D3D9: #ifdef SUPPORTD3D - if (!(glt->flags & TEXF_RENDERTARGET)) + if (!(glt->flags & TEXF_RENDERTARGET) && glt->d3dtexture && !glt->d3dsurface) { D3DLOCKED_RECT d3dlockedrect; D3DLOCKED_BOX d3dlockedbox; @@ -1620,6 +1637,7 @@ static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *iden { temppixels = (unsigned char *)Mem_Alloc(tempmempool, size); memcpy(temppixels, data, size); + data = temppixels; } Image_MakeLinearColorsFromsRGB(temppixels, temppixels, width*height*depth*sides); } @@ -1685,7 +1703,10 @@ static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *iden } } break; - case TEXTYPE_SHADOWMAP: + case TEXTYPE_SHADOWMAP16_COMP: + case TEXTYPE_SHADOWMAP16_RAW: + case TEXTYPE_SHADOWMAP24_COMP: + case TEXTYPE_SHADOWMAP24_RAW: break; case TEXTYPE_DXT1: case TEXTYPE_SRGB_DXT1: @@ -1738,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; @@ -1779,20 +1801,15 @@ static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *iden case TEXTYPE_COLORBUFFER: d3dformat = D3DFMT_A8R8G8B8;break; case TEXTYPE_COLORBUFFER16F: d3dformat = D3DFMT_A16B16G16R16F;break; case TEXTYPE_COLORBUFFER32F: d3dformat = D3DFMT_A32B32G32R32F;break; - case TEXTYPE_SHADOWMAP: d3dformat = D3DFMT_D16;d3dusage = D3DUSAGE_DEPTHSTENCIL;break; // note: can not use D3DUSAGE_RENDERTARGET here case TEXTYPE_ALPHA: d3dformat = D3DFMT_A8;break; default: d3dformat = D3DFMT_A8R8G8B8;Sys_Error("R_LoadTexture: unsupported texture type %i when picking D3DFMT", (int)textype);break; } glt->d3dformat = d3dformat; glt->d3dusage = d3dusage; glt->d3dpool = d3dpool; - glt->d3disdepthsurface = textype == TEXTYPE_SHADOWMAP; - if (glt->d3disdepthsurface) - { - if (FAILED(d3dresult = IDirect3DDevice9_CreateDepthStencilSurface(vid_d3d9dev, glt->tilewidth, glt->tileheight, (D3DFORMAT)glt->d3dformat, D3DMULTISAMPLE_NONE, 0, false, (IDirect3DSurface9 **)&glt->d3dtexture, NULL))) - Sys_Error("IDirect3DDevice9_CreateDepthStencilSurface failed!"); - } - else if (glt->tiledepth > 1) + glt->d3disrendertargetsurface = false; + glt->d3disdepthstencilsurface = false; + if (glt->tiledepth > 1) { if (FAILED(d3dresult = IDirect3DDevice9_CreateVolumeTexture(vid_d3d9dev, glt->tilewidth, glt->tileheight, glt->tiledepth, glt->miplevels, glt->d3dusage, (D3DFORMAT)glt->d3dformat, (D3DPOOL)glt->d3dpool, (IDirect3DVolumeTexture9 **)&glt->d3dtexture, NULL))) Sys_Error("IDirect3DDevice9_CreateVolumeTexture failed!"); @@ -1827,7 +1844,13 @@ static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *iden case TEXTYPE_COLORBUFFER: tflags = DPSOFTRAST_TEXTURE_FORMAT_BGRA8;break; case TEXTYPE_COLORBUFFER16F: tflags = DPSOFTRAST_TEXTURE_FORMAT_RGBA16F;break; case TEXTYPE_COLORBUFFER32F: tflags = DPSOFTRAST_TEXTURE_FORMAT_RGBA32F;break; - case TEXTYPE_SHADOWMAP: tflags = DPSOFTRAST_TEXTURE_FORMAT_DEPTH;break; + case TEXTYPE_SHADOWMAP16_COMP: + case TEXTYPE_SHADOWMAP16_RAW: + case TEXTYPE_SHADOWMAP24_COMP: + case TEXTYPE_SHADOWMAP24_RAW: tflags = DPSOFTRAST_TEXTURE_FORMAT_DEPTH;break; + case TEXTYPE_DEPTHBUFFER16: + case TEXTYPE_DEPTHBUFFER24: + case TEXTYPE_DEPTHBUFFER24STENCIL8: tflags = DPSOFTRAST_TEXTURE_FORMAT_DEPTH;break; case TEXTYPE_ALPHA: tflags = DPSOFTRAST_TEXTURE_FORMAT_ALPHA8;break; default: Sys_Error("R_LoadTexture: unsupported texture type %i when picking DPSOFTRAST_TEXTURE_FLAGS", (int)textype); } @@ -1870,21 +1893,126 @@ rtexture_t *R_LoadTextureCubeMap(rtexturepool_t *rtexturepool, const char *ident return R_SetupTexture(rtexturepool, identifier, width, width, 1, 6, flags, miplevel, textype, GLTEXTURETYPE_CUBEMAP, data, palette); } -static int R_ShadowMapTextureFlags(int precision, qboolean filter) +rtexture_t *R_LoadTextureShadowMap2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, textype_t textype, qboolean filter) { - int flags = TEXF_RENDERTARGET | TEXF_CLAMP; - if (filter) - flags |= TEXF_FORCELINEAR | TEXF_COMPARE; - else - flags |= TEXF_FORCENEAREST; - if (precision <= 16) - flags |= TEXF_LOWPRECISION; - return flags; + return R_SetupTexture(rtexturepool, identifier, width, height, 1, 1, TEXF_RENDERTARGET | TEXF_CLAMP | (filter ? TEXF_FORCELINEAR : TEXF_FORCENEAREST), -1, textype, GLTEXTURETYPE_2D, NULL, NULL); } -rtexture_t *R_LoadTextureShadowMap2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int precision, qboolean filter) +rtexture_t *R_LoadTextureRenderBuffer(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, textype_t textype) { - return R_SetupTexture(rtexturepool, identifier, width, height, 1, 1, R_ShadowMapTextureFlags(precision, filter), -1, TEXTYPE_SHADOWMAP, GLTEXTURETYPE_2D, NULL, NULL); + gltexture_t *glt; + gltexturepool_t *pool = (gltexturepool_t *)rtexturepool; + textypeinfo_t *texinfo; + + if (cls.state == ca_dedicated) + return NULL; + + texinfo = R_GetTexTypeInfo(textype, TEXF_RENDERTARGET | TEXF_CLAMP); + + glt = (gltexture_t *)Mem_ExpandableArray_AllocRecord(&texturearray); + if (identifier) + strlcpy (glt->identifier, identifier, sizeof(glt->identifier)); + glt->pool = pool; + glt->chain = pool->gltchain; + pool->gltchain = glt; + glt->inputwidth = width; + glt->inputheight = height; + glt->inputdepth = 1; + glt->flags = TEXF_RENDERTARGET | TEXF_CLAMP | TEXF_FORCENEAREST; + glt->miplevel = 0; + glt->textype = texinfo; + glt->texturetype = textype; + glt->inputdatasize = width*height*texinfo->internalbytesperpixel; + glt->palette = NULL; + glt->glinternalformat = texinfo->glinternalformat; + glt->glformat = texinfo->glformat; + glt->gltype = texinfo->gltype; + glt->bytesperpixel = texinfo->internalbytesperpixel; + 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; + glt->updatacallback_data = NULL; + + GL_Texture_CalcImageSize(glt->texturetype, glt->flags, glt->miplevel, glt->inputwidth, glt->inputheight, glt->inputdepth, &glt->tilewidth, &glt->tileheight, &glt->tiledepth, &glt->miplevels); + + // upload the texture + // data may be NULL (blank texture for dynamic rendering) + switch(vid.renderpath) + { + case RENDERPATH_GL11: + case RENDERPATH_GL13: + case RENDERPATH_GL20: + case RENDERPATH_GLES1: + case RENDERPATH_GLES2: + 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 + qglBindRenderbuffer(GL_RENDERBUFFER, 0);CHECKGLERROR + break; + case RENDERPATH_D3D9: +#ifdef SUPPORTD3D + { + D3DFORMAT d3dformat; + HRESULT d3dresult; + glt->d3disrendertargetsurface = false; + glt->d3disdepthstencilsurface = false; + switch(textype) + { + case TEXTYPE_COLORBUFFER: d3dformat = D3DFMT_A8R8G8B8;glt->d3disrendertargetsurface = true;break; + case TEXTYPE_COLORBUFFER16F: d3dformat = D3DFMT_A16B16G16R16F;glt->d3disrendertargetsurface = true;break; + case TEXTYPE_COLORBUFFER32F: d3dformat = D3DFMT_A32B32G32R32F;glt->d3disrendertargetsurface = true;break; + case TEXTYPE_DEPTHBUFFER16: d3dformat = D3DFMT_D16;glt->d3disdepthstencilsurface = true;break; + case TEXTYPE_DEPTHBUFFER24: d3dformat = D3DFMT_D24X8;glt->d3disdepthstencilsurface = true;break; + case TEXTYPE_DEPTHBUFFER24STENCIL8: d3dformat = D3DFMT_D24S8;glt->d3disdepthstencilsurface = true;break; + default: d3dformat = D3DFMT_A8R8G8B8;Sys_Error("R_LoadTextureRenderbuffer: unsupported texture type %i when picking D3DFMT", (int)textype);break; + } + glt->d3dformat = d3dformat; + glt->d3dusage = 0; + glt->d3dpool = 0; + if (glt->d3disrendertargetsurface) + { + if (FAILED(d3dresult = IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, glt->tilewidth, glt->tileheight, (D3DFORMAT)glt->d3dformat, D3DMULTISAMPLE_NONE, 0, false, (IDirect3DSurface9 **)&glt->d3dsurface, NULL))) + Sys_Error("IDirect3DDevice9_CreateRenderTarget failed!"); + } + else if (glt->d3disdepthstencilsurface) + { + if (FAILED(d3dresult = IDirect3DDevice9_CreateDepthStencilSurface(vid_d3d9dev, glt->tilewidth, glt->tileheight, (D3DFORMAT)glt->d3dformat, D3DMULTISAMPLE_NONE, 0, false, (IDirect3DSurface9 **)&glt->d3dsurface, NULL))) + Sys_Error("IDirect3DDevice9_CreateDepthStencilSurface failed!"); + } + } +#endif + break; + case RENDERPATH_D3D10: + Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__); + break; + case RENDERPATH_D3D11: + Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__); + break; + case RENDERPATH_SOFT: + { + int tflags = 0; + switch(textype) + { + case TEXTYPE_COLORBUFFER: tflags = DPSOFTRAST_TEXTURE_FORMAT_BGRA8 | DPSOFTRAST_TEXTURE_FLAG_USEALPHA | DPSOFTRAST_TEXTURE_FLAG_CLAMPTOEDGE;break; + case TEXTYPE_COLORBUFFER16F: tflags = DPSOFTRAST_TEXTURE_FORMAT_RGBA16F | DPSOFTRAST_TEXTURE_FLAG_USEALPHA | DPSOFTRAST_TEXTURE_FLAG_CLAMPTOEDGE;break; + case TEXTYPE_COLORBUFFER32F: tflags = DPSOFTRAST_TEXTURE_FORMAT_RGBA32F | DPSOFTRAST_TEXTURE_FLAG_USEALPHA | DPSOFTRAST_TEXTURE_FLAG_CLAMPTOEDGE;break; + case TEXTYPE_DEPTHBUFFER16: + case TEXTYPE_DEPTHBUFFER24: + case TEXTYPE_DEPTHBUFFER24STENCIL8: tflags = DPSOFTRAST_TEXTURE_FORMAT_DEPTH | DPSOFTRAST_TEXTURE_FLAG_CLAMPTOEDGE;break; + default: Sys_Error("R_LoadTextureRenderbuffer: unsupported texture type %i when picking DPSOFTRAST_TEXTURE_FLAGS", (int)textype); + } + glt->texnum = DPSOFTRAST_Texture_New(tflags, glt->tilewidth, glt->tileheight, glt->tiledepth); + } + break; + } + + return (rtexture_t *)glt; } int R_SaveTextureDDSFile(rtexture_t *rt, const char *filename, qboolean skipuncompressed, qboolean hasalpha) @@ -1941,7 +2069,7 @@ int R_SaveTextureDDSFile(rtexture_t *rt, const char *filename, qboolean skipunco mipinfo[0][0] = glt->tilewidth; mipinfo[0][1] = glt->tileheight; mipmaps = 1; - if (glt->flags & TEXF_MIPMAP) + if ((glt->flags & TEXF_MIPMAP) && !(glt->tilewidth == 1 && glt->tilewidth == 1)) { for (mip = 1;mip < 16;mip++) { @@ -2020,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, 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) // 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; @@ -2031,9 +2159,11 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen gltexturepool_t *pool = (gltexturepool_t *)rtexturepool; textypeinfo_t *texinfo; int mip, mipwidth, mipheight, mipsize, mipsize_total; - unsigned int c; + unsigned int c, r, g, b; GLint oldbindtexnum = 0; - const unsigned char *mippixels, *ddspixels, *mippixels_start; + unsigned char *mippixels; + unsigned char *mippixels_start; + unsigned char *ddspixels; unsigned char *dds; fs_offset_t ddsfilesize; unsigned int ddssize; @@ -2199,6 +2329,18 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen return NULL; } + // when requesting a non-alpha texture and we have DXT3/5, convert to DXT1 + if(!(flags & TEXF_ALPHA) && (textype == TEXTYPE_DXT3 || textype == TEXTYPE_DXT5)) + { + textype = TEXTYPE_DXT1; + bytesperblock = 8; + ddssize -= 128; + ddssize /= 2; + for (i = 0;i < (int)ddssize;i += bytesperblock) + memcpy(&ddspixels[i], &ddspixels[(i<<1)+8], 8); + ddssize += 128; + } + force_swdecode = false; if(bytesperblock) { @@ -2351,6 +2493,101 @@ rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filen } } + // if we want sRGB, convert now + if(srgb) + { + if (vid.support.ext_texture_srgb) + { + switch(textype) + { + case TEXTYPE_DXT1: textype = TEXTYPE_SRGB_DXT1 ;break; + case TEXTYPE_DXT1A: textype = TEXTYPE_SRGB_DXT1A ;break; + case TEXTYPE_DXT3: textype = TEXTYPE_SRGB_DXT3 ;break; + case TEXTYPE_DXT5: textype = TEXTYPE_SRGB_DXT5 ;break; + case TEXTYPE_RGBA: textype = TEXTYPE_SRGB_RGBA ;break; + default: + break; + } + } + else + { + switch(textype) + { + case TEXTYPE_DXT1: + case TEXTYPE_DXT1A: + case TEXTYPE_DXT3: + case TEXTYPE_DXT5: + { + for (i = bytesperblock == 16 ? 8 : 0;i < mipsize_total;i += bytesperblock) + { + int c0, c1, c0new, c1new; + c0 = mippixels_start[i] + 256*mippixels_start[i+1]; + r = ((c0 >> 11) & 0x1F); + g = ((c0 >> 5) & 0x3F); + b = ((c0 ) & 0x1F); + r = floor(Image_LinearFloatFromsRGB(r * (255.0f / 31.0f)) * 31.0f + 0.5f); // these multiplications here get combined with multiplications in Image_LinearFloatFromsRGB + g = floor(Image_LinearFloatFromsRGB(g * (255.0f / 63.0f)) * 63.0f + 0.5f); // these multiplications here get combined with multiplications in Image_LinearFloatFromsRGB + b = floor(Image_LinearFloatFromsRGB(b * (255.0f / 31.0f)) * 31.0f + 0.5f); // these multiplications here get combined with multiplications in Image_LinearFloatFromsRGB + c0new = (r << 11) | (g << 5) | b; + c1 = mippixels_start[i+2] + 256*mippixels_start[i+3]; + r = ((c1 >> 11) & 0x1F); + g = ((c1 >> 5) & 0x3F); + b = ((c1 ) & 0x1F); + r = floor(Image_LinearFloatFromsRGB(r * (255.0f / 31.0f)) * 31.0f + 0.5f); // these multiplications here get combined with multiplications in Image_LinearFloatFromsRGB + g = floor(Image_LinearFloatFromsRGB(g * (255.0f / 63.0f)) * 63.0f + 0.5f); // these multiplications here get combined with multiplications in Image_LinearFloatFromsRGB + b = floor(Image_LinearFloatFromsRGB(b * (255.0f / 31.0f)) * 31.0f + 0.5f); // these multiplications here get combined with multiplications in Image_LinearFloatFromsRGB + c1new = (r << 11) | (g << 5) | b; + // swap the colors if needed to fix order + if(c0 > c1) // thirds + { + if(c0new < c1new) + { + c = c0new; + c0new = c1new; + c1new = c; + if(c0new == c1new) + mippixels_start[i+4] ^= 0x55; + mippixels_start[i+5] ^= 0x55; + mippixels_start[i+6] ^= 0x55; + mippixels_start[i+7] ^= 0x55; + } + else if(c0new == c1new) + { + mippixels_start[i+4] = 0x00; + mippixels_start[i+5] = 0x00; + mippixels_start[i+6] = 0x00; + mippixels_start[i+7] = 0x00; + } + } + else // half + transparent + { + if(c0new > c1new) + { + c = c0new; + c0new = c1new; + c1new = c; + mippixels_start[i+4] ^= (~mippixels_start[i+4] >> 1) & 0x55; + mippixels_start[i+5] ^= (~mippixels_start[i+5] >> 1) & 0x55; + mippixels_start[i+6] ^= (~mippixels_start[i+6] >> 1) & 0x55; + mippixels_start[i+7] ^= (~mippixels_start[i+7] >> 1) & 0x55; + } + } + mippixels_start[i] = c0new & 255; + mippixels_start[i+1] = c0new >> 8; + mippixels_start[i+2] = c1new & 255; + mippixels_start[i+3] = c1new >> 8; + } + } + break; + case TEXTYPE_RGBA: + Image_MakeLinearColorsFromsRGB(mippixels, mippixels, mipsize_total / bytesperblock); + break; + default: + break; + } + } + } + // when not requesting mipmaps, do not load them if(!(flags & TEXF_MIPMAP)) dds_miplevels = 0;