739 lines
70 KiB
JavaScript
739 lines
70 KiB
JavaScript
|
|
/**
|
||
|
|
* Kepler - Core
|
||
|
|
*
|
||
|
|
* All rights reserved.
|
||
|
|
*
|
||
|
|
* Author: Kaj Dijksta
|
||
|
|
*
|
||
|
|
**/
|
||
|
|
|
||
|
|
|
||
|
|
import programInfo from './programInfo.js';
|
||
|
|
import {vector2, vector3} from './math.js';
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* ResourceManager object
|
||
|
|
*/
|
||
|
|
class resourceManager{
|
||
|
|
|
||
|
|
constructor( engine ) {
|
||
|
|
this.engine = engine;
|
||
|
|
this.gl = engine.gl;
|
||
|
|
|
||
|
|
this.baseUrl = "http://localhost:4000/";
|
||
|
|
this.directory = "media/textures/";
|
||
|
|
|
||
|
|
|
||
|
|
this.numberOfModels = 0;
|
||
|
|
this.numberOfTextures = 0;
|
||
|
|
this.textureTotal = 0;
|
||
|
|
|
||
|
|
this.textures = [];
|
||
|
|
this.models = [];
|
||
|
|
this.shaders = [];
|
||
|
|
|
||
|
|
this.finishCallback;
|
||
|
|
this.loadingList = [];
|
||
|
|
|
||
|
|
this.fileCache = [];
|
||
|
|
this.programCashe = [];
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* add program
|
||
|
|
* @param {string} url
|
||
|
|
*/
|
||
|
|
loadShader( url ) {
|
||
|
|
var shader = new shader();
|
||
|
|
|
||
|
|
shader.createFomFile(url);
|
||
|
|
|
||
|
|
this.shaders.push(shader);
|
||
|
|
}
|
||
|
|
|
||
|
|
getShader( url ) {
|
||
|
|
var shaders = this.shaders;
|
||
|
|
for(var c = 0; c<shaders.length; c++) {
|
||
|
|
if(shaders[c].url == url) {
|
||
|
|
|
||
|
|
|
||
|
|
return shaders[c];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
console.log("shader "+ url +" not loaded ");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* add program
|
||
|
|
* @param {string} url
|
||
|
|
*/
|
||
|
|
addProgram( programInfo ) {
|
||
|
|
this.programCashe.push(programInfo);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* get shader program by url and array of pragma's
|
||
|
|
* @param {string} url
|
||
|
|
*/
|
||
|
|
getShaderProgram(url, pragmas, librarys) {
|
||
|
|
var programInfo = this.createShaderProgram(url, pragmas, librarys);
|
||
|
|
|
||
|
|
this.addProgram(programInfo);
|
||
|
|
|
||
|
|
return programInfo;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Create shader program based on shader url and pragma array
|
||
|
|
* @param {string} url
|
||
|
|
*/
|
||
|
|
createShaderProgram(url, pragmas, librarys) {
|
||
|
|
|
||
|
|
var rawShaderText = kepler.resources.loadTextFileSynchronous(url, pragmas);
|
||
|
|
var splitShader = rawShaderText.split("// #keplerEngine - Split");
|
||
|
|
|
||
|
|
var vertextShaderRawText = splitShader[0];
|
||
|
|
var fragmentShaderRawText = splitShader[1];
|
||
|
|
|
||
|
|
var vertexShader = this.gl.createShader(this.gl.VERTEX_SHADER);
|
||
|
|
var fragmentShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
|
||
|
|
|
||
|
|
for(var c = 0; c<librarys.length; c++) {
|
||
|
|
var lib = librarys[c];
|
||
|
|
|
||
|
|
if(lib.type == 0) {
|
||
|
|
vertextShaderRawText = lib.content + vertextShaderRawText;
|
||
|
|
} else {
|
||
|
|
var index = fragmentShaderRawText.indexOf("void main()");
|
||
|
|
|
||
|
|
fragmentShaderRawText = insertAt(fragmentShaderRawText, index, lib.content);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
rawShaderText = lib.content + rawShaderText;
|
||
|
|
}
|
||
|
|
|
||
|
|
//add pragma's
|
||
|
|
for(var c = 0; c<pragmas.length; c++) {
|
||
|
|
var currentPragma = pragmas[c];
|
||
|
|
|
||
|
|
switch (currentPragma.type) {
|
||
|
|
case "define":
|
||
|
|
|
||
|
|
var pragma = "#define " + currentPragma.name + " " + currentPragma.value + ' \n ';
|
||
|
|
|
||
|
|
fragmentShaderRawText = pragma + fragmentShaderRawText;
|
||
|
|
vertextShaderRawText = pragma + vertextShaderRawText;
|
||
|
|
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
var shader_version_3 = fragmentShaderRawText.includes("#version 300 es");
|
||
|
|
|
||
|
|
|
||
|
|
if(shader_version_3) {
|
||
|
|
|
||
|
|
|
||
|
|
fragmentShaderRawText = fragmentShaderRawText.replace("#version 300 es",'');
|
||
|
|
fragmentShaderRawText = fragmentShaderRawText.replace("#version 300 es",'');
|
||
|
|
vertextShaderRawText = vertextShaderRawText.replace("#version 300 es",'');
|
||
|
|
vertextShaderRawText = vertextShaderRawText.replace("#version 300 es",'');
|
||
|
|
|
||
|
|
fragmentShaderRawText = "#version 300 es \n" + fragmentShaderRawText;
|
||
|
|
vertextShaderRawText = "#version 300 es \n" + vertextShaderRawText;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
//console.log(fragmentShaderRawText);
|
||
|
|
//console.log(vertextShaderRawText);
|
||
|
|
this.rawShader = fragmentShaderRawText + vertextShaderRawText;
|
||
|
|
|
||
|
|
this.gl.shaderSource(vertexShader, vertextShaderRawText);
|
||
|
|
this.gl.compileShader(vertexShader);
|
||
|
|
|
||
|
|
this.gl.shaderSource(fragmentShader, fragmentShaderRawText);
|
||
|
|
this.gl.compileShader(fragmentShader);
|
||
|
|
|
||
|
|
var program = this.gl.createProgram();
|
||
|
|
|
||
|
|
this.gl.attachShader(program, vertexShader);
|
||
|
|
this.gl.attachShader(program, fragmentShader);
|
||
|
|
|
||
|
|
if (!this.gl.getShaderParameter(vertexShader, this.gl.COMPILE_STATUS)) {
|
||
|
|
alert(this.gl.getShaderInfoLog(vertexShader));
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!this.gl.getShaderParameter(fragmentShader, this.gl.COMPILE_STATUS)) {
|
||
|
|
alert(this.gl.getShaderInfoLog(fragmentShader));
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
this.gl.linkProgram(program);
|
||
|
|
|
||
|
|
if (!this.gl.getProgramParameter(program, this.gl.LINK_STATUS)) {
|
||
|
|
alert("Could not initialise shaders");
|
||
|
|
}
|
||
|
|
|
||
|
|
this.gl.useProgram(program);
|
||
|
|
|
||
|
|
var programInfo = {};
|
||
|
|
|
||
|
|
programInfo.program = program;
|
||
|
|
programInfo.rawData = this.rawShader;
|
||
|
|
programInfo.vertextShaderRawText = vertextShaderRawText;
|
||
|
|
programInfo.vertexShader = vertexShader;
|
||
|
|
programInfo.fragmentShader = fragmentShader;
|
||
|
|
programInfo.url = url;
|
||
|
|
programInfo.pragmas = pragmas;
|
||
|
|
programInfo.librarys = librarys;
|
||
|
|
|
||
|
|
console.log('compiled shader: ', programInfo);
|
||
|
|
|
||
|
|
return programInfo;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
get_filesize(url, callback) {
|
||
|
|
var xhr = new XMLHttpRequest();
|
||
|
|
xhr.open("HEAD", url, true); // Notice "HEAD" instead of "GET",
|
||
|
|
// to get only the header
|
||
|
|
|
||
|
|
xhr.onreadystatechange = function(ev) {
|
||
|
|
|
||
|
|
if (this.readyState == this.DONE) {
|
||
|
|
|
||
|
|
console.log('ev', ev.target.responseURL);
|
||
|
|
var url = ev.target.responseURL;
|
||
|
|
var size = parseInt(ev.target.getResponseHeader("Content-Length"));
|
||
|
|
//this.engine.loader.add(url, size );
|
||
|
|
|
||
|
|
}
|
||
|
|
};
|
||
|
|
xhr.send();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* load url
|
||
|
|
* @param {string} url
|
||
|
|
*/
|
||
|
|
loadTextFileSynchronous(url) {
|
||
|
|
|
||
|
|
///this.get_filesize( url );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
var fileContent = this.engine.resources.getFile(url)
|
||
|
|
|
||
|
|
if(fileContent) {
|
||
|
|
return fileContent.data;
|
||
|
|
}
|
||
|
|
|
||
|
|
var request;
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
if (window.XMLHttpRequest) {
|
||
|
|
request = new XMLHttpRequest();
|
||
|
|
if (request.overrideMimeType) {
|
||
|
|
request.overrideMimeType('text/plain');
|
||
|
|
}
|
||
|
|
} else if (window.ActiveXObject) {
|
||
|
|
request = new ActiveXObject('MSXML2.XMLHTTP.3.0');
|
||
|
|
} else {
|
||
|
|
throw 'XMLHttpRequest is disabled';
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
request.onreadystatechange = function (evt) {
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
//this.engine.loader.finish( evt.target.responseURL );
|
||
|
|
|
||
|
|
};
|
||
|
|
|
||
|
|
request.open('GET', this.baseUrl + url, false);
|
||
|
|
|
||
|
|
|
||
|
|
request.send();
|
||
|
|
|
||
|
|
if (request.readyState != 4) {
|
||
|
|
throw error;
|
||
|
|
}
|
||
|
|
|
||
|
|
var data = request.responseText;
|
||
|
|
|
||
|
|
if(!fileContent) {
|
||
|
|
//this.get_filesize( url );
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
this.addFile(data, url);
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
return data;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Add file
|
||
|
|
* @param {string} date (Filedata)
|
||
|
|
* @param {string} url
|
||
|
|
*/
|
||
|
|
addFile(data, url) {
|
||
|
|
var file = {};
|
||
|
|
|
||
|
|
file.data = data;
|
||
|
|
file.url = url;
|
||
|
|
|
||
|
|
this.fileCache.push(file);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get file
|
||
|
|
* @param {string} url
|
||
|
|
*/
|
||
|
|
getFile(url) {
|
||
|
|
for(var c = 0; c<this.fileCache.length; c++) {
|
||
|
|
var file = this.fileCache[c];
|
||
|
|
if(file.url == url)
|
||
|
|
return file;
|
||
|
|
}
|
||
|
|
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Add Texture
|
||
|
|
* @param {string} address
|
||
|
|
* @param {string} name
|
||
|
|
* @param {boolean} direct
|
||
|
|
*/
|
||
|
|
addTexture(adress, name, direct) {
|
||
|
|
|
||
|
|
this.numberOfTextures++;
|
||
|
|
this.textureTotal++;
|
||
|
|
|
||
|
|
var texture = {};
|
||
|
|
|
||
|
|
texture.adress = adress;
|
||
|
|
texture.name = name;
|
||
|
|
texture.loaded = false;
|
||
|
|
|
||
|
|
this.loadingList.push(texture);
|
||
|
|
|
||
|
|
if(direct)
|
||
|
|
this.loadNextTexture(adress, name);
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Load next texture
|
||
|
|
*/
|
||
|
|
loadNextTexture() {
|
||
|
|
|
||
|
|
|
||
|
|
if(this.loadingList.length > 0) {
|
||
|
|
var currentTexture = this.loadingList.pop();
|
||
|
|
this.loadTexture(currentTexture.adress, currentTexture.name);
|
||
|
|
}
|
||
|
|
|
||
|
|
for(var c = 0; c<this.loadingList.length; c++) {
|
||
|
|
//var currentTexture = this.loadingList.pop();
|
||
|
|
//this.loadTexture(currentTexture.adress, currentTexture.name);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Load Texture
|
||
|
|
* @param {string} url
|
||
|
|
* @param {string} name
|
||
|
|
* @param {string} force
|
||
|
|
*/
|
||
|
|
loadTexture(url, name, force){
|
||
|
|
var parts = url.split('.');
|
||
|
|
var extension = parts[parts.length-1];
|
||
|
|
|
||
|
|
//this.engine.setLoadingText("loading texture: " + url);
|
||
|
|
|
||
|
|
// if texture is compressed
|
||
|
|
if(extension == 'dds') {
|
||
|
|
|
||
|
|
var image = loadDDSTexture(url, name, function(texture, name, url){
|
||
|
|
|
||
|
|
//var texture = this.engine.textureFromDDS( mipmaps );
|
||
|
|
texture.name = name;
|
||
|
|
texture.url = url;
|
||
|
|
|
||
|
|
this.engine.resources.textures.push(texture);
|
||
|
|
this.engine.resources.loadNextTexture();
|
||
|
|
this.engine.resources.CheckIfAllObjectsTexturesLoaded(texture);
|
||
|
|
|
||
|
|
});
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
//this.get_filesize( url );
|
||
|
|
|
||
|
|
var image = new Image();
|
||
|
|
|
||
|
|
image.engine = this.engine;
|
||
|
|
|
||
|
|
|
||
|
|
image.onload = function(a) {
|
||
|
|
|
||
|
|
//var texture = this.engine.textureFromImage( this, this.width, this.height);
|
||
|
|
var texture = {};
|
||
|
|
texture.image = this;
|
||
|
|
texture.width = this.width;
|
||
|
|
texture.height = this.height;
|
||
|
|
texture.name = this.name;
|
||
|
|
texture.url = this.relativeSrc;
|
||
|
|
|
||
|
|
//updateLoadingBarTexture(this.engine.resources.textureTotal,this.engine.resources.textures.length);
|
||
|
|
|
||
|
|
this.engine.resources.textures.push(texture);
|
||
|
|
|
||
|
|
|
||
|
|
this.engine.resources.loadNextTexture();
|
||
|
|
this.engine.resources.CheckIfAllObjectsTexturesLoaded(texture);
|
||
|
|
//this.engine.loader.finish( image.src );
|
||
|
|
}
|
||
|
|
|
||
|
|
image.onerror = function (a) {
|
||
|
|
|
||
|
|
this.engine.resources.loadNextTexture();
|
||
|
|
this.engine.resources.CheckIfAllObjectsTexturesLoaded();
|
||
|
|
}
|
||
|
|
|
||
|
|
image.name = name;
|
||
|
|
image.src = this.baseUrl + url;
|
||
|
|
image.relativeSrc = url;
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
hasExtension( name ){
|
||
|
|
|
||
|
|
var numOfParts = name.split(".").length;
|
||
|
|
|
||
|
|
if(numOfParts > 1) {
|
||
|
|
return true;
|
||
|
|
} else {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get texture by name
|
||
|
|
* @param {String} name
|
||
|
|
*/
|
||
|
|
getTexture( name ) {
|
||
|
|
|
||
|
|
if(this.hasExtension(name)) {
|
||
|
|
|
||
|
|
var url = name;
|
||
|
|
|
||
|
|
this.addTexture(this.directory + url, name);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
for(var c = 0;c<this.loadingList.length; c++) {
|
||
|
|
if(this.loadingList[c].name == name){
|
||
|
|
|
||
|
|
return this.loadingList[c];
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return false;
|
||
|
|
|
||
|
|
};
|
||
|
|
/**
|
||
|
|
* Get texture by name
|
||
|
|
* @param {String} name
|
||
|
|
*/
|
||
|
|
getLoadedTexture( name, viewport ) {
|
||
|
|
|
||
|
|
for(var c = 0;c<this.textures.length; c++) {
|
||
|
|
if(this.textures[c].name == name){
|
||
|
|
|
||
|
|
var textureInfo = this.textures[c];
|
||
|
|
|
||
|
|
var texture = this.engine.textureFromImage( textureInfo.image, viewport );
|
||
|
|
return texture;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return false;
|
||
|
|
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Check if all objects are loaded
|
||
|
|
*/
|
||
|
|
CheckIfAllObjectsTexturesLoaded() {
|
||
|
|
this.numberOfTextures--;
|
||
|
|
|
||
|
|
if( this.numberOfTextures == 0 ) {
|
||
|
|
this.finishCallback();
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* copy a array buffer
|
||
|
|
* @param {array} source
|
||
|
|
* @param {array} destination
|
||
|
|
* @param {int} byteofffset
|
||
|
|
* @param {int} number of bytes
|
||
|
|
*/
|
||
|
|
arrayBufferCopy(src, dst, dstByteOffset, numBytes) {
|
||
|
|
var dst32Offset = dstByteOffset / 4,
|
||
|
|
tail = (numBytes % 4),
|
||
|
|
src32 = new Uint32Array(src.buffer, 0, (numBytes - tail) / 4),
|
||
|
|
dst32 = new Uint32Array(dst.buffer),
|
||
|
|
i;
|
||
|
|
|
||
|
|
for (i = 0; i < src32.length; i++) {
|
||
|
|
dst32[dst32Offset + i] = src32[i];
|
||
|
|
}
|
||
|
|
for (i = numBytes - tail; i < numBytes; i++) {
|
||
|
|
dst[dstByteOffset + i] = src[i];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* load dds texture
|
||
|
|
* @param {string} source
|
||
|
|
* @param {string} name
|
||
|
|
* @param {function} callback
|
||
|
|
*/
|
||
|
|
loadDDSTexture(src, name, callback) {
|
||
|
|
|
||
|
|
loadDDSTextureEx(src, name, texture, true, callback);
|
||
|
|
|
||
|
|
return texture;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* load dds textureEx
|
||
|
|
* @param {string} url
|
||
|
|
* @param {string} name
|
||
|
|
* @param {textureObject} texture
|
||
|
|
* @param {boolean} loadMipmaps
|
||
|
|
* @param {function} callback
|
||
|
|
*/
|
||
|
|
loadDDSTextureEx( url, name, texture, loadMipmaps, callback) {
|
||
|
|
var xhr = new XMLHttpRequest();
|
||
|
|
|
||
|
|
xhr.open('GET', url, true);
|
||
|
|
xhr.responseType = "arraybuffer";
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
xhr.onload = function (){
|
||
|
|
|
||
|
|
if(this.status == 200) {
|
||
|
|
var mipmaps = uploadDDSLevels(this.engine.extensions.textureCompression, this.response, loadMipmaps);
|
||
|
|
|
||
|
|
texture = new texture();
|
||
|
|
|
||
|
|
texture.mipmaps = mipmaps;
|
||
|
|
texture.dataType = 'COMPRESSED_RGBA';
|
||
|
|
}
|
||
|
|
|
||
|
|
if(callback) {
|
||
|
|
callback(texture, name, url);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
xhr.send(null);
|
||
|
|
|
||
|
|
return texture;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Upload DDS Levels
|
||
|
|
* @param {string} ext
|
||
|
|
* @param {arrayBuffer} arrayBuffer
|
||
|
|
* @param {boolean} loadMipmaps
|
||
|
|
* @param {texture} texture
|
||
|
|
*/
|
||
|
|
uploadDDSLevels(ext, arrayBuffer, loadMipmaps, texture) {
|
||
|
|
|
||
|
|
var DDS_MAGIC = 0x20534444;
|
||
|
|
|
||
|
|
var DDSD_CAPS = 0x1,
|
||
|
|
DDSD_HEIGHT = 0x2,
|
||
|
|
DDSD_WIDTH = 0x4,
|
||
|
|
DDSD_PITCH = 0x8,
|
||
|
|
DDSD_PIXELFORMAT = 0x1000,
|
||
|
|
DDSD_MIPMAPCOUNT = 0x20000,
|
||
|
|
DDSD_LINEARSIZE = 0x80000,
|
||
|
|
DDSD_DEPTH = 0x800000;
|
||
|
|
|
||
|
|
var DDSCAPS_COMPLEX = 0x8,
|
||
|
|
DDSCAPS_MIPMAP = 0x400000,
|
||
|
|
DDSCAPS_TEXTURE = 0x1000;
|
||
|
|
|
||
|
|
var DDSCAPS2_CUBEMAP = 0x200,
|
||
|
|
DDSCAPS2_CUBEMAP_POSITIVEX = 0x400,
|
||
|
|
DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800,
|
||
|
|
DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000,
|
||
|
|
DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000,
|
||
|
|
DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000,
|
||
|
|
DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000,
|
||
|
|
DDSCAPS2_VOLUME = 0x200000;
|
||
|
|
|
||
|
|
var DDPF_ALPHAPIXELS = 0x1,
|
||
|
|
DDPF_ALPHA = 0x2,
|
||
|
|
DDPF_FOURCC = 0x4,
|
||
|
|
DDPF_RGB = 0x40,
|
||
|
|
DDPF_YUV = 0x200,
|
||
|
|
DDPF_LUMINANCE = 0x20000;
|
||
|
|
|
||
|
|
function FourCCToInt32(value) {
|
||
|
|
return value.charCodeAt(0) +
|
||
|
|
(value.charCodeAt(1) << 8) +
|
||
|
|
(value.charCodeAt(2) << 16) +
|
||
|
|
(value.charCodeAt(3) << 24);
|
||
|
|
}
|
||
|
|
|
||
|
|
function Int32ToFourCC(value) {
|
||
|
|
return String.fromCharCode(
|
||
|
|
value & 0xff,
|
||
|
|
(value >> 8) & 0xff,
|
||
|
|
(value >> 16) & 0xff,
|
||
|
|
(value >> 24) & 0xff
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
var FOURCC_DXT1 = FourCCToInt32("DXT1");
|
||
|
|
var FOURCC_DXT5 = FourCCToInt32("DXT5");
|
||
|
|
|
||
|
|
var headerLengthInt = 31; // The header length in 32 bit ints
|
||
|
|
|
||
|
|
// Offsets into the header array
|
||
|
|
var off_magic = 0;
|
||
|
|
|
||
|
|
var off_size = 1;
|
||
|
|
var off_flags = 2;
|
||
|
|
var off_height = 3;
|
||
|
|
var off_width = 4;
|
||
|
|
|
||
|
|
var off_mipmapCount = 7;
|
||
|
|
|
||
|
|
var off_pfFlags = 20;
|
||
|
|
var off_pfFourCC = 21;
|
||
|
|
|
||
|
|
|
||
|
|
var header = new Int32Array(arrayBuffer, 0, headerLengthInt),
|
||
|
|
fourCC, blockBytes, internalFormat,
|
||
|
|
width, height, dataLength, dataOffset,
|
||
|
|
byteArray, mipmapCount, i;
|
||
|
|
|
||
|
|
if(header[off_magic] != DDS_MAGIC) {
|
||
|
|
console.error("Invalid magic number in DDS header");
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(!header[off_pfFlags] & DDPF_FOURCC) {
|
||
|
|
console.error("Unsupported format, must contain a FourCC code");
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
fourCC = header[off_pfFourCC];
|
||
|
|
switch(fourCC) {
|
||
|
|
case FOURCC_DXT1:
|
||
|
|
blockBytes = 8;
|
||
|
|
internalFormat = ext.COMPRESSED_RGBA_S3TC_DXT1_EXT;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case FOURCC_DXT5:
|
||
|
|
blockBytes = 16;
|
||
|
|
internalFormat = ext.COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||
|
|
break;
|
||
|
|
|
||
|
|
default:
|
||
|
|
console.error("Unsupported FourCC code:", Int32ToFourCC(fourCC));
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
mipmapCount = 1;
|
||
|
|
if(header[off_flags] & DDSD_MIPMAPCOUNT && loadMipmaps !== false) {
|
||
|
|
mipmapCount = Math.max(1, header[off_mipmapCount]);
|
||
|
|
}
|
||
|
|
|
||
|
|
width = header[off_width];
|
||
|
|
height = header[off_height];
|
||
|
|
dataOffset = header[off_size] + 4;
|
||
|
|
|
||
|
|
var mipmaps = [];
|
||
|
|
|
||
|
|
for(i = 0; i < mipmapCount; ++i) {
|
||
|
|
var mipmap = {}; // createObject("mipmap");
|
||
|
|
|
||
|
|
mipmap.dataLength = Math.max( 4, width )/4 * Math.max( 4, height )/4 * blockBytes;
|
||
|
|
mipmap.byteArray = new Uint8Array(arrayBuffer, dataOffset, mipmap.dataLength);
|
||
|
|
mipmap.height = width;
|
||
|
|
mipmap.width = height;
|
||
|
|
mipmap.internalFormat = internalFormat;
|
||
|
|
|
||
|
|
mipmaps.push(mipmap);
|
||
|
|
|
||
|
|
dataOffset += dataLength;
|
||
|
|
|
||
|
|
width *= 0.5;
|
||
|
|
height *= 0.5;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
return mipmaps;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export {resourceManager as default};
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
var randomImage = new Uint8Array ( [255,0,255,255,0,143,255,255,62,0,255,255,0,3,255,255,0,0,255,255,0,162,255,255,180,180,255,255,0,0,255,255,255,0,255,255,24,0,255,255,249,55,255,255,0,0,255,255,190,170,255,255,253,31,255,255,172,188,255,255,254,16,255,255,141,0,255,255,219,0,255,255,0,126,255,255,0,0,255,255,27,254,255,255,219,130,255,255,0,255,255,255,141,0,255,255,0,239,255,255,248,61,255,255,203,154,255,255,254,0,255,255,0,170,255,255,0,8,255,255,0,229,255,255,0,0,255,255,55,249,255,255,0,0,255,255,0,241,255,255,254,26,255,255,0,0,255,255,242,81,255,255,255,0,255,255,229,112,255,255,0,238,255,255,207,0,255,255,0,0,255,255,255,0,255,255,254,0,255,255,254,0,255,255,0,89,255,255,0,35,255,255,0,0,255,255,0,0,255,255,0,0,255,255,240,87,255,255,0,255,255,255,0,0,255,255,0,133,255,255,255,0,255,255,104,0,255,255,55,249,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,201,156,255,255,221,127,255,255,255,0,255,255,0,135,255,255,0,0,255,255,255,0,255,255,0,0,255,255,255,0,255,255,0,67,255,255,148,0,255,255,249,0,255,255,75,0,255,255,0,0,255,255,252,38,255,255,0,1,255,255,0,108,255,255,250,0,255,255,0,0,255,255,170,190,255,255,0,255,255,255,0,15,255,255,0,76,255,255,224,123,255,255,0,231,255,255,0,255,255,255,247,64,255,255,213,140,255,255,0,195,255,255,102,234,255,255,0,0,255,255,241,84,255,255,0,0,255,255,0,0,255,255,0,197,255,255,27,254,255,255,196,0,255,255,71,245,255,255,0,0,255,255,71,245,255,255,0,0,255,255,246,65,255,255,0,3,255,255,0,0,255,255,147,0,255,255,210,0,255,255,255,0,255,255,0,0,255,255,251,0,255,255,0,25,255,255,68,246,255,255,242,81,255,255,0,16,255,255,0,42,255,255,117,0,255,255,250,50,255,255,255,0,255,255,255,6,255,255,255,12,255,255,252,0,255,255,0,0,255,255,0,0,255,255,40,0,255,255,0,0,255,255,165,0,255,255,175,185,255,255,0,221,255,255,0,90,255,255,236,0,255,255,180,0,255,255,0,0,255,255,0,0,255,255,0,253,255,255,255,0,255,255,0,32,255,255,0,0,255,255,0,0,255,255,159,200,255,255,255,0,255,255,195,0,255,255,0,71,255,255,3,255,255,255,255,0,255,255,0,0,255,255,241,0,255,255,238,92,255,255,193,0,255,255,189,0,255,255,0,245,255,255,0,0,255,255,171,189,255,255,242,81,255,255,0,48,255,255,0,42,255,255,0,0,255,255,102,234,255,255,8,0,255,255,180,180,255,255,152,204,255,255,0,15,255,255,150,0,255,255,0,0,255,255,59,248,255,255,167,193,255,255,0,3,255,255,255,10,255,255,124,0,255,255,213,140,255,255,0,0,255,255,0,254,255,255,0,0,255,255,0,0,255,255,0,0,255,255,219,131,255,255,86,240,255,255,0,104,255,255,255,1,255,255,7,0,255,255,0,0,255,255,0,23,255,255,49,0,255,255,0,0,255,255,155,203,255,255,0,254,255,255,180,0,255,255,145,210,255,255,138,0,255,255,255,7,255,255,145,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,8,255,255,0,236,255,255,150,206,255,255,0,102,255,255,187,0,255,255,0,5,255,255,255,1,255,255,182,0,255,255,102,0,255,255,0,0,255,255,242,0,255,255,149,0,255,255,0,0,255,255,0,5,255,255,254,24,255,255,255,0,255,255,0,0,255,255,255,0,255,255,0,1,255,255,0,210,255,255,0,1,255,255,114,0,255,255,0,0,255,255,205,0,255,255,251,43,255,255,189,171,255,255,0,0,255,255,149,207,255,255,0,0,255,255,0,251,255,255,76,0,255,255,0,159,255,255,0,0,255,255,0,68,255,255,0,164,255,255,0,254,255,255,0,169,255,255,202,0,255,255,0,0,255,255,222,0,255,255,0,0,255,255,0,0,255,255,255,0,255,255,178,0,255,255,180,180,255,255,210,0,255,255,210,0,255,255,0,0,255,255,0,121,255,255,247,62,255,255,0,255,255,255,0,163,255,255,0,47,255,255,248,0,255,255,243,0,255,255,0,180,255,255,0,0,255,255,137,215,255,255,192,0,255,255,255,0,255,255,255,0,255,255,244,75,255,255,0,0,255,255,165,0,255,255,0,0,255,255,180,0,255,255,0,147,255,255,246,0,255,255,0,0,255,255,190,170,255,255,0,8,255,255,254,0,255,255,0,165,255,255,50,250,255,255,0,5,255,255,4,0,255,255,195,0,255,255,255,10,255,255,255,0,255,255,0,164,255,255,0,0,255,255,0,0,255,255,0,0,255,255,212,0,255,255,254,21,255,255,0,90,255,255,255,5,255,255,226,118,255,255,0,0,255,255,249,0,255,255,0,178,255,255,0,187,255,255,0,70,255,255,0,33,255,255,0,0,255,255,0,35,255,255,0,188,255,255,0,0,255,255,241,82,255,255,0,249,255,255,237,93,255,255,254,17,255,255,180,180,255,255,0,0,255,2
|
||
|
|
|
||
|
|
var randomImage2 = new Uint8Array ( [149,123,253,255, 126,3,96,255, 164,246,98,255, 154,177,13,255,
|
||
|
|
52,83,220,255, 1,142,142,255, 32,57,79,255, 48,159,32,255,
|
||
|
|
56,232,114,255, 177,216,203,255, 69,196,217,255, 240,165,81,255,
|
||
|
|
224,56,85,255, 232,89,189,255, 143,25,202,255, 117,73,12,255] );
|
||
|
|
|