babylon.tools.dds.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. "use strict";
  2. var BABYLON = BABYLON || {};
  3. (function () {
  4. BABYLON.Tools = BABYLON.Tools|| {};
  5. // Based on demo done by Brandon Jones - http://media.tojicode.com/webgl-samples/dds.html
  6. // All values and structures referenced from:
  7. // http://msdn.microsoft.com/en-us/library/bb943991.aspx/
  8. var DDS_MAGIC = 0x20534444;
  9. var DDSD_CAPS = 0x1,
  10. DDSD_HEIGHT = 0x2,
  11. DDSD_WIDTH = 0x4,
  12. DDSD_PITCH = 0x8,
  13. DDSD_PIXELFORMAT = 0x1000,
  14. DDSD_MIPMAPCOUNT = 0x20000,
  15. DDSD_LINEARSIZE = 0x80000,
  16. DDSD_DEPTH = 0x800000;
  17. var DDSCAPS_COMPLEX = 0x8,
  18. DDSCAPS_MIPMAP = 0x400000,
  19. DDSCAPS_TEXTURE = 0x1000;
  20. var DDSCAPS2_CUBEMAP = 0x200,
  21. DDSCAPS2_CUBEMAP_POSITIVEX = 0x400,
  22. DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800,
  23. DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000,
  24. DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000,
  25. DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000,
  26. DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000,
  27. DDSCAPS2_VOLUME = 0x200000;
  28. var DDPF_ALPHAPIXELS = 0x1,
  29. DDPF_ALPHA = 0x2,
  30. DDPF_FOURCC = 0x4,
  31. DDPF_RGB = 0x40,
  32. DDPF_YUV = 0x200,
  33. DDPF_LUMINANCE = 0x20000;
  34. function FourCCToInt32(value) {
  35. return value.charCodeAt(0) +
  36. (value.charCodeAt(1) << 8) +
  37. (value.charCodeAt(2) << 16) +
  38. (value.charCodeAt(3) << 24);
  39. }
  40. function Int32ToFourCC(value) {
  41. return String.fromCharCode(
  42. value & 0xff,
  43. (value >> 8) & 0xff,
  44. (value >> 16) & 0xff,
  45. (value >> 24) & 0xff
  46. );
  47. }
  48. var FOURCC_DXT1 = FourCCToInt32("DXT1");
  49. var FOURCC_DXT5 = FourCCToInt32("DXT5");
  50. var headerLengthInt = 31; // The header length in 32 bit ints
  51. // Offsets into the header array
  52. var off_magic = 0;
  53. var off_size = 1;
  54. var off_flags = 2;
  55. var off_height = 3;
  56. var off_width = 4;
  57. var off_mipmapCount = 7;
  58. var off_pfFlags = 20;
  59. var off_pfFourCC = 21;
  60. BABYLON.Tools.GetDDSInfo = function (arrayBuffer) {
  61. var header = new Int32Array(arrayBuffer, 0, headerLengthInt);
  62. var mipmapCount = 1;
  63. if (header[off_flags] & DDSD_MIPMAPCOUNT) {
  64. mipmapCount = Math.max(1, header[off_mipmapCount]);
  65. }
  66. return {
  67. width: header[off_width],
  68. height: header[off_height],
  69. mipmapCount: mipmapCount
  70. };
  71. };
  72. BABYLON.Tools.UploadDDSLevels = function (gl, ext, arrayBuffer, loadMipmaps) {
  73. var header = new Int32Array(arrayBuffer, 0, headerLengthInt),
  74. fourCC, blockBytes, internalFormat,
  75. width, height, dataLength, dataOffset,
  76. byteArray, mipmapCount, i;
  77. if (header[off_magic] != DDS_MAGIC) {
  78. console.error("Invalid magic number in DDS header");
  79. return;
  80. }
  81. if (!header[off_pfFlags] & DDPF_FOURCC) {
  82. console.error("Unsupported format, must contain a FourCC code");
  83. return;
  84. }
  85. fourCC = header[off_pfFourCC];
  86. switch (fourCC) {
  87. case FOURCC_DXT1:
  88. blockBytes = 8;
  89. internalFormat = ext.COMPRESSED_RGBA_S3TC_DXT1_EXT;
  90. break;
  91. case FOURCC_DXT5:
  92. blockBytes = 16;
  93. internalFormat = ext.COMPRESSED_RGBA_S3TC_DXT5_EXT;
  94. break;
  95. default:
  96. console.error("Unsupported FourCC code:", Int32ToFourCC(fourCC));
  97. return;
  98. }
  99. mipmapCount = 1;
  100. if (header[off_flags] & DDSD_MIPMAPCOUNT && loadMipmaps !== false) {
  101. mipmapCount = Math.max(1, header[off_mipmapCount]);
  102. }
  103. width = header[off_width];
  104. height = header[off_height];
  105. dataOffset = header[off_size] + 4;
  106. for (i = 0; i < mipmapCount; ++i) {
  107. dataLength = Math.max(4, width) / 4 * Math.max(4, height) / 4 * blockBytes;
  108. byteArray = new Uint8Array(arrayBuffer, dataOffset, dataLength);
  109. gl.compressedTexImage2D(gl.TEXTURE_2D, i, internalFormat, width, height, 0, byteArray);
  110. dataOffset += dataLength;
  111. width *= 0.5;
  112. height *= 0.5;
  113. }
  114. };
  115. })();