ソースを参照

Added PVRTC1 support.

bkaradzic 12 年 前
コミット
19ce130464
8 ファイル変更258 行追加49 行削除
  1. 8 6
      include/bgfx.h
  2. 2 0
      src/bgfx.cpp
  3. 194 33
      src/image.cpp
  4. 1 1
      src/image.h
  5. 4 4
      src/renderer_d3d11.cpp
  6. 4 2
      src/renderer_d3d9.cpp
  7. 29 3
      src/renderer_gl.cpp
  8. 16 0
      src/renderer_gl.h

+ 8 - 6
include/bgfx.h

@@ -302,12 +302,14 @@ namespace bgfx
 	{
 		enum Enum
 		{
-			BC1, // DXT1
-			BC2, // DXT3
-			BC3, // DXT5
-			BC4, // LATC1/ATI1
-			BC5, // LATC2/ATI2
-			ETC1,
+			BC1,   // DXT1
+			BC2,   // DXT3
+			BC3,   // DXT5
+			BC4,   // LATC1/ATI1
+			BC5,   // LATC2/ATI2
+			ETC1,  // ETC1_RGB8
+			PTC12, // PVRTC1_2BPP_RGBA
+			PTC14, // PVRTC1_4BPP_RGBA
 			Unknown,
 			L8,
 			BGRX8,

+ 2 - 0
src/bgfx.cpp

@@ -1001,6 +1001,8 @@ namespace bgfx
 		4,  // BC4
 		8,  // BC5
 		4,  // ETC1
+		2,  // PVRTC1_2BPP_RGBA
+		4,  // PVRTC1_2BPP_RGBA
 		0,  // Unknown
 		8,  // L8
 		32, // BGRX8

+ 194 - 33
src/image.cpp

@@ -9,6 +9,7 @@
 
 #include "image.h"
 
+// DDS
 #define DDS_MAGIC             BX_MAKEFOURCC('D', 'D', 'S', ' ')
 #define DDS_HEADER_SIZE       124
 #define DDS_IMAGE_DATA_OFFSET (DDS_HEADER_SIZE + 4)
@@ -61,6 +62,7 @@
 
 #define DDSCAPS2_VOLUME             0x00200000
 
+// KTX
 #define KTX_MAGIC       BX_MAKEFOURCC(0xAB, 'K', 'T', 'X')
 #define KTX_HEADER_SIZE 64
 
@@ -87,6 +89,28 @@
 #define KTX_RGBA16                                    0x805B
 #define KTX_RGBA16F                                   0x881A
 
+// PVR3
+#define PVR3_MAKE8CC(_a, _b, _c, _d, _e, _f, _g, _h) (uint64_t(BX_MAKEFOURCC(_a, _b, _c, _d) ) | (uint64_t(BX_MAKEFOURCC(_e, _f, _g, _h) )<<32) )
+
+#define PVR3_MAGIC            BX_MAKEFOURCC('P', 'V', 'R', 3)
+#define PVR3_HEADER_SIZE      52
+
+#define PVR3_PVRTC1_2BPP_RGB  0
+#define PVR3_PVRTC1_2BPP_RGBA 1
+#define PVR3_PVRTC1_4BPP_RGB  2
+#define PVR3_PVRTC1_4BPP_RGBA 3
+#define PVR3_ETC1             6
+#define PVR3_DXT1             7
+#define PVR3_DXT2             8
+#define PVR3_DXT3             9
+#define PVR3_DXT4             10
+#define PVR3_DXT5             11
+#define PVR3_BC4              12
+#define PVR3_BC5              13
+#define PVR3_RGBA16           PVR3_MAKE8CC('r', 'g', 'b', 'a', 16, 16, 16, 16)
+
+#define PVR3_CHANNEL_TYPE_FLOAT 12
+
 namespace bgfx
 {
 	void imageSolid(uint32_t _width, uint32_t _height, uint32_t _solid, void* _dst)
@@ -98,7 +122,7 @@ namespace bgfx
 		}
 	}
 
-	void imageChessboard(uint32_t _width, uint32_t _height, uint32_t _step, uint32_t _0, uint32_t _1, void* _dst)
+	void imageCheckerboard(uint32_t _width, uint32_t _height, uint32_t _step, uint32_t _0, uint32_t _1, void* _dst)
 	{
 		uint32_t* dst = (uint32_t*)_dst;
 		for (uint32_t yy = 0; yy < _height; ++yy)
@@ -738,6 +762,11 @@ namespace bgfx
 					}
 				}
 				break;
+
+			default:
+				// Decompression not implemented... Make ugly red-yellow checkerboard texture.
+				imageCheckerboard(m_width, m_height, 16, UINT32_C(0xffff0000), UINT32_C(0xffffff00), _dst);
+				break;
 			}
 		}
 		else
@@ -927,10 +956,6 @@ namespace bgfx
 				bpp = 8;
 				break;
 
-	// 			type = TextureFormat::A8;
-	// 			bpp = 1;
-	// 			break;
-
 			default:
 				bpp = 0;
 				break;
@@ -983,29 +1008,29 @@ namespace bgfx
 		uint32_t glBaseInternalFormat;
 		bx::readHE(_reader, glBaseInternalFormat, fromLittleEndian);
 
-		uint32_t pixelWidth;
-		bx::readHE(_reader, pixelWidth, fromLittleEndian);
+		uint32_t width;
+		bx::readHE(_reader, width, fromLittleEndian);
 
-		uint32_t pixelHeight;
-		bx::readHE(_reader, pixelHeight, fromLittleEndian);
+		uint32_t height;
+		bx::readHE(_reader, height, fromLittleEndian);
 
-		uint32_t pixelDepth;
-		bx::readHE(_reader, pixelDepth, fromLittleEndian);
+		uint32_t depth;
+		bx::readHE(_reader, depth, fromLittleEndian);
 
 		uint32_t numberOfArrayElements;
 		bx::readHE(_reader, numberOfArrayElements, fromLittleEndian);
 
-		uint32_t numberOfFaces;
-		bx::readHE(_reader, numberOfFaces, fromLittleEndian);
+		uint32_t numFaces;
+		bx::readHE(_reader, numFaces, fromLittleEndian);
 
-		uint32_t numberOfMipmapLevels;
-		bx::readHE(_reader, numberOfMipmapLevels, fromLittleEndian);
+		uint32_t numMips;
+		bx::readHE(_reader, numMips, fromLittleEndian);
 
-		uint32_t bytesOfKeyValueData;
-		bx::readHE(_reader, bytesOfKeyValueData, fromLittleEndian);
+		uint32_t metaDataSize;
+		bx::readHE(_reader, metaDataSize, fromLittleEndian);
 
 		// skip meta garbage...
-		int64_t offset = bx::skip(_reader, bytesOfKeyValueData);
+		int64_t offset = bx::skip(_reader, metaDataSize);
 
 		uint8_t bpp = 0;
 		uint8_t blockSize = 1;
@@ -1014,12 +1039,6 @@ namespace bgfx
 
 		switch (glInternalFormat)
 		{
-		case KTX_ETC1_RGB8_OES:
-			type = TextureFormat::ETC1;
-			bpp = 4;
-			blockSize = 4*4*bpp/8;
-			break;
-
 		case KTX_COMPRESSED_RGBA_S3TC_DXT1_EXT:
 			type = TextureFormat::BC1;
 			bpp = 4;
@@ -1050,6 +1069,26 @@ namespace bgfx
 			blockSize = 4*4*bpp/8;
 			break;
 
+		case KTX_ETC1_RGB8_OES:
+			type = TextureFormat::ETC1;
+			bpp = 4;
+			blockSize = 4*4*bpp/8;
+			break;
+
+		case KTX_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
+		case KTX_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
+			type = TextureFormat::PTC12;
+			bpp = 2;
+			blockSize = 4*4*bpp/8;
+			break;
+
+		case KTX_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
+		case KTX_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
+			type = TextureFormat::PTC14;
+			bpp = 2;
+			blockSize = 4*4*bpp/8;
+			break;
+
 		case KTX_RGBA16:
 			type = TextureFormat::RGBA16;
 			blockSize = 8;
@@ -1072,29 +1111,147 @@ namespace bgfx
 		case KTX_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
 		case KTX_COMPRESSED_RGBA8_ETC2_EAC:
 		case KTX_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
-		case KTX_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
-		case KTX_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
-		case KTX_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
-		case KTX_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
 		default:
 			break;
 		}
 
 		_imageContainer.m_type = type;
 		_imageContainer.m_offset = (uint32_t)offset;
-		_imageContainer.m_width = pixelWidth;
-		_imageContainer.m_height = pixelHeight;
-		_imageContainer.m_depth = pixelDepth;
+		_imageContainer.m_width = width;
+		_imageContainer.m_height = height;
+		_imageContainer.m_depth = depth;
 		_imageContainer.m_blockSize = blockSize;
-		_imageContainer.m_numMips = numberOfMipmapLevels;
+		_imageContainer.m_numMips = numMips;
 		_imageContainer.m_bpp = bpp;
 		_imageContainer.m_hasAlpha = hasAlpha;
-		_imageContainer.m_cubeMap = numberOfFaces > 1;
+		_imageContainer.m_cubeMap = numFaces > 1;
 		_imageContainer.m_ktx = true;
 
 		return TextureFormat::Unknown != type;
 	}
 
+	bool imageParsePvr3(ImageContainer& _imageContainer, bx::ReaderSeekerI* _reader)
+	{
+		uint32_t flags;
+		bx::read(_reader, flags);
+
+		uint64_t pixelFormat;
+		bx::read(_reader, pixelFormat);
+
+		uint32_t colorSpace;
+		bx::read(_reader, colorSpace); // 0 - linearRGB, 1 - sRGB
+
+		uint32_t channelType;
+		bx::read(_reader, channelType);
+
+		uint32_t height;
+		bx::read(_reader, height);
+
+		uint32_t width;
+		bx::read(_reader, width);
+
+		uint32_t depth;
+		bx::read(_reader, depth);
+
+		uint32_t numSurfaces;
+		bx::read(_reader, numSurfaces);
+
+		uint32_t numFaces;
+		bx::read(_reader, numFaces);
+
+		uint32_t numMips;
+		bx::read(_reader, numMips);
+
+		uint32_t metaDataSize;
+		bx::read(_reader, metaDataSize);
+
+		// skip meta garbage...
+		int64_t offset = bx::skip(_reader, metaDataSize);
+
+		uint8_t bpp = 0;
+		uint8_t blockSize = 1;
+		TextureFormat::Enum type = TextureFormat::Unknown;
+		bool hasAlpha = false;
+
+		switch (pixelFormat)
+		{
+		case PVR3_PVRTC1_2BPP_RGB:
+		case PVR3_PVRTC1_2BPP_RGBA:
+			type = TextureFormat::PTC12;
+			bpp = 2;
+			blockSize = 4*4*bpp/8;
+			break;
+
+		case PVR3_PVRTC1_4BPP_RGB:
+		case PVR3_PVRTC1_4BPP_RGBA:
+			type = TextureFormat::PTC14;
+			bpp = 2;
+			blockSize = 4*4*bpp/8;
+			break;
+
+		case PVR3_ETC1:
+			type = TextureFormat::ETC1;
+			bpp = 4;
+			blockSize = 4*4*bpp/8;
+			break;
+
+		case PVR3_DXT1:
+			type = TextureFormat::BC1;
+			bpp = 4;
+			blockSize = 4*4*bpp/8;
+			break;
+
+		case PVR3_DXT2:
+		case PVR3_DXT3:
+			type = TextureFormat::BC2;
+			bpp = 8;
+			blockSize = 4*4*bpp/8;
+			break;
+
+		case PVR3_DXT4:
+		case PVR3_DXT5:
+			type = TextureFormat::BC3;
+			bpp = 8;
+			blockSize = 4*4*bpp/8;
+			break;
+
+		case PVR3_BC4:
+			type = TextureFormat::BC4;
+			bpp = 4;
+			blockSize = 4*4*bpp/8;
+			break;
+
+		case PVR3_BC5:
+			type = TextureFormat::BC5;
+			bpp = 8;
+			blockSize = 4*4*bpp/8;
+			break;
+
+		case PVR3_RGBA16:
+			type = PVR3_CHANNEL_TYPE_FLOAT == channelType
+				 ? TextureFormat::RGBA16F
+				 : TextureFormat::RGBA16
+				 ;
+			blockSize = 8;
+			bpp = 64;
+			break;
+		}
+
+		_imageContainer.m_type = type;
+		_imageContainer.m_offset = (uint32_t)offset;
+		_imageContainer.m_width = width;
+		_imageContainer.m_height = height;
+		_imageContainer.m_depth = depth;
+		_imageContainer.m_blockSize = blockSize;
+		_imageContainer.m_numMips = numMips;
+		_imageContainer.m_bpp = bpp;
+		_imageContainer.m_hasAlpha = hasAlpha;
+		_imageContainer.m_cubeMap = numFaces > 1;
+		_imageContainer.m_ktx = false;
+
+		return TextureFormat::Unknown != type;
+	}
+
 	bool imageParse(ImageContainer& _imageContainer, bx::ReaderSeekerI* _reader)
 	{
 		uint32_t magic;
@@ -1108,6 +1265,10 @@ namespace bgfx
 		{
 			return imageParseKtx(_imageContainer, _reader);
 		}
+		else if (PVR3_MAGIC == magic)
+		{
+			return imageParsePvr3(_imageContainer, _reader);
+		}
 
 		return false;
 	}

+ 1 - 1
src/image.h

@@ -43,7 +43,7 @@ namespace bgfx
 	void imageSolid(uint32_t _width, uint32_t _height, uint32_t _solid, void* _dst);
 
 	///
-	void imageChessboard(uint32_t _width, uint32_t _height, uint32_t _step, uint32_t _0, uint32_t _1, void* _dst);
+	void imageCheckerboard(uint32_t _width, uint32_t _height, uint32_t _step, uint32_t _0, uint32_t _1, void* _dst);
 
 	///
 	void imageRgba8Downsample2x2(uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src, void* _dst);

+ 4 - 4
src/renderer_d3d11.cpp

@@ -188,7 +188,9 @@ namespace bgfx
 		{ DXGI_FORMAT_BC3_UNORM          },
 		{ DXGI_FORMAT_BC4_UNORM          },
 		{ DXGI_FORMAT_BC5_UNORM          },
-		{ DXGI_FORMAT_UNKNOWN            },
+		{ DXGI_FORMAT_UNKNOWN            }, // ETC1
+		{ DXGI_FORMAT_UNKNOWN            }, // PVRTC1_2BPP_RGBA
+		{ DXGI_FORMAT_UNKNOWN            }, // PVRTC1_4BPP_RGBA
 		{ DXGI_FORMAT_UNKNOWN            },
 		{ DXGI_FORMAT_R8_UNORM           },
 		{ DXGI_FORMAT_B8G8R8A8_UNORM     },
@@ -1634,9 +1636,7 @@ namespace bgfx
 
 		if (imageParse(imageContainer, _mem->data, _mem->size) )
 		{
-			bool decompress = false
-				|| (TextureFormat::ETC1 == imageContainer.m_type)
-				;
+			bool decompress = DXGI_FORMAT_UNKNOWN == s_textureFormat[imageContainer.m_type].m_fmt;
 
 			if (imageContainer.m_cubeMap)
 			{

+ 4 - 2
src/renderer_d3d9.cpp

@@ -193,7 +193,9 @@ namespace bgfx
 		{ D3DFMT_DXT5,           8 },
 		{ D3DFMT_ATI1,           4 },
 		{ D3DFMT_ATI2,           8 },
-		{ D3DFMT_UNKNOWN,        0 },
+		{ D3DFMT_UNKNOWN,        0 }, // ETC1
+		{ D3DFMT_UNKNOWN,        0 }, // PVRTC1_2BPP_RGBA
+		{ D3DFMT_UNKNOWN,        0 }, // PVRTC1_4BPP_RGBA
 		{ D3DFMT_UNKNOWN,        0 },
 		{ D3DFMT_L8,             8 },
 		{ D3DFMT_X8R8G8B8,      32 },
@@ -1515,7 +1517,7 @@ namespace bgfx
 			bool decompress = false
 				|| (TextureFormat::BC4  == imageContainer.m_type && !s_extendedFormats[ExtendedFormat::Ati1].m_supported)
 				|| (TextureFormat::BC5  == imageContainer.m_type && !s_extendedFormats[ExtendedFormat::Ati2].m_supported)
-				|| (TextureFormat::ETC1 == imageContainer.m_type)
+				|| (D3DFMT_UNKNOWN == tfi.m_fmt)
 				;
 
 			D3DFORMAT format = decompress ? D3DFMT_A8R8G8B8 : tfi.m_fmt;

+ 29 - 3
src/renderer_gl.cpp

@@ -200,6 +200,8 @@ namespace bgfx
 		{ GL_COMPRESSED_LUMINANCE_LATC1_EXT,       GL_COMPRESSED_LUMINANCE_LATC1_EXT,       GL_ZERO,                        false },
 		{ GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT, GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT, GL_ZERO,                        false },
 		{ GL_ETC1_RGB8_OES,                        GL_ETC1_RGB8_OES,                        GL_ZERO,                        false },
+		{ GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG,     GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG,     GL_ZERO,                        false },
+		{ GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG,     GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG,     GL_ZERO,                        false },
 		{ GL_ZERO,                                 GL_ZERO,                                 GL_ZERO,                        true  },
 		{ GL_LUMINANCE,                            GL_LUMINANCE,                            GL_UNSIGNED_BYTE,               true  },
 		{ GL_RGBA,                                 GL_RGBA,                                 GL_UNSIGNED_BYTE,               true  },
@@ -218,6 +220,7 @@ namespace bgfx
 		{
 			ANGLE_instanced_arrays,
 			ANGLE_translated_shader_source,
+			APPLE_texture_format_BGRA8888,
 			ARB_debug_output,
 			ARB_depth_clamp,
 			ARB_framebuffer_sRGB,
@@ -256,13 +259,16 @@ namespace bgfx
 			EXT_texture_type_2_10_10_10_REV,
 			EXT_timer_query,
 			IMG_multisampled_render_to_texture,
+			IMG_read_format,
 			IMG_shader_binary,
 			IMG_texture_compression_pvrtc,
+			IMG_texture_compression_pvrtc2,
 			IMG_texture_format_BGRA8888,
 			NVX_gpu_memory_info,
 			OES_compressed_ETC1_RGB8_texture,
 			OES_depth_texture,
 			OES_get_program_binary,
+			OES_read_format,
 			OES_rgb8_rgba8,
 			OES_standard_derivatives,
 			OES_texture_float,
@@ -285,6 +291,7 @@ namespace bgfx
 	{
 		{ "GL_ANGLE_instanced_arrays",             false,                             true  },
 		{ "GL_ANGLE_translated_shader_source",     false,                             true  },
+		{ "GL_APPLE_texture_format_BGRA8888",      false,                             true  },
 		{ "GL_ARB_debug_output",                   BGFX_CONFIG_RENDERER_OPENGL >= 43, true  },
 		{ "GL_ARB_depth_clamp",                    BGFX_CONFIG_RENDERER_OPENGL >= 31, true  },
 		{ "GL_ARB_framebuffer_sRGB",               false,                             true  },
@@ -323,13 +330,16 @@ namespace bgfx
 		{ "GL_EXT_texture_type_2_10_10_10_REV",    false,                             true  },
 		{ "GL_EXT_timer_query",                    false,                             true  },
 		{ "GL_IMG_multisampled_render_to_texture", false,                             true  },
+		{ "GL_IMG_read_format",                    false,                             true  },
 		{ "GL_IMG_shader_binary",                  false,                             true  },
 		{ "GL_IMG_texture_compression_pvrtc",      false,                             true  },
+		{ "GL_IMG_texture_compression_pvrtc2",     false,                             true  },
 		{ "GL_IMG_texture_format_BGRA8888",        false,                             true  },
 		{ "GL_NVX_gpu_memory_info",                false,                             true  },
 		{ "GL_OES_compressed_ETC1_RGB8_texture",   false,                             true  },
 		{ "GL_OES_depth_texture",                  false,                             true  },
-		{ "GL_OES_get_program_binary",             false,                             false },
+		{ "GL_OES_get_program_binary",             false,                             true  },
+		{ "GL_OES_read_format",                    false,                             true  },
 		{ "GL_OES_rgb8_rgba8",                     false,                             true  },
 		{ "GL_OES_standard_derivatives",           false,                             true  },
 		{ "GL_OES_texture_float",                  false,                             true  },
@@ -2475,8 +2485,14 @@ namespace bgfx
 			;
 		s_textureFormat[TextureFormat::BC4].m_supported = bc45Supported;
 		s_textureFormat[TextureFormat::BC5].m_supported = bc45Supported;
+
 		s_textureFormat[TextureFormat::ETC1].m_supported = s_extension[Extension::OES_compressed_ETC1_RGB8_texture].m_supported;
 
+		bool pvr1Supported = s_extension[Extension::IMG_texture_compression_pvrtc ].m_supported;
+//		bool pvr2Supported = s_extension[Extension::IMG_texture_compression_pvrtc2].m_supported;
+		s_textureFormat[TextureFormat::PTC12].m_supported = pvr1Supported;
+		s_textureFormat[TextureFormat::PTC14].m_supported = pvr1Supported;
+
 		s_renderCtx.m_vaoSupport = !!BGFX_CONFIG_RENDERER_OPENGLES3
 			|| s_extension[Extension::ARB_vertex_array_object].m_supported
 			|| s_extension[Extension::OES_vertex_array_object].m_supported
@@ -2509,10 +2525,20 @@ namespace bgfx
 		}
 #endif // BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
 
-		s_renderCtx.m_readPixelsFmt = GL_RGBA;
+		if (s_extension[Extension::IMG_read_format].m_supported
+		&&  s_extension[Extension::OES_read_format].m_supported)
+		{
+			s_renderCtx.m_readPixelsFmt = GL_BGRA_EXT;
+		}
+		else
+		{
+			s_renderCtx.m_readPixelsFmt = GL_RGBA;
+		}
 
 		if (s_extension[Extension::EXT_texture_format_BGRA8888].m_supported
-		||  s_extension[Extension::EXT_bgra].m_supported)
+		||  s_extension[Extension::EXT_bgra].m_supported
+		||  s_extension[Extension::IMG_texture_format_BGRA8888].m_supported
+		||  s_extension[Extension::APPLE_texture_format_BGRA8888].m_supported)
 		{
 #if BGFX_CONFIG_RENDERER_OPENGL
 			s_renderCtx.m_readPixelsFmt = GL_BGRA_EXT;

+ 16 - 0
src/renderer_gl.h

@@ -175,6 +175,22 @@ typedef void (*PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC)(GLuint shader, GLsizei b
 #		define GL_ETC1_RGB8_OES 0x8D64
 #	endif // GL_ETC1_RGB8_OES
 
+#	ifndef GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG
+#		define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01
+#	endif // GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG
+
+#	ifndef GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG
+#		define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03
+#	endif // GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG
+
+#	ifndef GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG
+#		define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00
+#	endif // GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG
+
+#	ifndef GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG
+#		define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02
+#	endif // GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG
+
 #	ifndef GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE
 #		define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0
 #	endif // GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE