Skip to content

Instantly share code, notes, and snippets.

@showa-yojyo
Created July 31, 2021 14:39
Show Gist options
  • Save showa-yojyo/a21b1feb0dca84bcc61fe50c4c00c714 to your computer and use it in GitHub Desktop.
Save showa-yojyo/a21b1feb0dca84bcc61fe50c4c00c714 to your computer and use it in GitHub Desktop.
TBW
const FOURCC_DXT1 = 0x31545844 // Equivalent to "DXT1" in ASCII
const FOURCC_DXT3 = 0x33545844 // Equivalent to "DXT3" in ASCII
const FOURCC_DXT5 = 0x35545844 // Equivalent to "DXT5" in ASCII
async function loadDDS(gl, url) {
const ext = gl.getExtension('WEBGL_compressed_texture_s3tc');
if (!ext) {
alert('WEBGL_compressed_texture_s3tc notavailable');
return;
}
const dataArrayBuffer = await fetch(url)
.then(response => response.arrayBuffer());
const header = new Int32Array(dataArrayBuffer, 0, 32);
let height = header[3];
let width = header[4];
const mipMapCount = header[7];
const fourCC = header[21];
let offset = header[1] + 4; // ??
// how big is it going to be including all mipmaps?
//const linearSize = header[5];
//const bufSize = mipMapCount > 1 ? linearSize * 2 : linearSize;
//const numComponents = (fourCC == FOURCC_DXT1) ? 3 : 4;
let blockBytes, format;
switch (fourCC) {
case FOURCC_DXT1:
blockBytes = 8;
format = ext.COMPRESSED_RGBA_S3TC_DXT1_EXT;
break;
case FOURCC_DXT3:
blockBytes = 16;
format = ext.COMPRESSED_RGBA_S3TC_DXT3_EXT;
break;
case FOURCC_DXT5:
blockBytes = 16;
format = ext.COMPRESSED_RGBA_S3TC_DXT5_EXT;
break;
default:
assert("invalid or unsupported fourCC");
break;
}
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
for (let level = 0; level < mipMapCount && (width || height); ++level) {
const size = Math.max(4, width) / 4 * Math.max(4, height) / 4 * blockBytes;
console.log(`Mipmap ${level}: ${width}x${height} length: ${size}`);
gl.compressedTexImage2D(gl.TEXTURE_2D,
level, format, width, height, 0,
new DataView(dataArrayBuffer, offset, size));
offset += size;
width /= 2;
height /= 2;
// Deal with Non-Power-Of-Two textures.
if (width < 1) width = 1;
if (height < 1) height = 1;
}
return texture;
}