提交 15d308d8 编写于 作者: P Pierre Lepers

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

上级 248bb966
......@@ -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++;
}
......
......@@ -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 );
......
文件模式从 100644 更改为 100755
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册