PVRLoader.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * PVRLoader
  3. * Author: pierre lepers
  4. * Date: 17/09/2014 11:09
  5. *
  6. * PVR v2 (legacy) parser
  7. * TODO : Add Support for PVR v3 format
  8. */
  9. THREE.PVRLoader = function () {
  10. this._parser = THREE.PVRLoader.parse;
  11. };
  12. THREE.PVRLoader.prototype = Object.create( THREE.CompressedTextureLoader.prototype );
  13. THREE.PVRLoader.parse = function ( buffer, loadMipmaps ) {
  14. var pvr = { mipmaps: [], width: 0, height: 0, format: null, mipmapCount: 1, isCubemap : false };
  15. var headerLengthInt = 13;
  16. var header = new Uint32Array( buffer, 0, headerLengthInt );
  17. // texturetool format
  18. var headerLength = header[0],
  19. height = header[1],
  20. width = header[2],
  21. numMipmaps = header[3],
  22. flags = header[4],
  23. dataLength = header[5],
  24. bpp = header[6],
  25. bitmaskRed = header[7],
  26. bitmaskGreen = header[8],
  27. bitmaskBlue = header[9],
  28. bitmaskAlpha = header[10],
  29. pvrTag = header[11],
  30. numSurfs = header[12]
  31. var PVR_TEXTURE_FLAG_TYPE_MASK = 0xff
  32. var PVRTextureFlagTypePVRTC_2 = 24,
  33. PVRTextureFlagTypePVRTC_4 = 25
  34. var formatFlags = flags & PVR_TEXTURE_FLAG_TYPE_MASK;
  35. // console.log( "--------------------------" );
  36. // console.log( "headerLength ", headerLength);
  37. // console.log( "height ", height );
  38. // console.log( "width ", width );
  39. // console.log( "numMipmaps ", numMipmaps );
  40. // console.log( "flags ", flags );
  41. // console.log( "dataLength ", dataLength );
  42. // console.log( "bpp ", bpp );
  43. // console.log( "bitmaskRed ", bitmaskRed );
  44. // console.log( "bitmaskGreen ", bitmaskGreen);
  45. // console.log( "bitmaskBlue ", bitmaskBlue );
  46. // console.log( "bitmaskAlpha ", bitmaskAlpha);
  47. // console.log( "pvrTag ", pvrTag );
  48. // console.log( "numSurfs ", numSurfs );
  49. if (formatFlags == PVRTextureFlagTypePVRTC_4 || formatFlags == PVRTextureFlagTypePVRTC_2)
  50. {
  51. var _hasAlpha = bitmaskAlpha > 0;
  52. // has alpha???
  53. if (formatFlags == PVRTextureFlagTypePVRTC_4)
  54. pvr.format = _hasAlpha ? THREE.RGBA_PVRTC_4BPPV1_Format : THREE.RGB_PVRTC_4BPPV1_Format;
  55. else if (formatFlags == PVRTextureFlagTypePVRTC_2)
  56. pvr.format = _hasAlpha ? THREE.RGBA_PVRTC_2BPPV1_Format : THREE.RGB_PVRTC_2BPPV1_Format;
  57. else
  58. throw new Error( "pvrtc - unknown format "+formatFlags);
  59. pvr.width = width;
  60. pvr.height = height;
  61. pvr.isCubemap = (numSurfs === 6);
  62. var dataOffset = headerLength,
  63. dataSize = 0,
  64. blockSize = 0,
  65. widthBlocks = 0,
  66. heightBlocks = 0,
  67. bpp = 4;
  68. dataLength += headerLength;
  69. for ( var surfIndex = 0; surfIndex < numSurfs; surfIndex ++ ) {
  70. var sWidth = width,
  71. sHeight = height;
  72. var mipLevel = 0;
  73. while (mipLevel < numMipmaps + 1 ) {
  74. if (formatFlags == PVRTextureFlagTypePVRTC_4)
  75. {
  76. blockSize = 4 * 4; // Pixel by pixel block size for 4bpp
  77. widthBlocks = sWidth / 4;
  78. heightBlocks = sHeight / 4;
  79. bpp = 4;
  80. }
  81. else
  82. {
  83. blockSize = 8 * 4; // Pixel by pixel block size for 2bpp
  84. widthBlocks = sWidth / 8;
  85. heightBlocks = sHeight / 4;
  86. bpp = 2;
  87. }
  88. // Clamp to minimum number of blocks
  89. if (widthBlocks < 2)
  90. widthBlocks = 2;
  91. if (heightBlocks < 2)
  92. heightBlocks = 2;
  93. dataSize = widthBlocks * heightBlocks * ((blockSize * bpp) / 8);
  94. var byteArray = new Uint8Array( buffer, dataOffset, dataSize );
  95. var mipmap = { "data": byteArray, "width": sWidth, "height": sHeight };
  96. pvr.mipmaps.push( mipmap );
  97. dataOffset += dataSize;
  98. sWidth = Math.max(sWidth >> 1, 1);
  99. sHeight = Math.max(sHeight >> 1, 1);
  100. mipLevel++;
  101. }
  102. }
  103. }
  104. // Assert file is fully parsed?
  105. //console.log( "data left : ", dataOffset - dataLength );
  106. //assert( dataOffset === dataLength );
  107. return pvr;
  108. }