+ return R_SetupTexture(rtexturepool, identifier, width, width, 1, 6, R_ShadowMapTextureFlags(precision, filter), TEXTYPE_SHADOWMAP, GLTEXTURETYPE_CUBEMAP, NULL, NULL);
+}
+
+int R_SaveTextureDDSFile(rtexture_t *rt, const char *filename, qboolean skipuncompressed)
+{
+ gltexture_t *glt = (gltexture_t *)rt;
+ unsigned char *dds;
+ int oldbindtexnum;
+ int bytesperpixel = 0;
+ int bytesperblock = 0;
+ int dds_flags;
+ int dds_format_flags;
+ int dds_caps1;
+ int dds_caps2;
+ int ret;
+ int mip;
+ int mipmaps;
+ int mipinfo[16][4];
+ int ddssize = 128;
+ GLint internalformat;
+ const char *ddsfourcc;
+ if (!rt)
+ return -1; // NULL pointer
+ if (!strcmp(gl_version, "2.0.5885 WinXP Release"))
+ return -2; // broken driver - crashes on reading internal format
+ if (!qglGetTexLevelParameteriv)
+ return -2;
+ GL_ActiveTexture(0);
+ oldbindtexnum = R_Mesh_TexBound(0, gltexturetypeenums[glt->texturetype]);
+ qglBindTexture(gltexturetypeenums[glt->texturetype], glt->texnum);CHECKGLERROR
+ qglGetTexLevelParameteriv(gltexturetypeenums[glt->texturetype], 0, GL_TEXTURE_INTERNAL_FORMAT, &internalformat);
+ switch(internalformat)
+ {
+ default: ddsfourcc = NULL;bytesperpixel = 4;break;
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: ddsfourcc = "DXT1";bytesperblock = 8;break;
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: ddsfourcc = "DXT3";bytesperblock = 16;break;
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: ddsfourcc = "DXT5";bytesperblock = 16;break;
+ }
+ if (!bytesperblock && skipuncompressed)
+ return -3; // skipped
+ memset(mipinfo, 0, sizeof(mipinfo));
+ mipinfo[0][0] = glt->tilewidth;
+ mipinfo[0][1] = glt->tileheight;
+ mipmaps = 1;
+ if (glt->flags & TEXF_MIPMAP)
+ {
+ for (mip = 1;mip < 16;mip++)
+ {
+ mipinfo[mip][0] = mipinfo[mip-1][0] > 1 ? mipinfo[mip-1][0] >> 1 : 1;
+ mipinfo[mip][1] = mipinfo[mip-1][1] > 1 ? mipinfo[mip-1][1] >> 1 : 1;
+ if (mipinfo[mip][0] == 1 && mipinfo[mip][1] == 1)
+ {
+ mip++;
+ break;
+ }
+ }
+ mipmaps = mip;
+ }
+ for (mip = 0;mip < mipmaps;mip++)
+ {
+ mipinfo[mip][2] = bytesperblock ? ((mipinfo[mip][0]+3)/4)*((mipinfo[mip][1]+3)/4)*bytesperblock : mipinfo[mip][0]*mipinfo[mip][1]*bytesperpixel;
+ mipinfo[mip][3] = ddssize;
+ ddssize += mipinfo[mip][2];
+ }
+ dds = Mem_Alloc(tempmempool, ddssize);
+ if (!dds)
+ return -4;
+ dds_caps1 = 0x1000; // DDSCAPS_TEXTURE
+ dds_caps2 = 0;
+ if (bytesperblock)
+ {
+ dds_flags = 0x81007; // DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_LINEARSIZE
+ dds_format_flags = 0x4; // DDPF_FOURCC
+ }
+ else
+ {
+ dds_flags = 0x100F; // DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH
+ dds_format_flags = 0x41; // DDPF_RGB | DDPF_ALPHAPIXELS
+ }
+ if (mipmaps)
+ {
+ dds_flags |= 0x20000; // DDSD_MIPMAPCOUNT
+ dds_caps1 |= 0x400008; // DDSCAPS_MIPMAP | DDSCAPS_COMPLEX
+ }
+ memcpy(dds, "DDS ", 4);
+ StoreLittleLong(dds+4, ddssize);
+ StoreLittleLong(dds+8, dds_flags);
+ StoreLittleLong(dds+12, mipinfo[0][1]); // height
+ StoreLittleLong(dds+16, mipinfo[0][0]); // width
+ StoreLittleLong(dds+24, 1); // depth
+ StoreLittleLong(dds+28, mipmaps); // mipmaps
+ StoreLittleLong(dds+76, 32); // format size
+ StoreLittleLong(dds+80, dds_format_flags);
+ StoreLittleLong(dds+108, dds_caps1);
+ StoreLittleLong(dds+112, dds_caps2);
+ if (bytesperblock)
+ {
+ StoreLittleLong(dds+20, mipinfo[0][2]); // linear size
+ memcpy(dds+84, ddsfourcc, 4);
+ for (mip = 0;mip < mipmaps;mip++)
+ {
+ qglGetCompressedTexImageARB(gltexturetypeenums[glt->texturetype], mip, dds + mipinfo[mip][3]);CHECKGLERROR
+ }
+ }
+ else
+ {
+ StoreLittleLong(dds+20, mipinfo[0][0]*bytesperpixel); // pitch
+ StoreLittleLong(dds+88, bytesperpixel*8); // bits per pixel
+ dds[94] = dds[97] = dds[100] = dds[107] = 255; // bgra byte order masks
+ for (mip = 0;mip < mipmaps;mip++)
+ {
+ qglGetTexImage(gltexturetypeenums[glt->texturetype], mip, GL_BGRA, GL_UNSIGNED_BYTE, dds + mipinfo[mip][3]);CHECKGLERROR
+ }
+ }
+ qglBindTexture(gltexturetypeenums[glt->texturetype], oldbindtexnum);CHECKGLERROR
+ ret = FS_WriteFile(filename, dds, ddssize);
+ Mem_Free(dds);
+ return ret ? ddssize : -5;
+}
+
+rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filename, int flags, qboolean *hasalphaflag, float *avgcolor)
+{
+ int i, size, dds_format_flags, dds_miplevels, dds_width, dds_height;
+ //int dds_flags;
+ textype_t textype;
+ int bytesperblock, bytesperpixel;
+ int mipcomplete;