mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
Rewrite GL_LoadQuakeMipTex to generate mips itself.
Relying on GL to generate mips for 8 bit textures doesn't produce nice results. These aren't the greatest, either, but they're better.
This commit is contained in:
parent
7739ba3ea9
commit
de022ae72d
1 changed files with 69 additions and 43 deletions
|
@ -104,12 +104,32 @@ GL_Resample8BitTexture (unsigned char *in, int inwidth, int inheight,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
GL_Mipmap8BitTexture (const byte *src, unsigned width, unsigned height,
|
||||
byte *mip)
|
||||
{
|
||||
unsigned mw = width >> 1;
|
||||
unsigned mh = height >> 1;
|
||||
unsigned i, j;
|
||||
|
||||
mw = max (mw, 1);
|
||||
mh = max (mh, 1);
|
||||
|
||||
for (j = 0; j < mh; j++) {
|
||||
for (i = 0; i < mw; i++) {
|
||||
*mip++ = src [j * 2 * width + i * 2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
GL_LoadQuakeMipTex (const texture_t *tex)
|
||||
{
|
||||
unsigned swidth, sheight;
|
||||
GLuint tnum;
|
||||
byte *data = (byte *) tex;
|
||||
byte *buffer = 0;
|
||||
byte *scaled;
|
||||
int lod;
|
||||
|
||||
for (swidth = 1; swidth < tex->width; swidth <<= 1);
|
||||
|
@ -119,54 +139,60 @@ GL_LoadQuakeMipTex (const texture_t *tex)
|
|||
qfglBindTexture (GL_TEXTURE_2D, tnum);
|
||||
qfglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
qfglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
//FIXME GL generated mipmaps and paletted textures don't mix (Quake's
|
||||
//mipmaps do only 4 levels, while many textures need 6+)
|
||||
qfglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||
GL_NEAREST);
|
||||
GL_NEAREST_MIPMAP_NEAREST);
|
||||
qfglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
if (swidth == tex->width && sheight == tex->height) {
|
||||
qfglTexImage2D (GL_TEXTURE_2D, 0, GL_LUMINANCE,
|
||||
swidth, sheight, 0, GL_LUMINANCE,
|
||||
GL_UNSIGNED_BYTE, data + tex->offsets[0]);
|
||||
// generate mips first so supplied mips don't get overwritten
|
||||
if (swidth > (1 << MIPLEVELS) || sheight > (1 << MIPLEVELS))
|
||||
qfglGenerateMipmap (GL_TEXTURE_2D);
|
||||
for (lod = 1; lod < MIPLEVELS; lod++) {
|
||||
swidth >>= 1;
|
||||
sheight >>= 1;
|
||||
swidth = max (swidth, 1);
|
||||
sheight = max (sheight, 1);
|
||||
qfglTexImage2D (GL_TEXTURE_2D, lod, GL_LUMINANCE,
|
||||
swidth, sheight, 0, GL_LUMINANCE,
|
||||
GL_UNSIGNED_BYTE, data + tex->offsets[lod]);
|
||||
if (swidth != tex->width || sheight != tex->height)
|
||||
buffer = malloc (swidth * sheight);
|
||||
|
||||
// preshift so swidth and sheight are the correct sizes end the end of
|
||||
// the loop
|
||||
swidth <<= 1;
|
||||
sheight <<= 1;
|
||||
for (lod = 0; lod < MIPLEVELS; lod++) {
|
||||
// preshift so swidth and sheight are the correct sizes end the end of
|
||||
// the loop
|
||||
swidth >>= 1;
|
||||
sheight >>= 1;
|
||||
swidth = max (swidth, 1);
|
||||
sheight = max (sheight, 1);
|
||||
if (buffer) {
|
||||
unsigned w = tex->width;
|
||||
unsigned h = tex->height;
|
||||
|
||||
w = max (w >> lod, 1);
|
||||
h = max (h >> lod, 1);
|
||||
GL_Resample8BitTexture (data + tex->offsets[lod], w, h,
|
||||
buffer, swidth, sheight);
|
||||
scaled = buffer;
|
||||
} else {
|
||||
scaled = data + tex->offsets[lod];
|
||||
}
|
||||
} else {
|
||||
byte *scaled;
|
||||
scaled = malloc (swidth * sheight);
|
||||
GL_Resample8BitTexture (data + tex->offsets[0],
|
||||
tex->width, tex->height,
|
||||
scaled, swidth, sheight);
|
||||
qfglTexImage2D (GL_TEXTURE_2D, 0, GL_LUMINANCE,
|
||||
swidth, sheight, 0, GL_LUMINANCE,
|
||||
GL_UNSIGNED_BYTE, scaled);
|
||||
// generate mips first so supplied mips don't get overwritten
|
||||
if (swidth > (1 << MIPLEVELS) || sheight > (1 << MIPLEVELS))
|
||||
qfglGenerateMipmap (GL_TEXTURE_2D);
|
||||
for (lod = 1; lod < MIPLEVELS; lod++) {
|
||||
swidth >>= 1;
|
||||
sheight >>= 1;
|
||||
swidth = max (swidth, 1);
|
||||
sheight = max (sheight, 1);
|
||||
GL_Resample8BitTexture (data + tex->offsets[lod],
|
||||
tex->width, tex->height,
|
||||
scaled, swidth, sheight);
|
||||
qfglTexImage2D (GL_TEXTURE_2D, lod, GL_LUMINANCE,
|
||||
swidth, sheight, 0, GL_LUMINANCE,
|
||||
GL_UNSIGNED_BYTE, data + tex->offsets[lod]);
|
||||
}
|
||||
free (scaled);
|
||||
qfglTexImage2D (GL_TEXTURE_2D, lod, GL_LUMINANCE, swidth, sheight,
|
||||
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, scaled);
|
||||
}
|
||||
if (swidth > 1 || sheight > 1) {
|
||||
// mipmap will hold the reduced image, so this is more than enough
|
||||
byte *mipmap = malloc (swidth * sheight);
|
||||
byte *mip = mipmap;
|
||||
while (swidth > 1 || sheight > 1) {
|
||||
// scaled holds the source of the last lod uploaded
|
||||
GL_Mipmap8BitTexture (scaled, swidth, sheight, mip);
|
||||
swidth >>= 1;
|
||||
sheight >>= 1;
|
||||
swidth = max (swidth, 1);
|
||||
sheight = max (sheight, 1);
|
||||
qfglTexImage2D (GL_TEXTURE_2D, lod, GL_LUMINANCE, swidth, sheight,
|
||||
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, mip);
|
||||
scaled = mip;
|
||||
mip += swidth * sheight;
|
||||
lod++;
|
||||
}
|
||||
free (mipmap);
|
||||
}
|
||||
if (buffer)
|
||||
free (buffer);
|
||||
return tnum;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue