HTML and CSS Reference
In-Depth Information
Once the data has been copied into the heap, you use a “pointer” to it (an integer offset into the heap typed array)
to call several functions to query information about the DXT data the Crunch file contains, such as the width and
height, number of mip levels, etc. Once you have all that, you calculate how large the decompressed DXT will be. You
use this to “ malloc ” the appropriate amount of space on the Emscripten heap to receive the decoded data.
Finally, you get to call the all-important _crn_decompress function, which does all the heavy lifting of
decompressing the bytes of the Crunch file into the plain old DXT information the GPU needs! Once that's done, you
free up the memory that you allocated to copy the Crunch data into and then call the provided callback, giving it the
newly decoded DXT data and all the necessary numbers to go with it. Note that you didn't actually need to copy the
decoded data out of the Emscripten heap, but instead you just created a view of the heap data at the appropriate offset
and size. This is because the Emscripten heap is already a TypedArray , which is what compressedTexImage2D requires
anyway. As such, as long as you don't allow anything to overwrite the Emscripten data before you've uploaded the
texture, you can simply give compressedTexImage2D the view. Less copying equals faster code, so this is definitely a win!
So now that you can decode the Crunch data, let's tie it all together by adding another method to the DXTLoader
class (see Listing 21-13).
Listing 21-13. loadCRN Method
// Loads a CRN (Crunch) file into the given texture.
// If no texture is provided one is created and returned.
DXTLoader.prototype.loadCRN = function(src, texture, callback) {
var self = this;
if(!texture) {
texture =;
// Load the file via XHR.
var xhr = new XMLHttpRequest();
xhr.addEventListener('load', function (ev) {
if (xhr.status == 200) {
// If the file loaded successfully parse and decompress it.
decompressCRN(xhr.response, function(dxtData, width, height, levels, internalFormat,
bytesPerBlock) {
// Upload the parsed and decompressed DXT data to the texture.
self._uploadDXT(dxtData, width, height, levels, internalFormat, bytesPerBlock, texture,
}, function(error) {
self._clearOnError(error, texture, callback);
} else {
self._clearOnError(xhr.statusText, texture, callback);
}, false);'GET', src, true);
xhr.responseType = 'arraybuffer';
return texture;
This is practically identical to the loadDDS function, so there's not much to say about it. The only real difference is
that you're calling decompressCRN on the xhr.response instead of parseDDS !
Search WWH ::

Custom Search