Explorar o código

start PVRTC V3 support

Pierre Lepers %!s(int64=11) %!d(string=hai) anos
pai
achega
248bb9662c
Modificáronse 2 ficheiros con 104 adicións e 57 borrados
  1. 104 57
      examples/js/loaders/PVRLoader.js
  2. BIN=BIN
      examples/textures/compressed/disturb_4bpp_rgb_v3.pvr

+ 104 - 57
examples/js/loaders/PVRLoader.js

@@ -5,6 +5,7 @@
  *
  *	 PVR v2 (legacy) parser
  *   TODO : Add Support for PVR v3 format
+ *   TODO : implement loadMipmaps option
  */
 
 
@@ -16,16 +17,39 @@ THREE.PVRLoader.prototype = Object.create( THREE.CompressedTextureLoader.prototy
 
 
 THREE.PVRLoader.parse = function ( buffer, loadMipmaps ) {
-	
-	var pvr = { mipmaps: [], width: 0, height: 0, format: null, mipmapCount: 1, isCubemap : false };
+	var headerLengthInt = 13;
+	var header = new Uint32Array( buffer, 0, headerLengthInt );
 
+	var pvrDatas = {
+		buffer: buffer,
+		header : header,
+		loadMipmaps : loadMipmaps
+	};
+
+	if( header[0] === 0x03525650 ) {
+		// PVR v3
+		return THREE.PVRLoader._parseV3( pvrDatas );
+	} else if( header[11] === 0x21525650) {
+		// PVR v2
+		return THREE.PVRLoader._parseV2( pvrDatas );
+
+	} else {
+		throw new Error( "[THREE.PVRLoader] Unknown PVR format" );
+	}
 
-	var headerLengthInt = 13;
+};
 
-	var header = new Uint32Array( buffer, 0, headerLengthInt );
+THREE.PVRLoader._parseV3 = function ( pvrDatas ) {
+	
+	var buffer = pvrDatas.buffer;
+	var header = pvrDatas.header;
+};
 
+THREE.PVRLoader._parseV2 = function ( pvrDatas ) {
+
+	var buffer = pvrDatas.buffer;
+	var header = pvrDatas.header;
 
-	// texturetool format
 	var headerLength  =  header[0],
 		height        =  header[1],
 		width         =  header[2],
@@ -38,15 +62,56 @@ THREE.PVRLoader.parse = function ( buffer, loadMipmaps ) {
 		bitmaskBlue   =  header[9],
 		bitmaskAlpha  =  header[10],
 		pvrTag        =  header[11],
-		numSurfs      =  header[12]
+		numSurfs      =  header[12];
+
+
+	var TYPE_MASK = 0xff
+	var PVRTC_2 = 24,
+		PVRTC_4 = 25
+
+	var formatFlags = flags & TYPE_MASK;
 
 
 
-	var PVR_TEXTURE_FLAG_TYPE_MASK = 0xff
-	var PVRTextureFlagTypePVRTC_2 = 24,
-		PVRTextureFlagTypePVRTC_4 = 25
+	var bpp, format;
+	var _hasAlpha = bitmaskAlpha > 0;
+
+	if (formatFlags == PVRTC_4 ) {
+		format = _hasAlpha ? THREE.RGBA_PVRTC_4BPPV1_Format : THREE.RGB_PVRTC_4BPPV1_Format;
+		bpp = 4;
+	}
+	else if( formatFlags == PVRTC_2) {
+		format = _hasAlpha ? THREE.RGBA_PVRTC_4BPPV1_Format : THREE.RGB_PVRTC_4BPPV1_Format;
+		bpp = 2;
+	}
+	else
+		throw new Error( "pvrtc - unknown format "+formatFlags);
+	
+
+
+	pvrDatas.dataPtr 	= headerLength;
+  	pvrDatas.bpp 		= bpp;
+  	pvrDatas.format 	= format;
+  	pvrDatas.width 		= width;
+  	pvrDatas.height 	= height;
+  	pvrDatas.numSurfaces = numSurfs;
+  	pvrDatas.numMipmaps 	= numMipmaps;
+
+  	// guess cubemap type seems tricky in v2
+  	// it juste a pvr containing 6 surface (no explicit cubemap type)
+  	pvrDatas.isCubemap 	= (numSurfs === 6);
+
+  	return THREE.PVRLoader._extract( pvrDatas );
+
+};
+
+THREE.PVRLoader._extract = function ( pvrDatas ) {
+	
+	var pvr = { mipmaps: [], width: pvrDatas.width, height: pvrDatas.height, format: pvrDatas.format, mipmapCount: pvrDatas.numMipmaps+1, isCubemap : pvrDatas.isCubemap };
+
+	var buffer = pvrDatas.buffer;
+
 
-	var formatFlags = flags & PVR_TEXTURE_FLAG_TYPE_MASK;
 
 	// console.log( "--------------------------" );
 
@@ -65,64 +130,51 @@ THREE.PVRLoader.parse = function ( buffer, loadMipmaps ) {
 	// console.log( "numSurfs     ", numSurfs    );
 
 
-	if (formatFlags == PVRTextureFlagTypePVRTC_4 || formatFlags == PVRTextureFlagTypePVRTC_2)
-	{
 
-	  var _hasAlpha = bitmaskAlpha > 0;
-	  // has alpha???
 
-	  if (formatFlags == PVRTextureFlagTypePVRTC_4)
-		pvr.format = _hasAlpha ? THREE.RGBA_PVRTC_4BPPV1_Format : THREE.RGB_PVRTC_4BPPV1_Format;
-	  else if (formatFlags == PVRTextureFlagTypePVRTC_2)
-		pvr.format = _hasAlpha ? THREE.RGBA_PVRTC_2BPPV1_Format : THREE.RGB_PVRTC_2BPPV1_Format;
-	  else
-		throw new Error( "pvrtc - unknown format "+formatFlags);
+	var dataOffset = pvrDatas.dataPtr,
+		bpp = pvrDatas.bpp,
+		numSurfs = pvrDatas.numSurfaces,
+		dataSize = 0,
+		blockSize = 0,
+		blockWidth = 0,
+		blockHeight = 0,
+		widthBlocks = 0,
+		heightBlocks = 0;
 
-	  pvr.width  = width;
-	  pvr.height = height;
-	  pvr.isCubemap = (numSurfs === 6);
 
 
-	  var dataOffset = headerLength,
-		  dataSize = 0,
-		  blockSize = 0,
-		  widthBlocks = 0,
-		  heightBlocks = 0,
-		  bpp = 4;
+	if( bpp === 2 ){
+		blockWidth = 8;
+		blockHeight = 4;
+	} else {
+		blockWidth = 4;
+		blockHeight = 4;
+	}
+
+	blockSize = blockWidth * blockHeight;
 
-	  dataLength += headerLength;
 
-	  for ( var surfIndex = 0; surfIndex < numSurfs; surfIndex ++ ) {
 
-		  var sWidth = width,
-			  sHeight = height;
+	for ( var surfIndex = 0; surfIndex < numSurfs; surfIndex ++ ) {
 
-		  var mipLevel = 0;
+		var sWidth = pvrDatas.width,
+			sHeight = pvrDatas.height;
 
-		  while (mipLevel < numMipmaps + 1 ) {
+		var mipLevel = 0;
 
+		while (mipLevel < pvrDatas.numMipmaps + 1 ) {
 
 
-			if (formatFlags == PVRTextureFlagTypePVRTC_4)
-			{
-			  blockSize = 4 * 4; // Pixel by pixel block size for 4bpp
-			  widthBlocks = sWidth / 4;
-			  heightBlocks = sHeight / 4;
-			  bpp = 4;
-			}
-			else
-			{
-			  blockSize = 8 * 4; // Pixel by pixel block size for 2bpp
-			  widthBlocks = sWidth / 8;
-			  heightBlocks = sHeight / 4;
-			  bpp = 2;
-			}
+
+			widthBlocks = sWidth / blockWidth;
+			heightBlocks = sHeight / blockHeight;
 
 			// Clamp to minimum number of blocks
 			if (widthBlocks < 2)
-			  widthBlocks = 2;
+				widthBlocks = 2;
 			if (heightBlocks < 2)
-			  heightBlocks = 2;
+				heightBlocks = 2;
 
 
 			dataSize = widthBlocks * heightBlocks * ((blockSize  * bpp) / 8);
@@ -139,15 +191,10 @@ THREE.PVRLoader.parse = function ( buffer, loadMipmaps ) {
 
 			mipLevel++;
 
-		  }
-
-	  }
+		}
 
 	}
 
-	// Assert file is fully parsed?
-	//console.log( "data left : ", dataOffset - dataLength );
-	//assert( dataOffset === dataLength );
 
 	return pvr;
 }

BIN=BIN
examples/textures/compressed/disturb_4bpp_rgb_v3.pvr