Files
Kepler/engine/resourceManager.js

739 lines
70 KiB
JavaScript
Raw Normal View History

2025-11-17 17:18:43 +01:00
/**
* 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] );