[iortcw] 480/497: All: Rend2: Switch to RGTC from LATC for normal maps Also added a RGTC compressor as a workaround on Intel graphics

Simon McVittie smcv at debian.org
Fri Sep 8 10:38:00 UTC 2017


This is an automated email from the git hooks/post-receive script.

smcv pushed a commit to annotated tag 1.42d
in repository iortcw.

commit e72efe24be0f697d93fadf2a00c29ab596b3c405
Author: MAN-AT-ARMS <M4N4T4RMS at gmail.com>
Date:   Wed Dec 16 07:39:12 2015 -0500

    All: Rend2: Switch to RGTC from LATC for normal maps
    Also added a RGTC compressor as a workaround on Intel graphics
---
 MP/code/rend2/qgl.h           |  12 +-
 MP/code/rend2/tr_extensions.c |  26 ++++-
 MP/code/rend2/tr_glsl.c       |   2 +-
 MP/code/rend2/tr_image.c      | 247 +++++++++++++++++++++++++-----------------
 MP/code/rend2/tr_local.h      |   4 +-
 MP/rend2-readme.txt           |   4 +-
 SP/code/rend2/qgl.h           |  12 +-
 SP/code/rend2/tr_extensions.c |  26 ++++-
 SP/code/rend2/tr_glsl.c       |   2 +-
 SP/code/rend2/tr_image.c      | 247 +++++++++++++++++++++++++-----------------
 SP/code/rend2/tr_local.h      |   4 +-
 SP/rend2-readme.txt           |   4 +-
 12 files changed, 360 insertions(+), 230 deletions(-)

diff --git a/MP/code/rend2/qgl.h b/MP/code/rend2/qgl.h
index ed7eae1..1600de7 100644
--- a/MP/code/rend2/qgl.h
+++ b/MP/code/rend2/qgl.h
@@ -755,12 +755,12 @@ extern void (APIENTRY * qglRenderbufferStorageMultisampleEXT)(GLenum target, GLs
 #define GL_FRAMEBUFFER_SRGB_EXT                         0x8DB9
 #endif
 
-#ifndef GL_EXT_texture_compression_latc
-#define GL_EXT_texture_compression_latc
-#define GL_COMPRESSED_LUMINANCE_LATC1_EXT                 0x8C70
-#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT          0x8C71
-#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT           0x8C72
-#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT    0x8C73
+#ifndef GL_ARB_texture_compression_rgtc
+#define GL_ARB_texture_compression_rgtc
+#define GL_COMPRESSED_RED_RGTC1                       0x8DBB
+#define GL_COMPRESSED_SIGNED_RED_RGTC1                0x8DBC
+#define GL_COMPRESSED_RG_RGTC2                        0x8DBD
+#define GL_COMPRESSED_SIGNED_RG_RGTC2                 0x8DBE
 #endif
 
 #ifndef GL_ARB_texture_compression_bptc
diff --git a/MP/code/rend2/tr_extensions.c b/MP/code/rend2/tr_extensions.c
index c0f4d04..07e188c 100644
--- a/MP/code/rend2/tr_extensions.c
+++ b/MP/code/rend2/tr_extensions.c
@@ -585,6 +585,22 @@ void GLimp_InitExtraExtensions()
 		ri.Printf(PRINT_ALL, result[2], extension);
 	}
 
+	// GL_ARB_texture_compression
+	extension = "GL_ARB_texture_compression";
+	glRefConfig.arbTextureCompression = qfalse;
+	if (GLimp_HaveExtension(extension))
+	{
+		qglCompressedTexImage3DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexImage3DARB");
+		qglCompressedTexImage2DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexImage2DARB");
+		qglCompressedTexImage1DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexImage1DARB");
+		qglCompressedTexSubImage3DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexSubImage3DARB");
+		qglCompressedTexSubImage2DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexSubImage2DARB");
+		qglCompressedTexSubImage1DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexSubImage1DARB");
+		qglGetCompressedTexImageARB = (void *)SDL_GL_GetProcAddress("glGetCompressedTexImageARB");
+		glRefConfig.arbTextureCompression = qtrue;
+		ri.Printf(PRINT_ALL, result[glRefConfig.arbTextureCompression], extension);
+	}
+
 	// GL_EXT_framebuffer_multisample
 	extension = "GL_EXT_framebuffer_multisample";
 	glRefConfig.framebufferMultisample = qfalse;
@@ -601,12 +617,12 @@ void GLimp_InitExtraExtensions()
 
 	glRefConfig.textureCompression = TCR_NONE;
 
-	// GL_EXT_texture_compression_latc
-	extension = "GL_EXT_texture_compression_latc";
+	// GL_ARB_texture_compression_rgtc
+	extension = "GL_ARB_texture_compression_rgtc";
 	if (GLimp_HaveExtension(extension))
 	{
-		if (r_ext_compressed_textures->integer)
-			glRefConfig.textureCompression |= TCR_LATC;
+		if (r_ext_compressed_textures->integer && glRefConfig.arbTextureCompression)
+			glRefConfig.textureCompression |= TCR_RGTC;
 
 		ri.Printf(PRINT_ALL, result[r_ext_compressed_textures->integer ? 1 : 0], extension);
 	}
@@ -615,6 +631,8 @@ void GLimp_InitExtraExtensions()
 		ri.Printf(PRINT_ALL, result[2], extension);
 	}
 
+	glRefConfig.swizzleNormalmap = r_ext_compressed_textures->integer && !(glRefConfig.textureCompression & TCR_RGTC);
+
 	// GL_ARB_texture_compression_bptc
 	extension = "GL_ARB_texture_compression_bptc";
 	if (GLimp_HaveExtension(extension))
diff --git a/MP/code/rend2/tr_glsl.c b/MP/code/rend2/tr_glsl.c
index 9d87bad..ce83a62 100644
--- a/MP/code/rend2/tr_glsl.c
+++ b/MP/code/rend2/tr_glsl.c
@@ -1049,7 +1049,7 @@ void GLSL_InitGPUShaders(void)
 		if (r_dlightMode->integer >= 2)
 			Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n");
 
-		if (1)
+		if (glRefConfig.swizzleNormalmap)
 			Q_strcat(extradefines, 1024, "#define SWIZZLE_NORMALMAP\n");
 
 		if (r_hdr->integer && !glRefConfig.floatLightmap)
diff --git a/MP/code/rend2/tr_image.c b/MP/code/rend2/tr_image.c
index 1dacfff..6688a25 100644
--- a/MP/code/rend2/tr_image.c
+++ b/MP/code/rend2/tr_image.c
@@ -195,15 +195,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
@@ -1447,41 +1452,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;
@@ -1817,13 +1787,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;
 			}
@@ -1840,6 +1810,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)
 	{
@@ -1935,10 +1932,100 @@ 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)
 	{
@@ -1962,7 +2049,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)
 	{
@@ -1975,14 +2067,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
 				{
@@ -2009,7 +2094,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);
 			}
 		}
 	}
@@ -2076,25 +2164,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 ) ) {
@@ -2116,14 +2190,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
 			{
@@ -2359,26 +2426,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 );
@@ -2411,14 +2463,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
 			{
diff --git a/MP/code/rend2/tr_local.h b/MP/code/rend2/tr_local.h
index 9d61c06..1ba9fe8 100644
--- a/MP/code/rend2/tr_local.h
+++ b/MP/code/rend2/tr_local.h
@@ -1513,7 +1513,7 @@ typedef enum {
 
 typedef enum {
 	TCR_NONE = 0x0000,
-	TCR_LATC = 0x0001,
+	TCR_RGTC = 0x0001,
 	TCR_BPTC = 0x0002,
 } textureCompressionRef_t;
 
@@ -1537,7 +1537,9 @@ typedef struct {
 	qboolean textureFloat;
 	qboolean halfFloatPixel;
 	qboolean packedDepthStencil;
+	qboolean arbTextureCompression;
 	textureCompressionRef_t textureCompression;
+	qboolean swizzleNormalmap;
 	
 	qboolean framebufferMultisample;
 	qboolean framebufferBlit;
diff --git a/MP/rend2-readme.txt b/MP/rend2-readme.txt
index 79cb636..9504c42 100644
--- a/MP/rend2-readme.txt
+++ b/MP/rend2-readme.txt
@@ -18,7 +18,7 @@ compatibility with existing RTCW mods.
   - Texture upsampling.
   - Advanced materials support.
   - Advanced shading and specular methods.
-  - LATC and BPTC texture compression support.
+  - RGTC and BPTC texture compression support.
   - Screen-space ambient occlusion.
 
 
@@ -64,7 +64,7 @@ For Win32:
 Cvars for simple rendering features:
   r_ext_compressed_textures       - Automatically compress textures.
                                      0 - No texture compression. (default)
-                                     1 - DXT/LATC texture compression if
+                                     1 - DXT/RGTC texture compression if
                                          supported.
                                      2 - BPTC texture compression if supported.
 
diff --git a/SP/code/rend2/qgl.h b/SP/code/rend2/qgl.h
index 0a58f11..f3736c3 100644
--- a/SP/code/rend2/qgl.h
+++ b/SP/code/rend2/qgl.h
@@ -755,12 +755,12 @@ extern void (APIENTRY * qglRenderbufferStorageMultisampleEXT)(GLenum target, GLs
 #define GL_FRAMEBUFFER_SRGB_EXT                         0x8DB9
 #endif
 
-#ifndef GL_EXT_texture_compression_latc
-#define GL_EXT_texture_compression_latc
-#define GL_COMPRESSED_LUMINANCE_LATC1_EXT                 0x8C70
-#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT          0x8C71
-#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT           0x8C72
-#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT    0x8C73
+#ifndef GL_ARB_texture_compression_rgtc
+#define GL_ARB_texture_compression_rgtc
+#define GL_COMPRESSED_RED_RGTC1                       0x8DBB
+#define GL_COMPRESSED_SIGNED_RED_RGTC1                0x8DBC
+#define GL_COMPRESSED_RG_RGTC2                        0x8DBD
+#define GL_COMPRESSED_SIGNED_RG_RGTC2                 0x8DBE
 #endif
 
 #ifndef GL_ARB_texture_compression_bptc
diff --git a/SP/code/rend2/tr_extensions.c b/SP/code/rend2/tr_extensions.c
index c0f4d04..07e188c 100644
--- a/SP/code/rend2/tr_extensions.c
+++ b/SP/code/rend2/tr_extensions.c
@@ -585,6 +585,22 @@ void GLimp_InitExtraExtensions()
 		ri.Printf(PRINT_ALL, result[2], extension);
 	}
 
+	// GL_ARB_texture_compression
+	extension = "GL_ARB_texture_compression";
+	glRefConfig.arbTextureCompression = qfalse;
+	if (GLimp_HaveExtension(extension))
+	{
+		qglCompressedTexImage3DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexImage3DARB");
+		qglCompressedTexImage2DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexImage2DARB");
+		qglCompressedTexImage1DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexImage1DARB");
+		qglCompressedTexSubImage3DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexSubImage3DARB");
+		qglCompressedTexSubImage2DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexSubImage2DARB");
+		qglCompressedTexSubImage1DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexSubImage1DARB");
+		qglGetCompressedTexImageARB = (void *)SDL_GL_GetProcAddress("glGetCompressedTexImageARB");
+		glRefConfig.arbTextureCompression = qtrue;
+		ri.Printf(PRINT_ALL, result[glRefConfig.arbTextureCompression], extension);
+	}
+
 	// GL_EXT_framebuffer_multisample
 	extension = "GL_EXT_framebuffer_multisample";
 	glRefConfig.framebufferMultisample = qfalse;
@@ -601,12 +617,12 @@ void GLimp_InitExtraExtensions()
 
 	glRefConfig.textureCompression = TCR_NONE;
 
-	// GL_EXT_texture_compression_latc
-	extension = "GL_EXT_texture_compression_latc";
+	// GL_ARB_texture_compression_rgtc
+	extension = "GL_ARB_texture_compression_rgtc";
 	if (GLimp_HaveExtension(extension))
 	{
-		if (r_ext_compressed_textures->integer)
-			glRefConfig.textureCompression |= TCR_LATC;
+		if (r_ext_compressed_textures->integer && glRefConfig.arbTextureCompression)
+			glRefConfig.textureCompression |= TCR_RGTC;
 
 		ri.Printf(PRINT_ALL, result[r_ext_compressed_textures->integer ? 1 : 0], extension);
 	}
@@ -615,6 +631,8 @@ void GLimp_InitExtraExtensions()
 		ri.Printf(PRINT_ALL, result[2], extension);
 	}
 
+	glRefConfig.swizzleNormalmap = r_ext_compressed_textures->integer && !(glRefConfig.textureCompression & TCR_RGTC);
+
 	// GL_ARB_texture_compression_bptc
 	extension = "GL_ARB_texture_compression_bptc";
 	if (GLimp_HaveExtension(extension))
diff --git a/SP/code/rend2/tr_glsl.c b/SP/code/rend2/tr_glsl.c
index 9d87bad..ce83a62 100644
--- a/SP/code/rend2/tr_glsl.c
+++ b/SP/code/rend2/tr_glsl.c
@@ -1049,7 +1049,7 @@ void GLSL_InitGPUShaders(void)
 		if (r_dlightMode->integer >= 2)
 			Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n");
 
-		if (1)
+		if (glRefConfig.swizzleNormalmap)
 			Q_strcat(extradefines, 1024, "#define SWIZZLE_NORMALMAP\n");
 
 		if (r_hdr->integer && !glRefConfig.floatLightmap)
diff --git a/SP/code/rend2/tr_image.c b/SP/code/rend2/tr_image.c
index a17ac5f..087e9d1 100644
--- a/SP/code/rend2/tr_image.c
+++ b/SP/code/rend2/tr_image.c
@@ -195,15 +195,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
@@ -1442,41 +1447,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;
@@ -1811,13 +1781,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;
 			}
@@ -1834,6 +1804,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)
 	{
@@ -1929,10 +1926,100 @@ 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)
 	{
@@ -1956,7 +2043,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)
 	{
@@ -1969,14 +2061,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
 				{
@@ -2003,7 +2088,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);
 			}
 		}
 	}
@@ -2070,25 +2158,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 ) ) {
@@ -2110,14 +2184,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
 			{
@@ -2364,26 +2431,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 );
@@ -2416,14 +2468,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
 			{
diff --git a/SP/code/rend2/tr_local.h b/SP/code/rend2/tr_local.h
index 8ffa3f1..1dffcb7 100644
--- a/SP/code/rend2/tr_local.h
+++ b/SP/code/rend2/tr_local.h
@@ -1526,7 +1526,7 @@ typedef enum {
 
 typedef enum {
 	TCR_NONE = 0x0000,
-	TCR_LATC = 0x0001,
+	TCR_RGTC = 0x0001,
 	TCR_BPTC = 0x0002,
 } textureCompressionRef_t;
 
@@ -1550,7 +1550,9 @@ typedef struct {
 	qboolean textureFloat;
 	qboolean halfFloatPixel;
 	qboolean packedDepthStencil;
+	qboolean arbTextureCompression;
 	textureCompressionRef_t textureCompression;
+	qboolean swizzleNormalmap;
 	
 	qboolean framebufferMultisample;
 	qboolean framebufferBlit;
diff --git a/SP/rend2-readme.txt b/SP/rend2-readme.txt
index 9aa34bc..235d844 100644
--- a/SP/rend2-readme.txt
+++ b/SP/rend2-readme.txt
@@ -18,7 +18,7 @@ compatibility with existing RTCW mods.
   - Texture upsampling.
   - Advanced materials support.
   - Advanced shading and specular methods.
-  - LATC and BPTC texture compression support.
+  - RGTC and BPTC texture compression support.
   - Screen-space ambient occlusion.
 
 
@@ -64,7 +64,7 @@ For Win32:
 Cvars for simple rendering features:
   r_ext_compressed_textures       - Automatically compress textures.
                                      0 - No texture compression. (default)
-                                     1 - DXT/LATC texture compression if
+                                     1 - DXT/RGTC texture compression if
                                          supported.
                                      2 - BPTC texture compression if supported.
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/iortcw.git



More information about the Pkg-games-commits mailing list