فهرست منبع

pvr format - add pvr v3 support - fixed wrong parsing order for faces -> mipmaps in cubemaps

Pierre Lepers 11 سال پیش
والد
کامیت
15d308d882

+ 89 - 38
examples/js/loaders/PVRLoader.js

@@ -26,11 +26,12 @@ THREE.PVRLoader.parse = function ( buffer, loadMipmaps ) {
 		loadMipmaps : loadMipmaps
 	};
 
+	// PVR v3
 	if( header[0] === 0x03525650 ) {
-		// PVR v3
 		return THREE.PVRLoader._parseV3( pvrDatas );
-	} else if( header[11] === 0x21525650) {
-		// PVR v2
+	} 
+	// PVR v2
+	else if( header[11] === 0x21525650) {
 		return THREE.PVRLoader._parseV2( pvrDatas );
 
 	} else {
@@ -41,13 +42,54 @@ THREE.PVRLoader.parse = function ( buffer, loadMipmaps ) {
 
 THREE.PVRLoader._parseV3 = function ( pvrDatas ) {
 	
-	var buffer = pvrDatas.buffer;
 	var header = pvrDatas.header;
+	var bpp, format;
+	
+
+	var metaLen 	  = header[12],
+		pixelFormat   =  header[2],
+		height        =  header[6],
+		width         =  header[7],
+		numSurfs      =  header[9],
+		numFaces      =  header[10],
+		numMipmaps    =  header[11];
+
+	switch( pixelFormat ) {
+		case 0 : // PVRTC 2bpp RGB
+			bpp = 2;
+			format = THREE.RGB_PVRTC_2BPPV1_Format;
+			break;
+		case 1 : // PVRTC 2bpp RGBA
+			bpp = 2
+			format = THREE.RGBA_PVRTC_2BPPV1_Format;
+			break;
+		case 2 : // PVRTC 4bpp RGB
+			bpp = 4
+			format = THREE.RGB_PVRTC_4BPPV1_Format;
+			break;
+		case 3 : // PVRTC 4bpp RGBA
+			bpp = 4
+			format = THREE.RGBA_PVRTC_4BPPV1_Format;
+			break;
+		default :
+			throw new Error( "pvrtc - unsupported PVR format "+pixelFormat);
+	}
+
+	pvrDatas.dataPtr 	 = 52 + metaLen;
+  	pvrDatas.bpp 		 = bpp;
+  	pvrDatas.format 	 = format;
+  	pvrDatas.width 		 = width;
+  	pvrDatas.height 	 = height;
+  	pvrDatas.numSurfaces = numFaces;
+  	pvrDatas.numMipmaps  = numMipmaps;
+
+  	pvrDatas.isCubemap 	= (numFaces === 6);
+
+  	return THREE.PVRLoader._extract( pvrDatas );
 };
 
 THREE.PVRLoader._parseV2 = function ( pvrDatas ) {
 
-	var buffer = pvrDatas.buffer;
 	var header = pvrDatas.header;
 
 	var headerLength  =  header[0],
@@ -76,12 +118,12 @@ THREE.PVRLoader._parseV2 = function ( pvrDatas ) {
 	var bpp, format;
 	var _hasAlpha = bitmaskAlpha > 0;
 
-	if (formatFlags == PVRTC_4 ) {
+	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;
+	else if( formatFlags === PVRTC_2) {
+		format = _hasAlpha ? THREE.RGBA_PVRTC_2BPPV1_Format : THREE.RGB_PVRTC_2BPPV1_Format;
 		bpp = 2;
 	}
 	else
@@ -89,13 +131,13 @@ THREE.PVRLoader._parseV2 = function ( pvrDatas ) {
 	
 
 
-	pvrDatas.dataPtr 	= headerLength;
-  	pvrDatas.bpp 		= bpp;
-  	pvrDatas.format 	= format;
-  	pvrDatas.width 		= width;
-  	pvrDatas.height 	= height;
+	pvrDatas.dataPtr 	 = headerLength;
+  	pvrDatas.bpp 		 = bpp;
+  	pvrDatas.format 	 = format;
+  	pvrDatas.width 		 = width;
+  	pvrDatas.height 	 = height;
   	pvrDatas.numSurfaces = numSurfs;
-  	pvrDatas.numMipmaps 	= numMipmaps;
+  	pvrDatas.numMipmaps  = numMipmaps + 1;
 
   	// guess cubemap type seems tricky in v2
   	// it juste a pvr containing 6 surface (no explicit cubemap type)
@@ -105,9 +147,17 @@ THREE.PVRLoader._parseV2 = function ( 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 pvr = {
+		mipmaps: [], 
+		width: pvrDatas.width, 
+		height: pvrDatas.height, 
+		format: pvrDatas.format, 
+		mipmapCount: pvrDatas.numMipmaps, 
+		isCubemap : pvrDatas.isCubemap 
+	};
 
 	var buffer = pvrDatas.buffer;
 
@@ -152,47 +202,48 @@ THREE.PVRLoader._extract = function ( pvrDatas ) {
 		blockHeight = 4;
 	}
 
-	blockSize = blockWidth * blockHeight;
-
-
+	blockSize = (blockWidth * blockHeight) * bpp / 8;
 
-	for ( var surfIndex = 0; surfIndex < numSurfs; surfIndex ++ ) {
+	pvr.mipmaps.length = pvrDatas.numMipmaps * numSurfs;
 
-		var sWidth = pvrDatas.width,
-			sHeight = pvrDatas.height;
+	var mipLevel = 0;
 
-		var mipLevel = 0;
+	while (mipLevel < pvrDatas.numMipmaps) {
 
-		while (mipLevel < pvrDatas.numMipmaps + 1 ) {
+		var sWidth = pvrDatas.width >> mipLevel,
+		sHeight = pvrDatas.height >> mipLevel;
 
+		widthBlocks = sWidth / blockWidth;
+		heightBlocks = sHeight / blockHeight;
 
+		// Clamp to minimum number of blocks
+		if (widthBlocks < 2)
+			widthBlocks = 2;
+		if (heightBlocks < 2)
+			heightBlocks = 2;
 
-			widthBlocks = sWidth / blockWidth;
-			heightBlocks = sHeight / blockHeight;
+		dataSize = widthBlocks * heightBlocks * blockSize;
 
-			// Clamp to minimum number of blocks
-			if (widthBlocks < 2)
-				widthBlocks = 2;
-			if (heightBlocks < 2)
-				heightBlocks = 2;
 
-
-			dataSize = widthBlocks * heightBlocks * ((blockSize  * bpp) / 8);
+		for ( var surfIndex = 0; surfIndex < numSurfs; surfIndex ++ ) {
 
 			var byteArray = new Uint8Array( buffer, dataOffset, dataSize );
 
-			var mipmap = { "data": byteArray, "width": sWidth, "height": sHeight };
-			pvr.mipmaps.push( mipmap );
+			var mipmap = { 
+				data: byteArray, 
+				width: sWidth, 
+				height: sHeight 
+			};
 
-			dataOffset += dataSize;
+			pvr.mipmaps[ surfIndex * pvrDatas.numMipmaps + mipLevel] = mipmap;
 
-			sWidth = Math.max(sWidth >> 1, 1);
-			sHeight = Math.max(sHeight >> 1, 1);
+			dataOffset += dataSize;
 
-			mipLevel++;
 
 		}
 
+		mipLevel++;
+
 	}
 
 

BIN
examples/textures/compressed/park3_cube_mip_2bpp_rgb_v3.pvr


BIN
examples/textures/compressed/park3_cube_nomip_4bpp_rgb.pvr


+ 37 - 10
examples/webgl_materials_texture_pvrtc.html

@@ -70,22 +70,31 @@
 
 				*/
               
-    			var onCubeLoaded = function(texture){
-					texture.magFilter = THREE.LinearFilter
+    			var onCube1Loaded = function(texture){
+					texture.magFilter = THREE.LinearFilter;
 					texture.minFilter = THREE.LinearFilter;
 					texture.mapping = new THREE.CubeReflectionMapping();
 					material6.needsUpdate = true;
     			};
+    			var onCube2Loaded = function(texture){
+					texture.magFilter = THREE.LinearFilter;
+					// texture.minFilter = THREE.LinearMipMapNearestFilter;
+					texture.minFilter = THREE.LinearFilter;
+					texture.mapping = new THREE.CubeReflectionMapping();
+					material8.needsUpdate = true;
+    			};
      
     
 				var loader = new THREE.PVRLoader();
 
 				var disturb_4bpp_rgb            = loader.load( 'textures/compressed/disturb_4bpp_rgb.pvr');
+				var disturb_4bpp_rgb_v3         = loader.load( 'textures/compressed/disturb_4bpp_rgb_v3.pvr');
 				var disturb_4bpp_rgb_mips       = loader.load( 'textures/compressed/disturb_4bpp_rgb_mips.pvr');
 				var disturb_2bpp_rgb            = loader.load( 'textures/compressed/disturb_2bpp_rgb.pvr');
 				var flare_4bpp_rgba             = loader.load( 'textures/compressed/flare_4bpp_rgba.pvr');
 				var flare_2bpp_rgba             = loader.load( 'textures/compressed/flare_2bpp_rgba.pvr');
-				var park3_cube_nomip_4bpp_rgb   = loader.load( 'textures/compressed/park3_cube_nomip_4bpp_rgb.pvr', onCubeLoaded );
+				var park3_cube_nomip_4bpp_rgb   = loader.load( 'textures/compressed/park3_cube_nomip_4bpp_rgb.pvr', onCube1Loaded );
+				var park3_cube_mip_2bpp_rgb_v3  = loader.load( 'textures/compressed/park3_cube_mip_2bpp_rgb_v3.pvr', onCube2Loaded );
 
 
 				disturb_2bpp_rgb.minFilter = 
@@ -94,6 +103,8 @@
 				flare_4bpp_rgba.magFilter  =
 				disturb_4bpp_rgb.minFilter =
 				disturb_4bpp_rgb.magFilter =
+				disturb_4bpp_rgb_v3.minFilter =
+				disturb_4bpp_rgb_v3.magFilter =
 				flare_2bpp_rgba.minFilter  =
 				flare_2bpp_rgba.magFilter  = THREE.LinearFilter;
 
@@ -103,41 +114,57 @@
 				var material4 = new THREE.MeshBasicMaterial( { map: flare_4bpp_rgba       , side: THREE.DoubleSide, depthTest: false, transparent: true } );
 				var material5 = new THREE.MeshBasicMaterial( { map: flare_2bpp_rgba       , side: THREE.DoubleSide, depthTest: false, transparent: true } );
 				var material6 = new THREE.MeshBasicMaterial( { envMap: park3_cube_nomip_4bpp_rgb } );
+				var material8 = new THREE.MeshBasicMaterial( { envMap: park3_cube_mip_2bpp_rgb_v3 } );
 
+				var material7 = new THREE.MeshBasicMaterial( { map: disturb_4bpp_rgb_v3       } );
 			
 
 				var mesh = new THREE.Mesh( geometry, material1 );
-				mesh.position.x = -400;
+				mesh.position.x = -500;
 				mesh.position.y = 200;
 				scene.add( mesh );
 				meshes.push( mesh );
 
 				mesh = new THREE.Mesh( geometry, material2 );
-				mesh.position.x = 0;
+				mesh.position.x = -166;
 				mesh.position.y = 200;
 				scene.add( mesh );
 				meshes.push( mesh );
 
 				mesh = new THREE.Mesh( geometry, material3 );
-				mesh.position.x = 400;
+				mesh.position.x = 166;
+				mesh.position.y = 200;
+				scene.add( mesh );
+				meshes.push( mesh );
+
+				mesh = new THREE.Mesh( geometry, material7 );
+				mesh.position.x = 500;
 				mesh.position.y = 200;
 				scene.add( mesh );
 				meshes.push( mesh );
 
 				mesh = new THREE.Mesh( geometry, material4 );
-				mesh.position.x = -400;
+				mesh.position.x = -500;
 				mesh.position.y = -200;
 				scene.add( mesh );
 				meshes.push( mesh );
 
 				mesh = new THREE.Mesh( geometry, material5 );
-				mesh.position.x = 0;
+				mesh.position.x = -166;
+				mesh.position.y = -200;
+				scene.add( mesh );
+				meshes.push( mesh );
+
+				var torus =  new THREE.TorusGeometry( 100, 50, 32, 24 )
+
+				mesh = new THREE.Mesh( torus, material6 );
+				mesh.position.x = 166;
 				mesh.position.y = -200;
 				scene.add( mesh );
 				meshes.push( mesh );
 
-				mesh = new THREE.Mesh( new THREE.TorusGeometry( 100, 50, 32, 16 ), material6 );
-				mesh.position.x = 400;
+				mesh = new THREE.Mesh( torus, material8 );
+				mesh.position.x = 500;
 				mesh.position.y = -200;
 				scene.add( mesh );
 				meshes.push( mesh );

+ 0 - 0
utils/servers/nodejs_server.sh