Ok first succes story.
Code: Select all
/* messy stuff below warning */
static unsigned int trans[4096*4096];
static unsigned char glosspix[4096*4096];
static unsigned char bumppix[4096*4096];
/*
================
GL_FindTexture
================
*/
int GL_FindTexture (char *identifier)
{
int i;
gltexture_t *glt;
for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
{
if (!strcmp (identifier, glt->identifier))
{
return gltextures[i].texnum;
}
}
return -1;
}
/*
================
GL_ResampleTextureLerpLine
Interpolates between pixels on line - Eradicator
================
*/
void GL_ResampleTextureLerpLine (byte *in, byte *out, int inwidth, int outwidth)
{
int j, xi, oldx = 0, f, fstep, endx;
fstep = (int) (inwidth * 65536.0f / outwidth);
endx = (inwidth-1);
for (j = 0,f = 0; j < outwidth; j++, f += fstep)
{
xi = (int) f >> 16;
if (xi != oldx)
{
in += (xi - oldx) * 4;
oldx = xi;
}
if (xi < endx)
{
int lerp = f & 0xFFFF;
*out++ = (byte) ((((in[4] - in[0]) * lerp) >> 16) + in[0]);
*out++ = (byte) ((((in[5] - in[1]) * lerp) >> 16) + in[1]);
*out++ = (byte) ((((in[6] - in[2]) * lerp) >> 16) + in[2]);
*out++ = (byte) ((((in[7] - in[3]) * lerp) >> 16) + in[3]);
}
else
{
*out++ = in[0];
*out++ = in[1];
*out++ = in[2];
*out++ = in[3];
}
}
}
/*
================
GL_ResampleTexture
================
*/
void GL_ResampleTexture (void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight)
{
//New Interpolated Texture Code - Eradicator
int i, j, yi, oldy, f, fstep, endy = (inheight-1);
byte *inrow, *out, *row1, *row2;
out = outdata;
fstep = (int) (inheight*65536.0f/outheight);
row1 = malloc(outwidth*4);
row2 = malloc(outwidth*4);
inrow = indata;
oldy = 0;
GL_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth);
GL_ResampleTextureLerpLine (inrow + inwidth*4, row2, inwidth, outwidth);
for (i = 0, f = 0; i < outheight; i++,f += fstep)
{
yi = f >> 16;
if (yi < endy)
{
int lerp = f & 0xFFFF;
if (yi != oldy)
{
inrow = (byte *)indata + inwidth*4*yi;
if (yi == oldy + 1)
{
memcpy(row1, row2, outwidth * 4);
}
else
{
GL_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth);
}
GL_ResampleTextureLerpLine (inrow + inwidth*4, row2, inwidth, outwidth);
oldy = yi;
}
j = outwidth - 4;
while(j >= 0)
{
out[ 0] = (byte) ((((row2[ 0] - row1[ 0]) * lerp) >> 16) + row1[ 0]);
out[ 1] = (byte) ((((row2[ 1] - row1[ 1]) * lerp) >> 16) + row1[ 1]);
out[ 2] = (byte) ((((row2[ 2] - row1[ 2]) * lerp) >> 16) + row1[ 2]);
out[ 3] = (byte) ((((row2[ 3] - row1[ 3]) * lerp) >> 16) + row1[ 3]);
out[ 4] = (byte) ((((row2[ 4] - row1[ 4]) * lerp) >> 16) + row1[ 4]);
out[ 5] = (byte) ((((row2[ 5] - row1[ 5]) * lerp) >> 16) + row1[ 5]);
out[ 6] = (byte) ((((row2[ 6] - row1[ 6]) * lerp) >> 16) + row1[ 6]);
out[ 7] = (byte) ((((row2[ 7] - row1[ 7]) * lerp) >> 16) + row1[ 7]);
out[ 8] = (byte) ((((row2[ 8] - row1[ 8]) * lerp) >> 16) + row1[ 8]);
out[ 9] = (byte) ((((row2[ 9] - row1[ 9]) * lerp) >> 16) + row1[ 9]);
out[10] = (byte) ((((row2[10] - row1[10]) * lerp) >> 16) + row1[10]);
out[11] = (byte) ((((row2[11] - row1[11]) * lerp) >> 16) + row1[11]);
out[12] = (byte) ((((row2[12] - row1[12]) * lerp) >> 16) + row1[12]);
out[13] = (byte) ((((row2[13] - row1[13]) * lerp) >> 16) + row1[13]);
out[14] = (byte) ((((row2[14] - row1[14]) * lerp) >> 16) + row1[14]);
out[15] = (byte) ((((row2[15] - row1[15]) * lerp) >> 16) + row1[15]);
out += 16;
row1 += 16;
row2 += 16;
j -= 4;
}
if (j & 2)
{
out[ 0] = (byte) ((((row2[ 0] - row1[ 0]) * lerp) >> 16) + row1[ 0]);
out[ 1] = (byte) ((((row2[ 1] - row1[ 1]) * lerp) >> 16) + row1[ 1]);
out[ 2] = (byte) ((((row2[ 2] - row1[ 2]) * lerp) >> 16) + row1[ 2]);
out[ 3] = (byte) ((((row2[ 3] - row1[ 3]) * lerp) >> 16) + row1[ 3]);
out[ 4] = (byte) ((((row2[ 4] - row1[ 4]) * lerp) >> 16) + row1[ 4]);
out[ 5] = (byte) ((((row2[ 5] - row1[ 5]) * lerp) >> 16) + row1[ 5]);
out[ 6] = (byte) ((((row2[ 6] - row1[ 6]) * lerp) >> 16) + row1[ 6]);
out[ 7] = (byte) ((((row2[ 7] - row1[ 7]) * lerp) >> 16) + row1[ 7]);
out += 8;
row1 += 8;
row2 += 8;
}
if (j & 1)
{
out[ 0] = (byte) ((((row2[ 0] - row1[ 0]) * lerp) >> 16) + row1[ 0]);
out[ 1] = (byte) ((((row2[ 1] - row1[ 1]) * lerp) >> 16) + row1[ 1]);
out[ 2] = (byte) ((((row2[ 2] - row1[ 2]) * lerp) >> 16) + row1[ 2]);
out[ 3] = (byte) ((((row2[ 3] - row1[ 3]) * lerp) >> 16) + row1[ 3]);
out += 4;
row1 += 4;
row2 += 4;
}
row1 -= outwidth*4;
row2 -= outwidth*4;
}
else
{
if (yi != oldy)
{
inrow = (byte *)indata + inwidth*4*yi;
if (yi == oldy + 1)
{
memcpy(row1, row2, outwidth * 4);
}
else
{
GL_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth);
}
oldy = yi;
}
memcpy(out, row1, outwidth * 4);
}
}
free(row1);
free(row2);
}
/*
================
GL_Resample8BitTexture -- JACK
================
*/
void GL_Resample8BitTexture (unsigned char *in, int inwidth, int inheight, unsigned char *out, int outwidth, int outheight)
{
int i, j;
unsigned char *inrow;
unsigned frac, fracstep;
fracstep = inwidth*0x10000/outwidth;
for (i=0 ; i<outheight ; i++, out += outwidth)
{
inrow = in + inwidth*(i*inheight/outheight);
frac = fracstep >> 1;
for (j=0 ; j<outwidth ; j+=4)
{
out[j] = inrow[frac>>16];
frac += fracstep;
out[j+1] = inrow[frac>>16];
frac += fracstep;
out[j+2] = inrow[frac>>16];
frac += fracstep;
out[j+3] = inrow[frac>>16];
frac += fracstep;
}
}
}
/*
================
GL_MipMap
Operates in place, quartering the size of the texture
================
*/
void GL_MipMap (byte *in, int width, int height)
{
int i, j;
byte *out;
width <<=2;
height >>= 1;
out = in;
for (i=0 ; i<height ; i++, in+=width)
{
for (j=0 ; j<width ; j+=8, out+=4, in+=8)
{
out[0] = (in[0] + in[4] + in[width+0] + in[width+4])>>2;
out[1] = (in[1] + in[5] + in[width+1] + in[width+5])>>2;
out[2] = (in[2] + in[6] + in[width+2] + in[width+6])>>2;
out[3] = (in[3] + in[7] + in[width+3] + in[width+7])>>2;
}
}
}
/*
================
GL_MipMapNormal
Operates in place, quartering the size of the texture
Works on normal maps instead of rgb
================
*/
void GL_MipMapNormal (byte *in, int width, int height)
{
int i, j;
byte *out;
float x, y, z, l, mag00, mag01, mag10, mag11;
width <<= 2;
height >>= 1;
out = in;
for (i=0 ; i<height ; i++, in+=width)
{
for (j=0 ; j<width ; j+=8, out+=4, in+=8)
{
mag00 = ONEOVER255 * in[3];
mag01 = ONEOVER255 * in[7];
mag10 = ONEOVER255 * in[width+3];
mag11 = ONEOVER255 * in[width+7];
x = mag00*(ONEOVER127*in[0]-1.0)+
mag01*(ONEOVER127*in[4]-1.0)+
mag10*(ONEOVER127*in[width+0]-1.0)+
mag11*(ONEOVER127*in[width+4]-1.0);
y = mag00*(ONEOVER127*in[1]-1.0)+
mag01*(ONEOVER127*in[5]-1.0)+
mag10*(ONEOVER127*in[width+1]-1.0)+
mag11*(ONEOVER127*in[width+5]-1.0);
z = mag00*(ONEOVER127*in[2]-1.0)+
mag01*(ONEOVER127*in[6]-1.0)+
mag10*(ONEOVER127*in[width+2]-1.0)+
mag11*(ONEOVER127*in[width+6]-1.0);
l = sqrt(x * x + y * y + z * z);
if (l == 0.0)
{
x = 0.0;
y = 0.0;
z = 1.0;
}
else
{
//normalize it.
l=1/l;
x *=l;
y *=l;
z *=l;
}
out[0] = (unsigned char)128 + 127*x;
out[1] = (unsigned char)128 + 127*y;
out[2] = (unsigned char)128 + 127*z;
l = l/4.0;
if (l > 1.0)
{
out[3] = 255;
}
else
{
out[3] = (byte)(255.0 * l);
}
}
}
}
/*
================
GL_MipMap8Bit
Mipping for 8 bit textures
================
*/
void GL_MipMap8Bit (byte *in, int width, int height)
{
int i, j;
unsigned short r, g, b;
byte *out, *at1, *at2, *at3, *at4;
height >>= 1;
out = in;
for (i=0 ; i<height ; i++, in+=width)
{
for (j=0 ; j<width ; j+=2, out+=1, in+=2)
{
at1 = (byte *) (d_8to24table + in[0]);
at2 = (byte *) (d_8to24table + in[1]);
at3 = (byte *) (d_8to24table + in[width+0]);
at4 = (byte *) (d_8to24table + in[width+1]);
r = (at1[0]+at2[0]+at3[0]+at4[0]);
r>>=5;
g = (at1[1]+at2[1]+at3[1]+at4[1]);
g>>=5;
b = (at1[2]+at2[2]+at3[2]+at4[2]);
b>>=5;
out[0] = d_15to8table[(r<<0) + (g<<5) + (b<<10)];
}
}
}
/*
===============
GL_MakeNormal
===============
*/
void GL_MakeNormal(byte *in, int width, int height)
{
int i, j;
byte *out;
float x, y, z, l;
width <<= 2;
out = in;
for (i=0 ; i<height ; i++)
{
for (j=0 ; j<width ; j+=4, out+=4, in+=4)
{
x = (ONEOVER127 * in[0] - 1.0);
y = (ONEOVER127 * in[1] - 1.0);
z = (ONEOVER127 * in[2] - 1.0);
l = sqrt(x * x + y * y + z * z);
if (l == 0.0f)
{
x = 0.0;
y = 0.0;
z = 1.0;
}
else
{
//normalize it.
l = 1.0f / l;
x *=l;
y *=l;
z *=l;
}
out[0] = (unsigned char)128 + 127 * x;
out[1] = (unsigned char)128 + 127 * y;
out[2] = (unsigned char)128 + 127 * z;
}
}
}
/*
===============
GL_NormalFromHeightMap
===============
*/
unsigned int *GL_NormalFromHeightMap(byte *in, int width, int height, int mode)
{
int i, j, wr, hr;
unsigned char r, g, b;
static unsigned int out[4096*4096];
float sqlen, reciplen, nx, ny, nz;
float c, cx, cy, dcx, dcy;
wr = width;
hr = height;
for (i=0; i<height; i++)
{
for (j=0; j<width; j++)
{
/* Expand [0,255] texel values to the [0,1] range. */
c = in[i * wr + j] * ONEOVER255;
/* Expand the texel to its right. */
cx = in[i * wr + (j + 1) % wr] * ONEOVER255;
/* Expand the texel one up. */
cy = in[((i + 1) % hr) * wr + j] * ONEOVER255;
/* scale it according to source */
dcx = (mode & TEX_SCALE) ? 10.0f : 4.0f * (c - cx);
dcy = (mode & TEX_SCALE) ? 10.0f : 4.0f * (c - cy);
/* Normalize the vector. */
sqlen = dcx * dcx + dcy * dcy + 1;
reciplen = 1.0f / (float) sqrt(sqlen);
nx = dcx * reciplen;
ny = -dcy * reciplen;
nz = reciplen;
/* Repack the normalized vector into an RGB unsigned byte
vector in the normal map image. */
r = (byte) (128 + 127 * nx);
g = (byte) (128 + 127 * ny);
b = (byte) (128 + 127 * nz);
/* The highest resolution mipmap level always has a
unit length magnitude. */
out[i * width + j] = LittleLong ((in[i * wr + j] << 24) | (b << 16) | (g << 8) | (r)); // <AWE> Added support for big endian.
}
}
return &out[0];
}
/*
===============
GL_PackGloss
Packs a gloss byte in destination
===============
*/
void GL_PackGloss(byte *gloss, unsigned *dest, int length)
{
int i;
for (i=0; i<length; i++, gloss++, dest++)
{
*dest = *dest & LittleLong (0x00FFFFFF); // <AWE> Added support for big endian.
*dest = *dest | LittleLong (*gloss << 24); // <AWE> Added support for big endian.
}
}
/*
================
ScaleDimensions
================
*/
void GL_ScaleDimensions (int width, int height, int *scaled_width, int *scaled_height, int mode)
{
int maxsize;
for (*scaled_width = 1 ; *scaled_width < width ; *scaled_width *= 2);
for (*scaled_height = 1 ; *scaled_height < height ; *scaled_height *= 2);
if (mode & TEX_MIPMAP)
{
*scaled_width >>= (int)gl_picmip.value;
*scaled_height >>= (int)gl_picmip.value;
}
maxsize = (mode & TEX_MIPMAP) ? gl_max_size.value : gl_max_size_default;
*scaled_width = bound(1, *scaled_width, maxsize);
*scaled_height = bound(1, *scaled_height, maxsize);
}
/*
===============
GL_UploadColor
===============
*/
void GL_UploadColor (unsigned *data, int width, int height, int mode)
{
static unsigned scaled[4096*4096];
int scaled_width, scaled_height;
int internal_format, format;
if ( gl_gray_colormaps.value )
{
Q_memset(data, 0x7f, width * height * 4);
}
GL_ScaleDimensions (width, height, &scaled_width, &scaled_height, mode);
format = ( gl_texcomp && ((int)gl_compress_textures.value) & 1 ) ? GL_COMPRESSED_RGBA_ARB : GL_RGBA;
internal_format = (mode & TEX_ALPHA) ? gl_alpha_format : gl_solid_format;
if (scaled_width == width && scaled_height == height)
{
if (!(mode & TEX_MIPMAP))
{
glTexImage2D (GL_TEXTURE_2D, 0, internal_format, scaled_width, scaled_height, 0, format, GL_UNSIGNED_BYTE, data);
goto done;
}
memcpy (scaled, data, width * height * 4);
}
else
{
GL_ResampleTexture (data, width, height, scaled, scaled_width, scaled_height);
}
glTexImage2D (GL_TEXTURE_2D, 0, internal_format, scaled_width, scaled_height, 0, format, GL_UNSIGNED_BYTE, scaled);
if (mode & TEX_MIPMAP)
{
int miplevel = 0;
while (scaled_width > 1 || scaled_height > 1)
{
GL_MipMap ((byte *)scaled, scaled_width, scaled_height);
scaled_width >>= 1;
scaled_height >>= 1;
if (scaled_width < 1)
{
scaled_width = 1;
}
if (scaled_height < 1)
{
scaled_height = 1;
}
miplevel++;
glTexImage2D (GL_TEXTURE_2D, miplevel, internal_format, scaled_width, scaled_height, 0, format, GL_UNSIGNED_BYTE, scaled);
}
}
done:
;
if (mode & TEX_MIPMAP)
{
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
}
else
{
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
}
if (gl_texturefilteranisotropic)
{
glTexParameterfv (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &gl_textureanisotropylevel);
}
}
void GL_UploadColor8 (byte *data, int width, int height, int mode)
{
static unsigned char scaled[4096*4096];
int scaled_width, scaled_height;
GL_ScaleDimensions (width, height, &scaled_width, &scaled_height, mode);
if (scaled_width == width && scaled_height == height)
{
if (!(mode & TEX_MIPMAP))
{
glTexImage2D (GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX , GL_UNSIGNED_BYTE, data);
goto done;
}
memcpy (scaled, data, width*height);
}
else
{
GL_Resample8BitTexture (data, width, height, scaled, scaled_width, scaled_height);
}
glTexImage2D (GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, scaled);
if (mode & TEX_MIPMAP)
{
int miplevel = 0;
while (scaled_width > 1 || scaled_height > 1)
{
GL_MipMap8Bit ((byte *)scaled, scaled_width, scaled_height);
scaled_width >>= 1;
scaled_height >>= 1;
if (scaled_width < 1)
{
scaled_width = 1;
}
if (scaled_height < 1)
{
scaled_height = 1;
}
miplevel++;
glTexImage2D (GL_TEXTURE_2D, miplevel, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, scaled);
}
}
done:
;
if (mode & TEX_MIPMAP)
{
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
}
else
{
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
}
if (gl_texturefilteranisotropic)
{
glTexParameterfv (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &gl_textureanisotropylevel);
}
}
void GL_UploadNormal(unsigned int *data, int width, int height, int mode)
{
static unsigned int scaled[4096*4096];
int scaled_width, scaled_height;
int internal_format, format;
//Resize to power of 2 and maximum texture size
GL_ScaleDimensions (width, height, &scaled_width, &scaled_height, mode);
//To resize or not to resize
if (scaled_width == width && scaled_height == height)
{
memcpy (scaled, data, width*height*4);
scaled_width = width;
scaled_height = height;
}
else
{
GL_ResampleTexture (data, width, height, scaled, scaled_width, scaled_height);
}
GL_MakeNormal((byte *)scaled, scaled_width, scaled_height);
format = ( gl_texcomp && ((int)gl_compress_textures.value) & 1 ) ? GL_COMPRESSED_RGBA_ARB : GL_RGBA;
internal_format = (mode & TEX_ALPHA) ? gl_alpha_format : gl_solid_format;
glTexImage2D (GL_TEXTURE_2D, 0, internal_format, scaled_width, scaled_height, 0, format, GL_UNSIGNED_BYTE, scaled);
if (mode & TEX_MIPMAP)
{
int miplevel = 0;
while (scaled_width > 1 || scaled_height > 1)
{
GL_MipMapNormal((byte *)scaled, scaled_width, scaled_height);
scaled_width >>= 1;
scaled_height >>= 1;
if (scaled_width < 1)
{
scaled_width = 1;
}
if (scaled_height < 1)
{
scaled_height = 1;
}
miplevel++;
glTexImage2D (GL_TEXTURE_2D, miplevel, internal_format, scaled_width, scaled_height, 0, format, GL_UNSIGNED_BYTE, scaled);
}
}
if (mode & TEX_MIPMAP)
{
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
}
else
{
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
}
if (gl_texturefilteranisotropic)
{
glTexParameterfv (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &gl_textureanisotropylevel);
}
}
void GL_UploadBump(byte *data, int width, int height, int mode)
{
static unsigned char scaled[4096*4096];
byte *scalednormal;
int scaled_width, scaled_height;
int internal_format, format;
//Resize to power of 2 and maximum texture size
GL_ScaleDimensions (width, height, &scaled_width, &scaled_height, mode);
//To resize or not to resize
if (scaled_width == width && scaled_height == height)
{
memcpy (scaled, data, width*height);
scaled_width = width;
scaled_height = height;
}
else
{
//Just picks pixels so grayscale is equivalent with 8 bit.
GL_Resample8BitTexture (data, width, height, scaled, scaled_width, scaled_height);
}
scalednormal = (unsigned char *) GL_NormalFromHeightMap(scaled, width, height, mode);
format = ( gl_texcomp && ((int)gl_compress_textures.value) & 1 ) ? GL_COMPRESSED_RGBA_ARB : GL_RGBA;
internal_format = (mode & TEX_ALPHA) ? gl_alpha_format : gl_solid_format;
glTexImage2D (GL_TEXTURE_2D, 0, internal_format, scaled_width, scaled_height, 0, format, GL_UNSIGNED_BYTE, scalednormal);
if (mode & TEX_MIPMAP)
{
int miplevel = 0;
while (scaled_width > 1 || scaled_height > 1)
{
GL_MipMapNormal(scalednormal, scaled_width, scaled_height);
scaled_width >>= 1;
scaled_height >>= 1;
if (scaled_width < 1)
{
scaled_width = 1;
}
if (scaled_height < 1)
{
scaled_height = 1;
}
miplevel++;
glTexImage2D (GL_TEXTURE_2D, miplevel, internal_format, scaled_width, scaled_height, 0, format, GL_UNSIGNED_BYTE, scalednormal);
}
}
if (mode & TEX_MIPMAP)
{
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
}
else
{
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
}
if (gl_texturefilteranisotropic)
{
glTexParameterfv (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &gl_textureanisotropylevel);
}
}
/*
===============
GL_GetOverrideName
===============
*/
void GL_GetOverrideName(char *identifier, char *tail, char *dest)
{
unsigned i;
sprintf(dest, "override/%s%s.ext", identifier, tail);
for (i=0; i<strlen(dest); i++)
{
if (dest[i] == '*')
{
dest[i] = '#';
}
}
}
/*
===============
GL_ConvertPalette
Handles palette conversion and searches
the image for alpha pixels.
===============
*/
void GL_ConvertPalette (unsigned char *data, unsigned int *trans2, unsigned char *bumppix2, int size, int mode)
{
int i, p;
/* check pixels */
if (mode & TEX_FULLBRIGHT)
{
// this is a fullbright mask, so make all non-fullbright
// colors transparent
mode |= TEX_ALPHA;
for (i=0 ; i<size ; i++)
{
p = data[i];
if (p < 224)
{
// transparent
trans2[i] = d_8to24table[p] & 0x00FFFFFF;
bumppix2[i] = d_8to8graytable[p] & 0x00FFFFFF;
}
else
{
// fullbright
trans2[i] = d_8to24table[p];
bumppix2[i] = d_8to8graytable[p];
}
}
}
else if (mode & TEX_ALPHA)
{
/* set to invalid at start */
mode &= ~TEX_ALPHA;
for (i=0 ; i<size ; i++)
{
p = data[i];
/* if byte equals 255 then we have an alpha channel */
if (p == 255)
{
mode |= TEX_ALPHA;
}
trans2[i] = d_8to24table[p];
bumppix2[i] = d_8to8graytable[p];
}
}
else
{
/* no alpha convert the palette and upload like a 3 component texture */
mode &= ~TEX_ALPHA;
for (i=0 ; i<size ; i+=4)
{
trans2[i] = d_8to24table[data[i]];
trans2[i+1] = d_8to24table[data[i+1]];
trans2[i+2] = d_8to24table[data[i+2]];
trans2[i+3] = d_8to24table[data[i+3]];
bumppix2[i] = d_8to8graytable[data[i]];
bumppix2[i+1] = d_8to8graytable[data[i+1]];
bumppix2[i+2] = d_8to8graytable[data[i+2]];
bumppix2[i+3] = d_8to8graytable[data[i+3]];
}
}
}
/*
===============
GL_ConvertPixels
Handles Color conversion
===============
*/
void GL_ConvertPixels (unsigned int *in, unsigned char *out, int size)
{
int i;
byte r, g, b;
for (i=0; i<size; i++)
{
r = (in[i] & 0x00FF0000) >> 16;
g = (in[i] & 0x0000FF00) >> 8;
b = (in[i] & 0x000000FF);
out[i] = (r + g + b) / 3;
}
}
/*
===============
GL_LoadFromFile
Attempt at making a better texture managment system.
Still a few todo's models are allways fullbright.
===============
*/
void GL_LoadFromFile (char *identifier, int width, int height, byte *data, int mode)
{
int size;
char colormap[MAX_OSPATH];
char normalmap[MAX_OSPATH];
char bumpmap[MAX_OSPATH];
char glossmap[MAX_OSPATH];
// get size
size = width * height;
// upload a colormap
GL_GetOverrideName(identifier, "", colormap);
if (Image_LoadTextureInPlace(colormap, 4, (unsigned char *)&trans[0], &width, &height))
{
Con_DPrintf("Overriding colormap for %s\n", identifier);
mode |= TEX_SCALE;
GL_ConvertPixels (trans, bumppix, size);
}
else
{
Con_DPrintf("Applying 8 to 32 bit conversion for %s\n", identifier);
GL_ConvertPalette (data, trans, bumppix, size, mode);
}
//upload scrap texels
if (!strcmp("scrap", identifier))
{
GL_UploadColor (trans, width, height, mode);
return;
}
//force it to upload a 32 bit texture
GL_Bind(texture_extension_number);
GL_UploadColor (trans, width, height, mode);
texture_extension_number++;
if (!COM_CheckParm("-nobumpmaps") && (sh_bumpmaps.value) && (mode & TEX_BUMP))
{
GL_Bind(texture_extension_number);
GL_GetOverrideName(identifier, "_norm", normalmap);
// now try a normalmap
if (Image_LoadTextureInPlace(normalmap, 4, (unsigned char *)&trans[0], &width, &height))
{
int gwidth = 0, gheight = 0;
Con_DPrintf("Overriding normal map for %s\n",identifier);
GL_GetOverrideName(identifier, "_gloss", glossmap);
if (Image_LoadTextureInPlace(glossmap, 1, &glosspix[0], &gwidth, &gheight))
{
Con_DPrintf("Overriding gloss map for %s\n", identifier);
}
else
{
//set some gloss by default
gwidth = width;
gheight = height;
Q_memset(&glosspix[0], 255*gl_gloss.value, size);
}
// if the textures match pack gloss in the alpha channel of dest
if ((gwidth != width) && (gheight != height))
{
Con_SafePrintf("\002Warning: %s Gloss map must have same size as color map\n", identifier);
}
else
{
GL_PackGloss(glosspix, trans, size);
}
GL_UploadNormal (trans, width, height, mode);
}
else
{
// if no normalmap try a greyscale bumpmap
GL_GetOverrideName(identifier, "_bump", bumpmap);
if (Image_LoadTextureInPlace(bumpmap, 1, (unsigned char *)&bumppix[0], &width, &height))
{
int gwidth = 0, gheight = 0;
Con_DPrintf("Overriding bump map for %s\n", identifier);
GL_GetOverrideName(identifier, "_gloss", glossmap);
if (Image_LoadTextureInPlace(glossmap, 1, &glosspix[0], &gwidth, &gheight))
{
Con_DPrintf("Overriding gloss map for %s\n", identifier);
}
else
{
//set some gloss by default
gwidth = width;
gheight = height;
Q_memset(&glosspix[0], 255 * gl_gloss.value, size);
}
// if the textures match pack gloss in the alpha channel of dest
if ((gwidth != width) && (gheight != height))
{
Con_SafePrintf("\002Warning: %s Gloss map must have same size as color map\n", identifier);
}
else
{
GL_PackGloss(glosspix, (unsigned int *)bumppix, size);
}
}
GL_UploadBump (bumppix, width, height, mode);
}
}
texture_extension_number++;
}
/*
===============
GL_LoadLumaTexture
===============
*/
int GL_LoadLumaTexture(char *identifier, int width, int height, int mode)
{
int i;
char lumamap[MAX_OSPATH];
if (gl_gray_colormaps.value) return;
GL_GetOverrideName(identifier, "_luma", lumamap);
if (Image_LoadTextureInPlace(lumamap, 4, (unsigned char *)&trans[0], &width, &height))
{
/* scale the heightmap on lumas wtf ??? */
mode |= TEX_SCALE;
/* check if the alpha channel really works */
if (mode & TEX_ALPHA)
{
mode &= ~TEX_ALPHA;
for (i=0 ; i<width*height ; i++)
{
if ((((trans)[i] >> 24) & 0xFF) < 255)
{
mode |= TEX_ALPHA;
break;
}
}
}
GL_Bind(texture_extension_number);
GL_UploadColor (trans, width, height, mode);
texture_extension_number++;
return texture_extension_number-1;
}
return 0;
}
/*
================
GL_LoadTexture
================
*/
int GL_LoadTexture (char *identifier, int width, int height, byte *data, int mode)
{
int i, scaled_width, scaled_height;
gltexture_t *glt;
GL_ScaleDimensions (width, height, &scaled_width, &scaled_height, mode);
// see if the texture is allready present
if (identifier[0])
{
for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
{
if (!strncmp(identifier, glt->identifier, sizeof(glt->identifier)))
{
if (width != glt->width || height != glt->height || scaled_width != glt->scaled_width || scaled_height != glt->scaled_height)
{
Con_Printf ("%s: warning: textures dont match\n", identifier);
}
return gltextures[i].texnum;
}
}
}
glt = &gltextures[numgltextures];
numgltextures++;
strncpy (glt->identifier, identifier, sizeof(glt->identifier) -1);
glt->texnum = texture_extension_number;
glt->width = width;
glt->height = height;
glt->scaled_width = scaled_width;
glt->scaled_height = scaled_height;
glt->mode = mode;
GL_LoadFromFile(identifier, width, height, data, mode);
return texture_extension_number-2;
}
not including stuff made in other source files heh.