diff --git a/examples/js/loaders/PVRLoader.js b/examples/js/loaders/PVRLoader.js index 46377446b6f0b818e94adfcea4056155c2c034b6..7315a9527c4d6760ca8a81ea4c962096d425450c 100644 --- a/examples/js/loaders/PVRLoader.js +++ b/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++; + } diff --git a/examples/textures/compressed/park3_cube_mip_2bpp_rgb_v3.pvr b/examples/textures/compressed/park3_cube_mip_2bpp_rgb_v3.pvr new file mode 100644 index 0000000000000000000000000000000000000000..d653e9962667e1771860f47f12d1be1328ace967 Binary files /dev/null and b/examples/textures/compressed/park3_cube_mip_2bpp_rgb_v3.pvr differ diff --git a/examples/textures/compressed/park3_cube_nomip_4bpp_rgb.pvr b/examples/textures/compressed/park3_cube_nomip_4bpp_rgb.pvr index 02495fe05e60b81408e1f7fb5e64bc45d840bf52..ab6337b9db19bbbc89484cb7e9e0776c289a6eb1 100644 Binary files a/examples/textures/compressed/park3_cube_nomip_4bpp_rgb.pvr and b/examples/textures/compressed/park3_cube_nomip_4bpp_rgb.pvr differ diff --git a/examples/webgl_materials_texture_pvrtc.html b/examples/webgl_materials_texture_pvrtc.html index 19b0848544d02f8281b0446ec818adcc4f3a190c..7444036a8d1ce7258bd1c7c30798d9ced5ff64ea 100644 --- a/examples/webgl_materials_texture_pvrtc.html +++ b/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 ); diff --git a/utils/servers/nodejs_server.sh b/utils/servers/nodejs_server.sh old mode 100644 new mode 100755