Home | History | Annotate | Download | only in OGLES3
      1 /******************************************************************************
      2 
      3  @File         OGLES3/PVRTTextureAPI.cpp
      4 
      5  @Title        OGLES3/PVRTTextureAPI
      6 
      7  @Version
      8 
      9  @Copyright    Copyright (c) Imagination Technologies Limited.
     10 
     11  @Platform     ANSI compatible
     12 
     13  @Description  OGLES3 texture loading.
     14 
     15 ******************************************************************************/
     16 
     17 #include <string.h>
     18 #include <stdlib.h>
     19 
     20 #include "PVRTContext.h"
     21 #include "PVRTgles3Ext.h"
     22 #include "PVRTTexture.h"
     23 #include "PVRTTextureAPI.h"
     24 #include "PVRTDecompress.h"
     25 #include "PVRTFixedPoint.h"
     26 #include "PVRTMap.h"
     27 #include "PVRTMatrix.h"
     28 #include "PVRTMisc.h"
     29 #include "PVRTResourceFile.h"
     30 
     31 /*****************************************************************************
     32 ** Functions
     33 ****************************************************************************/
     34 
     35 /*!***********************************************************************
     36 	@Function:		PVRTGetOGLES3TextureFormat
     37 	@Input:			sTextureHeader
     38 	@Modified:		glInternalFormat
     39 	@Modified:		glFormat
     40 	@Modified:		glType
     41 	@Description:	Gets the OpenGLES equivalent values of internal format,
     42 					format and type for this texture header. This will return
     43 					any supported OpenGLES texture values, it is up to the user
     44 					to decide if these are valid for their current platform.
     45 *************************************************************************/
     46 static const void PVRTGetOGLES3TextureFormat(const PVRTextureHeaderV3& sTextureHeader, PVRTuint32& glInternalFormat, PVRTuint32& glFormat, PVRTuint32& glType)
     47 {
     48 	PVRTuint64 PixelFormat = sTextureHeader.u64PixelFormat;
     49 	EPVRTVariableType ChannelType = (EPVRTVariableType)sTextureHeader.u32ChannelType;
     50 	EPVRTColourSpace ColourSpace = (EPVRTColourSpace)sTextureHeader.u32ColourSpace;
     51 
     52 	//Initialisation. Any invalid formats will return 0 always.
     53 	glFormat = 0;
     54 	glType = 0;
     55 	glInternalFormat=0;
     56 
     57 	//Get the last 32 bits of the pixel format.
     58 	PVRTuint64 PixelFormatPartHigh = PixelFormat&PVRTEX_PFHIGHMASK;
     59 
     60 	//Check for a compressed format (The first 8 bytes will be 0, so the whole thing will be equal to the last 32 bits).
     61 	if (PixelFormatPartHigh==0)
     62 	{
     63 		//Format and type == 0 for compressed textures.
     64 		switch (PixelFormat)
     65 		{
     66 		case ePVRTPF_PVRTCI_2bpp_RGB:
     67 			{
     68 				if (ColourSpace == ePVRTCSpacesRGB)
     69 				{
     70 					//glInternalFormat=GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT;
     71 				}
     72 				else
     73 				{
     74 					glInternalFormat=GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
     75 				}
     76 				return;
     77 			}
     78 		case ePVRTPF_PVRTCI_2bpp_RGBA:
     79 			{
     80 				if (ColourSpace == ePVRTCSpacesRGB)
     81 				{
     82 					//glInternalFormat=GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT;
     83 				}
     84 				else
     85 				{
     86 					glInternalFormat=GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
     87 				}
     88 				return;
     89 			}
     90 		case ePVRTPF_PVRTCI_4bpp_RGB:
     91 			{
     92 				if (ColourSpace == ePVRTCSpacesRGB)
     93 				{
     94 					//glInternalFormat=GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT;
     95 				}
     96 				else
     97 				{
     98 					glInternalFormat=GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
     99 				}
    100 				return;
    101 			}
    102 		case ePVRTPF_PVRTCI_4bpp_RGBA:
    103 			{
    104 				if (ColourSpace == ePVRTCSpacesRGB)
    105 				{
    106 					//glInternalFormat=GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT;
    107 				}
    108 				else
    109 				{
    110 					glInternalFormat=GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
    111 				}
    112 				return;
    113 			}
    114 #ifndef TARGET_OS_IPHONE
    115 		case ePVRTPF_PVRTCII_2bpp:
    116 			{
    117 				if (ColourSpace == ePVRTCSpacesRGB)
    118 				{
    119 					//glInternalFormat=GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG;
    120 				}
    121 				else
    122 				{
    123 					glInternalFormat=GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG;
    124 				}
    125 				return;
    126 			}
    127 		case ePVRTPF_PVRTCII_4bpp:
    128 			{
    129 				if (ColourSpace == ePVRTCSpacesRGB)
    130 				{
    131 					//glInternalFormat=GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG;
    132 				}
    133 				else
    134 				{
    135 					glInternalFormat=GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG;
    136 				}
    137 				return;
    138 			}
    139 		case ePVRTPF_ETC1:
    140 			{
    141 				glInternalFormat=GL_ETC1_RGB8_OES;
    142 				return;
    143 			}
    144 #endif
    145 		case ePVRTPF_ETC2_RGB:
    146 			{
    147 				if (ColourSpace==ePVRTCSpacesRGB)
    148 					glInternalFormat=GL_COMPRESSED_SRGB8_ETC2;
    149 				else
    150 					glInternalFormat=GL_COMPRESSED_RGB8_ETC2;
    151 				return;
    152 			}
    153 		case ePVRTPF_ETC2_RGBA:
    154 			{
    155 				if (ColourSpace==ePVRTCSpacesRGB)
    156 					glInternalFormat=GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
    157 				else
    158 					glInternalFormat=GL_COMPRESSED_RGBA8_ETC2_EAC;
    159 				return;
    160 			}
    161 		case ePVRTPF_ETC2_RGB_A1:
    162 			{
    163 				if (ColourSpace==ePVRTCSpacesRGB)
    164 					glInternalFormat=GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2;
    165 				else
    166 					glInternalFormat=GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
    167 				return;
    168 			}
    169 		case ePVRTPF_EAC_R11:
    170 			{
    171 				if (ChannelType==ePVRTVarTypeSignedInteger || ChannelType==ePVRTVarTypeSignedIntegerNorm ||
    172 					ChannelType==ePVRTVarTypeSignedShort || ChannelType==ePVRTVarTypeSignedShortNorm ||
    173 					ChannelType==ePVRTVarTypeSignedByte || ChannelType==ePVRTVarTypeSignedByteNorm ||
    174 					ChannelType==ePVRTVarTypeSignedFloat)
    175 				{
    176 					glInternalFormat=GL_COMPRESSED_SIGNED_R11_EAC;
    177 				}
    178 				else
    179 				{
    180 					glInternalFormat=GL_COMPRESSED_R11_EAC;
    181 				}
    182 				return;
    183 			}
    184 		case ePVRTPF_EAC_RG11:
    185 			{
    186 				if (ChannelType==ePVRTVarTypeSignedInteger || ChannelType==ePVRTVarTypeSignedIntegerNorm ||
    187 					ChannelType==ePVRTVarTypeSignedShort || ChannelType==ePVRTVarTypeSignedShortNorm ||
    188 					ChannelType==ePVRTVarTypeSignedByte || ChannelType==ePVRTVarTypeSignedByteNorm ||
    189 					ChannelType==ePVRTVarTypeSignedFloat)
    190 				{
    191 					glInternalFormat=GL_COMPRESSED_SIGNED_RG11_EAC;
    192 				}
    193 				else
    194 				{
    195 					glInternalFormat=GL_COMPRESSED_RG11_EAC;
    196 				}
    197 				return;
    198 			}
    199 		}
    200 	}
    201 	else
    202 	{
    203 		switch (ChannelType)
    204 		{
    205 		case ePVRTVarTypeUnsignedFloat:
    206 			if (PixelFormat==PVRTGENPIXELID3('r','g','b',11,11,10) )
    207 			{
    208 				glType=GL_UNSIGNED_INT_10F_11F_11F_REV;
    209 				glFormat = GL_RGB;
    210 				glInternalFormat=GL_R11F_G11F_B10F;
    211 				return;
    212 			}
    213 			break;
    214 		case ePVRTVarTypeSignedFloat:
    215 			{
    216 				switch (PixelFormat)
    217 				{
    218 					//HALF_FLOAT
    219 				case PVRTGENPIXELID4('r','g','b','a',16,16,16,16):
    220 					{
    221 						glType=GL_HALF_FLOAT;
    222 						glFormat = GL_RGBA;
    223 						glInternalFormat=GL_RGBA;
    224 						return;
    225 					}
    226 				case PVRTGENPIXELID3('r','g','b',16,16,16):
    227 					{
    228 						glType=GL_HALF_FLOAT;
    229 						glFormat = GL_RGB;
    230 						glInternalFormat=GL_RGB16F;
    231 						return;
    232 					}
    233 				case PVRTGENPIXELID2('r','g',16,16):
    234 					{
    235 						glType=GL_HALF_FLOAT;
    236 						glFormat = GL_RG;
    237 						glInternalFormat=GL_RG16F;
    238 						return;
    239 					}
    240 				case PVRTGENPIXELID1('r',16):
    241 					{
    242 						glType=GL_HALF_FLOAT;
    243 						glFormat = GL_RED;
    244 						glInternalFormat=GL_R16F;
    245 						return;
    246 					}
    247 				case PVRTGENPIXELID2('l','a',16,16):
    248 					{
    249 						glType=GL_HALF_FLOAT;
    250 						glFormat = GL_LUMINANCE_ALPHA;
    251 						glInternalFormat=GL_LUMINANCE_ALPHA;
    252 						return;
    253 					}
    254 				case PVRTGENPIXELID1('l',16):
    255 					{
    256 						glType=GL_HALF_FLOAT;
    257 						glFormat = GL_LUMINANCE;
    258 						glInternalFormat=GL_LUMINANCE;
    259 						return;
    260 					}
    261 				case PVRTGENPIXELID1('a',16):
    262 					{
    263 						glType=GL_HALF_FLOAT;
    264 						glFormat = GL_ALPHA;
    265 						glInternalFormat=GL_ALPHA;
    266 						return;
    267 					}
    268 					//FLOAT
    269 				case PVRTGENPIXELID4('r','g','b','a',32,32,32,32):
    270 					{
    271 						glType=GL_FLOAT;
    272 						glFormat = GL_RGBA;
    273 						glInternalFormat=GL_RGBA32F;
    274 						return;
    275 					}
    276 				case PVRTGENPIXELID3('r','g','b',32,32,32):
    277 					{
    278 						glType=GL_FLOAT;
    279 						glFormat = GL_RGB;
    280 						glInternalFormat=GL_RGB32F;
    281 						return;
    282 					}
    283 				case PVRTGENPIXELID2('r','g',32,32):
    284 					{
    285 						glType=GL_FLOAT;
    286 						glFormat = GL_RG;
    287 						glInternalFormat=GL_RG32F;
    288 						return;
    289 					}
    290 				case PVRTGENPIXELID1('r',32):
    291 					{
    292 						glType=GL_FLOAT;
    293 						glFormat = GL_RED;
    294 						glInternalFormat=GL_R32F;
    295 						return;
    296 					}
    297 				case PVRTGENPIXELID2('l','a',32,32):
    298 					{
    299 						glType=GL_FLOAT;
    300 						glFormat = GL_LUMINANCE_ALPHA;
    301 						glInternalFormat=GL_LUMINANCE_ALPHA;
    302 						return;
    303 					}
    304 				case PVRTGENPIXELID1('l',32):
    305 					{
    306 						glType=GL_FLOAT;
    307 						glFormat = GL_LUMINANCE;
    308 						glInternalFormat=GL_LUMINANCE;
    309 						return;
    310 					}
    311 				case PVRTGENPIXELID1('a',32):
    312 					{
    313 						glType=GL_FLOAT;
    314 						glFormat = GL_ALPHA;
    315 						glInternalFormat=GL_ALPHA;
    316 						return;
    317 					}
    318 				}
    319 				break;
    320 			}
    321 		case ePVRTVarTypeUnsignedByteNorm:
    322 			{
    323 				glType = GL_UNSIGNED_BYTE;
    324 				switch (PixelFormat)
    325 				{
    326 				case PVRTGENPIXELID4('r','g','b','a',8,8,8,8):
    327 					{
    328 						glFormat = GL_RGBA;
    329 						if (ColourSpace==ePVRTCSpacesRGB)
    330 							glInternalFormat=GL_SRGB8_ALPHA8;
    331 						else
    332 							glInternalFormat=GL_RGBA8;
    333 						return;
    334 					}
    335 				case PVRTGENPIXELID3('r','g','b',8,8,8):
    336 					{
    337 						glFormat = GL_RGB;
    338 						if (ColourSpace==ePVRTCSpacesRGB)
    339 							glInternalFormat=GL_SRGB8;
    340 						else
    341 							glInternalFormat=GL_RGB8;
    342 						return;
    343 					}
    344 				case PVRTGENPIXELID2('r','g',8,8):
    345 					{
    346 						glFormat = GL_RG;
    347 						glInternalFormat=GL_RG8;
    348 						return;
    349 					}
    350 				case PVRTGENPIXELID1('r',8):
    351 					{
    352 						glFormat = GL_RED;
    353 						glInternalFormat=GL_R8;
    354 						return;
    355 					}
    356 				case PVRTGENPIXELID2('l','a',8,8):
    357 					{
    358 						glFormat = GL_LUMINANCE_ALPHA;
    359 						glInternalFormat=GL_LUMINANCE_ALPHA;
    360 						return;
    361 					}
    362 				case PVRTGENPIXELID1('l',8):
    363 					{
    364 						glFormat = GL_LUMINANCE;
    365 						glInternalFormat=GL_LUMINANCE;
    366 						return;
    367 					}
    368 				case PVRTGENPIXELID1('a',8):
    369 					{
    370 						glFormat = GL_ALPHA;
    371 						glInternalFormat=GL_ALPHA;
    372 						return;
    373 					}
    374 				case PVRTGENPIXELID4('b','g','r','a',8,8,8,8):
    375 					{
    376 						glFormat = GL_BGRA_EXT;
    377 						glInternalFormat=GL_BGRA_EXT;
    378 						return;
    379 					}
    380 				}
    381 				break;
    382 			}
    383 		case ePVRTVarTypeSignedByteNorm:
    384 			{
    385 				glType = GL_BYTE;
    386 				switch (PixelFormat)
    387 				{
    388 				case PVRTGENPIXELID4('r','g','b','a',8,8,8,8):
    389 					{
    390 						glFormat = GL_RGBA;
    391 						glInternalFormat=GL_RGBA8_SNORM;
    392 						return;
    393 					}
    394 				case PVRTGENPIXELID3('r','g','b',8,8,8):
    395 					{
    396 						glFormat = GL_RGB;
    397 						glInternalFormat=GL_RGB8_SNORM;
    398 						return;
    399 					}
    400 				case PVRTGENPIXELID2('r','g',8,8):
    401 					{
    402 						glFormat = GL_RG;
    403 						glInternalFormat=GL_RGB8_SNORM;
    404 						return;
    405 					}
    406 				case PVRTGENPIXELID1('r',8):
    407 					{
    408 						glFormat = GL_RED;
    409 						glInternalFormat=GL_R8_SNORM;
    410 						return;
    411 					}
    412 				}
    413 				break;
    414 			}
    415 		case ePVRTVarTypeUnsignedByte:
    416 			{
    417 				glType = GL_UNSIGNED_BYTE;
    418 				switch (PixelFormat)
    419 				{
    420 				case PVRTGENPIXELID4('r','g','b','a',8,8,8,8):
    421 					{
    422 						glFormat = GL_RGBA_INTEGER;
    423 						glInternalFormat=GL_RGBA8UI;
    424 						return;
    425 					}
    426 				case PVRTGENPIXELID3('r','g','b',8,8,8):
    427 					{
    428 						glFormat = GL_RGB_INTEGER;
    429 						glInternalFormat=GL_RGB8UI;
    430 						return;
    431 					}
    432 				case PVRTGENPIXELID2('r','g',8,8):
    433 					{
    434 						glFormat = GL_RG_INTEGER;
    435 						glInternalFormat=GL_RG8UI;
    436 						return;
    437 					}
    438 				case PVRTGENPIXELID1('r',8):
    439 					{
    440 						glFormat = GL_RED_INTEGER;
    441 						glInternalFormat=GL_R8UI;
    442 						return;
    443 					}
    444 				}
    445 				break;
    446 			}
    447 		case ePVRTVarTypeSignedByte:
    448 			{
    449 				glType = GL_BYTE;
    450 				switch (PixelFormat)
    451 				{
    452 				case PVRTGENPIXELID4('r','g','b','a',8,8,8,8):
    453 					{
    454 						glFormat = GL_RGBA_INTEGER;
    455 						glInternalFormat=GL_RGBA8I;
    456 						return;
    457 					}
    458 				case PVRTGENPIXELID3('r','g','b',8,8,8):
    459 					{
    460 						glFormat = GL_RGB_INTEGER;
    461 						glInternalFormat=GL_RGB8I;
    462 						return;
    463 					}
    464 				case PVRTGENPIXELID2('r','g',8,8):
    465 					{
    466 						glFormat = GL_RG_INTEGER;
    467 						glInternalFormat=GL_RG8I;
    468 						return;
    469 					}
    470 				case PVRTGENPIXELID1('r',8):
    471 					{
    472 						glFormat = GL_RED_INTEGER;
    473 						glInternalFormat=GL_R8I;
    474 						return;
    475 					}
    476 				}
    477 				break;
    478 			}
    479 		case ePVRTVarTypeUnsignedShortNorm:
    480 			{
    481 				switch (PixelFormat)
    482 				{
    483 				case PVRTGENPIXELID4('r','g','b','a',4,4,4,4):
    484 					{
    485 						glType = GL_UNSIGNED_SHORT_4_4_4_4;
    486 						glFormat = GL_RGBA;
    487 						glInternalFormat=GL_RGBA4;
    488 						return;
    489 					}
    490 				case PVRTGENPIXELID4('r','g','b','a',5,5,5,1):
    491 					{
    492 						glType = GL_UNSIGNED_SHORT_5_5_5_1;
    493 						glFormat = GL_RGBA;
    494 						glInternalFormat=GL_RGB5_A1;
    495 						return;
    496 					}
    497 				case PVRTGENPIXELID3('r','g','b',5,6,5):
    498 					{
    499 						glType = GL_UNSIGNED_SHORT_5_6_5;
    500 						glFormat = GL_RGB;
    501 						glInternalFormat=GL_RGB565;
    502 						return;
    503 					}
    504 				}
    505 				break;
    506 			}
    507 		case ePVRTVarTypeUnsignedShort:
    508 			{
    509 				glType = GL_UNSIGNED_SHORT;
    510 				switch (PixelFormat)
    511 				{
    512 				case PVRTGENPIXELID4('r','g','b','a',16,16,16,16):
    513 					{
    514 						glFormat = GL_RGBA_INTEGER;
    515 						glInternalFormat=GL_RGBA16UI;
    516 						return;
    517 					}
    518 				case PVRTGENPIXELID3('r','g','b',16,16,16):
    519 					{
    520 						glFormat = GL_RGB_INTEGER;
    521 						glInternalFormat=GL_RGB16UI;
    522 						return;
    523 					}
    524 				case PVRTGENPIXELID2('r','g',16,16):
    525 					{
    526 						glFormat = GL_RG_INTEGER;
    527 						glInternalFormat=GL_RG16UI;
    528 						return;
    529 					}
    530 				case PVRTGENPIXELID1('r',16):
    531 					{
    532 						glFormat = GL_RED_INTEGER;
    533 						glInternalFormat=GL_R16UI;
    534 						return;
    535 					}
    536 				}
    537 				break;
    538 			}
    539 		case ePVRTVarTypeSignedShort:
    540 			{
    541 				glType = GL_SHORT;
    542 				switch (PixelFormat)
    543 				{
    544 				case PVRTGENPIXELID4('r','g','b','a',16,16,16,16):
    545 					{
    546 						glFormat = GL_RGBA_INTEGER;
    547 						glInternalFormat=GL_RGBA16I;
    548 						return;
    549 					}
    550 				case PVRTGENPIXELID3('r','g','b',16,16,16):
    551 					{
    552 						glFormat = GL_RGB_INTEGER;
    553 						glInternalFormat=GL_RGB16I;
    554 						return;
    555 					}
    556 				case PVRTGENPIXELID2('r','g',16,16):
    557 					{
    558 						glFormat = GL_RG_INTEGER;
    559 						glInternalFormat=GL_RG16I;
    560 						return;
    561 					}
    562 				case PVRTGENPIXELID1('r',16):
    563 					{
    564 						glFormat = GL_RED_INTEGER;
    565 						glInternalFormat=GL_R16I;
    566 						return;
    567 					}
    568 				}
    569 				break;
    570 			}
    571 		case ePVRTVarTypeUnsignedIntegerNorm:
    572 			{
    573 				if (PixelFormat==PVRTGENPIXELID4('a','b','g','r',2,10,10,10))
    574 				{
    575 					glType = GL_UNSIGNED_INT_2_10_10_10_REV;
    576 					glFormat = GL_RGBA;
    577 					glInternalFormat=GL_RGB10_A2;
    578 					return;
    579 				}
    580 				break;
    581 			}
    582 		case ePVRTVarTypeUnsignedInteger:
    583 			{
    584 				glType = GL_UNSIGNED_INT;
    585 				switch (PixelFormat)
    586 				{
    587 				case PVRTGENPIXELID4('r','g','b','a',32,32,32,32):
    588 					{
    589 						glFormat = GL_RGBA_INTEGER;
    590 						glInternalFormat=GL_RGBA32UI;
    591 						return;
    592 					}
    593 				case PVRTGENPIXELID3('r','g','b',32,32,32):
    594 					{
    595 						glFormat = GL_RGB_INTEGER;
    596 						glInternalFormat=GL_RGB32UI;
    597 						return;
    598 					}
    599 				case PVRTGENPIXELID2('r','g',32,32):
    600 					{
    601 						glFormat = GL_RG_INTEGER;
    602 						glInternalFormat=GL_RG32UI;
    603 						return;
    604 					}
    605 				case PVRTGENPIXELID1('r',32):
    606 					{
    607 						glFormat = GL_RED_INTEGER;
    608 						glInternalFormat=GL_R32UI;
    609 						return;
    610 					}
    611 				case PVRTGENPIXELID4('a','b','g','r',2,10,10,10):
    612 					{
    613 						glType = GL_UNSIGNED_INT_2_10_10_10_REV;
    614 						glFormat = GL_RGBA_INTEGER;
    615 						glInternalFormat=GL_RGB10_A2UI;
    616 						return;
    617 					}
    618 				}
    619 				break;
    620 			}
    621 		case ePVRTVarTypeSignedInteger:
    622 			{
    623 				glType = GL_INT;
    624 				switch (PixelFormat)
    625 				{
    626 				case PVRTGENPIXELID4('r','g','b','a',32,32,32,32):
    627 					{
    628 						glFormat = GL_RGBA_INTEGER;
    629 						glInternalFormat=GL_RGBA32I;
    630 						return;
    631 					}
    632 				case PVRTGENPIXELID3('r','g','b',32,32,32):
    633 					{
    634 						glFormat = GL_RGB_INTEGER;
    635 						glInternalFormat=GL_RGB32I;
    636 						return;
    637 					}
    638 				case PVRTGENPIXELID2('r','g',32,32):
    639 					{
    640 						glFormat = GL_RG_INTEGER;
    641 						glInternalFormat=GL_RG32I;
    642 						return;
    643 					}
    644 				case PVRTGENPIXELID1('r',32):
    645 					{
    646 						glFormat = GL_RED_INTEGER;
    647 						glInternalFormat=GL_R32I;
    648 						return;
    649 					}
    650 				}
    651 				break;
    652 			}
    653 		default: { }
    654 		}
    655 	}
    656 
    657 	//Default (erroneous) return values.
    658 	glType = glFormat = glInternalFormat = 0;
    659 }
    660 
    661 
    662 /*!***************************************************************************
    663 @Function		PVRTTextureTile
    664 @Modified		pOut		The tiled texture in system memory
    665 @Input			pIn			The source texture
    666 @Input			nRepeatCnt	Number of times to repeat the source texture
    667 @Description	Allocates and fills, in system memory, a texture large enough
    668 				to repeat the source texture specified number of times.
    669 *****************************************************************************/
    670 void PVRTTextureTile(
    671 	PVRTextureHeaderV3			**pOut,
    672 	const PVRTextureHeaderV3	* const pIn,
    673 	const int					nRepeatCnt)
    674 {
    675 	unsigned int		nFormat = 0, nType = 0, nBPP, nSize, nElW = 0, nElH = 0, nElD = 0;
    676 	PVRTuint8		*pMmSrc, *pMmDst;
    677 	unsigned int		nLevel;
    678 	PVRTextureHeaderV3	*psTexHeaderNew;
    679 
    680 	_ASSERT(pIn->u32Width);
    681 	_ASSERT(pIn->u32Width == pIn->u32Height);
    682 	_ASSERT(nRepeatCnt > 1);
    683 
    684 	PVRTGetOGLES3TextureFormat(*pIn,nFormat,nFormat,nType);
    685 	PVRTGetFormatMinDims(pIn->u64PixelFormat,nElW,nElH,nElD);
    686 
    687 	nBPP = PVRTGetBitsPerPixel(pIn->u64PixelFormat);
    688 	nSize = pIn->u32Width * nRepeatCnt;
    689 
    690 	psTexHeaderNew	= PVRTTextureCreate(nSize, nSize, nElW, nElH, nBPP, true);
    691 	*psTexHeaderNew	= *pIn;
    692 	pMmDst	= (PVRTuint8*)psTexHeaderNew + sizeof(*psTexHeaderNew);
    693 	pMmSrc	= (PVRTuint8*)pIn + sizeof(*pIn);
    694 
    695 	for(nLevel = 0; ((unsigned int)1 << nLevel) < nSize; ++nLevel)
    696 	{
    697 		int nBlocksDstW = PVRT_MAX((unsigned int)1, (nSize >> nLevel) / nElW);
    698 		int nBlocksDstH = PVRT_MAX((unsigned int)1, (nSize >> nLevel) / nElH);
    699 		int nBlocksSrcW = PVRT_MAX((unsigned int)1, (pIn->u32Width >> nLevel) / nElW);
    700 		int nBlocksSrcH = PVRT_MAX((unsigned int)1, (pIn->u32Height >> nLevel) / nElH);
    701 		int nBlocksS	= nBPP * nElW * nElH / 8;
    702 
    703 		PVRTTextureLoadTiled(
    704 			pMmDst,
    705 			nBlocksDstW,
    706 			nBlocksDstH,
    707 			pMmSrc,
    708 			nBlocksSrcW,
    709 			nBlocksSrcH,
    710 			nBlocksS,
    711 			(pIn->u64PixelFormat>=ePVRTPF_PVRTCI_2bpp_RGB && pIn->u64PixelFormat<=ePVRTPF_PVRTCI_4bpp_RGBA) ? true : false);
    712 
    713 		pMmDst += nBlocksDstW * nBlocksDstH * nBlocksS;
    714 		pMmSrc += nBlocksSrcW * nBlocksSrcH * nBlocksS;
    715 	}
    716 
    717 	psTexHeaderNew->u32Width = nSize;
    718 	psTexHeaderNew->u32Height = nSize;
    719 	psTexHeaderNew->u32MIPMapCount = nLevel+1;
    720 	*pOut = psTexHeaderNew;
    721 }
    722 
    723 /*!***************************************************************************
    724  @Function		PVRTTextureLoadFromPointer
    725  @Input			pointer				Pointer to header-texture's structure
    726  @Modified		texName				the OpenGL ES texture name as returned by glBindTexture
    727  @Modified		psTextureHeader		Pointer to a PVRTextureHeaderV3 struct. Modified to
    728 									contain the header data of the returned texture Ignored if NULL.
    729  @Input			bAllowDecompress	Allow decompression if PVRTC is not supported in hardware.
    730  @Input			nLoadFromLevel		Which mip map level to start loading from (0=all)
    731  @Input			texPtr				If null, texture follows header, else texture is here.
    732  @Modified		pMetaData			If a valid map is supplied, this will return any and all
    733 									MetaDataBlocks stored in the texture, organised by DevFourCC
    734 									then identifier. Supplying NULL will ignore all MetaData.
    735  @Return		PVR_SUCCESS on success
    736  @Description	Allows textures to be stored in C header files and loaded in. Can load parts of a
    737 				mip mapped texture (i.e. skipping the highest detailed levels). In OpenGL Cube Map, each
    738 				texture's up direction is defined as next (view direction, up direction),
    739 				(+x,-y)(-x,-y)(+y,+z)(-y,-z)(+z,-y)(-z,-y).
    740 				Sets the texture MIN/MAG filter to GL_LINEAR_MIPMAP_NEAREST/GL_LINEAR
    741 				if mip maps are present, GL_LINEAR/GL_LINEAR otherwise.
    742 *****************************************************************************/
    743 EPVRTError PVRTTextureLoadFromPointer(	const void* pointer,
    744 										GLuint *const texName,
    745 										const void *psTextureHeader,
    746 										bool bAllowDecompress,
    747 										const unsigned int nLoadFromLevel,
    748 										const void * const texPtr,
    749 										CPVRTMap<unsigned int, CPVRTMap<unsigned int, MetaDataBlock> > *pMetaData)
    750 {
    751 	//Compression bools
    752 	bool bIsCompressedFormatSupported=false;
    753 	bool bIsCompressedFormat=false;
    754 	bool bIsLegacyPVR=false;
    755 	bool bUsesTexImage3D=false;
    756 
    757 	//Texture setup
    758 	PVRTextureHeaderV3 sTextureHeader;
    759 	PVRTuint8* pTextureData=NULL;
    760 
    761 	//Just in case header and pointer for decompression.
    762 	PVRTextureHeaderV3 sTextureHeaderDecomp;
    763 	void* pDecompressedData=NULL;
    764 
    765 	//Check if it's an old header format
    766 	if((*(PVRTuint32*)pointer)!=PVRTEX3_IDENT)
    767 	{
    768 		//Convert the texture header to the new format.
    769 		PVRTConvertOldTextureHeaderToV3((PVR_Texture_Header*)pointer,sTextureHeader,pMetaData);
    770 
    771 		//Get the texture data.
    772 		pTextureData = texPtr? (PVRTuint8*)texPtr:(PVRTuint8*)pointer+*(PVRTuint32*)pointer;
    773 
    774 		bIsLegacyPVR=true;
    775 	}
    776 	else
    777 	{
    778 		//Get the header from the main pointer.
    779 		sTextureHeader=*(PVRTextureHeaderV3*)pointer;
    780 
    781 		//Get the texture data.
    782 		pTextureData = texPtr? (PVRTuint8*)texPtr:(PVRTuint8*)pointer+PVRTEX3_HEADERSIZE+sTextureHeader.u32MetaDataSize;
    783 
    784 		if (pMetaData)
    785 		{
    786 			//Read in all the meta data.
    787 			PVRTuint32 metaDataSize=0;
    788 			while (metaDataSize<sTextureHeader.u32MetaDataSize)
    789 			{
    790 				//Read the DevFourCC and advance the pointer offset.
    791 				PVRTuint32 DevFourCC=*(PVRTuint32*)((PVRTuint8*)pointer+PVRTEX3_HEADERSIZE+metaDataSize);
    792 				metaDataSize+=sizeof(DevFourCC);
    793 
    794 				//Read the Key and advance the pointer offset.
    795 				PVRTuint32 u32Key=*(PVRTuint32*)((PVRTuint8*)pointer+PVRTEX3_HEADERSIZE+metaDataSize);
    796 				metaDataSize+=sizeof(u32Key);
    797 
    798 				//Read the DataSize and advance the pointer offset.
    799 				PVRTuint32 u32DataSize = *(PVRTuint32*)((PVRTuint8*)pointer+PVRTEX3_HEADERSIZE+metaDataSize);
    800 				metaDataSize+=sizeof(u32DataSize);
    801 
    802 				//Get the current meta data.
    803 				MetaDataBlock& currentMetaData = (*pMetaData)[DevFourCC][u32Key];
    804 
    805 				//Assign the values to the meta data.
    806 				currentMetaData.DevFOURCC=DevFourCC;
    807 				currentMetaData.u32Key=u32Key;
    808 				currentMetaData.u32DataSize=u32DataSize;
    809 
    810 				//Check for data, if there is any, read it into the meta data.
    811 				if(u32DataSize > 0)
    812 				{
    813 					//Allocate memory.
    814 					currentMetaData.Data = new PVRTuint8[u32DataSize];
    815 
    816 					//Copy the data.
    817 					memcpy(currentMetaData.Data, ((PVRTuint8*)pointer+PVRTEX3_HEADERSIZE+metaDataSize), u32DataSize);
    818 
    819 					//Advance the meta data size.
    820 					metaDataSize+=u32DataSize;
    821 				}
    822 			}
    823 		}
    824 	}
    825 
    826 	//Return the PVRTextureHeader.
    827 	if (psTextureHeader)
    828 	{
    829 		*(PVRTextureHeaderV3*)psTextureHeader=sTextureHeader;
    830 	}
    831 
    832 	//Setup GL Texture format values.
    833 	GLenum eTextureFormat = 0;
    834 	GLenum eTextureInternalFormat = 0;	// often this is the same as textureFormat, but not for BGRA8888 on iOS, for instance
    835 	GLenum eTextureType = 0;
    836 
    837 	//Get the OGLES format values.
    838 	PVRTGetOGLES3TextureFormat(sTextureHeader,eTextureInternalFormat,eTextureFormat,eTextureType);
    839 
    840 	bool bIsPVRTCSupported = CPVRTgles3Ext::IsGLExtensionSupported("GL_IMG_texture_compression_pvrtc");
    841 #ifndef TARGET_OS_IPHONE
    842 	bool bIsBGRA8888Supported  = CPVRTgles3Ext::IsGLExtensionSupported("GL_IMG_texture_format_BGRA8888");
    843 #else
    844 	bool bIsBGRA8888Supported  = CPVRTgles3Ext::IsGLExtensionSupported("GL_APPLE_texture_format_BGRA8888");
    845 #endif
    846 #ifndef TARGET_OS_IPHONE
    847 	bool bIsETCSupported = CPVRTgles3Ext::IsGLExtensionSupported("GL_OES_compressed_ETC1_RGB8_texture");
    848 #endif
    849 
    850 	//Check for compressed formats
    851 	if (eTextureFormat==0 && eTextureType==0 && eTextureInternalFormat!=0)
    852 	{
    853 		if (eTextureInternalFormat>=GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG && eTextureInternalFormat<=GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG)
    854 		{
    855 			//Check for PVRTCI support.
    856 			if(bIsPVRTCSupported)
    857 			{
    858 				bIsCompressedFormatSupported = bIsCompressedFormat = true;
    859 			}
    860 			else
    861 			{
    862 				//Try to decompress the texture.
    863 				if(bAllowDecompress)
    864 				{
    865 					//Output a warning.
    866 					PVRTErrorOutputDebug("PVRTTextureLoadFromPointer warning: PVRTC not supported. Converting to RGBA8888 instead.\n");
    867 
    868 					//Modify boolean values.
    869 					bIsCompressedFormatSupported = false;
    870 					bIsCompressedFormat = true;
    871 
    872 					//Check if it's 2bpp.
    873 					bool bIs2bppPVRTC = (eTextureInternalFormat==GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG || eTextureInternalFormat==GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG);
    874 
    875 					//Change texture format.
    876 					eTextureFormat = eTextureInternalFormat = GL_RGBA;
    877 					eTextureType = GL_UNSIGNED_BYTE;
    878 
    879 					//Create a near-identical texture header for the decompressed header.
    880 					sTextureHeaderDecomp = sTextureHeader;
    881 					sTextureHeaderDecomp.u32ChannelType=ePVRTVarTypeUnsignedByteNorm;
    882 					sTextureHeaderDecomp.u32ColourSpace=ePVRTCSpacelRGB;
    883 					sTextureHeaderDecomp.u64PixelFormat=PVRTGENPIXELID4('r','g','b','a',8,8,8,8);
    884 
    885 					//Allocate enough memory for the decompressed data. OGLES2, so only decompress one surface/face.
    886 					pDecompressedData = malloc(PVRTGetTextureDataSize(sTextureHeaderDecomp, PVRTEX_ALLMIPLEVELS, false, true) );
    887 
    888 					//Check the malloc.
    889 					if (!pDecompressedData)
    890 					{
    891 						PVRTErrorOutputDebug("PVRTTextureLoadFromPointer error: Unable to allocate memory to decompress texture.\n");
    892 						return PVR_FAIL;
    893 					}
    894 
    895 					//Get the dimensions for the current MIP level.
    896 					PVRTuint32 uiMIPWidth = sTextureHeaderDecomp.u32Width>>nLoadFromLevel;
    897 					PVRTuint32 uiMIPHeight = sTextureHeaderDecomp.u32Height>>nLoadFromLevel;
    898 
    899 					//Setup temporary variables.
    900 					PVRTuint8* pTempDecompData = (PVRTuint8*)pDecompressedData;
    901 					PVRTuint8* pTempCompData = (PVRTuint8*)pTextureData;
    902 
    903 					if (bIsLegacyPVR)
    904 					{
    905 						//Decompress all the MIP levels.
    906 						for (PVRTuint32 uiFace=0;uiFace<sTextureHeader.u32NumFaces;++uiFace)
    907 						{
    908 
    909 							for (PVRTuint32 uiMIPMap=nLoadFromLevel;uiMIPMap<sTextureHeader.u32MIPMapCount;++uiMIPMap)
    910 							{
    911 								//Get the face offset. Varies per MIP level.
    912 								PVRTuint32 decompressedFaceOffset = PVRTGetTextureDataSize(sTextureHeaderDecomp, uiMIPMap, false, false);
    913 								PVRTuint32 compressedFaceOffset = PVRTGetTextureDataSize(sTextureHeader, uiMIPMap, false, false);
    914 
    915 								//Decompress the texture data.
    916 								PVRTDecompressPVRTC(pTempCompData,bIs2bppPVRTC?1:0,uiMIPWidth,uiMIPHeight,pTempDecompData);
    917 
    918 								//Move forward through the pointers.
    919 								pTempDecompData+=decompressedFaceOffset;
    920 								pTempCompData+=compressedFaceOffset;
    921 
    922 								//Work out the current MIP dimensions.
    923 								uiMIPWidth=PVRT_MAX(1,uiMIPWidth>>1);
    924 								uiMIPHeight=PVRT_MAX(1,uiMIPHeight>>1);
    925 							}
    926 
    927 							//Reset the dims.
    928 							uiMIPWidth=sTextureHeader.u32Width;
    929 							uiMIPHeight=sTextureHeader.u32Height;
    930 						}
    931 					}
    932 					else
    933 					{
    934 						//Decompress all the MIP levels.
    935 						for (PVRTuint32 uiMIPMap=nLoadFromLevel;uiMIPMap<sTextureHeader.u32MIPMapCount;++uiMIPMap)
    936 						{
    937 							//Get the face offset. Varies per MIP level.
    938 							PVRTuint32 decompressedFaceOffset = PVRTGetTextureDataSize(sTextureHeaderDecomp, uiMIPMap, false, false);
    939 							PVRTuint32 compressedFaceOffset = PVRTGetTextureDataSize(sTextureHeader, uiMIPMap, false, false);
    940 
    941 							for (PVRTuint32 uiFace=0;uiFace<sTextureHeader.u32NumFaces;++uiFace)
    942 							{
    943 								//Decompress the texture data.
    944 								PVRTDecompressPVRTC(pTempCompData,bIs2bppPVRTC?1:0,uiMIPWidth,uiMIPHeight,pTempDecompData);
    945 
    946 								//Move forward through the pointers.
    947 								pTempDecompData+=decompressedFaceOffset;
    948 								pTempCompData+=compressedFaceOffset;
    949 							}
    950 
    951 							//Work out the current MIP dimensions.
    952 							uiMIPWidth=PVRT_MAX(1,uiMIPWidth>>1);
    953 							uiMIPHeight=PVRT_MAX(1,uiMIPHeight>>1);
    954 						}
    955 					}
    956 				}
    957 				else
    958 				{
    959 					PVRTErrorOutputDebug("PVRTTextureLoadFromPointer error: PVRTC not supported.\n");
    960 					return PVR_FAIL;
    961 				}
    962 			}
    963 		}
    964 #ifndef TARGET_OS_IPHONE //TODO
    965 		else if (eTextureInternalFormat==GL_ETC1_RGB8_OES)
    966 		{
    967 			if(bIsETCSupported)
    968 			{
    969 				bIsCompressedFormatSupported = bIsCompressedFormat = true;
    970 			}
    971 			else
    972 			{
    973 				if(bAllowDecompress)
    974 				{
    975 					//Output a warning.
    976 					PVRTErrorOutputDebug("PVRTTextureLoadFromPointer warning: ETC not supported. Converting to RGBA8888 instead.\n");
    977 
    978 					//Modify boolean values.
    979 					bIsCompressedFormatSupported = false;
    980 					bIsCompressedFormat = true;
    981 
    982 					//Change texture format.
    983 					eTextureFormat = eTextureInternalFormat = GL_RGBA;
    984 					eTextureType = GL_UNSIGNED_BYTE;
    985 
    986 					//Create a near-identical texture header for the decompressed header.
    987 					sTextureHeaderDecomp = sTextureHeader;
    988 					sTextureHeaderDecomp.u32ChannelType=ePVRTVarTypeUnsignedByteNorm;
    989 					sTextureHeaderDecomp.u32ColourSpace=ePVRTCSpacelRGB;
    990 					sTextureHeaderDecomp.u64PixelFormat=PVRTGENPIXELID4('r','g','b','a',8,8,8,8);
    991 
    992 					//Allocate enough memory for the decompressed data. OGLES1, so only decompress one surface/face.
    993 					pDecompressedData = malloc(PVRTGetTextureDataSize(sTextureHeaderDecomp, PVRTEX_ALLMIPLEVELS, false, true) );
    994 
    995 					//Check the malloc.
    996 					if (!pDecompressedData)
    997 					{
    998 						PVRTErrorOutputDebug("PVRTTextureLoadFromPointer error: Unable to allocate memory to decompress texture.\n");
    999 						return PVR_FAIL;
   1000 					}
   1001 
   1002 					//Get the dimensions for the current MIP level.
   1003 					PVRTuint32 uiMIPWidth = sTextureHeaderDecomp.u32Width>>nLoadFromLevel;
   1004 					PVRTuint32 uiMIPHeight = sTextureHeaderDecomp.u32Height>>nLoadFromLevel;
   1005 
   1006 					//Setup temporary variables.
   1007 					PVRTuint8* pTempDecompData = (PVRTuint8*)pDecompressedData;
   1008 					PVRTuint8* pTempCompData = (PVRTuint8*)pTextureData;
   1009 
   1010 					if (bIsLegacyPVR)
   1011 					{
   1012 						//Decompress all the MIP levels.
   1013 						for (PVRTuint32 uiFace=0;uiFace<sTextureHeader.u32NumFaces;++uiFace)
   1014 						{
   1015 
   1016 							for (PVRTuint32 uiMIPMap=nLoadFromLevel;uiMIPMap<sTextureHeader.u32MIPMapCount;++uiMIPMap)
   1017 							{
   1018 								//Get the face offset. Varies per MIP level.
   1019 								PVRTuint32 decompressedFaceOffset = PVRTGetTextureDataSize(sTextureHeaderDecomp, uiMIPMap, false, false);
   1020 								PVRTuint32 compressedFaceOffset = PVRTGetTextureDataSize(sTextureHeader, uiMIPMap, false, false);
   1021 
   1022 								//Decompress the texture data.
   1023 								PVRTDecompressETC(pTempCompData,uiMIPWidth,uiMIPHeight,pTempDecompData,0);
   1024 
   1025 								//Move forward through the pointers.
   1026 								pTempDecompData+=decompressedFaceOffset;
   1027 								pTempCompData+=compressedFaceOffset;
   1028 
   1029 								//Work out the current MIP dimensions.
   1030 								uiMIPWidth=PVRT_MAX(1,uiMIPWidth>>1);
   1031 								uiMIPHeight=PVRT_MAX(1,uiMIPHeight>>1);
   1032 							}
   1033 
   1034 							//Reset the dims.
   1035 							uiMIPWidth=sTextureHeader.u32Width;
   1036 							uiMIPHeight=sTextureHeader.u32Height;
   1037 						}
   1038 					}
   1039 					else
   1040 					{
   1041 						//Decompress all the MIP levels.
   1042 						for (PVRTuint32 uiMIPMap=nLoadFromLevel;uiMIPMap<sTextureHeader.u32MIPMapCount;++uiMIPMap)
   1043 						{
   1044 							//Get the face offset. Varies per MIP level.
   1045 							PVRTuint32 decompressedFaceOffset = PVRTGetTextureDataSize(sTextureHeaderDecomp, uiMIPMap, false, false);
   1046 							PVRTuint32 compressedFaceOffset = PVRTGetTextureDataSize(sTextureHeader, uiMIPMap, false, false);
   1047 
   1048 							for (PVRTuint32 uiFace=0;uiFace<sTextureHeader.u32NumFaces;++uiFace)
   1049 							{
   1050 								//Decompress the texture data.
   1051 								PVRTDecompressETC(pTempCompData,uiMIPWidth,uiMIPHeight,pTempDecompData,0);
   1052 
   1053 								//Move forward through the pointers.
   1054 								pTempDecompData+=decompressedFaceOffset;
   1055 								pTempCompData+=compressedFaceOffset;
   1056 							}
   1057 
   1058 							//Work out the current MIP dimensions.
   1059 							uiMIPWidth=PVRT_MAX(1,uiMIPWidth>>1);
   1060 							uiMIPHeight=PVRT_MAX(1,uiMIPHeight>>1);
   1061 						}
   1062 					}
   1063 				}
   1064 				else
   1065 				{
   1066 					PVRTErrorOutputDebug("PVRTTextureLoadFromPointer error: ETC not supported.\n");
   1067 					return PVR_FAIL;
   1068 				}
   1069 			}
   1070 		}
   1071 #endif
   1072 	}
   1073 
   1074 	//Check for BGRA support.
   1075 	if(eTextureFormat==GL_BGRA_IMG)
   1076 	{
   1077 #ifdef TARGET_OS_IPHONE
   1078 		eTextureInternalFormat = GL_RGBA;
   1079 #endif
   1080 		if(!bIsBGRA8888Supported)
   1081 		{
   1082 #ifdef TARGET_OS_IPHONE
   1083 			PVRTErrorOutputDebug("PVRTTextureLoadFromPointer failed: Unable to load GL_BGRA_IMG texture as extension GL_APPLE_texture_format_BGRA8888 is unsupported.\n");
   1084 #else
   1085 			PVRTErrorOutputDebug("PVRTTextureLoadFromPointer failed: Unable to load GL_BGRA_IMG texture as extension GL_IMG_texture_format_BGRA8888 is unsupported.\n");
   1086 #endif
   1087 			return PVR_FAIL;
   1088 		}
   1089 	}
   1090 
   1091 	//Deal with unsupported texture formats
   1092 	if (eTextureInternalFormat==0)
   1093 	{
   1094 		PVRTErrorOutputDebug("PVRTTextureLoadFromPointer failed: pixel type not supported.\n");
   1095 		return PVR_FAIL;
   1096 	}
   1097 
   1098 	//PVR files are never row aligned.
   1099 	glPixelStorei(GL_UNPACK_ALIGNMENT,1);
   1100 
   1101 	//Generate a texture
   1102 	glGenTextures(1, texName);
   1103 
   1104 	//Initialise a texture target.
   1105 	GLint eTarget=GL_TEXTURE_2D;
   1106 
   1107 	//A mix of arrays/cubes/depths are not permitted in OpenGL ES. Check.
   1108 	if (sTextureHeader.u32NumFaces>1 || sTextureHeader.u32NumSurfaces>1 || sTextureHeader.u32Depth>1)
   1109 	{
   1110 		if((sTextureHeader.u32NumFaces>1) && (sTextureHeader.u32NumSurfaces>1))
   1111 		{
   1112 			PVRTErrorOutputDebug("PVRTTextureLoadFromPointer failed: Arrays of cubemaps are not supported by OpenGL ES 3.0\n");
   1113 			return PVR_FAIL;
   1114 		}
   1115 		else if ((sTextureHeader.u32NumFaces>1) && (sTextureHeader.u32Depth>1))
   1116 		{
   1117 			PVRTErrorOutputDebug("PVRTTextureLoadFromPointer failed: 3D Cubemap textures are not supported by OpenGL ES 3.0\n");
   1118 			return PVR_FAIL;
   1119 		}
   1120 		else if ((sTextureHeader.u32NumSurfaces>1) && (sTextureHeader.u32Depth>1))
   1121 		{
   1122 			PVRTErrorOutputDebug("PVRTTextureLoadFromPointer failed: Arrays of 3D textures are not supported by OpenGL ES 3.0\n");
   1123 			return PVR_FAIL;
   1124 		}
   1125 
   1126 		if(sTextureHeader.u32NumSurfaces>1)
   1127 		{
   1128 			eTarget=GL_TEXTURE_2D_ARRAY;
   1129 			bUsesTexImage3D=true;
   1130 		}
   1131 		else if(sTextureHeader.u32NumFaces>1)
   1132 		{
   1133 			eTarget=GL_TEXTURE_CUBE_MAP;
   1134 		}
   1135 		else if (sTextureHeader.u32Depth>1)
   1136 		{
   1137 			eTarget=GL_TEXTURE_3D;
   1138 			bUsesTexImage3D=true;
   1139 		}
   1140 	}
   1141 
   1142 	//Bind the texture
   1143 	glBindTexture(eTarget, *texName);
   1144 
   1145 	if(glGetError())
   1146 	{
   1147 		PVRTErrorOutputDebug("PVRTTextureLoadFromPointer failed: glBindTexture() failed.\n");
   1148 		return PVR_FAIL;
   1149 	}
   1150 
   1151 	//Temporary data to save on if statements within the load loops.
   1152 	PVRTuint8* pTempData=NULL;
   1153 	PVRTextureHeaderV3 *psTempHeader=NULL;
   1154 	if (bIsCompressedFormat && !bIsCompressedFormatSupported)
   1155 	{
   1156 		pTempData=(PVRTuint8*)pDecompressedData;
   1157 		psTempHeader=&sTextureHeaderDecomp;
   1158 	}
   1159 	else
   1160 	{
   1161 		pTempData=pTextureData;
   1162 		psTempHeader=&sTextureHeader;
   1163 	}
   1164 
   1165 	//Initialise the current MIP size.
   1166 	PVRTuint32 uiCurrentMIPSize=0;
   1167 
   1168 	//Initialise the width/height
   1169 	PVRTuint32 u32MIPWidth = sTextureHeader.u32Width;
   1170 	PVRTuint32 u32MIPHeight = sTextureHeader.u32Height;
   1171 	PVRTuint32 u32MIPDepth;
   1172 	if (psTempHeader->u32Depth>1)
   1173 	{
   1174 		u32MIPDepth=psTempHeader->u32Depth; //3d texture.
   1175 	}
   1176 	else
   1177 	{
   1178 		u32MIPDepth=psTempHeader->u32NumSurfaces; //2d arrays.
   1179 	}
   1180 
   1181 	//Loop through all MIP levels.
   1182 	if (bIsLegacyPVR)
   1183 	{
   1184 		//Temporary texture target.
   1185 		GLint eTextureTarget=eTarget;
   1186 
   1187 		//Cubemaps are special.
   1188 		if (eTextureTarget==GL_TEXTURE_CUBE_MAP)
   1189 		{
   1190 			eTextureTarget=GL_TEXTURE_CUBE_MAP_POSITIVE_X;
   1191 		}
   1192 
   1193 		//Loop through all the faces.
   1194 		for (PVRTuint32 uiFace=0; uiFace<psTempHeader->u32NumFaces; ++uiFace)
   1195 		{
   1196 			//Loop through all the mip levels.
   1197 			for (PVRTuint32 uiMIPLevel=0; uiMIPLevel<psTempHeader->u32MIPMapCount; ++uiMIPLevel)
   1198 			{
   1199 				//Get the current MIP size.
   1200 				uiCurrentMIPSize=PVRTGetTextureDataSize(*psTempHeader,uiMIPLevel,false,false);
   1201 
   1202 				if (uiMIPLevel>=nLoadFromLevel)
   1203 				{
   1204 					//Upload the texture
   1205 					if (bUsesTexImage3D)
   1206 					{
   1207 						if (bIsCompressedFormat && bIsCompressedFormatSupported)
   1208 						{
   1209 							glCompressedTexImage3D(eTextureTarget,uiMIPLevel-nLoadFromLevel,eTextureInternalFormat,u32MIPWidth, u32MIPHeight, u32MIPDepth, 0, uiCurrentMIPSize, pTempData);
   1210 						}
   1211 						else
   1212 						{
   1213 							glTexImage3D(eTextureTarget,uiMIPLevel-nLoadFromLevel,eTextureInternalFormat, u32MIPWidth, u32MIPHeight, u32MIPDepth,  0, eTextureFormat, eTextureType, pTempData);
   1214 						}
   1215 					}
   1216 					else
   1217 					{
   1218 						if (bIsCompressedFormat && bIsCompressedFormatSupported)
   1219 						{
   1220 							glCompressedTexImage2D(eTextureTarget,uiMIPLevel-nLoadFromLevel,eTextureInternalFormat,u32MIPWidth, u32MIPHeight, 0, uiCurrentMIPSize, pTempData);
   1221 						}
   1222 						else
   1223 						{
   1224 							glTexImage2D(eTextureTarget,uiMIPLevel-nLoadFromLevel,eTextureInternalFormat, u32MIPWidth, u32MIPHeight, 0, eTextureFormat, eTextureType, pTempData);
   1225 						}
   1226 					}
   1227 				}
   1228 				pTempData+=uiCurrentMIPSize;
   1229 
   1230 				//Reduce the MIP Size.
   1231 				u32MIPWidth=PVRT_MAX(1,u32MIPWidth>>1);
   1232 				u32MIPHeight=PVRT_MAX(1,u32MIPHeight>>1);
   1233 				if (psTempHeader->u32Depth>1)
   1234 				{
   1235 					u32MIPDepth=PVRT_MAX(1,u32MIPDepth>>1);
   1236 				}
   1237 			}
   1238 
   1239 			//Increase the texture target.
   1240 			eTextureTarget++;
   1241 
   1242 			//Reset the current MIP dimensions.
   1243 			u32MIPWidth=psTempHeader->u32Width;
   1244 			u32MIPHeight=psTempHeader->u32Height;
   1245 
   1246 			if (psTempHeader->u32Depth>1)
   1247 			{
   1248 				u32MIPDepth=psTempHeader->u32Depth;
   1249 			}
   1250 			else
   1251 			{
   1252 				u32MIPDepth=psTempHeader->u32NumSurfaces; //2d arrays.
   1253 			}
   1254 
   1255 			//Error check
   1256 			if(glGetError())
   1257 			{
   1258 				FREE(pDecompressedData);
   1259 				PVRTErrorOutputDebug("PVRTTextureLoadFromPointer failed: glTexImage2D() failed.\n");
   1260 				return PVR_FAIL;
   1261 			}
   1262 		}
   1263 	}
   1264 	else
   1265 	{
   1266 		for (PVRTuint32 uiMIPLevel=0; uiMIPLevel<psTempHeader->u32MIPMapCount; ++uiMIPLevel)
   1267 		{
   1268 			//Get the current MIP size.
   1269 			uiCurrentMIPSize=PVRTGetTextureDataSize(*psTempHeader,uiMIPLevel,false,false);
   1270 
   1271 			GLint eTextureTarget=eTarget;
   1272 			//Cubemaps are special.
   1273 			if (eTextureTarget==GL_TEXTURE_CUBE_MAP)
   1274 			{
   1275 				eTextureTarget=GL_TEXTURE_CUBE_MAP_POSITIVE_X;
   1276 			}
   1277 
   1278 			for (PVRTuint32 uiFace=0; uiFace<psTempHeader->u32NumFaces; ++uiFace)
   1279 			{
   1280 				if (uiMIPLevel>=nLoadFromLevel)
   1281 				{
   1282 					//Upload the texture
   1283 					if (bUsesTexImage3D)
   1284 					{
   1285 						//Upload the texture
   1286 						if (bIsCompressedFormat && bIsCompressedFormatSupported)
   1287 						{
   1288 							glCompressedTexImage3D(eTextureTarget,uiMIPLevel-nLoadFromLevel,eTextureInternalFormat,u32MIPWidth, u32MIPHeight, u32MIPDepth, 0, uiCurrentMIPSize, pTempData);
   1289 						}
   1290 						else
   1291 						{
   1292 							glTexImage3D(eTextureTarget,uiMIPLevel-nLoadFromLevel,eTextureInternalFormat, u32MIPWidth, u32MIPHeight, u32MIPDepth, 0, eTextureFormat, eTextureType, pTempData);
   1293 						}
   1294 					}
   1295 					else
   1296 					{
   1297 						//Upload the texture
   1298 						if (bIsCompressedFormat && bIsCompressedFormatSupported)
   1299 						{
   1300 							glCompressedTexImage2D(eTextureTarget,uiMIPLevel-nLoadFromLevel,eTextureInternalFormat,u32MIPWidth, u32MIPHeight, 0, uiCurrentMIPSize, pTempData);
   1301 						}
   1302 						else
   1303 						{
   1304 							glTexImage2D(eTextureTarget,uiMIPLevel-nLoadFromLevel,eTextureInternalFormat, u32MIPWidth, u32MIPHeight, 0, eTextureFormat, eTextureType, pTempData);
   1305 						}
   1306 					}
   1307 				}
   1308 				pTempData+=uiCurrentMIPSize;
   1309 				eTextureTarget++;
   1310 			}
   1311 
   1312 			//Reduce the MIP Size.
   1313 			u32MIPWidth=PVRT_MAX(1,u32MIPWidth>>1);
   1314 			u32MIPHeight=PVRT_MAX(1,u32MIPHeight>>1);
   1315 			if (psTempHeader->u32Depth>1)
   1316 			{
   1317 				u32MIPDepth=PVRT_MAX(1,u32MIPDepth>>1); //Only reduce depth for 3D textures, not texture arrays.
   1318 			}
   1319 
   1320 			//Error check
   1321 			if(glGetError())
   1322 			{
   1323 				FREE(pDecompressedData);
   1324 				PVRTErrorOutputDebug("PVRTTextureLoadFromPointer failed: glTexImage2D() failed.\n");
   1325 				return PVR_FAIL;
   1326 			}
   1327 		}
   1328 	}
   1329 
   1330 	FREE(pDecompressedData);
   1331 
   1332 	//Error check
   1333 	if(glGetError())
   1334 	{
   1335 		PVRTErrorOutputDebug("PVRTTextureLoadFromPointer failed: glTexImage2D() failed.\n");
   1336 		return PVR_FAIL;
   1337 	}
   1338 
   1339 	//Set Minification and Magnification filters according to whether MIP maps are present.
   1340 	if(eTextureType==GL_FLOAT || eTextureType==GL_HALF_FLOAT)
   1341 	{
   1342 		if(sTextureHeader.u32MIPMapCount==1)
   1343 		{	// Texture filter modes are limited to these for float textures
   1344 			glTexParameteri(eTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   1345 			glTexParameteri(eTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1346 		}
   1347 		else
   1348 		{
   1349 			glTexParameteri(eTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
   1350 			glTexParameteri(eTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1351 		}
   1352 	}
   1353 	else
   1354 	{
   1355 		if(sTextureHeader.u32MIPMapCount==1)
   1356 		{
   1357 			glTexParameteri(eTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   1358 			glTexParameteri(eTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   1359 		}
   1360 		else
   1361 		{
   1362 			glTexParameteri(eTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
   1363 			glTexParameteri(eTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   1364 		}
   1365 	}
   1366 
   1367 	if(	(sTextureHeader.u32Width & (sTextureHeader.u32Width - 1)) | (sTextureHeader.u32Height & (sTextureHeader.u32Height - 1)))
   1368 	{
   1369 		/*
   1370 			NPOT textures requires the wrap mode to be set explicitly to
   1371 			GL_CLAMP_TO_EDGE or the texture will be inconsistent.
   1372 		*/
   1373 		glTexParameteri(eTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   1374 		glTexParameteri(eTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   1375 	}
   1376 	else
   1377 	{
   1378 		glTexParameteri(eTarget, GL_TEXTURE_WRAP_S, GL_REPEAT);
   1379 		glTexParameteri(eTarget, GL_TEXTURE_WRAP_T, GL_REPEAT);
   1380 	}
   1381 
   1382 	//Error check
   1383 	if(glGetError())
   1384 	{
   1385 		PVRTErrorOutputDebug("PVRTTextureLoadFromPointer failed: glTexParameter() failed.\n");
   1386 		return PVR_FAIL;
   1387 	}
   1388 
   1389 	return PVR_SUCCESS;
   1390 }
   1391 
   1392 /*!***************************************************************************
   1393  @Function		PVRTTextureLoadFromPVR
   1394  @Input			filename			Filename of the .PVR file to load the texture from
   1395  @Modified		texName				the OpenGL ES texture name as returned by glBindTexture
   1396  @Modified		psTextureHeader		Pointer to a PVR_Texture_Header struct. Modified to
   1397 									contain the header data of the returned texture Ignored if NULL.
   1398  @Input			bAllowDecompress	Allow decompression if PVRTC is not supported in hardware.
   1399  @Input			nLoadFromLevel		Which mipmap level to start loading from (0=all)
   1400  @Modified		pMetaData			If a valid map is supplied, this will return any and all
   1401 									MetaDataBlocks stored in the texture, organised by DevFourCC
   1402 									then identifier. Supplying NULL will ignore all MetaData.
   1403  @Return		PVR_SUCCESS on success
   1404  @Description	Allows textures to be stored in binary PVR files and loaded in. Can load parts of a
   1405 				mipmaped texture (ie skipping the highest detailed levels).
   1406 				Sets the texture MIN/MAG filter to GL_LINEAR_MIPMAP_NEAREST/GL_LINEAR
   1407 				if mipmaps are present, GL_LINEAR/GL_LINEAR otherwise.
   1408 *****************************************************************************/
   1409 EPVRTError PVRTTextureLoadFromPVR(	const char * const filename,
   1410 									GLuint * const texName,
   1411 									const void *psTextureHeader,
   1412 									bool bAllowDecompress,
   1413 									const unsigned int nLoadFromLevel,
   1414 									CPVRTMap<unsigned int, CPVRTMap<unsigned int, MetaDataBlock> > *pMetaData)
   1415 {
   1416 	//Attempt to open file.
   1417 	CPVRTResourceFile TexFile(filename);
   1418 
   1419 	//Check file opened successfully.
   1420 	if (!TexFile.IsOpen())
   1421 	{
   1422 		return PVR_FAIL;
   1423 	}
   1424 
   1425 	//Header size.
   1426 	PVRTuint32 u32HeaderSize=0;
   1427 
   1428 	//Boolean whether to byte swap the texture data or not.
   1429 	bool bSwapDataEndianness=false;
   1430 
   1431 	//Texture header to check against.
   1432 	PVRTextureHeaderV3 sTextureHeader;
   1433 
   1434 	//The channel type for endian swapping.
   1435 	EPVRTVariableType u32CurrentChannelType=ePVRTVarTypeUnsignedByte;
   1436 
   1437 	//Check the first word of the file and see if it's equal to the current identifier (or reverse identifier)
   1438 	if(*(PVRTuint32*)TexFile.DataPtr()!=PVRTEX_CURR_IDENT && *(PVRTuint32*)TexFile.DataPtr()!=PVRTEX_CURR_IDENT_REV)
   1439 	{
   1440 		//Swap the header bytes if necessary.
   1441 		if(!PVRTIsLittleEndian())
   1442 		{
   1443 			bSwapDataEndianness=true;
   1444 			PVRTuint32 u32HeaderSize=PVRTByteSwap32(*(PVRTuint32*)TexFile.DataPtr());
   1445 
   1446 			for (PVRTuint32 i=0; i<u32HeaderSize; ++i)
   1447 			{
   1448 				PVRTByteSwap( (PVRTuint8*)( ( (PVRTuint32*)TexFile.DataPtr() )+i),sizeof(PVRTuint32) );
   1449 			}
   1450 		}
   1451 
   1452 		//Get a pointer to the header.
   1453 		PVR_Texture_Header* sLegacyTextureHeader=(PVR_Texture_Header*)TexFile.DataPtr();
   1454 
   1455 		//Set the header size.
   1456 		u32HeaderSize=sLegacyTextureHeader->dwHeaderSize;
   1457 
   1458 		//We only really need the channel type.
   1459 		PVRTuint64 tempFormat;
   1460 		EPVRTColourSpace tempColourSpace;
   1461 		bool tempIsPreMult;
   1462 
   1463 		//Map the enum to get the channel type.
   1464 		PVRTMapLegacyTextureEnumToNewFormat( (PVRTPixelType)( sLegacyTextureHeader->dwpfFlags&0xff),tempFormat,tempColourSpace, u32CurrentChannelType, tempIsPreMult);
   1465 	}
   1466 	// If the header file has a reverse identifier, then we need to swap endianness
   1467 	else if(*(PVRTuint32*)TexFile.DataPtr()==PVRTEX_CURR_IDENT_REV)
   1468 	{
   1469 		//Setup the texture header
   1470 		sTextureHeader=*(PVRTextureHeaderV3*)TexFile.DataPtr();
   1471 
   1472 		bSwapDataEndianness=true;
   1473 		PVRTextureHeaderV3* pTextureHeader=(PVRTextureHeaderV3*)TexFile.DataPtr();
   1474 
   1475 		pTextureHeader->u32ChannelType=PVRTByteSwap32(pTextureHeader->u32ChannelType);
   1476 		pTextureHeader->u32ColourSpace=PVRTByteSwap32(pTextureHeader->u32ColourSpace);
   1477 		pTextureHeader->u32Depth=PVRTByteSwap32(pTextureHeader->u32Depth);
   1478 		pTextureHeader->u32Flags=PVRTByteSwap32(pTextureHeader->u32Flags);
   1479 		pTextureHeader->u32Height=PVRTByteSwap32(pTextureHeader->u32Height);
   1480 		pTextureHeader->u32MetaDataSize=PVRTByteSwap32(pTextureHeader->u32MetaDataSize);
   1481 		pTextureHeader->u32MIPMapCount=PVRTByteSwap32(pTextureHeader->u32MIPMapCount);
   1482 		pTextureHeader->u32NumFaces=PVRTByteSwap32(pTextureHeader->u32NumFaces);
   1483 		pTextureHeader->u32NumSurfaces=PVRTByteSwap32(pTextureHeader->u32NumSurfaces);
   1484 		pTextureHeader->u32Version=PVRTByteSwap32(pTextureHeader->u32Version);
   1485 		pTextureHeader->u32Width=PVRTByteSwap32(pTextureHeader->u32Width);
   1486 		PVRTByteSwap((PVRTuint8*)&pTextureHeader->u64PixelFormat,sizeof(PVRTuint64));
   1487 
   1488 		//Channel type.
   1489 		u32CurrentChannelType=(EPVRTVariableType)pTextureHeader->u32ChannelType;
   1490 
   1491 		//Header size.
   1492 		u32HeaderSize=PVRTEX3_HEADERSIZE+sTextureHeader.u32MetaDataSize;
   1493 	}
   1494 	else
   1495 	{
   1496 		//Header size.
   1497 		u32HeaderSize=PVRTEX3_HEADERSIZE+sTextureHeader.u32MetaDataSize;
   1498 	}
   1499 
   1500 	// Convert the data if needed
   1501 	if(bSwapDataEndianness)
   1502 	{
   1503 		//Get the size of the variables types.
   1504 		PVRTuint32 ui32VariableSize=0;
   1505 		switch(u32CurrentChannelType)
   1506 		{
   1507 		case ePVRTVarTypeFloat:
   1508 		case ePVRTVarTypeUnsignedInteger:
   1509 		case ePVRTVarTypeUnsignedIntegerNorm:
   1510 		case ePVRTVarTypeSignedInteger:
   1511 		case ePVRTVarTypeSignedIntegerNorm:
   1512 			{
   1513 				ui32VariableSize=4;
   1514 				break;
   1515 			}
   1516 		case ePVRTVarTypeUnsignedShort:
   1517 		case ePVRTVarTypeUnsignedShortNorm:
   1518 		case ePVRTVarTypeSignedShort:
   1519 		case ePVRTVarTypeSignedShortNorm:
   1520 			{
   1521 				ui32VariableSize=2;
   1522 				break;
   1523 			}
   1524 		case ePVRTVarTypeUnsignedByte:
   1525 		case ePVRTVarTypeUnsignedByteNorm:
   1526 		case ePVRTVarTypeSignedByte:
   1527 		case ePVRTVarTypeSignedByteNorm:
   1528 			{
   1529 				ui32VariableSize=1;
   1530 				break;
   1531 			}
   1532         default:
   1533             return PVR_FAIL;
   1534 		}
   1535 
   1536 		//If the size of the variable type is greater than 1, then we need to byte swap.
   1537 		if (ui32VariableSize>1)
   1538 		{
   1539 			//Get the texture data.
   1540 			PVRTuint8* pu8OrigData = ( (PVRTuint8*)TexFile.DataPtr() + u32HeaderSize);
   1541 
   1542 			//Get the size of the texture data.
   1543 			PVRTuint32 ui32TextureDataSize = PVRTGetTextureDataSize(sTextureHeader);
   1544 
   1545 			//Loop through and byte swap all the data. It's swapped in place so no need to do anything special.
   1546 			for(PVRTuint32 i = 0; i < ui32TextureDataSize; i+=ui32VariableSize)
   1547 			{
   1548 				PVRTByteSwap(pu8OrigData+i,ui32VariableSize);
   1549 			}
   1550 		}
   1551 	}
   1552 
   1553 	return PVRTTextureLoadFromPointer(TexFile.DataPtr(), texName, psTextureHeader, bAllowDecompress, nLoadFromLevel,NULL,pMetaData);
   1554 }
   1555 
   1556 /*****************************************************************************
   1557  End of file (PVRTTextureAPI.cpp)
   1558 *****************************************************************************/
   1559 
   1560