From 7ebcf42f808b8c1a209cabdaa6f879b8e1790036 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Sun, 12 Jul 2015 20:41:41 -0500 Subject: Fix alloc size for default skin and single shader skin Found by Coverity. --- src/renderergl2/tr_image.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/renderergl2/tr_image.c') diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index 08894a4a..ef244d56 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -3121,7 +3121,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 +3192,7 @@ void R_InitSkins( void ) { skin = tr.skins[0] = ri.Hunk_Alloc( sizeof( skin_t ), h_low ); Q_strncpyz( skin->name, "", 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; } -- cgit From 3372e9eaf5c21e1e44f000e09a94584231ba9550 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Tue, 8 Dec 2015 05:17:05 -0800 Subject: OpenGL2: Add option in code for alternate overbright method. --- src/renderergl2/tr_image.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/renderergl2/tr_image.c') diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index ef244d56..541b1a38 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -2856,7 +2856,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 ) { -- cgit From f77b9694e3d2870f62b27589c70c2cf254248db3 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Tue, 15 Dec 2015 03:23:55 -0800 Subject: OpenGL2: Switch to RGTC from LATC for normal maps. Also added a RGTC compressor as a workaround on Intel graphics. --- src/renderergl2/tr_image.c | 248 +++++++++++++++++++++++++++------------------ 1 file changed, 147 insertions(+), 101 deletions(-) (limited to 'src/renderergl2/tr_image.c') diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index 541b1a38..93ee28e9 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -177,15 +177,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 +1337,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> 1; - out[3] = (in[3] + in[7]) >> 1; - } - return; - } - - for (i=0 ; i> 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; @@ -1657,13 +1627,13 @@ static GLenum RawImage_GetFormat(const byte *data, int numPixels, qboolean light if(normalmap) { - if ((!RawImage_HasAlpha(data, numPixels) || (type == IMGTYPE_NORMAL)) && !forceNoCompression && (glRefConfig.textureCompression & TCR_LATC)) - { - internalFormat = GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT; - } - else + if ((type == IMGTYPE_NORMALHEIGHT) && RawImage_HasAlpha(data, numPixels)) { - 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 +1650,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,10 +1772,101 @@ 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]; + + outbyte |= index << shift; + shift += 3; + if (shift >= 8) + { + *p++ = outbyte & 0xff; + shift -= 8; + outbyte >>= 8; + } + } +} + +static void RawImage_UploadToRgtc2Texture(byte *data, int width, int height, int mip) +{ + int wBlocks, hBlocks, y, x, size; + byte *compressedData, *p; + + 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; + } + } + } + + qglCompressedTexImage2DARB(GL_TEXTURE_2D, mip, GL_COMPRESSED_RG_RGTC2, width, height, 0, size, compressedData); + + ri.Hunk_FreeTempMemory(compressedData); +} + static void RawImage_UploadTexture( byte *data, int x, int y, int width, int height, GLenum internalFormat, imgType_t type, imgFlags_t flags, qboolean subtexture ) { int dataFormat, dataType; + qboolean rgtc = (internalFormat == GL_COMPRESSED_RG_RGTC2); switch(internalFormat) { @@ -1802,7 +1890,12 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei 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 (rgtc) + RawImage_UploadToRgtc2Texture(data, width, height, 0); + else + qglTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, dataFormat, dataType, data); + } if (flags & IMGFLAG_MIPMAP) { @@ -1815,14 +1908,7 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei { 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 { @@ -1849,7 +1935,10 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei } else { - qglTexImage2D (GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, dataFormat, dataType, data ); + if (rgtc) + RawImage_UploadToRgtc2Texture(data, width, height, miplevel); + else + qglTexImage2D(GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, dataFormat, dataType, data); } } } @@ -1903,25 +1992,11 @@ 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 ) ) { @@ -1943,14 +2018,7 @@ static void Upload32( byte *data, int width, int height, imgType_t type, imgFlag 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 { @@ -2186,26 +2254,11 @@ void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int h 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) + if (glRefConfig.swizzleNormalmap && (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 ); @@ -2238,14 +2291,7 @@ void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int h 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); - } + R_MipMapNormalHeight( data, data, width, height, glRefConfig.swizzleNormalmap ); } else { -- cgit From fad434534de2f0794f84d6d1c13d8ed171b6a3e1 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Wed, 16 Dec 2015 07:12:30 -0800 Subject: OpenGL2: Some tr_image.c cleanup. --- src/renderergl2/tr_image.c | 301 ++++++++++++--------------------------------- 1 file changed, 77 insertions(+), 224 deletions(-) (limited to 'src/renderergl2/tr_image.c') diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index 93ee28e9..7047a0d6 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -1452,7 +1452,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; @@ -1461,6 +1461,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 @@ -1507,22 +1508,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); @@ -1536,34 +1524,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 // @@ -1572,16 +1555,6 @@ static void RawImage_ScaleToPower2( byte **data, int *inout_width, int *inout_he scaled_height >>= r_picmip->integer; } - // - // 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 @@ -1593,10 +1566,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; } @@ -1951,23 +1949,30 @@ 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, 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); + 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 mipmap = !!(flags & IMGFLAG_MIPMAP); - scaledBuffer = ri.Hunk_AllocateTempMemory( sizeof( unsigned ) * scaled_width * scaled_height ); + if (!data) + { + RawImage_ScaleToPower2(NULL, &width, &height, type, flags, NULL); + RawImage_UploadTexture(NULL, 0, 0, width, height, internalFormat, type, flags, qfalse); + goto done; + } + else if (!subtexture) + { + 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; @@ -1993,100 +1998,28 @@ static void Upload32( byte *data, int width, int height, imgType_t type, imgFlag } if (glRefConfig.swizzleNormalmap && (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT)) - { RawImage_SwizzleRA(data, width, height); - } - // 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) - { - R_MipMapNormalHeight( data, data, width, height, glRefConfig.swizzleNormalmap ); - } - 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(data, x, y, width, height, 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(data, 0, 0, width, height, 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 ) ); + image->uploadWidth = width; + image->uploadHeight = height; - 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); - - if (flags & IMGFLAG_MIPMAP) + if (mipmap) { if ( glConfig.textureFilterAnisotropic ) qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, @@ -2121,6 +2054,9 @@ static void EmptyTexture( int width, int height, imgType_t type, imgFlags_t flag } GL_CheckErrors(); + + if ( resampledBuffer != NULL ) + ri.Hunk_FreeTempMemory( resampledBuffer ); } @@ -2186,9 +2122,10 @@ image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgT GL_SelectTexture( image->TMU ); } + GL_Bind(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); @@ -2219,20 +2156,7 @@ image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgT } 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 ); - } + Upload32( pic, 0, 0, image->width, image->height, image ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapClampMode ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapClampMode ); @@ -2249,86 +2173,15 @@ image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgT 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; - - if (glRefConfig.swizzleNormalmap && (image->type == IMGTYPE_NORMAL || image->type == IMGTYPE_NORMALHEIGHT)) - { - RawImage_SwizzleRA(pic, width, height); + if (qglActiveTextureARB) { + GL_SelectTexture(image->TMU); } - RawImage_ScaleToPower2(&pic, &width, &height, &scaled_width, &scaled_height, image->type, image->flags, &resampledBuffer); + GL_Bind(image); - scaledBuffer = ri.Hunk_AllocateTempMemory( sizeof( unsigned ) * scaled_width * scaled_height ); + Upload32(pic, x, y, width, height, image); - 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) - { - R_MipMapNormalHeight( data, data, width, height, glRefConfig.swizzleNormalmap ); - } - 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 ); - -done: - - GL_SelectTexture( 0 ); - - GL_CheckErrors(); - - if ( scaledBuffer != 0 ) - ri.Hunk_FreeTempMemory( scaledBuffer ); - if ( resampledBuffer != 0 ) - ri.Hunk_FreeTempMemory( resampledBuffer ); + GL_SelectTexture(0); } //=================================================================== -- cgit From 342a3bd68085cdc11f3167253492043459ee9910 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Fri, 18 Dec 2015 06:53:20 -0800 Subject: OpenGL2: DDS (compressed textures) support. --- src/renderergl2/tr_image.c | 130 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 115 insertions(+), 15 deletions(-) (limited to 'src/renderergl2/tr_image.c') diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index 7047a0d6..c35af4c2 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -1616,13 +1616,16 @@ 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 ((type == IMGTYPE_NORMALHEIGHT) && RawImage_HasAlpha(data, numPixels)) @@ -1861,11 +1864,67 @@ static void RawImage_UploadToRgtc2Texture(byte *data, int width, int height, int } -static void RawImage_UploadTexture( byte *data, int x, int y, int width, int height, GLenum internalFormat, imgType_t type, imgFlags_t flags, qboolean subtexture ) +static void RawImage_UploadTexture( byte *data, int x, int y, int width, int height, GLenum picFormat, int numMips, GLenum internalFormat, imgType_t type, imgFlags_t flags, qboolean subtexture ) { int dataFormat, dataType; qboolean rgtc = (internalFormat == GL_COMPRESSED_RG_RGTC2); + if (picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT) + { + int bytesPer4x4Block = 0; + int miplevel = 0; + + switch (picFormat) + { + case GL_COMPRESSED_RGB_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: + bytesPer4x4Block = 8; + break; + 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: + bytesPer4x4Block = 16; + break; + default: + ri.Printf(PRINT_ALL, "Unsupported texture format %08x\n", picFormat); + return; + break; + } + + for (miplevel = 0; miplevel < numMips; miplevel++) + { + int size; + + size = ((width + 3) / 4) * ((height + 3) / 4) * bytesPer4x4Block; + + if (subtexture) + qglCompressedTexSubImage2DARB(GL_TEXTURE_2D, miplevel, x, y, width, height, internalFormat, size, data); + else + qglCompressedTexImage2DARB(GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, size, data); + + x >>= 1; + y >>= 1; + x -= x % 4; + y -= y % 4; + + width = MAX(1, width >> 1); + height = MAX(1, height >> 1); + data += size; + } + + return; + } + switch(internalFormat) { case GL_DEPTH_COMPONENT: @@ -1949,7 +2008,7 @@ Upload32 =============== */ -static void Upload32(byte *data, int x, int y, int width, int height, image_t *image) +static void Upload32(byte *data, int x, int y, int width, int height, GLenum picFormat, int numMips, image_t *image) { byte *resampledBuffer = NULL; int i, c; @@ -1965,11 +2024,16 @@ static void Upload32(byte *data, int x, int y, int width, int height, image_t *i if (!data) { RawImage_ScaleToPower2(NULL, &width, &height, type, flags, NULL); - RawImage_UploadTexture(NULL, 0, 0, width, height, internalFormat, type, flags, qfalse); + RawImage_UploadTexture(NULL, 0, 0, width, height, GL_RGBA8, 0, internalFormat, type, flags, qfalse); goto done; } else if (!subtexture) { + if (picFormat != GL_RGBA8) + { + RawImage_UploadTexture(data, 0, 0, width, height, picFormat, numMips, internalFormat, type, flags, qfalse); + goto done; + } notScaled = RawImage_ScaleToPower2(&data, &width, &height, type, flags, &resampledBuffer); } @@ -2007,12 +2071,12 @@ static void Upload32(byte *data, int x, int y, int width, int height, image_t *i if (subtexture) { // FIXME: Incorrect if original texture was not a power of 2 texture or picmipped - RawImage_UploadTexture(data, x, y, width, height, internalFormat, type, flags, qtrue); + RawImage_UploadTexture(data, x, y, width, height, GL_RGBA8, 0, internalFormat, type, flags, qtrue); GL_CheckErrors(); return; } - RawImage_UploadTexture(data, 0, 0, width, height, internalFormat, type, flags, qfalse); + RawImage_UploadTexture(data, 0, 0, width, height, GL_RGBA8, 0, internalFormat, type, flags, qfalse); done: @@ -2062,12 +2126,12 @@ done: /* ================ -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; @@ -2105,7 +2169,7 @@ image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgT 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; @@ -2156,7 +2220,7 @@ image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgT } else { - Upload32( pic, 0, 0, image->width, image->height, image ); + Upload32( pic, 0, 0, image->width, image->height, picFormat, numMips, image ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapClampMode ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapClampMode ); @@ -2171,6 +2235,20 @@ image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgT return image; } + +/* +================ +R_CreateImage + +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); +} + + void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int height ) { if (qglActiveTextureARB) { @@ -2179,13 +2257,16 @@ void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int h GL_Bind(image); - Upload32(pic, x, y, width, height, image); + Upload32(pic, x, y, width, height, GL_RGBA8, 0, image); GL_SelectTexture(0); } //=================================================================== +// 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; @@ -2214,7 +2295,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; @@ -2226,11 +2307,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 @@ -2302,6 +2400,8 @@ 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; if (!name) { @@ -2328,12 +2428,12 @@ 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)) + if (r_normalMapping->integer && (picFormat == GL_RGBA8) && !(type == IMGTYPE_NORMAL) && (flags & IMGFLAG_PICMIP) && (flags & IMGFLAG_MIPMAP) && (flags & IMGFLAG_GENNORMALMAP)) { char normalName[MAX_QPATH]; image_t *normalImage; @@ -2436,7 +2536,7 @@ image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags ) } } - image = R_CreateImage( ( char * ) name, pic, width, height, type, flags, 0 ); + image = R_CreateImage2( ( char * ) name, pic, width, height, picFormat, picNumMips, type, flags, 0 ); ri.Free( pic ); return image; } -- cgit From e78dc015d1c94fbe4fa5014d412a2cdf23f2dc7d Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Mon, 21 Dec 2015 20:24:19 -0800 Subject: OpenGL2: Support picmip for DDS textures. --- src/renderergl2/tr_image.c | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) (limited to 'src/renderergl2/tr_image.c') diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index c35af4c2..74eddfe0 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -1869,7 +1869,7 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei int dataFormat, dataType; qboolean rgtc = (internalFormat == GL_COMPRESSED_RG_RGTC2); - if (picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT) + if (data && picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT) { int bytesPer4x4Block = 0; int miplevel = 0; @@ -1877,6 +1877,7 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei 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: @@ -1901,11 +1902,26 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei break; } - for (miplevel = 0; miplevel < numMips; miplevel++) + if (flags & IMGFLAG_PICMIP) { - int size; + for (miplevel = r_picmip->integer; miplevel > 0 && numMips > 1; miplevel--, numMips--) + { + int size = ((width + 3) / 4) * ((height + 3) / 4) * bytesPer4x4Block; - size = ((width + 3) / 4) * ((height + 3) / 4) * bytesPer4x4Block; + x >>= 1; + y >>= 1; + width = MAX(1, width >> 1); + height = MAX(1, height >> 1); + data += size; + } + } + + if (!(flags & IMGFLAG_MIPMAP)) + numMips = 1; + + for (miplevel = 0; miplevel < numMips; miplevel++) + { + int size = ((width + 3) / 4) * ((height + 3) / 4) * bytesPer4x4Block; if (subtexture) qglCompressedTexSubImage2DARB(GL_TEXTURE_2D, miplevel, x, y, width, height, internalFormat, size, data); @@ -1914,9 +1930,6 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei x >>= 1; y >>= 1; - x -= x % 4; - y -= y % 4; - width = MAX(1, width >> 1); height = MAX(1, height >> 1); data += size; @@ -1956,29 +1969,20 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei if (flags & IMGFLAG_MIPMAP) { - int miplevel; + int miplevel = 0; - miplevel = 0; while (width > 1 || height > 1) { if (data) { if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT) - { R_MipMapNormalHeight( data, data, width, height, glRefConfig.swizzleNormalmap ); - } else - { R_MipMapsRGB( data, width, height ); - } } - width >>= 1; - height >>= 1; - if (width < 1) - width = 1; - if (height < 1) - height = 1; + width = MAX(1, width >> 1); + height = MAX(1, height >> 1); miplevel++; if ( data && r_colorMipLevels->integer ) @@ -2029,7 +2033,7 @@ static void Upload32(byte *data, int x, int y, int width, int height, GLenum pic } else if (!subtexture) { - if (picFormat != GL_RGBA8) + if (picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT) { RawImage_UploadTexture(data, 0, 0, width, height, picFormat, numMips, internalFormat, type, flags, qfalse); goto done; -- cgit From fae2cb94e089fabe9a69d0909a5c25e1014cb25f Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Thu, 24 Dec 2015 16:34:58 -0800 Subject: OpenGL2: Add r_cubemapSize. --- src/renderergl2/tr_image.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/renderergl2/tr_image.c') diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index 74eddfe0..d01f42c4 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -2842,7 +2842,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); } } } -- cgit From 970b21fbcd3d42e641807ac0c5e9a29dc21095e9 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Mon, 18 Jan 2016 04:46:01 -0800 Subject: OpenGL2: Direct state access, part 1: Texture binds --- src/renderergl2/tr_image.c | 130 +++++++++++++++++---------------------------- 1 file changed, 49 insertions(+), 81 deletions(-) (limited to 'src/renderergl2/tr_image.c') diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index d01f42c4..aade799e 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]; @@ -115,9 +117,8 @@ void GL_TextureMode( const char *string ) { 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); + 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); } } } @@ -1818,7 +1819,7 @@ static void CompressMonoBlock(byte outdata[8], const byte indata[16]) } } -static void RawImage_UploadToRgtc2Texture(byte *data, int width, int height, int mip) +static void RawImage_UploadToRgtc2Texture(GLuint texture, byte *data, int width, int height, int mip) { int wBlocks, hBlocks, y, x, size; byte *compressedData, *p; @@ -1858,13 +1859,13 @@ static void RawImage_UploadToRgtc2Texture(byte *data, int width, int height, int } } - qglCompressedTexImage2DARB(GL_TEXTURE_2D, mip, GL_COMPRESSED_RG_RGTC2, width, height, 0, size, compressedData); + qglCompressedTextureImage2D(texture, GL_TEXTURE_2D, mip, GL_COMPRESSED_RG_RGTC2, width, height, 0, size, compressedData); ri.Hunk_FreeTempMemory(compressedData); } -static void RawImage_UploadTexture( byte *data, int x, int y, int width, int height, GLenum picFormat, int numMips, GLenum internalFormat, imgType_t type, imgFlags_t flags, qboolean subtexture ) +static void RawImage_UploadTexture(GLuint texture, byte *data, int x, int y, int width, int height, GLenum picFormat, int numMips, GLenum internalFormat, imgType_t type, imgFlags_t flags, qboolean subtexture ) { int dataFormat, dataType; qboolean rgtc = (internalFormat == GL_COMPRESSED_RG_RGTC2); @@ -1924,9 +1925,9 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei int size = ((width + 3) / 4) * ((height + 3) / 4) * bytesPer4x4Block; if (subtexture) - qglCompressedTexSubImage2DARB(GL_TEXTURE_2D, miplevel, x, y, width, height, internalFormat, size, data); + qglCompressedTextureSubImage2D(texture, GL_TEXTURE_2D, miplevel, x, y, width, height, internalFormat, size, data); else - qglCompressedTexImage2DARB(GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, size, data); + qglCompressedTextureImage2D(texture, GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, size, data); x >>= 1; y >>= 1; @@ -1958,13 +1959,13 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei } if ( subtexture ) - qglTexSubImage2D( GL_TEXTURE_2D, 0, x, y, width, height, dataFormat, dataType, data ); + qglTextureSubImage2D(texture, GL_TEXTURE_2D, 0, x, y, width, height, dataFormat, dataType, data ); else { if (rgtc) - RawImage_UploadToRgtc2Texture(data, width, height, 0); + RawImage_UploadToRgtc2Texture(texture, data, width, height, 0); else - qglTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, dataFormat, dataType, data); + qglTextureImage2D(texture, GL_TEXTURE_2D, 0, internalFormat, width, height, 0, dataFormat, dataType, data); } if (flags & IMGFLAG_MIPMAP) @@ -1992,14 +1993,14 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei { x >>= 1; y >>= 1; - qglTexSubImage2D( GL_TEXTURE_2D, miplevel, x, y, width, height, dataFormat, dataType, data ); + qglTextureSubImage2D(texture, GL_TEXTURE_2D, miplevel, x, y, width, height, dataFormat, dataType, data ); } else { if (rgtc) - RawImage_UploadToRgtc2Texture(data, width, height, miplevel); + RawImage_UploadToRgtc2Texture(texture, data, width, height, miplevel); else - qglTexImage2D(GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, dataFormat, dataType, data); + qglTextureImage2D(texture, GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, dataFormat, dataType, data); } } } @@ -2028,14 +2029,14 @@ static void Upload32(byte *data, int x, int y, int width, int height, GLenum pic if (!data) { RawImage_ScaleToPower2(NULL, &width, &height, type, flags, NULL); - RawImage_UploadTexture(NULL, 0, 0, width, height, GL_RGBA8, 0, internalFormat, type, flags, qfalse); + RawImage_UploadTexture(image->texnum, NULL, 0, 0, width, height, GL_RGBA8, 0, internalFormat, type, flags, qfalse); goto done; } else if (!subtexture) { if (picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT) { - RawImage_UploadTexture(data, 0, 0, width, height, picFormat, numMips, internalFormat, type, flags, qfalse); + RawImage_UploadTexture(image->texnum, data, 0, 0, width, height, picFormat, numMips, internalFormat, type, flags, qfalse); goto done; } notScaled = RawImage_ScaleToPower2(&data, &width, &height, type, flags, &resampledBuffer); @@ -2075,12 +2076,12 @@ static void Upload32(byte *data, int x, int y, int width, int height, GLenum pic if (subtexture) { // FIXME: Incorrect if original texture was not a power of 2 texture or picmipped - RawImage_UploadTexture(data, x, y, width, height, GL_RGBA8, 0, internalFormat, type, flags, qtrue); + RawImage_UploadTexture(image->texnum, data, x, y, width, height, GL_RGBA8, 0, internalFormat, type, flags, qtrue); GL_CheckErrors(); return; } - RawImage_UploadTexture(data, 0, 0, width, height, GL_RGBA8, 0, internalFormat, type, flags, qfalse); + RawImage_UploadTexture(image->texnum, data, 0, 0, width, height, GL_RGBA8, 0, internalFormat, type, flags, qfalse); done: @@ -2090,19 +2091,19 @@ done: 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 ) ); + qglTextureParameteri( image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, + (GLint)Com_Clamp( 1, 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, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); } else { if ( glConfig.textureFilterAnisotropic ) - qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1 ); + qglTextureParameteri(image->texnum, 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 ); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } // Fix for sampling depth buffer on old nVidia cards @@ -2113,9 +2114,9 @@ done: 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, GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); break; default: break; @@ -2178,46 +2179,32 @@ image_t *R_CreateImage2( const char *name, byte *pic, int width, int height, GLe 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 ); - } - - GL_Bind(image); - if (image->flags & IMGFLAG_CUBEMAP) { - 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); + qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglTextureParameteri(image->texnum, 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); + qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); } else { - qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTextureParameteri(image->texnum, 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); + qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); + qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); + qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); + qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); + qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); + qglTextureImage2D(image->texnum, 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); + qglGenerateTextureMipmap(image->texnum, GL_TEXTURE_CUBE_MAP); image->uploadWidth = width; image->uploadHeight = height; @@ -2226,12 +2213,10 @@ image_t *R_CreateImage2( const char *name, byte *pic, int width, int height, GLe { Upload32( pic, 0, 0, image->width, image->height, picFormat, numMips, image ); - 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; @@ -2255,15 +2240,7 @@ image_t *R_CreateImage(const char *name, byte *pic, int width, int height, imgTy void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int height ) { - if (qglActiveTextureARB) { - GL_SelectTexture(image->TMU); - } - - GL_Bind(image); - Upload32(pic, x, y, width, height, GL_RGBA8, 0, image); - - GL_SelectTexture(0); } //=================================================================== @@ -2830,11 +2807,10 @@ 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_MIN_FILTER, GL_LINEAR ); + qglTextureParameterf(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + 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); @@ -2947,15 +2923,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(); } /* -- cgit From 9f1aa0dfc09915681d66d16c6bce7768a280a08a Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Thu, 28 Jan 2016 16:39:42 -0800 Subject: OpenGL2: Load existing per-map cubemaps. --- src/renderergl2/tr_image.c | 317 +++++++++++++++++++++++---------------------- 1 file changed, 164 insertions(+), 153 deletions(-) (limited to 'src/renderergl2/tr_image.c') diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index aade799e..88335b7a 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -1864,82 +1864,57 @@ static void RawImage_UploadToRgtc2Texture(GLuint texture, byte *data, int width, ri.Hunk_FreeTempMemory(compressedData); } - -static void RawImage_UploadTexture(GLuint texture, byte *data, int x, int y, int width, int height, GLenum picFormat, int numMips, GLenum internalFormat, imgType_t type, imgFlags_t flags, qboolean subtexture ) +static int CalculateMipSize(int width, int height, GLenum picFormat) { - int dataFormat, dataType; - qboolean rgtc = (internalFormat == GL_COMPRESSED_RG_RGTC2); + int numBlocks = ((width + 3) / 4) * ((height + 3) / 4); + int numPixels = width * height; - if (data && picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT) + switch (picFormat) { - int bytesPer4x4Block = 0; - int miplevel = 0; - - 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: - bytesPer4x4Block = 8; - break; - 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: - bytesPer4x4Block = 16; - break; - default: - ri.Printf(PRINT_ALL, "Unsupported texture format %08x\n", picFormat); - return; - break; - } - - if (flags & IMGFLAG_PICMIP) - { - for (miplevel = r_picmip->integer; miplevel > 0 && numMips > 1; miplevel--, numMips--) - { - int size = ((width + 3) / 4) * ((height + 3) / 4) * bytesPer4x4Block; + 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; - x >>= 1; - y >>= 1; - width = MAX(1, width >> 1); - height = MAX(1, height >> 1); - data += size; - } - } - - if (!(flags & IMGFLAG_MIPMAP)) - numMips = 1; - - for (miplevel = 0; miplevel < numMips; miplevel++) - { - int size = ((width + 3) / 4) * ((height + 3) / 4) * bytesPer4x4Block; + default: + ri.Printf(PRINT_ALL, "Unsupported texture format %08x\n", picFormat); + return 0; + } - if (subtexture) - qglCompressedTextureSubImage2D(texture, GL_TEXTURE_2D, miplevel, x, y, width, height, internalFormat, size, data); - else - qglCompressedTextureImage2D(texture, GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, size, data); + return 0; +} - x >>= 1; - y >>= 1; - width = MAX(1, width >> 1); - height = MAX(1, height >> 1); - data += size; - } - return; - } +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) + switch (internalFormat) { case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT16_ARB: @@ -1958,52 +1933,83 @@ static void RawImage_UploadTexture(GLuint texture, byte *data, int x, int y, int break; } - if ( subtexture ) - qglTextureSubImage2D(texture, GL_TEXTURE_2D, 0, x, y, width, height, dataFormat, dataType, data ); - else + if (!data) { - if (rgtc) - RawImage_UploadToRgtc2Texture(texture, data, width, height, 0); - else - qglTextureImage2D(texture, GL_TEXTURE_2D, 0, internalFormat, width, height, 0, dataFormat, dataType, 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 = 0; - - while (width > 1 || height > 1) + for (miplevel = r_picmip->integer; miplevel > 0 && numMips > 1; miplevel--, numMips--) { - if (data) - { - if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT) - R_MipMapNormalHeight( data, data, width, height, glRefConfig.swizzleNormalmap ); - else - R_MipMapsRGB( data, width, height ); - } - + size = CalculateMipSize(width, height, picFormat); + x >>= 1; + y >>= 1; width = MAX(1, width >> 1); height = MAX(1, height >> 1); - miplevel++; + data += size; + } + } - if ( data && r_colorMipLevels->integer ) - R_BlendOverTexture( (byte *)data, width * height, mipBlendColors[miplevel] ); + miplevel = 0; + do + { + lastMip = (width == 1 && height == 1) || !mipmap; + size = CalculateMipSize(width, height, picFormat); - if ( subtexture ) - { - x >>= 1; - y >>= 1; - qglTextureSubImage2D(texture, GL_TEXTURE_2D, miplevel, x, y, width, height, dataFormat, dataType, data ); - } + if (compressed) + { + 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 (rgtc) - RawImage_UploadToRgtc2Texture(texture, data, width, height, miplevel); + if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT) + R_MipMapNormalHeight(data, data, width, height, glRefConfig.swizzleNormalmap); else - qglTextureImage2D(texture, GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, dataFormat, dataType, data); + R_MipMapsRGB(data, width, height); } } + + x >>= 1; + y >>= 1; + width = MAX(1, width >> 1); + height = MAX(1, height >> 1); + miplevel++; + + if (numMips > 1) + { + data += size; + numMips--; + } } + while (!lastMip); } @@ -2024,19 +2030,35 @@ static void Upload32(byte *data, int x, int y, int width, int height, GLenum pic GLenum internalFormat = image->internalFormat; qboolean subtexture = (x != 0) || (y != 0) || (width != image->width) || (height != image->height); qboolean notScaled = qtrue; - qboolean mipmap = !!(flags & IMGFLAG_MIPMAP); + 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); - RawImage_UploadTexture(image->texnum, NULL, 0, 0, width, height, GL_RGBA8, 0, internalFormat, type, flags, qfalse); + 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 (picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT) + if (compressed || cubemap) { - RawImage_UploadTexture(image->texnum, data, 0, 0, width, height, picFormat, numMips, internalFormat, type, flags, qfalse); + 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); @@ -2076,12 +2098,12 @@ static void Upload32(byte *data, int x, int y, int width, int height, GLenum pic if (subtexture) { // FIXME: Incorrect if original texture was not a power of 2 texture or picmipped - RawImage_UploadTexture(image->texnum, data, x, y, width, height, GL_RGBA8, 0, internalFormat, type, flags, qtrue); + RawImage_UploadTexture(image->texnum, data, x, y, width, height, uploadTarget, GL_RGBA8, 0, internalFormat, type, flags, qtrue); GL_CheckErrors(); return; } - RawImage_UploadTexture(image->texnum, data, 0, 0, width, height, GL_RGBA8, 0, internalFormat, type, flags, qfalse); + RawImage_UploadTexture(image->texnum, data, 0, 0, width, height, uploadTarget, GL_RGBA8, 0, internalFormat, type, flags, qfalse); done: @@ -2090,20 +2112,20 @@ done: if (mipmap) { - if ( glConfig.textureFilterAnisotropic ) - qglTextureParameteri( image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, - (GLint)Com_Clamp( 1, maxAnisotropy, r_ext_max_anisotropy->integer ) ); + if (glConfig.textureFilterAnisotropic && !cubemap) + qglTextureParameteri(image->texnum, textureTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, + (GLint)Com_Clamp(1, maxAnisotropy, r_ext_max_anisotropy->integer)); - qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); - qglTextureParameterf(image->texnum, 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 ) - qglTextureParameteri(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1); + if (glConfig.textureFilterAnisotropic && !cubemap) + qglTextureParameteri(image->texnum, textureTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1); - qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTextureParameterf(image->texnum, 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 @@ -2114,9 +2136,9 @@ done: case GL_DEPTH_COMPONENT16_ARB: case GL_DEPTH_COMPONENT24_ARB: case GL_DEPTH_COMPONENT32_ARB: - qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE); - qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - qglTextureParameterf(image->texnum, 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; @@ -2170,49 +2192,20 @@ image_t *R_CreateImage2( const char *name, byte *pic, int width, int height, GLe glWrapClampMode = GL_REPEAT; if (!internalFormat) - { - if (image->flags & IMGFLAG_CUBEMAP) - internalFormat = GL_RGBA8; - else - internalFormat = RawImage_GetFormat(pic, width * height, picFormat, isLightmap, image->type, image->flags); - } + internalFormat = RawImage_GetFormat(pic, width * height, picFormat, isLightmap, image->type, image->flags); image->internalFormat = internalFormat; + Upload32(pic, 0, 0, image->width, image->height, picFormat, numMips, image); + if (image->flags & IMGFLAG_CUBEMAP) { - qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - - qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - if (image->flags & IMGFLAG_MIPMAP) - { - qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - } - else - { - qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } - - qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - - if (image->flags & IMGFLAG_MIPMAP) - qglGenerateTextureMipmap(image->texnum, 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 { - Upload32( pic, 0, 0, image->width, image->height, picFormat, numMips, image ); - qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapClampMode); qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapClampMode); } @@ -2384,6 +2377,7 @@ image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags ) GLenum picFormat; int picNumMips; long hash; + imgFlags_t checkFlagsTrue, checkFlagsFalse; if (!name) { return NULL; @@ -2414,7 +2408,10 @@ image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags ) return NULL; } - if (r_normalMapping->integer && (picFormat == GL_RGBA8) && !(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; @@ -2517,6 +2514,20 @@ image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags ) } } + // 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; -- cgit From d5ba7bb70ef327c8856165475b58e946c8fbd8ce Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Mon, 1 Feb 2016 21:37:23 -0800 Subject: OpenGL2: Merge several cvars into r_pbr. r_glossIsRoughness, r_specularIsMetallic, r_framebufferGamma, r_tonemapGamma, r_materialGamma, r_lightGamma --- src/renderergl2/tr_image.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/renderergl2/tr_image.c') diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index 88335b7a..47843fe2 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -2859,6 +2859,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; -- cgit From 3043117bd95828ddc350a296f93489869474c4ea Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Wed, 17 Feb 2016 19:49:21 -0800 Subject: OpenGL2: Fix some GL errors and no sun shadows on older OpenGLs. --- src/renderergl2/tr_image.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/renderergl2/tr_image.c') diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index 47843fe2..d567193b 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -116,7 +116,7 @@ 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 ) { + 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); } @@ -2818,8 +2818,6 @@ 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); - qglTextureParameterf(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - qglTextureParameterf(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 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); } -- cgit From 5d1223366351d7ed9ee537d8f4245ab29b550d2c Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Mon, 7 Mar 2016 02:27:03 -0800 Subject: OpenGL2: Add r_shadowBlur. --- src/renderergl2/tr_image.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/renderergl2/tr_image.c') diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index d567193b..7e2d452e 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -2755,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); @@ -2802,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) -- cgit From 87abdd914988724e164ffb16380ad26be8420b84 Mon Sep 17 00:00:00 2001 From: Tim Angus Date: Thu, 7 Apr 2016 11:58:19 +0100 Subject: Make it compile --- src/renderergl2/tr_image.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/renderergl2/tr_image.c') diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index 7e2d452e..331e7f61 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -2114,7 +2114,7 @@ done: { if (glConfig.textureFilterAnisotropic && !cubemap) qglTextureParameteri(image->texnum, textureTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, - (GLint)Com_Clamp(1, maxAnisotropy, r_ext_max_anisotropy->integer)); + (GLint)Com_Clamp(1, glConfig.maxAnisotropy, r_ext_max_anisotropy->integer)); qglTextureParameterf(image->texnum, textureTarget, GL_TEXTURE_MIN_FILTER, gl_filter_min); qglTextureParameterf(image->texnum, textureTarget, GL_TEXTURE_MAG_FILTER, gl_filter_max); -- cgit