Added support for my extended miptex stuff for high-colour map textures.

This commit is contained in:
Shpoike 2020-03-07 09:03:46 +00:00
parent c2c9a68ff1
commit 27168ec47b
6 changed files with 342 additions and 92 deletions

View file

@ -560,6 +560,90 @@ qboolean Mod_CheckFullbrights (byte *pixels, int count)
return false;
}
static texture_t *Mod_LoadMipTex(miptex_t *mt, byte *lumpend, enum srcformat *fmt, unsigned int *width, unsigned int *height, unsigned int *pixelbytes)
{
//if offsets[0] is 0, then we've no legacy data (offsets[3] signifies the end of the extension data.
byte *extdata;
texture_t *tx;
byte *srcdata = NULL;
size_t sz;
if (!mt->offsets[0]) //the legacy data was omitted. we may still have block-compression though.
extdata = (byte*)(mt+1);
else if (mt->offsets[0] == sizeof(miptex_t) &&
mt->offsets[1] == mt->offsets[0]+(mt->width>>0)*(mt->height>>0) &&
mt->offsets[2] == mt->offsets[1]+(mt->width>>1)*(mt->height>>1) &&
mt->offsets[3] == mt->offsets[2]+(mt->width>>2)*(mt->height>>2))
{ //miptex makes sense and matches the standard 4-mip-levels.
extdata = (byte*)mt + mt->offsets[3]+(mt->width>>3)*(mt->height>>3);
//FIXME: halflife - leshort=256, palette[256][3].
//extdata += 2+256*3;
}
else //the numbers don't match what we expect... something weird is going on here... don't misinterpret it.
extdata = lumpend;
if (extdata+4 <= lumpend && extdata[0] == 0 && extdata[1]==0xfb && extdata[2]==0x2b && extdata[3]==0xaf)
for (extdata+=4; extdata+8 < lumpend; extdata += sz)
{
sz = (extdata[0]<<0)|(extdata[1]<<8)|(extdata[2]<<16)|(extdata[3]<<24);
if (sz < 8 || sz > lumpend-extdata) break; //bad! bad! bad!
else if (sz <= 16) continue; //nope, no idea
*fmt = TexMgr_FormatForCode((char*)extdata+4);
if (*fmt == SRC_EXTERNAL)
continue; //nope, no idea
*width = (extdata[8]<<0)|(extdata[9]<<8)|(extdata[10]<<16)|(extdata[11]<<24);
*height = (extdata[12]<<0)|(extdata[13]<<8)|(extdata[14]<<16)|(extdata[15]<<24);
if (*width != TexMgr_SafeTextureSize(*width) || *width != TexMgr_SafeTextureSize(*width))
continue; //nope, can't use that. drivers are too lame (or gl_max_size is too low).
*pixelbytes = TexMgr_ImageSize(*width, *height, *fmt);
if (16+*pixelbytes == sz)
srcdata = extdata+16;
break;
}
if (!srcdata)
{ //no replacements, load the 8bit data.
*fmt = SRC_INDEXED;
*width = mt->width;
*height = mt->height;
*pixelbytes = mt->width*mt->height;
if (LittleLong (mt->offsets[0]))
srcdata = (byte*)mt+LittleLong(mt->offsets[0]);
}
tx = (texture_t *) Hunk_AllocName (sizeof(texture_t) + *pixelbytes, loadname );
memcpy (tx->name, mt->name, sizeof(tx->name));
tx->name[sizeof(tx->name)-1] = 0; //just in case...
tx->width = mt->width;
tx->height = mt->height;
if (srcdata)
{
// ericw -- check for pixels extending past the end of the lump.
// appears in the wild; e.g. jam2_tronyn.bsp (func_mapjam2),
// kellbase1.bsp (quoth), and can lead to a segfault if we read past
// the end of the .bsp file buffer
if ((srcdata + *pixelbytes) > lumpend)
{
Con_DPrintf("Texture %s extends past end of lump\n", mt->name);
*pixelbytes = q_max(0, lumpend - srcdata);
}
memcpy ( tx+1, srcdata, *pixelbytes);
}
else
{
size_t x,y;
for(y=0;y<tx->width;y++)
for(x=0;x<tx->width;x++)
((byte*)(tx+1))[y*tx->width+x] = (((x>>2)^(y>>2))&1)?6:2;
}
return tx;
}
/*
=================
Mod_LoadTextures
@ -567,7 +651,7 @@ Mod_LoadTextures
*/
void Mod_LoadTextures (lump_t *l)
{
int i, j, pixels, num, maxanim, altmax;
int i, j, num, maxanim, altmax;
miptex_t *mt;
texture_t *tx, *tx2;
texture_t *anims[10];
@ -583,6 +667,9 @@ void Mod_LoadTextures (lump_t *l)
extern byte *hunk_base;
//johnfitz
qboolean malloced; //spike
enum srcformat fmt; //spike
unsigned int imgwidth, imgheight, imgpixels;
unsigned int mipend;
//johnfitz -- don't return early if no textures; still need to create dummy texture
if (!l->filelen)
@ -602,68 +689,37 @@ void Mod_LoadTextures (lump_t *l)
loadmodel->numtextures = nummiptex + 2; //johnfitz -- need 2 dummy texture chains for missing textures
loadmodel->textures = (texture_t **) Hunk_AllocName (loadmodel->numtextures * sizeof(*loadmodel->textures) , loadname);
for (i=0 ; i<nummiptex ; i++)
//spike -- rewrote this loop to run backwards (to make it easier to track the end of the miptex) and added handling for extra texture block compression.
for (i = nummiptex, mipend=l->filelen; i --> 0; )
{
m->dataofs[i] = LittleLong(m->dataofs[i]);
if (m->dataofs[i] == -1)
continue;
if (m->dataofs[i] >= mipend)
mipend = l->filelen; //o.O something weird!
mt = (miptex_t *)((byte *)m + m->dataofs[i]);
mt->width = LittleLong (mt->width);
mt->height = LittleLong (mt->height);
// for (j=0 ; j<MIPLEVELS ; j++)
// mt->offsets[j] = LittleLong (mt->offsets[j]);
for (j=0 ; j<MIPLEVELS ; j++)
mt->offsets[j] = LittleLong (mt->offsets[j]);
if ( (mt->width & 15) || (mt->height & 15) )
Sys_Error ("Texture %s is not 16 aligned", mt->name);
// spike -- quakespasm doesn't use the submips anyway
pixels = mt->width*mt->height;
//pixels = mt->width*mt->height/64*85;
tx = (texture_t *) Hunk_AllocName (sizeof(texture_t) +pixels, loadname );
tx = Mod_LoadMipTex(mt, (mod_base + l->fileofs + mipend), &fmt, &imgwidth, &imgheight, &imgpixels);
loadmodel->textures[i] = tx;
memcpy (tx->name, mt->name, sizeof(tx->name));
tx->width = mt->width;
tx->height = mt->height;
// for (j=0 ; j<MIPLEVELS ; j++)
// tx->offsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t);
// the pixels immediately follow the structures
if (!LittleLong (mt->offsets[0]))
{ // spike -- support tyrlight-ericw's -notex argument to avoid gpl violations from embedded textures
size_t x,y;
for(y=0;y<tx->width;y++)
for(x=0;x<tx->width;x++)
((byte*)(tx+1))[y*tx->width+x] = (((x>>2)^(y>>2))&1)?6:2;
}
else
{
// ericw -- check for pixels extending past the end of the lump.
// appears in the wild; e.g. jam2_tronyn.bsp (func_mapjam2),
// kellbase1.bsp (quoth), and can lead to a segfault if we read past
// the end of the .bsp file buffer
if (((byte*)(mt+1) + pixels) > (mod_base + l->fileofs + l->filelen))
{
Con_DPrintf("Texture %s extends past end of lump\n", mt->name);
pixels = q_max(0, (mod_base + l->fileofs + l->filelen) - (byte*)(mt+1));
}
//spike -- this is actually a pointless waste of memory.
//its not like this data will actually be used beyond this function in any gl renderer.
//this makes copying it pointless
//which in turn makes the pointer-to-array-of-pointers-to-texture a bit silly.
memcpy ( tx+1, mt+1, pixels);
}
tx->update_warp = false; //johnfitz
tx->warpimage = NULL; //johnfitz
tx->fullbright = NULL; //johnfitz
mipend = m->dataofs[i];
//johnfitz -- lots of changes
if (!isDedicated) //no texture uploading for dedicated server
{
if (!q_strncasecmp(tx->name,"sky",3)) //sky texture //also note -- was Q_strncmp, changed to match qbsp
Sky_LoadTexture (tx);
Sky_LoadTexture (tx, fmt, imgwidth, imgheight);
else if (tx->name[0] == '*') //warping texture
{
//external textures -- first look in "textures/mapname/" then look in "textures/"
@ -688,8 +744,8 @@ void Mod_LoadTextures (lump_t *l)
{
q_snprintf (texturename, sizeof(texturename), "%s:%s", loadmodel->name, tx->name);
offset = (src_offset_t)(mt+1) - (src_offset_t)mod_base;
tx->gltexture = TexMgr_LoadImage (loadmodel, texturename, tx->width, tx->height,
SRC_INDEXED, (byte *)(tx+1), loadmodel->name, offset, TEXPREF_NONE);
tx->gltexture = TexMgr_LoadImage (loadmodel, texturename, imgwidth, imgheight,
fmt, (byte *)(tx+1), loadmodel->name, offset, TEXPREF_NONE);
}
//now create the warpimage, using dummy data from the hunk to create the initial image
@ -749,18 +805,18 @@ void Mod_LoadTextures (lump_t *l)
{
q_snprintf (texturename, sizeof(texturename), "%s:%s", loadmodel->name, tx->name);
offset = (src_offset_t)(mt+1) - (src_offset_t)mod_base;
if (Mod_CheckFullbrights ((byte *)(tx+1), pixels))
if (fmt == SRC_INDEXED && Mod_CheckFullbrights ((byte *)(tx+1), imgpixels))
{
tx->gltexture = TexMgr_LoadImage (loadmodel, texturename, tx->width, tx->height,
SRC_INDEXED, (byte *)(tx+1), loadmodel->name, offset, TEXPREF_MIPMAP | TEXPREF_NOBRIGHT | extraflags);
tx->gltexture = TexMgr_LoadImage (loadmodel, texturename, imgwidth, imgheight,
fmt, (byte *)(tx+1), loadmodel->name, offset, TEXPREF_MIPMAP | TEXPREF_NOBRIGHT | extraflags);
q_snprintf (texturename, sizeof(texturename), "%s:%s_glow", loadmodel->name, tx->name);
tx->fullbright = TexMgr_LoadImage (loadmodel, texturename, tx->width, tx->height,
SRC_INDEXED, (byte *)(tx+1), loadmodel->name, offset, TEXPREF_MIPMAP | TEXPREF_FULLBRIGHT | extraflags);
tx->fullbright = TexMgr_LoadImage (loadmodel, texturename, imgwidth, imgheight,
fmt, (byte *)(tx+1), loadmodel->name, offset, TEXPREF_MIPMAP | TEXPREF_FULLBRIGHT | extraflags);
}
else
{
tx->gltexture = TexMgr_LoadImage (loadmodel, texturename, tx->width, tx->height,
SRC_INDEXED, (byte *)(tx+1), loadmodel->name, offset, TEXPREF_MIPMAP | extraflags);
tx->gltexture = TexMgr_LoadImage (loadmodel, texturename, imgwidth, imgheight,
fmt, (byte *)(tx+1), loadmodel->name, offset, TEXPREF_MIPMAP | extraflags);
}
}
if (malloced)

View file

@ -97,43 +97,55 @@ Sky_LoadTexture
A sky texture is 256*128, with the left side being a masked overlay
==============
*/
void Sky_LoadTexture (texture_t *mt)
void Sky_LoadTexture (texture_t *mt, enum srcformat fmt, unsigned int srcwidth, unsigned int height)
{
char texturename[64];
int i, j, p, r, g, b, count;
int i, p, r, g, b, count;
byte *src;
static byte front_data[128*128]; //FIXME: Hunk_Alloc
static byte back_data[128*128]; //FIXME: Hunk_Alloc
byte *front_data;
byte *back_data;
unsigned *rgba;
int rows, columns;
int bb,bw,bh;
int width = srcwidth/2;
TexMgr_BlockSize(fmt, &bb, &bw, &bh);
columns = (width+bw-1) / bw;
rows = (height+bh-1) / bh;
front_data = Hunk_AllocName (bb*columns*rows*2, "skytex");
back_data = front_data+bb*columns*rows;
src = (byte *)(mt+1);
// extract back layer and upload
for (i=0 ; i<128 ; i++)
for (j=0 ; j<128 ; j++)
back_data[(i*128) + j] = src[i*256 + j + 128];
for (i=0 ; i<rows ; i++)
memcpy(back_data+bb*i*columns, src+bb*(i*columns*2 + columns), columns*bb);
q_snprintf(texturename, sizeof(texturename), "%s:%s_back", loadmodel->name, mt->name);
solidskytexture = TexMgr_LoadImage (loadmodel, texturename, 128, 128, SRC_INDEXED, back_data, "", (src_offset_t)back_data, TEXPREF_NONE);
solidskytexture = TexMgr_LoadImage (loadmodel, texturename, width, height, fmt, back_data, "", (src_offset_t)back_data, TEXPREF_NONE);
// extract front layer and upload
for (i=0 ; i<128 ; i++)
for (j=0 ; j<128 ; j++)
for (i=0 ; i<rows ; i++)
memcpy(front_data+bb*i*columns, src+bb*(i*columns*2), columns*bb);
if (fmt == SRC_INDEXED)
{ //the lame texmgr only knows one transparent index...
for (i=0 ; i<width*height ; i++)
{
front_data[(i*128) + j] = src[i*256 + j];
if (front_data[(i*128) + j] == 0)
front_data[(i*128) + j] = 255;
if (front_data[i] == 0)
front_data[i] = 255;
}
}
q_snprintf(texturename, sizeof(texturename), "%s:%s_front", loadmodel->name, mt->name);
alphaskytexture = TexMgr_LoadImage (loadmodel, texturename, 128, 128, SRC_INDEXED, front_data, "", (src_offset_t)front_data, TEXPREF_ALPHA);
alphaskytexture = TexMgr_LoadImage (loadmodel, texturename, width, height, fmt, front_data, "", (src_offset_t)front_data, TEXPREF_ALPHA);
// calculate r_fastsky color based on average of all opaque foreground colors
// calculate r_fastsky color based on average of all opaque foreground colors, if we can.
r = g = b = count = 0;
for (i=0 ; i<128 ; i++)
for (j=0 ; j<128 ; j++)
if (fmt == SRC_INDEXED)
{
for (i=0 ; i<width*height ; i++)
{
p = src[i*256 + j];
p = src[i];
if (p != 0)
{
rgba = &d_8to24table[p];
@ -143,6 +155,7 @@ void Sky_LoadTexture (texture_t *mt)
count++;
}
}
}
skyflatcolor[0] = (float)r/(count*255);
skyflatcolor[1] = (float)g/(count*255);
skyflatcolor[2] = (float)b/(count*255);

View file

@ -47,6 +47,56 @@ unsigned int d_8to24table_conchars[256];
unsigned int d_8to24table_shirt[256];
unsigned int d_8to24table_pants[256];
static struct
{
const char *mipextname;
int internalformat;
int format;
int type; //for non-compressed formats
int blockbytes;
int blockwidth;
int blockheight;
qboolean *supported;
} compressedformats[] =
{
{NULL}, //SRC_INDEXED
{NULL}, //SRC_LIGHTMAP
{NULL}, //SRC_RGBA
{NULL}, //SRC_EXTERNAL
{"RGBA", GL_RGBA,GL_RGBA,GL_UNSIGNED_INT_8_8_8_8_REV, 4, 1, 1, NULL},
{"RGB", GL_RGB,GL_RGB,GL_UNSIGNED_BYTE, 3, 1, 1, NULL},
{"565", GL_RGB565,GL_RGB,GL_UNSIGNED_SHORT_5_6_5, 2, 1, 1, NULL},
{"4444", GL_RGBA4,GL_RGBA,GL_UNSIGNED_SHORT_4_4_4_4, 2, 1, 1, NULL},
{"5551", GL_RGB5_A1,GL_RGBA,GL_UNSIGNED_SHORT_5_5_5_1, 2, 1, 1, NULL},
{"LUM8", GL_LUMINANCE8,GL_LUMINANCE,GL_UNSIGNED_BYTE, 1, 1, 1, NULL},
{"EXP5", GL_RGB9_E5,GL_RGB,GL_UNSIGNED_INT_5_9_9_9_REV, 4, 1, 1, &gl_texture_astc},
{"BC1", GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,0,0, 8, 4, 4, &gl_texture_s3tc},
{"BC2", GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,0,0, 16, 4, 4, &gl_texture_s3tc},
{"BC3", GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,0,0, 16, 4, 4, &gl_texture_s3tc},
{"BC4", GL_COMPRESSED_RED_RGTC1,0,0, 8, 4, 4, &gl_texture_rgtc},
{"BC5", GL_COMPRESSED_RG_RGTC2,0,0, 16, 4, 4, &gl_texture_rgtc},
{"BC6", GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT,0,0, 16, 4, 4, &gl_texture_bptc},
{"BC7", GL_COMPRESSED_RGBA_BPTC_UNORM,0,0, 16, 4, 4, &gl_texture_bptc},
{"ETC1", GL_COMPRESSED_RGB8_ETC2,0,0, 8, 4, 4, &gl_texture_etc2},
{"ETC2", GL_COMPRESSED_RGB8_ETC2,0,0, 8, 4, 4, &gl_texture_etc2},
{"ETCP", GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,0,0,8, 4, 4, &gl_texture_etc2},
{"ETCA", GL_COMPRESSED_RGBA8_ETC2_EAC,0,0, 16, 4, 4, &gl_texture_etc2},
{"AST4", GL_COMPRESSED_RGBA_ASTC_4x4_KHR,0,0, 16, 4, 4, &gl_texture_astc},
{"AS54", GL_COMPRESSED_RGBA_ASTC_5x4_KHR,0,0, 16, 4, 4, &gl_texture_astc},
{"AST5", GL_COMPRESSED_RGBA_ASTC_5x5_KHR,0,0, 16, 5, 5, &gl_texture_astc},
{"AS65", GL_COMPRESSED_RGBA_ASTC_6x5_KHR,0,0, 16, 4, 4, &gl_texture_astc},
{"AST6", GL_COMPRESSED_RGBA_ASTC_6x6_KHR,0,0, 16, 6, 6, &gl_texture_astc},
{"AS85", GL_COMPRESSED_RGBA_ASTC_8x5_KHR,0,0, 16, 4, 4, &gl_texture_astc},
{"AS86", GL_COMPRESSED_RGBA_ASTC_8x6_KHR,0,0, 16, 4, 4, &gl_texture_astc},
{"AST8", GL_COMPRESSED_RGBA_ASTC_8x8_KHR,0,0, 16, 8, 8, &gl_texture_astc},
{"AS05", GL_COMPRESSED_RGBA_ASTC_10x5_KHR,0,0, 16, 4, 4, &gl_texture_astc},
{"AS06", GL_COMPRESSED_RGBA_ASTC_10x6_KHR,0,0, 16, 4, 4, &gl_texture_astc},
{"AS08", GL_COMPRESSED_RGBA_ASTC_10x8_KHR,0,0, 16, 4, 4, &gl_texture_astc},
{"AST0", GL_COMPRESSED_RGBA_ASTC_10x10_KHR,0,0, 16, 8, 8, &gl_texture_astc},
{"AST2", GL_COMPRESSED_RGBA_ASTC_12x12_KHR,0,0, 16, 8, 8, &gl_texture_astc},
};
/*
================================================================================
@ -1096,6 +1146,134 @@ static void TexMgr_LoadImage32 (gltexture_t *glt, unsigned *data)
TexMgr_SetFilterModes (glt);
}
void TexMgr_BlockSize (enum srcformat format, int *bytes, int *width, int *height)
{
*width = 1;
*height = 1;
switch(format)
{
case SRC_RGBA:
*bytes = 4;
break;
case SRC_LIGHTMAP:
*bytes = lightmap_bytes;
break;
case SRC_INDEXED:
*bytes = 1;
break;
case SRC_EXTERNAL:
*bytes = 0;
break;
default:
*bytes = compressedformats[format].blockbytes;
*width = compressedformats[format].blockwidth;
*height = compressedformats[format].blockheight;
break;
}
}
size_t TexMgr_ImageSize (int width, int height, enum srcformat format)
{
int miplevel, mipwidth, mipheight;
size_t mipbytes = 0, blockbytes;
unsigned int blockwidth, blockheight;
switch(format)
{
case SRC_RGBA:
return width*height*4;
case SRC_LIGHTMAP:
return width*height*lightmap_bytes;
case SRC_INDEXED:
return width*height;
case SRC_EXTERNAL: //panic
Con_Printf("TexMgr_ImageCompressedSize called for SRC_EXTERNAL\n");
return 0;
default:
//a compressed format with multiple mip levels in it
blockbytes = compressedformats[format].blockbytes;
blockwidth = compressedformats[format].blockwidth;
blockheight = compressedformats[format].blockheight;
for (miplevel = 0; ; miplevel++)
{
mipwidth = width >> miplevel;
mipheight = height >> miplevel;
if (!mipwidth && !mipheight)
break;
mipwidth = q_max(1,mipwidth); //include the 1*1 mip with non-square textures.
mipheight = q_max(1,mipheight);
mipbytes += blockbytes*((mipwidth+blockwidth-1)/blockwidth)*((mipheight+blockheight-1)/blockheight);
}
return mipbytes;
}
}
enum srcformat TexMgr_FormatForCode (const char *code)
{
size_t i;
for (i = 0; i < sizeof(compressedformats)/sizeof(compressedformats[0]); i++)
{
if (!compressedformats[i].mipextname)
continue;
if (!strncasecmp(code, compressedformats[i].mipextname, 4))
return i;
}
return SRC_EXTERNAL;
}
static void TexMgr_LoadImageCompressed (gltexture_t *glt, byte *data)
{
int internalformat, format, type, miplevel, mipwidth, mipheight, picmip;
size_t mipbytes, blockbytes;
unsigned int blockwidth, blockheight;
internalformat = compressedformats[glt->source_format].internalformat;
format = compressedformats[glt->source_format].format;
type = compressedformats[glt->source_format].type;
blockbytes = compressedformats[glt->source_format].blockbytes;
blockwidth = compressedformats[glt->source_format].blockwidth;
blockheight = compressedformats[glt->source_format].blockheight;
//no premultiply support.
//no npot fallback support
// mipmap down
picmip = ((glt->flags & TEXPREF_NOPICMIP) || !(glt->flags & TEXPREF_MIPMAP)) ? 0 : q_max((int)gl_picmip.value, 0);
//make sure the picmip level is not bigger than the number of mips that we have available...
while (picmip && (!(glt->width>>picmip) || !(glt->height>>picmip)))
picmip--;
if (type && blockbytes < 4)
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); //makes stuff work more reliably, if slower.
//upload each mip level in turn.
GL_Bind (glt);
for (miplevel = 0; ; miplevel++)
{
mipwidth = glt->width >> miplevel;
mipheight = glt->height >> miplevel;
if (!mipwidth && !mipheight)
break;
mipwidth = q_max(1,mipwidth); //include the 1*1 mip with non-square textures.
mipheight = q_max(1,mipheight);
mipbytes = blockbytes*((mipwidth+blockwidth-1)/blockwidth)*((mipheight+blockheight-1)/blockheight);
if (miplevel-picmip >= 0)
{
if (type)
glTexImage2D(GL_TEXTURE_2D, miplevel-picmip, internalformat, mipwidth, mipheight, 0, format, type, data);
else
glCompressedTexImage2D(GL_TEXTURE_2D, miplevel-picmip, internalformat, mipwidth, mipheight, 0, mipbytes, data);
}
data += mipbytes;
if (!(glt->flags & TEXPREF_MIPMAP))
break;
}
if (type && blockbytes < 4)
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); //back to opengl's default.
// set filter modes
TexMgr_SetFilterModes (glt);
}
/*
================
TexMgr_LoadImage8 -- handles 8bit source data, then passes it to LoadImage32
@ -1225,21 +1403,10 @@ gltexture_t *TexMgr_LoadImage (qmodel_t *owner, const char *name, int width, int
return NULL;
// cache check
switch (format)
{
case SRC_INDEXED:
crc = CRC_Block(data, width * height);
break;
case SRC_LIGHTMAP:
crc = CRC_Block(data, width * height * lightmap_bytes);
break;
case SRC_RGBA:
crc = CRC_Block(data, width * height * 4);
break;
case SRC_EXTERNAL:
default: /* not reachable but avoids compiler warnings */
if (format == SRC_EXTERNAL)
crc = 0;
}
else
crc = CRC_Block(data, TexMgr_ImageSize(width, height, format));
if ((flags & TEXPREF_OVERWRITE) && (glt = TexMgr_FindTexture (owner, name)))
{
if (glt->source_crc == crc)
@ -1295,6 +1462,9 @@ gltexture_t *TexMgr_LoadImage (qmodel_t *owner, const char *name, int width, int
case SRC_RGBA:
TexMgr_LoadImage32 (glt, (unsigned *)data);
break;
default:
TexMgr_LoadImageCompressed (glt, data);
break;
}
Hunk_FreeToLowMark(mark);
@ -1335,12 +1505,8 @@ void TexMgr_ReloadImage (gltexture_t *glt, int shirt, int pants)
if (!f)
goto invalid;
fseek (f, glt->source_offset, SEEK_CUR);
size = (long) (glt->source_width * glt->source_height);
/* should be SRC_INDEXED, but no harm being paranoid: */
if (glt->source_format == SRC_RGBA)
size *= 4;
else if (glt->source_format == SRC_LIGHTMAP)
size *= lightmap_bytes;
size = TexMgr_ImageSize(glt->source_width, glt->source_height, glt->source_format);
data = (byte *) Hunk_Alloc (size);
fread (data, 1, size, f);
fclose (f);
@ -1430,6 +1596,9 @@ invalid:
case SRC_RGBA:
TexMgr_LoadImage32 (glt, (unsigned *)data);
break;
default:
TexMgr_LoadImageCompressed (glt, data);
break;
}
if (malloced)

View file

@ -40,7 +40,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define TEXPREF_WARPIMAGE 0x0800 // resize this texture when warpimagesize changes
#define TEXPREF_PREMULTIPLY 0x1000 // rgb = rgb*a; a=a;
enum srcformat {SRC_INDEXED, SRC_LIGHTMAP, SRC_RGBA, SRC_EXTERNAL};
enum srcformat {SRC_INDEXED, SRC_LIGHTMAP, SRC_RGBA, SRC_EXTERNAL, SRC_FIRSTCOMPRESSED};
extern qboolean gl_texture_s3tc, gl_texture_rgtc, gl_texture_bptc, gl_texture_etc2, gl_texture_astc;
typedef uintptr_t src_offset_t;
@ -87,6 +88,9 @@ void TexMgr_FreeTexturesForOwner (qmodel_t *owner);
void TexMgr_NewGame (void);
void TexMgr_Init (void);
void TexMgr_DeleteTextureObjects (void);
enum srcformat TexMgr_FormatForCode (const char *code); //returns SRC_EXTERNAL when not known.
size_t TexMgr_ImageSize (int width, int height, enum srcformat format);
void TexMgr_BlockSize (enum srcformat format, int *bytes, int *width, int *height);
// IMAGE LOADING
gltexture_t *TexMgr_LoadImage (qmodel_t *owner, const char *name, int width, int height, enum srcformat format,

View file

@ -68,6 +68,8 @@ static int gl_version_minor;
static const char *gl_extensions;
static char * gl_extensions_nice;
qboolean gl_texture_s3tc, gl_texture_rgtc, gl_texture_bptc, gl_texture_etc2, gl_texture_astc;
static vmode_t modelist[MAX_MODE_LIST];
static int nummodes;
@ -1172,6 +1174,12 @@ static void GL_CheckExtensions (void)
{
Con_Warning ("texture_non_power_of_two not supported\n");
}
gl_texture_s3tc = ( GL_ParseExtensionList(gl_extensions, "GL_EXT_texture_compression_s3tc"));
gl_texture_rgtc = (gl_version_major >= 3 || GL_ParseExtensionList(gl_extensions, "GL_ARB_texture_compression_rgtc"));
gl_texture_bptc = (gl_version_major > 4 || (gl_version_major == 4 && gl_version_minor >= 2) || GL_ParseExtensionList(gl_extensions, "GL_ARB_texture_compression_bptc"));
gl_texture_etc2 = (gl_version_major > 4 || (gl_version_major == 4 && gl_version_minor >= 3) || GL_ParseExtensionList(gl_extensions, "GL_ARB_ES3_compatibility"));
gl_texture_astc = (gl_version_major > 4 || (gl_version_major == 4 && gl_version_minor >= 3) || GL_ParseExtensionList(gl_extensions, "GL_ARB_ES3_2_compatibility") || GL_ParseExtensionList(gl_extensions, "GL_KHR_texture_compression_astc_ldr"));
// GLSL
//

View file

@ -433,7 +433,7 @@ void GL_MakeAliasModelDisplayLists (qmodel_t *m, aliashdr_t *hdr);
void Sky_Init (void);
void Sky_DrawSky (void);
void Sky_NewMap (void);
void Sky_LoadTexture (texture_t *mt);
void Sky_LoadTexture (texture_t *mt, enum srcformat fmt, unsigned int width, unsigned int height);
void Sky_LoadSkyBox (const char *name);
extern qboolean skyroom_drawn; //we draw a skyroom this frame
extern qboolean skyroom_enabled; //we know where the skyroom is ...