|
@@ -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;
|
|
|
}
|