summaryrefslogtreecommitdiff
path: root/src/renderergl2/tr_image.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/renderergl2/tr_image.c')
-rw-r--r--src/renderergl2/tr_image.c894
1 files changed, 444 insertions, 450 deletions
diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c
index 08894a4a..331e7f61 100644
--- a/src/renderergl2/tr_image.c
+++ b/src/renderergl2/tr_image.c
@@ -23,6 +23,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// tr_image.c
#include "tr_local.h"
+#include "tr_dsa.h"
+
static byte s_intensitytable[256];
static unsigned char s_gammatable[256];
@@ -114,10 +116,9 @@ void GL_TextureMode( const char *string ) {
// change all the existing mipmap texture objects
for ( i = 0 ; i < tr.numImages ; i++ ) {
glt = tr.images[ i ];
- if ( glt->flags & IMGFLAG_MIPMAP ) {
- GL_Bind (glt);
- qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
- qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
+ if ( glt->flags & IMGFLAG_MIPMAP && !(glt->flags & IMGFLAG_CUBEMAP)) {
+ qglTextureParameterf(glt->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
+ qglTextureParameterf(glt->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
}
}
}
@@ -177,15 +178,20 @@ void R_ImageList_f( void ) {
format = "sBPTC";
// 128 bits per 16 pixels, so 1 byte per pixel
break;
- case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
- format = "LATC ";
+ case GL_COMPRESSED_RG_RGTC2:
+ format = "RGTC2";
// 128 bits per 16 pixels, so 1 byte per pixel
break;
- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
format = "DXT1 ";
// 64 bits per 16 pixels, so 4 bits per pixel
estSize /= 2;
break;
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ format = "DXT1a";
+ // 64 bits per 16 pixels, so 4 bits per pixel
+ estSize /= 2;
+ break;
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
format = "DXT5 ";
// 128 bits per 16 pixels, so 1 byte per pixel
@@ -1332,41 +1338,6 @@ static void R_MipMapsRGB( byte *in, int inWidth, int inHeight)
}
-static void R_MipMapLuminanceAlpha (const byte *in, byte *out, int width, int height)
-{
- int i, j, row;
-
- if ( width == 1 && height == 1 ) {
- return;
- }
-
- row = width * 4;
- width >>= 1;
- height >>= 1;
-
- if ( width == 0 || height == 0 ) {
- width += height; // get largest
- for (i=0 ; i<width ; i++, out+=4, in+=8 ) {
- out[0] =
- out[1] =
- out[2] = (in[0] + in[4]) >> 1;
- out[3] = (in[3] + in[7]) >> 1;
- }
- return;
- }
-
- for (i=0 ; i<height ; i++, in+=row) {
- for (j=0 ; j<width ; j++, out+=4, in+=8) {
- out[0] =
- out[1] =
- out[2] = (in[0] + in[4] + in[row ] + in[row+4]) >> 2;
- out[3] = (in[3] + in[7] + in[row+3] + in[row+7]) >> 2;
- }
- }
-
-}
-
-
static void R_MipMapNormalHeight (const byte *in, byte *out, int width, int height, qboolean swizzle)
{
int i, j;
@@ -1482,7 +1453,7 @@ RawImage_ScaleToPower2
===============
*/
-static void RawImage_ScaleToPower2( byte **data, int *inout_width, int *inout_height, int *inout_scaled_width, int *inout_scaled_height, imgType_t type, imgFlags_t flags, byte **resampledBuffer)
+static qboolean RawImage_ScaleToPower2( byte **data, int *inout_width, int *inout_height, imgType_t type, imgFlags_t flags, byte **resampledBuffer)
{
int width = *inout_width;
int height = *inout_height;
@@ -1491,6 +1462,7 @@ static void RawImage_ScaleToPower2( byte **data, int *inout_width, int *inout_he
qboolean picmip = flags & IMGFLAG_PICMIP;
qboolean mipmap = flags & IMGFLAG_MIPMAP;
qboolean clampToEdge = flags & IMGFLAG_CLAMPTOEDGE;
+ qboolean notScaled;
//
// convert to exact power of 2 sizes
@@ -1537,22 +1509,9 @@ static void RawImage_ScaleToPower2( byte **data, int *inout_width, int *inout_he
*resampledBuffer = ri.Hunk_AllocateTempMemory( finalwidth * finalheight * 4 );
if (scaled_width != width || scaled_height != height)
- {
ResampleTexture (*data, width, height, *resampledBuffer, scaled_width, scaled_height);
- }
else
- {
- byte *inbyte, *outbyte;
- int i;
-
- inbyte = *data;
- outbyte = *resampledBuffer;
-
- for (i = width * height * 4; i > 0; i--)
- {
- *outbyte++ = *inbyte++;
- }
- }
+ Com_Memcpy(*resampledBuffer, *data, width * height * 4);
if (type == IMGTYPE_COLORALPHA)
RGBAtoYCoCgA(*resampledBuffer, *resampledBuffer, scaled_width, scaled_height);
@@ -1566,34 +1525,29 @@ static void RawImage_ScaleToPower2( byte **data, int *inout_width, int *inout_he
}
if (type == IMGTYPE_COLORALPHA)
- {
YCoCgAtoRGBA(*resampledBuffer, *resampledBuffer, scaled_width, scaled_height);
- }
else if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT)
- {
FillInNormalizedZ(*resampledBuffer, *resampledBuffer, scaled_width, scaled_height);
- }
-
//endTime = ri.Milliseconds();
//ri.Printf(PRINT_ALL, "upsampled %dx%d to %dx%d in %dms\n", width, height, scaled_width, scaled_height, endTime - startTime);
*data = *resampledBuffer;
- width = scaled_width;
- height = scaled_height;
}
- else if ( scaled_width != width || scaled_height != height ) {
+ else if ( scaled_width != width || scaled_height != height )
+ {
if (data && resampledBuffer)
{
*resampledBuffer = ri.Hunk_AllocateTempMemory( scaled_width * scaled_height * 4 );
ResampleTexture (*data, width, height, *resampledBuffer, scaled_width, scaled_height);
*data = *resampledBuffer;
}
- width = scaled_width;
- height = scaled_height;
}
+ width = scaled_width;
+ height = scaled_height;
+
//
// perform optional picmip operation
//
@@ -1603,16 +1557,6 @@ static void RawImage_ScaleToPower2( byte **data, int *inout_width, int *inout_he
}
//
- // clamp to minimum size
- //
- if (scaled_width < 1) {
- scaled_width = 1;
- }
- if (scaled_height < 1) {
- scaled_height = 1;
- }
-
- //
// clamp to the current upper OpenGL limit
// scale both axis down equally so we don't have to
// deal with a half mip resampling
@@ -1623,10 +1567,35 @@ static void RawImage_ScaleToPower2( byte **data, int *inout_width, int *inout_he
scaled_height >>= 1;
}
- *inout_width = width;
- *inout_height = height;
- *inout_scaled_width = scaled_width;
- *inout_scaled_height = scaled_height;
+ //
+ // clamp to minimum size
+ //
+ scaled_width = MAX(1, scaled_width);
+ scaled_height = MAX(1, scaled_height);
+
+ notScaled = (width == scaled_width) && (height == scaled_height);
+
+ //
+ // rescale texture to new size using existing mipmap functions
+ //
+ if (data)
+ {
+ while (width > scaled_width || height > scaled_height)
+ {
+ if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT)
+ R_MipMapNormalHeight(*data, *data, width, height, qfalse);
+ else
+ R_MipMapsRGB(*data, width, height);
+
+ width = MAX(1, width >> 1);
+ height = MAX(1, height >> 1);
+ }
+ }
+
+ *inout_width = width;
+ *inout_height = height;
+
+ return notScaled;
}
@@ -1648,22 +1617,25 @@ static qboolean RawImage_HasAlpha(const byte *scan, int numPixels)
return qfalse;
}
-static GLenum RawImage_GetFormat(const byte *data, int numPixels, qboolean lightMap, imgType_t type, imgFlags_t flags)
+static GLenum RawImage_GetFormat(const byte *data, int numPixels, GLenum picFormat, qboolean lightMap, imgType_t type, imgFlags_t flags)
{
int samples = 3;
GLenum internalFormat = GL_RGB;
qboolean forceNoCompression = (flags & IMGFLAG_NO_COMPRESSION);
qboolean normalmap = (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT);
+ if (picFormat != GL_RGBA8)
+ return picFormat;
+
if(normalmap)
{
- if ((!RawImage_HasAlpha(data, numPixels) || (type == IMGTYPE_NORMAL)) && !forceNoCompression && (glRefConfig.textureCompression & TCR_LATC))
+ if ((type == IMGTYPE_NORMALHEIGHT) && RawImage_HasAlpha(data, numPixels))
{
- internalFormat = GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT;
- }
- else
- {
- if ( !forceNoCompression && glConfig.textureCompression == TC_S3TC_ARB )
+ if (!forceNoCompression && glRefConfig.textureCompression & TCR_BPTC)
+ {
+ internalFormat = GL_COMPRESSED_RGBA_BPTC_UNORM_ARB;
+ }
+ else if (!forceNoCompression && glConfig.textureCompression == TC_S3TC_ARB)
{
internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
}
@@ -1680,6 +1652,33 @@ static GLenum RawImage_GetFormat(const byte *data, int numPixels, qboolean light
internalFormat = GL_RGBA;
}
}
+ else
+ {
+ if (!forceNoCompression && glRefConfig.textureCompression & TCR_RGTC)
+ {
+ internalFormat = GL_COMPRESSED_RG_RGTC2;
+ }
+ else if (!forceNoCompression && glRefConfig.textureCompression & TCR_BPTC)
+ {
+ internalFormat = GL_COMPRESSED_RGBA_BPTC_UNORM_ARB;
+ }
+ else if (!forceNoCompression && glConfig.textureCompression == TC_S3TC_ARB)
+ {
+ internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
+ }
+ else if (r_texturebits->integer == 16)
+ {
+ internalFormat = GL_RGB5;
+ }
+ else if (r_texturebits->integer == 32)
+ {
+ internalFormat = GL_RGB8;
+ }
+ else
+ {
+ internalFormat = GL_RGB;
+ }
+ }
}
else if(lightMap)
{
@@ -1775,12 +1774,147 @@ static GLenum RawImage_GetFormat(const byte *data, int numPixels, qboolean light
return internalFormat;
}
+static void CompressMonoBlock(byte outdata[8], const byte indata[16])
+{
+ int hi, lo, diff, bias, outbyte, shift, i;
+ byte *p = outdata;
+
+ hi = lo = indata[0];
+ for (i = 1; i < 16; i++)
+ {
+ hi = MAX(indata[i], hi);
+ lo = MIN(indata[i], lo);
+ }
+
+ *p++ = hi;
+ *p++ = lo;
+
+ diff = hi - lo;
+
+ if (diff == 0)
+ {
+ outbyte = (hi == 255) ? 255 : 0;
+
+ for (i = 0; i < 6; i++)
+ *p++ = outbyte;
+
+ return;
+ }
+
+ bias = diff / 2 - lo * 7;
+ outbyte = shift = 0;
+ for (i = 0; i < 16; i++)
+ {
+ const byte fixIndex[8] = { 1, 7, 6, 5, 4, 3, 2, 0 };
+ byte index = fixIndex[(indata[i] * 7 + bias) / diff];
-static void RawImage_UploadTexture( byte *data, int x, int y, int width, int height, GLenum internalFormat, imgType_t type, imgFlags_t flags, qboolean subtexture )
+ outbyte |= index << shift;
+ shift += 3;
+ if (shift >= 8)
+ {
+ *p++ = outbyte & 0xff;
+ shift -= 8;
+ outbyte >>= 8;
+ }
+ }
+}
+
+static void RawImage_UploadToRgtc2Texture(GLuint texture, byte *data, int width, int height, int mip)
{
- int dataFormat, dataType;
+ int wBlocks, hBlocks, y, x, size;
+ byte *compressedData, *p;
- switch(internalFormat)
+ wBlocks = (width + 3) / 4;
+ hBlocks = (height + 3) / 4;
+ size = wBlocks * hBlocks * 16;
+
+ p = compressedData = ri.Hunk_AllocateTempMemory(size);
+ for (y = 0; y < height; y += 4)
+ {
+ int oh = MIN(4, height - y);
+
+ for (x = 0; x < width; x += 4)
+ {
+ byte workingData[16];
+ int component;
+
+ int ow = MIN(4, width - x);
+
+ for (component = 0; component < 2; component++)
+ {
+ int ox, oy;
+
+ for (oy = 0; oy < oh; oy++)
+ for (ox = 0; ox < ow; ox++)
+ workingData[oy * 4 + ox] = data[((y + oy) * width + x + ox) * 4 + component];
+
+ // dupe data to fill
+ for (oy = 0; oy < 4; oy++)
+ for (ox = (oy < oh) ? ow : 0; ox < 4; ox++)
+ workingData[oy * 4 + ox] = workingData[(oy % oh) * 4 + ox % ow];
+
+ CompressMonoBlock(p, workingData);
+ p += 8;
+ }
+ }
+ }
+
+ qglCompressedTextureImage2D(texture, GL_TEXTURE_2D, mip, GL_COMPRESSED_RG_RGTC2, width, height, 0, size, compressedData);
+
+ ri.Hunk_FreeTempMemory(compressedData);
+}
+
+static int CalculateMipSize(int width, int height, GLenum picFormat)
+{
+ int numBlocks = ((width + 3) / 4) * ((height + 3) / 4);
+ int numPixels = width * height;
+
+ switch (picFormat)
+ {
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RED_RGTC1:
+ case GL_COMPRESSED_SIGNED_RED_RGTC1:
+ return numBlocks * 8;
+
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
+ case GL_COMPRESSED_RG_RGTC2:
+ case GL_COMPRESSED_SIGNED_RG_RGTC2:
+ case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB:
+ case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB:
+ case GL_COMPRESSED_RGBA_BPTC_UNORM_ARB:
+ case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB:
+ return numBlocks * 16;
+
+ case GL_RGBA8:
+ case GL_SRGB8_ALPHA8_EXT:
+ return numPixels * 4;
+
+ default:
+ ri.Printf(PRINT_ALL, "Unsupported texture format %08x\n", picFormat);
+ return 0;
+ }
+
+ return 0;
+}
+
+
+static void RawImage_UploadTexture(GLuint texture, byte *data, int x, int y, int width, int height, GLenum target, GLenum picFormat, int numMips, GLenum internalFormat, imgType_t type, imgFlags_t flags, qboolean subtexture )
+{
+ int dataFormat, dataType;
+ qboolean rgtc = (internalFormat == GL_COMPRESSED_RG_RGTC2);
+ qboolean compressed = (!(picFormat == GL_RGBA8) || (picFormat == GL_SRGB8_ALPHA8_EXT));
+ qboolean mipmap = !!(flags & IMGFLAG_MIPMAP);
+ qboolean picmip = !!(flags & IMGFLAG_PICMIP);
+ int size, miplevel;
+ qboolean lastMip = qfalse;
+
+ switch (internalFormat)
{
case GL_DEPTH_COMPONENT:
case GL_DEPTH_COMPONENT16_ARB:
@@ -1799,60 +1933,83 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei
break;
}
- if ( subtexture )
- qglTexSubImage2D( GL_TEXTURE_2D, 0, x, y, width, height, dataFormat, dataType, data );
- else
- qglTexImage2D (GL_TEXTURE_2D, 0, internalFormat, width, height, 0, dataFormat, dataType, data );
+ if (!data)
+ {
+ miplevel = 0;
+ do
+ {
+ lastMip = (width == 1 && height == 1) || !mipmap;
+ qglTextureImage2D(texture, target, miplevel, internalFormat, width, height, 0, dataFormat, dataType, NULL);
+
+ width = MAX(1, width >> 1);
+ height = MAX(1, height >> 1);
+ miplevel++;
+ }
+ while (!lastMip);
+
+ return;
+ }
- if (flags & IMGFLAG_MIPMAP)
+ if (compressed && picmip)
{
- int miplevel;
+ for (miplevel = r_picmip->integer; miplevel > 0 && numMips > 1; miplevel--, numMips--)
+ {
+ size = CalculateMipSize(width, height, picFormat);
+ x >>= 1;
+ y >>= 1;
+ width = MAX(1, width >> 1);
+ height = MAX(1, height >> 1);
+ data += size;
+ }
+ }
- miplevel = 0;
- while (width > 1 || height > 1)
+ miplevel = 0;
+ do
+ {
+ lastMip = (width == 1 && height == 1) || !mipmap;
+ size = CalculateMipSize(width, height, picFormat);
+
+ if (compressed)
{
- if (data)
+ if (subtexture)
+ qglCompressedTextureSubImage2D(texture, target, miplevel, x, y, width, height, picFormat, size, data);
+ else
+ qglCompressedTextureImage2D(texture, target, miplevel, picFormat, width, height, 0, size, data);
+ }
+ else
+ {
+ if (miplevel != 0 && r_colorMipLevels->integer)
+ R_BlendOverTexture((byte *)data, width * height, mipBlendColors[miplevel]);
+
+ if (rgtc)
+ RawImage_UploadToRgtc2Texture(texture, data, width, height, miplevel);
+ else if (subtexture)
+ qglTextureSubImage2D(texture, target, miplevel, x, y, width, height, dataFormat, dataType, data);
+ else
+ qglTextureImage2D(texture, target, miplevel, internalFormat, width, height, 0, dataFormat, dataType, data);
+
+ if (!lastMip && numMips < 2)
{
if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT)
- {
- if (internalFormat == GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT)
- {
- R_MipMapLuminanceAlpha( data, data, width, height );
- }
- else
- {
- R_MipMapNormalHeight( data, data, width, height, qtrue);
- }
- }
+ R_MipMapNormalHeight(data, data, width, height, glRefConfig.swizzleNormalmap);
else
- {
- R_MipMapsRGB( data, width, height );
- }
+ R_MipMapsRGB(data, width, height);
}
-
- width >>= 1;
- height >>= 1;
- if (width < 1)
- width = 1;
- if (height < 1)
- height = 1;
- miplevel++;
+ }
- if ( data && r_colorMipLevels->integer )
- R_BlendOverTexture( (byte *)data, width * height, mipBlendColors[miplevel] );
+ x >>= 1;
+ y >>= 1;
+ width = MAX(1, width >> 1);
+ height = MAX(1, height >> 1);
+ miplevel++;
- if ( subtexture )
- {
- x >>= 1;
- y >>= 1;
- qglTexSubImage2D( GL_TEXTURE_2D, miplevel, x, y, width, height, dataFormat, dataType, data );
- }
- else
- {
- qglTexImage2D (GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, dataFormat, dataType, data );
- }
+ if (numMips > 1)
+ {
+ data += size;
+ numMips--;
}
}
+ while (!lastMip);
}
@@ -1862,23 +2019,51 @@ Upload32
===============
*/
-static void Upload32( byte *data, int width, int height, imgType_t type, imgFlags_t flags,
- qboolean lightMap, GLenum internalFormat, int *pUploadWidth, int *pUploadHeight)
+static void Upload32(byte *data, int x, int y, int width, int height, GLenum picFormat, int numMips, image_t *image)
{
- byte *scaledBuffer = NULL;
byte *resampledBuffer = NULL;
- int scaled_width, scaled_height;
int i, c;
byte *scan;
- RawImage_ScaleToPower2(&data, &width, &height, &scaled_width, &scaled_height, type, flags, &resampledBuffer);
-
- scaledBuffer = ri.Hunk_AllocateTempMemory( sizeof( unsigned ) * scaled_width * scaled_height );
+ imgType_t type = image->type;
+ imgFlags_t flags = image->flags;
+ GLenum internalFormat = image->internalFormat;
+ qboolean subtexture = (x != 0) || (y != 0) || (width != image->width) || (height != image->height);
+ qboolean notScaled = qtrue;
+ qboolean compressed = (picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT);
+ qboolean mipmap = !!(flags & IMGFLAG_MIPMAP) && (!compressed || numMips > 1);
+ qboolean cubemap = !!(flags & IMGFLAG_CUBEMAP);
+ GLenum uploadTarget = cubemap ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : GL_TEXTURE_2D;
+ GLenum textureTarget = cubemap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
+ int depth = cubemap ? 6 : 1;
+
+ if (!data)
+ {
+ RawImage_ScaleToPower2(NULL, &width, &height, type, flags, NULL);
+ for (i = 0; i < depth; i++)
+ RawImage_UploadTexture(image->texnum, NULL, 0, 0, width, height, uploadTarget + i, GL_RGBA8, 0, internalFormat, type, flags, qfalse);
+ goto done;
+ }
+ else if (!subtexture)
+ {
+ if (compressed || cubemap)
+ {
+ for (i = 0; i < depth; i++)
+ {
+ int w2 = width, h2 = height;
+ RawImage_UploadTexture(image->texnum, data, 0, 0, width, height, uploadTarget + i, picFormat, numMips, internalFormat, type, flags, qfalse);
+ for (c = numMips; c; c--)
+ {
+ data += CalculateMipSize(w2, h2, picFormat);
+ w2 = MAX(1, w2 >> 1);
+ h2 = MAX(1, h2 >> 1);
+ }
+ }
+ goto done;
+ }
+ notScaled = RawImage_ScaleToPower2(&data, &width, &height, type, flags, &resampledBuffer);
+ }
- //
- // scan the texture for each channel's max values
- // and verify if the alpha channel is being used or not
- //
c = width*height;
scan = data;
@@ -1903,137 +2088,44 @@ static void Upload32( byte *data, int width, int height, imgType_t type, imgFlag
}
}
- // normals are always swizzled
- if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT)
- {
+ if (glRefConfig.swizzleNormalmap && (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT))
RawImage_SwizzleRA(data, width, height);
- }
- // LATC2 is only used for normals
- if (internalFormat == GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT)
- {
- byte *in = data;
- int c = width * height;
- while (c--)
- {
- in[0] = in[1];
- in[2] = in[1];
- in += 4;
- }
- }
-
- // copy or resample data as appropriate for first MIP level
- if ( ( scaled_width == width ) &&
- ( scaled_height == height ) ) {
- if (!(flags & IMGFLAG_MIPMAP))
- {
- RawImage_UploadTexture( data, 0, 0, scaled_width, scaled_height, internalFormat, type, flags, qfalse );
- //qglTexImage2D (GL_TEXTURE_2D, 0, internalFormat, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
- *pUploadWidth = scaled_width;
- *pUploadHeight = scaled_height;
+ // This corresponds to what the OpenGL1 renderer does
+ if (!(flags & IMGFLAG_NOLIGHTSCALE) && (!notScaled || mipmap))
+ R_LightScaleTexture(data, width, height, !mipmap);
- goto done;
- }
- Com_Memcpy (scaledBuffer, data, width*height*4);
- }
- else
+ if (subtexture)
{
- // use the normal mip-mapping function to go down from here
- while ( width > scaled_width || height > scaled_height ) {
-
- if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT)
- {
- if (internalFormat == GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT)
- {
- R_MipMapLuminanceAlpha( data, data, width, height );
- }
- else
- {
- R_MipMapNormalHeight( data, data, width, height, qtrue);
- }
- }
- else
- {
- R_MipMapsRGB( data, width, height );
- }
-
- width >>= 1;
- height >>= 1;
- if ( width < 1 ) {
- width = 1;
- }
- if ( height < 1 ) {
- height = 1;
- }
- }
- Com_Memcpy( scaledBuffer, data, width * height * 4 );
+ // FIXME: Incorrect if original texture was not a power of 2 texture or picmipped
+ RawImage_UploadTexture(image->texnum, data, x, y, width, height, uploadTarget, GL_RGBA8, 0, internalFormat, type, flags, qtrue);
+ GL_CheckErrors();
+ return;
}
- if (!(flags & IMGFLAG_NOLIGHTSCALE))
- R_LightScaleTexture (scaledBuffer, scaled_width, scaled_height, !(flags & IMGFLAG_MIPMAP) );
-
- *pUploadWidth = scaled_width;
- *pUploadHeight = scaled_height;
-
- RawImage_UploadTexture(scaledBuffer, 0, 0, scaled_width, scaled_height, internalFormat, type, flags, qfalse);
+ RawImage_UploadTexture(image->texnum, data, 0, 0, width, height, uploadTarget, GL_RGBA8, 0, internalFormat, type, flags, qfalse);
done:
- if (flags & IMGFLAG_MIPMAP)
- {
- if ( glConfig.textureFilterAnisotropic )
- qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,
- (GLint)Com_Clamp( 1, glConfig.maxAnisotropy, r_ext_max_anisotropy->integer ) );
-
- qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
- qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
- }
- else
- {
- if ( glConfig.textureFilterAnisotropic )
- qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1 );
-
- qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
- qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
- }
-
- GL_CheckErrors();
-
- if ( scaledBuffer != 0 )
- ri.Hunk_FreeTempMemory( scaledBuffer );
- if ( resampledBuffer != 0 )
- ri.Hunk_FreeTempMemory( resampledBuffer );
-}
-
-
-static void EmptyTexture( int width, int height, imgType_t type, imgFlags_t flags,
- qboolean lightMap, GLenum internalFormat, int *pUploadWidth, int *pUploadHeight )
-{
- int scaled_width, scaled_height;
-
- RawImage_ScaleToPower2(NULL, &width, &height, &scaled_width, &scaled_height, type, flags, NULL);
-
- *pUploadWidth = scaled_width;
- *pUploadHeight = scaled_height;
-
- RawImage_UploadTexture(NULL, 0, 0, scaled_width, scaled_height, internalFormat, type, flags, qfalse);
+ image->uploadWidth = width;
+ image->uploadHeight = height;
- if (flags & IMGFLAG_MIPMAP)
+ if (mipmap)
{
- if ( glConfig.textureFilterAnisotropic )
- qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,
- (GLint)Com_Clamp( 1, glConfig.maxAnisotropy, r_ext_max_anisotropy->integer ) );
+ if (glConfig.textureFilterAnisotropic && !cubemap)
+ qglTextureParameteri(image->texnum, textureTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT,
+ (GLint)Com_Clamp(1, glConfig.maxAnisotropy, r_ext_max_anisotropy->integer));
- qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
- qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
+ qglTextureParameterf(image->texnum, textureTarget, GL_TEXTURE_MIN_FILTER, gl_filter_min);
+ qglTextureParameterf(image->texnum, textureTarget, GL_TEXTURE_MAG_FILTER, gl_filter_max);
}
else
{
- if ( glConfig.textureFilterAnisotropic )
- qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1 );
+ if (glConfig.textureFilterAnisotropic && !cubemap)
+ qglTextureParameteri(image->texnum, textureTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
- qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
- qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ qglTextureParameterf(image->texnum, textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ qglTextureParameterf(image->texnum, textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
// Fix for sampling depth buffer on old nVidia cards
@@ -2044,26 +2136,29 @@ static void EmptyTexture( int width, int height, imgType_t type, imgFlags_t flag
case GL_DEPTH_COMPONENT16_ARB:
case GL_DEPTH_COMPONENT24_ARB:
case GL_DEPTH_COMPONENT32_ARB:
- qglTexParameterf(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE );
- qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
- qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+ qglTextureParameterf(image->texnum, textureTarget, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
+ qglTextureParameterf(image->texnum, textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ qglTextureParameterf(image->texnum, textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
break;
default:
break;
}
GL_CheckErrors();
+
+ if ( resampledBuffer != NULL )
+ ri.Hunk_FreeTempMemory( resampledBuffer );
}
/*
================
-R_CreateImage
+R_CreateImage2
This is the only way any image_t are created
================
*/
-image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgType_t type, imgFlags_t flags, int internalFormat ) {
+image_t *R_CreateImage2( const char *name, byte *pic, int width, int height, GLenum picFormat, int numMips, imgType_t type, imgFlags_t flags, int internalFormat ) {
image_t *image;
qboolean isLightmap = qfalse;
long hash;
@@ -2097,81 +2192,24 @@ image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgT
glWrapClampMode = GL_REPEAT;
if (!internalFormat)
- {
- if (image->flags & IMGFLAG_CUBEMAP)
- internalFormat = GL_RGBA8;
- else
- internalFormat = RawImage_GetFormat(pic, width * height, isLightmap, image->type, image->flags);
- }
+ internalFormat = RawImage_GetFormat(pic, width * height, picFormat, isLightmap, image->type, image->flags);
image->internalFormat = internalFormat;
-
- // lightmaps are always allocated on TMU 1
- if ( qglActiveTextureARB && isLightmap ) {
- image->TMU = 1;
- } else {
- image->TMU = 0;
- }
-
- if ( qglActiveTextureARB ) {
- GL_SelectTexture( image->TMU );
- }
+ Upload32(pic, 0, 0, image->width, image->height, picFormat, numMips, image);
if (image->flags & IMGFLAG_CUBEMAP)
{
- GL_Bind(image);
- qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
-
- qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- if (image->flags & IMGFLAG_MIPMAP)
- {
- qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- }
- else
- {
- qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- }
-
- qglTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic);
- qglTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic);
- qglTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic);
- qglTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic);
- qglTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic);
- qglTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic);
-
- if (image->flags & IMGFLAG_MIPMAP)
- qglGenerateMipmapEXT(GL_TEXTURE_CUBE_MAP);
-
- image->uploadWidth = width;
- image->uploadHeight = height;
+ qglTextureParameterf(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, glWrapClampMode);
+ qglTextureParameterf(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, glWrapClampMode);
+ qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, glWrapClampMode);
}
else
{
- GL_Bind(image);
-
- if (pic)
- {
- Upload32( pic, image->width, image->height, image->type, image->flags,
- isLightmap, image->internalFormat, &image->uploadWidth,
- &image->uploadHeight );
- }
- else
- {
- EmptyTexture(image->width, image->height, image->type, image->flags,
- isLightmap, image->internalFormat, &image->uploadWidth,
- &image->uploadHeight );
- }
-
- qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapClampMode );
- qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapClampMode );
+ qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapClampMode);
+ qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapClampMode);
}
- GL_SelectTexture( 0 );
-
hash = generateHashValue(name);
image->next = hashTable[hash];
hashTable[hash] = image;
@@ -2179,114 +2217,30 @@ image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgT
return image;
}
-void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int height )
-{
- byte *scaledBuffer = NULL;
- byte *resampledBuffer = NULL;
- int scaled_width, scaled_height, scaled_x, scaled_y;
- byte *data = pic;
-
- // normals are always swizzled
- if (image->type == IMGTYPE_NORMAL || image->type == IMGTYPE_NORMALHEIGHT)
- {
- RawImage_SwizzleRA(pic, width, height);
- }
-
- // LATC2 is only used for normals
- if (image->internalFormat == GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT)
- {
- byte *in = data;
- int c = width * height;
- while (c--)
- {
- in[0] = in[1];
- in[2] = in[1];
- in += 4;
- }
- }
-
-
- RawImage_ScaleToPower2(&pic, &width, &height, &scaled_width, &scaled_height, image->type, image->flags, &resampledBuffer);
-
- scaledBuffer = ri.Hunk_AllocateTempMemory( sizeof( unsigned ) * scaled_width * scaled_height );
-
- if ( qglActiveTextureARB ) {
- GL_SelectTexture( image->TMU );
- }
-
- GL_Bind(image);
-
- // copy or resample data as appropriate for first MIP level
- if ( ( scaled_width == width ) &&
- ( scaled_height == height ) ) {
- if (!(image->flags & IMGFLAG_MIPMAP))
- {
- scaled_x = x * scaled_width / width;
- scaled_y = y * scaled_height / height;
- RawImage_UploadTexture( data, scaled_x, scaled_y, scaled_width, scaled_height, image->internalFormat, image->type, image->flags, qtrue );
- //qglTexSubImage2D( GL_TEXTURE_2D, 0, scaled_x, scaled_y, scaled_width, scaled_height, GL_RGBA, GL_UNSIGNED_BYTE, data );
-
- GL_CheckErrors();
- goto done;
- }
- Com_Memcpy (scaledBuffer, data, width*height*4);
- }
- else
- {
- // use the normal mip-mapping function to go down from here
- while ( width > scaled_width || height > scaled_height ) {
-
- if (image->type == IMGTYPE_NORMAL || image->type == IMGTYPE_NORMALHEIGHT)
- {
- if (image->internalFormat == GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT)
- {
- R_MipMapLuminanceAlpha( data, data, width, height );
- }
- else
- {
- R_MipMapNormalHeight( data, data, width, height, qtrue);
- }
- }
- else
- {
- R_MipMapsRGB( data, width, height );
- }
-
- width >>= 1;
- height >>= 1;
- x >>= 1;
- y >>= 1;
- if ( width < 1 ) {
- width = 1;
- }
- if ( height < 1 ) {
- height = 1;
- }
- }
- Com_Memcpy( scaledBuffer, data, width * height * 4 );
- }
- if (!(image->flags & IMGFLAG_NOLIGHTSCALE))
- R_LightScaleTexture (scaledBuffer, scaled_width, scaled_height, !(image->flags & IMGFLAG_MIPMAP) );
-
- scaled_x = x * scaled_width / width;
- scaled_y = y * scaled_height / height;
- RawImage_UploadTexture( (byte *)data, scaled_x, scaled_y, scaled_width, scaled_height, image->internalFormat, image->type, image->flags, qtrue );
+/*
+================
+R_CreateImage
-done:
-
- GL_SelectTexture( 0 );
+Wrapper for R_CreateImage2(), for the old parameters.
+================
+*/
+image_t *R_CreateImage(const char *name, byte *pic, int width, int height, imgType_t type, imgFlags_t flags, int internalFormat)
+{
+ return R_CreateImage2(name, pic, width, height, GL_RGBA8, 0, type, flags, internalFormat);
+}
- GL_CheckErrors();
- if ( scaledBuffer != 0 )
- ri.Hunk_FreeTempMemory( scaledBuffer );
- if ( resampledBuffer != 0 )
- ri.Hunk_FreeTempMemory( resampledBuffer );
+void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int height )
+{
+ Upload32(pic, x, y, width, height, GL_RGBA8, 0, image);
}
//===================================================================
+// Prototype for dds loader function which isn't common to both renderers
+void R_LoadDDS(const char *filename, byte **pic, int *width, int *height, GLenum *picFormat, int *numMips);
+
typedef struct
{
char *ext;
@@ -2315,7 +2269,7 @@ Loads any of the supported image types into a cannonical
32 bit format.
=================
*/
-void R_LoadImage( const char *name, byte **pic, int *width, int *height )
+void R_LoadImage( const char *name, byte **pic, int *width, int *height, GLenum *picFormat, int *numMips )
{
qboolean orgNameFailed = qfalse;
int orgLoader = -1;
@@ -2327,11 +2281,28 @@ void R_LoadImage( const char *name, byte **pic, int *width, int *height )
*pic = NULL;
*width = 0;
*height = 0;
+ *picFormat = GL_RGBA8;
+ *numMips = 0;
Q_strncpyz( localName, name, MAX_QPATH );
ext = COM_GetExtension( localName );
+ // If compressed textures are enabled, try loading a DDS first, it'll load fastest
+ if (r_ext_compressed_textures->integer)
+ {
+ char ddsName[MAX_QPATH];
+
+ COM_StripExtension(name, ddsName, MAX_QPATH);
+ Q_strcat(ddsName, MAX_QPATH, ".dds");
+
+ R_LoadDDS(ddsName, pic, width, height, picFormat, numMips);
+
+ // If loaded, we're done.
+ if (*pic)
+ return;
+ }
+
if( *ext )
{
// Look for the correct loader and use it
@@ -2403,7 +2374,10 @@ image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags )
image_t *image;
int width, height;
byte *pic;
+ GLenum picFormat;
+ int picNumMips;
long hash;
+ imgFlags_t checkFlagsTrue, checkFlagsFalse;
if (!name) {
return NULL;
@@ -2429,12 +2403,15 @@ image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags )
//
// load the pic from disk
//
- R_LoadImage( name, &pic, &width, &height );
+ R_LoadImage( name, &pic, &width, &height, &picFormat, &picNumMips );
if ( pic == NULL ) {
return NULL;
}
- if (r_normalMapping->integer && !(type == IMGTYPE_NORMAL) && (flags & IMGFLAG_PICMIP) && (flags & IMGFLAG_MIPMAP) && (flags & IMGFLAG_GENNORMALMAP))
+ checkFlagsTrue = IMGFLAG_PICMIP | IMGFLAG_MIPMAP | IMGFLAG_GENNORMALMAP;
+ checkFlagsFalse = IMGFLAG_CUBEMAP;
+ if (r_normalMapping->integer && (picFormat == GL_RGBA8) && (type == IMGTYPE_COLORALPHA) &&
+ ((flags & checkFlagsTrue) == checkFlagsTrue) && !(flags & checkFlagsFalse))
{
char normalName[MAX_QPATH];
image_t *normalImage;
@@ -2537,7 +2514,21 @@ image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags )
}
}
- image = R_CreateImage( ( char * ) name, pic, width, height, type, flags, 0 );
+ // force mipmaps off if image is compressed but doesn't have enough mips
+ if ((flags & IMGFLAG_MIPMAP) && picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT)
+ {
+ int wh = MAX(width, height);
+ int neededMips = 0;
+ while (wh)
+ {
+ neededMips++;
+ wh >>= 1;
+ }
+ if (neededMips > picNumMips)
+ flags &= ~IMGFLAG_MIPMAP;
+ }
+
+ image = R_CreateImage2( ( char * ) name, pic, width, height, picFormat, picNumMips, type, flags, 0 );
ri.Free( pic );
return image;
}
@@ -2764,6 +2755,12 @@ void R_CreateBuiltinImages( void ) {
tr.renderImage = R_CreateImage("_render", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, hdrFormat);
+ if (r_shadowBlur->integer)
+ tr.screenScratchImage = R_CreateImage("screenScratch", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, rgbFormat);
+
+ if (r_shadowBlur->integer || r_ssao->integer)
+ tr.hdrDepthImage = R_CreateImage("*hdrDepth", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_INTENSITY32F_ARB);
+
if (r_drawSunRays->integer)
tr.sunRaysImage = R_CreateImage("*sunRays", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, rgbFormat);
@@ -2811,7 +2808,6 @@ void R_CreateBuiltinImages( void ) {
if (r_ssao->integer)
{
tr.screenSsaoImage = R_CreateImage("*screenSsao", NULL, width / 2, height / 2, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8);
- tr.hdrDepthImage = R_CreateImage("*hdrDepth", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_INTENSITY32F_ARB);
}
if (r_shadows->integer == 4)
@@ -2827,11 +2823,8 @@ void R_CreateBuiltinImages( void ) {
for ( x = 0; x < 4; x++)
{
tr.sunShadowDepthImage[x] = R_CreateImage(va("*sunshadowdepth%i", x), NULL, r_shadowMapSize->integer, r_shadowMapSize->integer, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB);
- GL_Bind(tr.sunShadowDepthImage[x]);
- qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
- qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
- qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
- qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
+ qglTextureParameterf(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
+ qglTextureParameterf(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
}
tr.screenShadowImage = R_CreateImage("*screenShadow", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8);
@@ -2839,7 +2832,7 @@ void R_CreateBuiltinImages( void ) {
if (r_cubeMapping->integer)
{
- tr.renderCubeImage = R_CreateImage("*renderCube", NULL, CUBE_MAP_SIZE, CUBE_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_CUBEMAP, rgbFormat);
+ tr.renderCubeImage = R_CreateImage("*renderCube", NULL, r_cubemapSize->integer, r_cubemapSize->integer, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_CUBEMAP, rgbFormat);
}
}
}
@@ -2856,7 +2849,11 @@ void R_SetColorMappings( void ) {
int inf;
// setup the overbright lighting
+#if defined(USE_OVERBRIGHT)
tr.overbrightBits = r_overBrightBits->integer;
+#else
+ tr.overbrightBits = 0;
+#endif
// allow 2 overbright bits
if ( tr.overbrightBits > 2 ) {
@@ -2865,6 +2862,11 @@ void R_SetColorMappings( void ) {
tr.overbrightBits = 0;
}
+ // don't allow more overbright bits than map overbright bits
+ if ( tr.overbrightBits > r_mapOverBrightBits->integer ) {
+ tr.overbrightBits = r_mapOverBrightBits->integer;
+ }
+
tr.identityLight = 1.0f / ( 1 << tr.overbrightBits );
tr.identityLightByte = 255 * tr.identityLight;
@@ -2940,15 +2942,7 @@ void R_DeleteTextures( void ) {
tr.numImages = 0;
- Com_Memset( glState.currenttextures, 0, sizeof( glState.currenttextures ) );
- if ( qglActiveTextureARB ) {
- GL_SelectTexture( 1 );
- qglBindTexture( GL_TEXTURE_2D, 0 );
- GL_SelectTexture( 0 );
- qglBindTexture( GL_TEXTURE_2D, 0 );
- } else {
- qglBindTexture( GL_TEXTURE_2D, 0 );
- }
+ GL_BindNullTextures();
}
/*
@@ -3121,7 +3115,7 @@ qhandle_t RE_RegisterSkin( const char *name ) {
// If not a .skin file, load as a single shader
if ( strcmp( name + strlen( name ) - 5, ".skin" ) ) {
skin->numSurfaces = 1;
- skin->surfaces[0] = ri.Hunk_Alloc( sizeof(skin->surfaces[0]), h_low );
+ skin->surfaces[0] = ri.Hunk_Alloc( sizeof( *skin->surfaces[0] ), h_low );
skin->surfaces[0]->shader = R_FindShader( name, LIGHTMAP_NONE, qtrue );
return hSkin;
}
@@ -3192,7 +3186,7 @@ void R_InitSkins( void ) {
skin = tr.skins[0] = ri.Hunk_Alloc( sizeof( skin_t ), h_low );
Q_strncpyz( skin->name, "<default skin>", sizeof( skin->name ) );
skin->numSurfaces = 1;
- skin->surfaces[0] = ri.Hunk_Alloc( sizeof( *skin->surfaces ), h_low );
+ skin->surfaces[0] = ri.Hunk_Alloc( sizeof( *skin->surfaces[0] ), h_low );
skin->surfaces[0]->shader = tr.defaultShader;
}