meta-next
Version:
1,929 lines (1,869 loc) • 107 kB
JavaScript
"use strict";
(function(scope) {
scope.module = { exports: {} };
scope.modules = {};
scope.modulesCached = {};
scope.modulesPath = { };
if(scope.process) {
scope.process.env = { NODE_ENV: "dev" }
}
else
{
scope.process = {
env: {
NODE_ENV: "dev"
}
}
}
scope._inherits = function(a, b)
{
var protoA = a.prototype;
var proto = Object.create(b.prototype);
for(var key in protoA)
{
var param = Object.getOwnPropertyDescriptor(protoA, key);
if(param.get || param.set) {
Object.defineProperty(proto, key, param);
}
else {
proto[key] = protoA[key];
}
}
a.prototype = proto;
a.prototype.constructor = a;
a.__parent = b;
if(b.__inherit === undefined) {
b.__inherit = {};
}
b.__inherit[a.name] = a;
var parent = b.__parent;
while(parent)
{
parent.__inherit[a.name] = a;
parent = parent.__parent;
}
}
})(window || global);
"use strict";
(function() {
const listeners = {};
let str_fullscreen = null;
let str_fullscreenEnabled = null;
let str_fullscreenElement = null;
let str_onfullscreenchange = null;
let str_onfullscreenerror = null;
let str_exitFullscreen = null;
let str_requestFullscreen = null;
let str_hidden = null;
let str_visibilityChange = null;
let str_requestPointerLock = null;
let str_exitPointerLock = null;
let str_onpointerlockchange = null;
let str_pointerLockElement = null;
const Device = {
name: "Unknown",
version: "0",
versionBuffer: null,
vendor: "",
vendors: [ "", "webkit", "moz", "ms", "o" ],
supports: {},
mobile: false,
portrait: false,
visible: true,
pointerlock: false,
audioFormats: [],
backingStoreRatio: 1,
pointerLock: function(element) {
if(!Device.supports.pointerLock) {
return ;
}
if(element) {
element[str_requestPointerLock]();
}
else {
document[str_exitPointerLock]();
}
},
get pointerLockElement() {
if(!Device.supports.pointerLock) {
return null;
}
return document[str_pointerLockElement];
},
set fullscreen(element) {
if(Device.fullscreenEnabled) {
element[str_requestFullscreen]();
}
else {
console.warn("Device cannot use fullscreen right now.");
}
},
get fullscreen() {
if(Device.fullscreenEnabled) {
return document[str_fullscreen];
}
return false;
},
get fullscreenEnabled() {
if(Device.supports.fullscreen && document[str_fullscreenEnabled]) {
return true;
}
return false;
},
get fullscreenElement() {
if(!Device.fullscreenEnabled) {
return null;
}
return document[str_fullscreenElement];
},
fullscreenExit: function() {
if(Device.fullscreenEnabled) {
document[str_exitFullscreen]();
}
},
on: function(event, func) {
let buffer = listeners[event];
if(buffer) {
buffer.push(func);
}
else {
buffer = [ func ];
listeners[event] = buffer;
}
},
off: function(event, func) {
const buffer = listeners[event];
if(!buffer) {
return ;
}
const index = buffer.indexOf(func);
if(index === -1) {
return ;
}
buffer[index] = buffer[buffer.length - 1];
buffer.pop();
},
emit: function(event, arg) {
const buffer = listeners[event];
if(!buffer) {
return ;
}
for(let n = 0; n < buffer.length; n++) {
buffer[n](arg);
}
}
};
const load = function() {
checkBrowser();
checkMobileAgent();
checkCanvas();
checkWebGL();
checkBackingStoreRatio();
checkAudioFormats();
checkAudioAPI();
checkPageVisibility();
checkFullscreen();
checkConsoleCSS();
checkFileAPI();
checkFileSystemAPI();
checkPointerLock();
Device.supports.onloadedmetadata = (typeof window.onloadedmetadata === "object");
Device.supports.onkeyup = (typeof window.onkeyup === "object");
Device.supports.onkeydown = (typeof window.onkeydown === "object");
Device.portrait = (window.innerHeight > window.innerWidth);
polyfill();
addEventListeners();
};
const checkBrowser = function() {
const regexps = {
"Chrome": [ /Chrome\/(\S+)/ ],
"Firefox": [ /Firefox\/(\S+)/ ],
"MSIE": [ /MSIE (\S+);/ ],
"Opera": [ /OPR\/(\S+)/, /Opera\/.*?Version\/(\S+)/, /Opera\/(\S+)/ ],
"Safari": [ /Version\/(\S+).*?Safari\// ]
};
const userAgent = navigator.userAgent;
let name, currRegexp, match;
let numElements = 2;
for(name in regexps) {
while(currRegexp = regexps[name].shift()) {
if(match = userAgent.match(currRegexp)) {
Device.version = match[1].match(new RegExp(("[^.]+(?:\.[^.]+){0," + --numElements) + "}"))[0];
Device.name = name;
const versionBuffer = Device.version.split(".");
const versionBufferLength = versionBuffer.length;
Device.versionBuffer = new Array(versionBufferLength);
for(let n = 0; n < versionBufferLength; n++) {
Device.versionBuffer[n] = parseInt(versionBuffer[n]);
}
break;
}
}
}
if((Device.versionBuffer === null) || (Device.name === "unknown")) {
console.warn("(Device) Could not detect browser.");
}
else {
if(((Device.name === "Chrome") || (Device.name === "Safari")) || (Device.name === "Opera")) {
Device.vendor = "webkit";
}
else if(Device.name === "Firefox") {
Device.vendor = "moz";
}
else if(Device.name === "MSIE") {
Device.vendor = "ms";
}
}
};
const checkMobileAgent = function() {
Device.mobile = (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i).test(navigator.userAgent);
};
const checkBackingStoreRatio = function() {
if(!Device.supports.canvas) {
return ;
}
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
if(ctx.backingStorePixelRatio !== undefined) {
Device.backingStoreRatio = ctx.backingStorePixelRatio;
}
else if(ctx[Device.vendor + "BackingStorePixelRatio"]) {
Device.backingStoreRatio = ctx[Device.vendor + "BackingStorePixelRatio"];
}
};
const checkCanvas = function() {
Device.supports.canvas = !!window.CanvasRenderingContext2D;
};
const checkWebGL = function() {
const canvas = document.createElement("canvas");
const context = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
Device.supports.webgl = !!context;
};
const checkAudioFormats = function() {
const audio = document.createElement("audio");
if(audio.canPlayType("audio/mp4")) {
Device.audioFormats.push("m4a");
}
if(audio.canPlayType("audio/ogg")) {
Device.audioFormats.push("ogg");
}
if(audio.canPlayType("audio/mpeg")) {
Device.audioFormats.push("mp3");
}
if(audio.canPlayType("audio/wav")) {
Device.audioFormats.push("wav");
}
};
const checkAudioAPI = function() {
if(!window.AudioContext) {
window.AudioContext = ((window.webkitAudioContext || window.mozAudioContext) || window.oAudioContext) || window.msAudioContext;
}
if(window.AudioContext) {
Device.supports.audioAPI = true;
}
};
const checkPageVisibility = function() {
if(document.hidden !== undefined) {
str_hidden = "hidden";
str_visibilityChange = "visibilitychange";
Device.supports.pageVisibility = true;
}
else if(document[Device.vendor + "Hidden"] !== undefined) {
str_hidden = (Device.vendor + "Hidden");
str_visibilityChange = (Device.vendor + "visibilitychange");
Device.supports.pageVisibility = true;
}
else {
Device.supports.pageVisibility = false;
}
};
const checkFullscreen = function() {
if(document.fullscreen !== undefined) {
str_fullscreen = "fullscreen";
}
else if(document[Device.vendor + "IsFullScreen"] !== undefined) {
str_fullscreen = (Device.vendor + "IsFullScreen");
}
else if(document[Device.vendor + "Fullscreen"] !== undefined) {
str_fullscreen = (Device.vendor + "Fullscreen");
}
else {
Device.supports.fullscreen = false;
return ;
}
Device.supports.fullscreen = true;
if(document.fullscreenEnabled !== undefined) {
str_fullscreenEnabled = "fullscreenEnabled";
}
else if(document[Device.vendor + "FullscreenEnabled"] !== undefined) {
str_fullscreenEnabled = (Device.vendor + "FullscreenEnabled");
}
if(document.fullscreenElement !== undefined) {
str_fullscreenElement = "fullscreenElement";
}
else if(document[Device.vendor + "FullscreenElement"] !== undefined) {
str_fullscreenElement = (Device.vendor + "FullscreenElement");
}
if(document.exitFullscreen !== undefined) {
str_exitFullscreen = "exitFullscreen";
}
else if(document[Device.vendor + "ExitFullscreen"] !== undefined) {
str_exitFullscreen = (Device.vendor + "ExitFullscreen");
}
if(Element.prototype.requestFullscreen !== undefined) {
str_requestFullscreen = "requestFullscreen";
}
else if(Element.prototype[Device.vendor + "RequestFullscreen"] !== undefined) {
str_requestFullscreen = (Device.vendor + "RequestFullscreen");
}
if(document.onfullscreenchange !== undefined) {
str_onfullscreenchange = "fullscreenchange";
}
else if(document[("on" + Device.vendor) + "fullscreenchange"] !== undefined) {
str_onfullscreenchange = (Device.vendor + "fullscreenchange");
}
if(document.onfullscreenerror !== undefined) {
str_onfullscreenerror = "fullscreenerror";
}
else if(document[("on" + Device.vendor) + "fullscreenerror"] !== undefined) {
str_onfullscreenerror = (Device.vendor + "fullscreenerror");
}
};
const checkConsoleCSS = function() {
if(!Device.mobile && ((Device.name === "Chrome") || (Device.name === "Opera"))) {
Device.supports.consoleCSS = true;
}
else {
Device.supports.consoleCSS = false;
}
};
const checkFileAPI = function() {
if(((window.File && window.FileReader) && window.FileList) && window.Blob) {
Device.supports.fileAPI = true;
}
else {
Device.supports.fileAPI = false;
}
};
const checkFileSystemAPI = function() {
if(!window.requestFileSystem) {
window.requestFileSystem = ((window.webkitRequestFileSystem || window.mozRequestFileSystem) || window.oRequestFileSystem) || window.msRequestFileSystem;
}
if(window.requestFileSystem) {
Device.supports.fileSystemAPI = true;
}
};
const polyfill = function() {
if(!Number.MAX_SAFE_INTEGER) {
Number.MAX_SAFE_INTEGER = 9007199254740991;
}
supportConsole();
supportRequestAnimFrame();
supportPerformanceNow();
};
const supportConsole = function() {
if(!window.console) {
window.console = {
log: function() {},
warn: function() {},
error: function() {}
};
}
};
const supportRequestAnimFrame = function() {
if(!window.requestAnimationFrame) {
window.requestAnimationFrame = (function() {
return (((window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame) || window.oRequestAnimationFrame) || window.msRequestAnimationFrame) || function(callback, element) {
window.setTimeout(callback, 1000 / 60);
};
}) ();
}
};
const supportPerformanceNow = function() {
if(window.performance === undefined) {
window.performance = {};
}
if(window.performance.now === undefined) {
window.performance.now = Date.now;
}
};
const addEventListeners = function() {
window.addEventListener("resize", onResize, false);
window.addEventListener("orientationchange", onOrientationChange, false);
if(Device.supports.pageVisibility) {
Device.visible = !document[str_hidden];
document.addEventListener(str_visibilityChange, onVisibilityChange);
}
window.addEventListener("focus", onFocus);
window.addEventListener("blur", onBlur);
if(Device.supports.fullscreen) {
document.addEventListener(str_onfullscreenchange, onFullscreenChange);
document.addEventListener(str_onfullscreenerror, onFullscreenError);
}
if(Device.supports.pointerLock) {
document.addEventListener(str_onpointerlockchange, onPointerLockChange);
}
};
const onResize = function(domEvent) {
Device.emit("resize", window);
if(window.innerHeight > window.innerWidth) {
if(!Device.portrait) {
Device.portrait = true;
Device.emit("portrait", true);
}
}
else if(Device.portrait) {
Device.portrait = false;
Device.emit("portrait", false);
}
};
const onOrientationChange = function(domEvent) {
Device.emit("resize", window);
if(window.innerHeight > window.innerWidth) {
Device.portrait = true;
Device.emit("portrait", true);
}
else {
Device.portrait = false;
Device.emit("portrait", false);
}
};
const onFocus = function(domEvent) {
Device.visible = true;
Device.emit("visibile", true);
};
const onBlur = function(domEvent) {
Device.visible = false;
Device.emit("visibile", false);
};
const onVisibilityChange = function(domEvent) {
Device.visible = !document[str_hidden];
Device.emit("visibile", Device.visible);
};
const onFullscreenChange = function(domEvent) {
Device.emit("fullscreen", Device.fullscreenElement);
};
const onFullscreenError = function(domEvent) {
console.error("Fullscreen denied.");
};
const onPointerLockChange = function(domEvent) {};
const checkPointerLock = function() {
const canvas = HTMLCanvasElement.prototype;
if(canvas.requestPointerLock !== undefined) {
str_requestPointerLock = "requestPointerLock";
}
else if(document[Device.vendor + "RequestPointerLock"] !== undefined) {
str_requestPointerLock = (Device.vendor + "RequestPointerLock");
}
else {
return ;
}
Device.supports.pointerLock = true;
if(document.exitPointerLock !== undefined) {
str_exitPointerLock = "exitPointerLock";
}
else if(document[Device.vendor + "ExitPointerLock"] !== undefined) {
str_exitPointerLock = (Device.vendor + "ExitPointerLock");
}
if(document.onpointerlockchange !== undefined) {
str_onpointerlockchange = "pointerlockchange";
}
else if(document[("on" + Device.vendor) + "pointerlockchange"] !== undefined) {
str_onpointerlockchange = (Device.vendor + "pointerlockchange");
}
if(document.pointerLockElement !== undefined) {
str_pointerLockElement = "pointerLockElement";
}
else if(document[Device.vendor + "PointerLockElement"] !== undefined) {
str_pointerLockElement = (Device.vendor + "PointerLockElement");
}
};
load();
modules[1] = Device;
})();
//# sourceURL=src/Device.js
"use strict";
(function() {
const watchers = {};
const Engine = {
app: null,
container: null,
canvas: null,
gl: null,
window: null,
camera: null,
defaultSettings: {
width: 0,
height: 0,
antialias: true,
upscale: true
},
on: function(event, func) {
const buffer = watchers[event];
if(!buffer) {
watchers[event] = [ func ];
}
else {
buffer.push(func);
}
},
off: function(event, func) {
const buffer = watchers[event];
if(!buffer) {
return ;
}
const index = buffer.indexOf(func);
if(index === -1) {
return ;
}
buffer[index] = buffer[buffer.length - 1];
buffer.pop();
},
emit: function(event) {
const buffer = watchers[event];
if(!buffer) {
return ;
}
for(let n = 0; n < buffer.length; n++) {
buffer[n]();
}
}
};
modules[2] = Engine;
})();
//# sourceURL=src/Engine.js
"use strict";
(function() {
let timerId = 0;
function Time() {
this.delta = 0;
this.deltaF = 0;
this.deltaRender = 0;
this.deltaRenderF = 0;
this.maxDelta = 250;
this.scale = 1;
this.fps = 0;
this.current = Date.now();
this.prev = this.current;
this.currentRender = this.current;
this.prevRender = this.current;
this.accumulator = 0;
this.frameIndex = 0;
this.updateFreq = (1000 / 10);
this.timers = [];
this.timersRemove = [];
this.paused = false;
this.updating = false;
this._fpsCurrent = this.current;
this._fps = 0;
}
Time.prototype = {
start: function() {
this.current = Date.now();
if(this.paused) {
this.delta = 0;
this.deltaF = 0;
}
else {
this.delta = (this.current - this.prev);
if(this.delta > this.maxDelta) {
this.delta = this.maxDelta;
}
this.delta *= this.scale;
this.deltaF = (this.delta / 1000);
}
this.updating = true;
for(let n = 0; n < this.timers.length; n++) {
this.timers[n].update(this.delta);
}
this.updating = false;
if(this.timersRemove.length > 0) {
for(let n = 0; n < this.timersRemove.length; n++) {
const timerA = this.timersRemove[n];
const timerB = this.timers[this.timers.length - 1];
timerB.__index = timerA.__index;
timerA.__index = -1;
this.timers[timerB.__index] = timerB;
this.timers.pop();
}
this.timersRemove.length = 0;
}
},
end: function() {
this.prev = this.current;
},
startRender: function() {
this.frameIndex++;
this.currentRender = Date.now();
if(this.paused) {
this.deltaRender = 0;
this.deltaRenderF = 0;
}
else {
this.deltaRender = (this.currentRender - this.prevRender);
this.deltaRender *= this.scale;
this.deltaRenderF = (this.deltaRender / 1000);
this.accumulator += this.deltaRender;
}
if((this.currentRender - this._fpsCurrent) >= 1000) {
this._fpsCurrent = this.currentRender;
this.fps = this._fps;
this._fps = 0;
}
},
endRender: function() {
this._fps++;
this.prevRender = this.currentRender;
},
timer: function(func, tDelta, numTimes) {
if(!func || !tDelta) {
console.warn("(Timer.create) Invalid params passed");
return null;
}
const timer = new Timer(this, func, tDelta, numTimes);
timer.play();
return timer;
}
};
function Timer(time, func, tDelta, numTimes) {
this.time = time;
this.id = timerId++;
this.func = func;
this.tDelta = tDelta;
this.numTimes = (numTimes !== undefined ? numTimes : -1);
this.initNumTimes = this.numTimes;
this.onDone = null;
this.tAccumulator = 0;
this.tStart = Date.now();
this.paused = false;
this.__index = -1;
}
Timer.prototype = {
play: function() {
if(this.__index !== -1) {
return ;
}
this.__index = (this.time.timers.push(this) - 1);
},
_stop: function() {
if(this.__index === -1) {
return ;
}
if(this.updating) {
this.time.timersRemove.push(this);
}
else {
const timers = this.time.timers;
const timer = timers[timers.length - 1];
timer.__index = this.__index;
timers[this.__index] = timer;
timers.pop();
}
this.__index = -1;
},
stop: function() {
this._stop();
this.paused = false;
this.numTimes = 0;
if(this.onDone) {
this.onDone(this);
}
},
pause: function() {
this._stop();
this.paused = true;
},
resume: function() {
if(!this.paused) {
return ;
}
this.paused = false;
this.tStart = Date.now();
},
reset: function() {
this.tAccumulator = 0;
this.numTimes = this.initNumTimes;
this.paused = false;
this.play();
},
update: function(tDelta) {
this.tAccumulator += tDelta;
while(this.tAccumulator >= this.tDelta) {
this.tAccumulator -= this.tDelta;
if(this.numTimes !== 0) {
this.func(this);
}
this.tStart += this.tDelta;
if(this.numTimes !== -1) {
this.numTimes--;
if(this.numTimes <= 0) {
this.stop();
}
}
}
}
};
const instance = new Time();
modules[4] = instance;
})();
//# sourceURL=src/Time.js
"use strict";
(function() {
function Resources() {
this.resources = {};
this.watchers = {};
this.loading = false;
this.numToLoad = 0;
}
Resources.prototype = {
load: function(config) {
const classes = this.Resource.__inherit;
for(let key in config) {
if(this.resources[key]) {
console.warn("(Resources.load) There is already resource with id: " + key + "");
continue;
}
const itemConfig = config[key];
const cls = classes[itemConfig.type];
if(!cls) {
console.warn("(Resources.load) No such resoruce type registered: " + itemConfig.type + "");
continue;
}
const resource = new cls(itemConfig);
this.resources[key] = resource;
}
},
resourceLoading: function(resource) {
if(this.numToLoad === 0) {
this.loading = true;
this.emit("loading");
}
this.numToLoad++;
},
resourceLoaded: function(resource) {
this.numToLoad--;
if(this.numToLoad === 0) {
this.loading = false;
this.emit("ready");
}
},
get: function(id) {
const resource = this.resources[id];
return resource || null;
},
on: function(event, func) {
const buffer = this.watchers[event];
if(buffer) {
buffer.push(func);
}
else {
this.watchers[event] = [ func ];
}
},
off: function(event, func) {
const buffer = this.watchers[event];
if(!buffer) {
return ;
}
const index = buffer.indexOf(func);
if(index === -1) {
return ;
}
buffer[index] = buffer[buffer.length - 1];
buffer.pop();
},
emit: function(event) {
const buffer = this.watchers[event];
if(!buffer) {
return ;
}
for(let n = 0; n < buffer.length; n++) {
buffer[n]();
}
}
};
const instance = new Resources();
modules[5] = instance;
})();
//# sourceURL=src/resources/Resources.js
"use strict";
(function() {
var Engine = modules[2];
var Device = modules[1];
var Time = modules[4];
var Resources = modules[5];
function EngineWindow() {
this.width = 0;
this.height = 0;
this.offsetLeft = 0;
this.offsetTop = 0;
this.ratio = 1;
this.scaleX = 1;
this.scaleY = 1;
this._cursor = "auto";
}
EngineWindow.prototype = {
create: function() {
const container = document.createElement("div");
container.style.cssText = "position:absolute; width:100%; height:100%; background: #222; display:flex; align-items:center; justify-content:center;";
const canvas = document.createElement("canvas");
const gl = canvas.getContext("webgl", {
antialias: Engine.settings.antialias
});
if(!gl) {
console.error("Unable to initialize WebGL. Your browser or machine may not support it.");
return ;
}
container.appendChild(canvas);
document.body.appendChild(container);
Engine.container = container;
Engine.canvas = canvas;
Engine.gl = gl;
this.setupWebGL();
Engine.emit("setup");
if(Engine.app.setup) {
Engine.app.setup();
}
this.updateScreenSize();
Device.on("resize", this.updateScreenSize.bind(this));
this.readyFunc = this.ready.bind(this);
this.updateFunc = this.update.bind(this);
this.renderFunc = this.render.bind(this);
Resources.on("ready", this.readyFunc);
if(!Resources.loading) {
this.ready();
}
},
setupWebGL: function() {
const gl = Engine.gl;
gl.clearColor(0, 0, 0, 1);
gl.clearDepth(1);
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);
gl.enable(gl.BLEND);
gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
},
updateScreenSize: function() {
const settings = Engine.settings;
const container = Engine.container;
const canvas = Engine.canvas;
const targetWidth = settings.width ? settings.width : window.innerWidth;
const targetHeight = settings.height ? settings.height : window.innerHeight;
const widthRatio = window.innerWidth / targetWidth;
const heightRatio = window.innerHeight / targetHeight;
const currRatio = widthRatio < heightRatio ? widthRatio : heightRatio;
let ratio;
if(settings.upscale) {
ratio = currRatio;
}
else {
ratio = (currRatio > 1 ? 1 : currRatio);
}
this.width = targetWidth;
this.height = targetHeight;
canvas.width = targetWidth;
canvas.height = targetHeight;
canvas.style.width = "" + targetWidth * ratio + "px";
canvas.style.height = "" + targetHeight * ratio + "px";
Engine.gl.viewport(0, 0, targetWidth, targetHeight);
this.updateOffset();
Engine.camera.updateProjectionTransform();
},
updateOffset: function() {
this.offsetLeft = 0;
this.offsetTop = 0;
let element = Engine.container;
if(element.offsetParent) {
do {
this.offsetLeft += element.offsetLeft;
this.offsetTop += element.offsetTop;
} while(element = element.offsetParent)
}
let rect = Engine.container.getBoundingClientRect();
this.offsetLeft += rect.left;
this.offsetTop += rect.top;
rect = Engine.canvas.getBoundingClientRect();
this.offsetLeft += rect.left;
this.offsetTop += rect.top;
},
ready: function() {
Resources.off("ready", this.readyFunc);
if(Engine.app.ready) {
Engine.app.ready();
}
this.render();
setInterval(this.updateFunc, 1 / 60);
},
update: function() {
Time.start();
if(Engine.app.update) {
Engine.app.update(Time.deltaF);
}
Time.end();
},
render: function() {
const gl = Engine.gl;
Time.startRender();
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
if(Engine.app.render) {
Engine.app.render();
}
Time.endRender();
requestAnimationFrame(this.renderFunc);
},
background: function(r, g, b) {
const weight = 1 / 255;
Engine.gl.clearColor(r * weight, g * weight, b * weight, 1);
},
set cursor(type) {
if(this._cursor === type) {
return ;
}
this._cursor = type;
document.body.style.cursor = type;
},
get cursor() {
return this._cursor;
}
};
modules[3] = EngineWindow;
})();
//# sourceURL=src/EngineWindow.js
"use strict";
(function() {
const pools = {};
const create = (cls) => {
const buffer = pools[cls.name];
if(buffer && (buffer.length > 0)) {
return buffer.pop();
}
const instance = new cls();
return instance;
};
const remove = (instance) => {
const buffer = pools[instance.constructor.name];
if(!buffer) {
pools[instance.constructor.name] = [ instance ];
}
else {
buffer = [ instance ];
}
};
modules[6] = { create: create, remove: remove };
})();
//# sourceURL=src/Pool.js
"use strict";
(function() {
const BUTTON_ENUM_OFFSET = 256;
const Key = {
BUTTON_ENUM_OFFSET: BUTTON_ENUM_OFFSET,
BACKSPACE: 8,
TAB: 9,
ENTER: 13,
SHIFT: 16,
ESC: 27,
SPACE: 32,
LEFT: 37,
UP: 38,
RIGHT: 39,
DOWN: 40,
DELETE: 46,
NUM_0: 48,
NUM_1: 49,
NUM_2: 50,
NUM_3: 51,
NUM_4: 52,
NUM_5: 53,
NUM_6: 54,
NUM_7: 55,
NUM_8: 56,
NUM_9: 57,
NUMPAD_0: 96,
NUMPAD_1: 97,
NUMPAD_2: 98,
NUMPAD_3: 99,
NUMPAD_4: 100,
NUMPAD_5: 101,
NUMPAD_6: 102,
NUMPAD_7: 103,
NUMPAD_8: 104,
NUMPAD_9: 105,
MULTIPLY: 106,
ADD: 107,
SUBTRACT: 109,
DECIMAL: 110,
DIVIDE: 111,
A: 65,
B: 66,
C: 67,
D: 68,
E: 69,
F: 70,
G: 71,
H: 72,
I: 73,
J: 74,
K: 75,
L: 76,
M: 77,
N: 78,
O: 79,
P: 80,
Q: 81,
R: 82,
S: 83,
T: 84,
U: 85,
V: 86,
W: 87,
X: 88,
Y: 89,
Z: 90,
SQUARE_BRACKET_LEFT: 91,
SQUARE_BRACKET_RIGHT: 91,
PARENTHESES_LEFT: 91,
PARENTHESES_RIGHT: 91,
BRACES_LEFT: 91,
BRACES_RIGHT: 92,
F1: 112,
F2: 113,
F3: 114,
F4: 115,
F5: 116,
F6: 117,
F7: 118,
F8: 119,
F9: 120,
F10: 121,
F11: 122,
F12: 123,
PLUS: 187,
MINUS: 189,
TILDE: 192,
APOSTROPHE: 222,
BUTTON_LEFT: 0 + BUTTON_ENUM_OFFSET,
BUTTON_MIDDLE: 1 + BUTTON_ENUM_OFFSET,
BUTTON_RIGHT: 2 + BUTTON_ENUM_OFFSET
};
modules[8] = Key;
})();
//# sourceURL=src/Key.js
"use strict";
(function() {
var Device = modules[1];
var Engine = modules[2];
var Key = modules[8];
const numKeys = 256;
const numInputs = 10;
const numTotalKeys = (numKeys + numInputs) + 1;
function Subscriber(owner, func) {
this.owner = owner;
this.func = func;
}
function Input() {
this.listeners = {};
this.ignoreKeys = {};
this.cmdKeys = {};
this.iframeKeys = {};
this.enable = true;
this.stickyKeys = false;
this.metaPressed = false;
this.firstInputEvent = true;
this.inputs = new Array(numTotalKeys);
this.touches = [];
Device.on("visible", (value) => {
if(!value) {
this.reset();
}
});
this.x = 0;
this.y = 0;
this.screenX = 0;
this.screenY = 0;
this.prevX = 0;
this.prevY = 0;
this.prevScreenX = 0;
this.prevScreenY = 0;
loadIgnoreKeys(this);
addEventListeners(this);
}
Input.prototype = {
handleKeyDown: function(domEvent) {
this.checkIgnoreKey(domEvent);
if(!this.enable) {
return ;
}
const keyCode = domEvent.keyCode;
if(this.stickyKeys && this.inputs[keyCode]) {
return ;
}
if(domEvent.keyIdentifier === "Meta") {
this.metaPressed = true;
}
else if(this.metaPressed) {
return ;
}
this.inputs[keyCode] = 1;
const inputEvent = new Input.Event();
inputEvent.domEvent = domEvent;
inputEvent.keyCode = keyCode;
this.emit("keydown", inputEvent);
},
handleKeyUp: function(domEvent) {
this.checkIgnoreKey(domEvent);
if(!this.enable) {
return ;
}
const keyCode = domEvent.keyCode;
this.metaPressed = false;
this.inputs[keyCode] = 0;
const inputEvent = new Input.Event();
inputEvent.domEvent = domEvent;
inputEvent.keyCode = keyCode;
this.emit("keyup", inputEvent);
},
handleMouseDown: function(domEvent) {
this.handleMouseEvent("down", domEvent);
},
handleMouseUp: function(domEvent) {
this.handleMouseEvent("up", domEvent);
},
handleMouseDblClick: function(domEvent) {
this.handleMouseEvent("dblclick", domEvent);
},
handleMouseMove: function(domEvent) {
if(document.activeElement === document.body) {
domEvent.preventDefault();
}
this.handleMouseEvent("move", domEvent);
},
handleMouseWheel: function(domEvent) {
if(document.activeElement === document.body) {
domEvent.preventDefault();
}
this.handleMouseEvent("wheel", domEvent);
},
handleMouseEvent: function(eventType, domEvent) {
if(!Engine.gl || (domEvent.target !== Engine.gl.canvas)) {
return ;
}
if(!this.enable) {
return ;
}
const wnd = Engine.window;
const camera = Engine.camera;
this.prevScreenX = this.screenX;
this.prevScreenY = this.screenY;
this.screenX = (((domEvent.pageX - wnd.offsetLeft) * wnd.scaleX) / wnd.ratio);
this.screenY = (((domEvent.pageY - wnd.offsetTop) * wnd.scaleY) / wnd.ratio);
this.prevX = this.x;
this.prevY = this.y;
this.x = ((((this.screenX * camera._scale.x) - camera.x) / wnd.ratio) | 0);
this.y = ((((this.screenY * camera._scale.y) - camera.y) / wnd.ratio) | 0);
const inputEvent = new Input.Event();
inputEvent.domEvent = domEvent;
inputEvent.screenX = this.screenX;
inputEvent.screenY = this.screenY;
inputEvent.x = this.x;
inputEvent.y = this.y;
switch(eventType) {
case "down":
case "dblclick":
case "up":
{
const keyCode = domEvent.button + Key.BUTTON_ENUM_OFFSET;
this.inputs[keyCode] = (eventType === "up" ? 0 : 1);
if(this.firstInputEvent) {
inputEvent.deltaX = 0;
inputEvent.deltaY = 0;
this.firstInputEvent = false;
}
else {
inputEvent.deltaX = (((this.prevScreenX - this.screenX) * camera.zoomRatio) / wnd.ratio);
inputEvent.deltaY = (((this.prevScreenY - this.screenY) * camera.zoomRatio) / wnd.ratio);
}
inputEvent.keyCode = keyCode;
} break;
case "move":
{
if(this.firstInputEvent) {
inputEvent.deltaX = 0;
inputEvent.deltaY = 0;
this.firstInputEvent = false;
}
else {
inputEvent.deltaX = ((-domEvent.movementX * camera.zoomRatio) / wnd.ratio);
inputEvent.deltaY = ((-domEvent.movementY * camera.zoomRatio) / wnd.ratio);
}
inputEvent.keyCode = 0;
} break;
case "wheel":
{
inputEvent.deltaX = Math.max(-1, Math.min(1, domEvent.wheelDelta || -domEvent.detail));
inputEvent.deltaY = inputEvent.deltaX;
inputEvent.keyCode = 0;
} break;
}
this.emit(eventType, inputEvent);
},
handleTouchDown: function(domEvent) {
this.handleTouchEvent(domEvent, "down");
},
handleTouchUp: function(domEvent) {
this.handleTouchEvent(domEvent, "up");
},
handleTouchMove: function(domEvent) {
this.handleTouchEvent(domEvent, "move");
},
handleTouchEvent: function(domEvent, eventType) {
if(!Engine.gl || (domEvent.target !== Engine.gl.canvas)) {
return ;
}
const wnd = Engine.window;
const camera = Engine.camera;
const changedTouches = domEvent.changedTouches;
for(let n = 0; n < changedTouches.length; n++) {
const touch = changedTouches[n];
let id;
switch(eventType) {
case "down":
id = this.touches.length;
this.touches.push(touch.identifier);
break;
case "up":
id = this.getTouchID(touch.identifier);
if(id === -1) {
continue;
};
this.touches.splice(id, 1);
break;
case "move":
id = this.getTouchID(touch.identifier);
break;
}
const screenX = (touch.pageX - wnd.offsetLeft) * wnd.scaleX;
const screenY = (touch.pageY - wnd.offsetTop) * wnd.scaleY;
const x = ((screenX * camera.zoomRatio) - camera.x) | 0;
const y = ((screenY * camera.zoomRatio) - camera.y) | 0;
const keyCode = id + Key.BUTTON_ENUM_OFFSET;
const inputEvent = new Input.Event();
inputEvent.domEvent = domEvent;
inputEvent.screenX = screenX;
inputEvent.screenY = screenY;
inputEvent.x = x;
inputEvent.y = y;
inputEvent.keyCode = keyCode;
if(id === 0) {
this.prevX = this.x;
this.prevY = this.y;
this.prevScreenX = this.screenX;
this.prevScreenY = this.screenY;
this.x = x;
this.y = y;
this.screenX = screenX;
this.screenY = screenY;
if(this.firstInputEvent) {
inputEvent.deltaX = 0;
inputEvent.deltaY = 0;
this.firstInputEvent = false;
}
else {
inputEvent.deltaX = (this.prevScreenX - this.screenX);
inputEvent.deltaY = (this.prevScreenY - this.screenY);
}
}
switch(eventType) {
case "down":
this.inputs[keyCode] = 1;
break;
case "up":
this.inputs[keyCode] = 0;
break;
}
this.emit(eventType, inputEvent);
}
},
pressed: function(keyCode) {
return this.inputs[keyCode];
},
on: function(event, func, owner) {
const sub = new Subscriber(owner, func);
let buffer = this.listeners[event];
if(buffer) {
buffer.push(sub);
}
else {
buffer = [ sub ];
this.listeners[event] = buffer;
}
},
off: function(event, func, owner) {
const buffer = this.listeners[event];
if(!buffer) {
return ;
}
for(let n = 0; n < buffer.length; n++) {
const sub = buffer[n];
if((sub.func === func) && (sub.owner === owner)) {
buffer[n] = buffer[buffer.length - 1];
buffer.pop();
return ;
}
}
},
emit: function(event, arg) {
const buffer = this.listeners[event];
if(!buffer) {
return ;
}
for(let n = 0; n < buffer.length; n++) {
const sub = buffer[n];
sub.func.call(sub.owner, arg);
}
},
reset: function() {
for(let n = 0; n < numKeys.length; n++) {
if(!this.inputs[n]) {
continue;
}
this.inputs[n] = 0;
const inputEvent = new Input.Event();
inputEvent.domEvent = domEvent;
inputEvent.keyCode = keyCode;
this.emit("keyup", inputEvent);
}
for(let n = numKeys; n <= (numKeys + numTouches); n++) {
const keyCode = n + Key.BUTTON_ENUM_OFFSET;
if(!this.inputs[keyCode]) {
continue;
}
const inputEvent = new Input.Event();
inputEvent.domEvent = domEvent;
inputEvent.keyCode = keyCode;
this.emit("up", inputEvent);
}
for(let n = 0; n < this.touches.length; n++) {
if(!this.touches[n]) {
continue;
}
const keyCode = n + Key.BUTTON_ENUM_OFFSET;
if(!this.inputs[keyCode]) {
continue;
}
const inputEvent = new Input.Event();
inputEvent.domEvent = domEvent;
inputEvent.keyCode = keyCode;
this.emit("up", inputEvent);
}
},
getTouchID: function(eventTouchID) {
for(let n = 0; n < this.touches.length; n++) {
if(this.touches[n] === eventTouchID) {
return n;
}
}
return -1;
},
checkIgnoreKey: function(domEvent) {
const keyCode = domEvent.keyCode;
if(document.activeElement === document.body) {
if(window.top && this.iframeKeys[keyCode]) {
domEvent.preventDefault();
}
if(this.cmdKeys[keyCode] !== undefined) {
this.numCmdKeysPressed++;
}
if((this.ignoreKeys[keyCode] !== undefined) && (this.numCmdKeysPressed <= 0)) {
domEvent.preventDefault();
}
}
},
set ignoreFKeys(flag) {
if(flag) {
ignoreFKeys(this, 1);
}
else {
ignoreFKeys(this, 0);
}
},
get ignoreFKeys() {
return !!this.ignoreKeys[112];
}
};
const addEventListeners = (input) => {
window.addEventListener("mousedown", input.handleMouseDown.bind(input));
window.addEventListener("mouseup", input.handleMouseUp.bind(input));
window.addEventListener("mousemove", input.handleMouseMove.bind(input));
window.addEventListener("mousewheel", input.handleMouseWheel.bind(input));
window.addEventListener("dblclick", input.handleMouseDblClick.bind(input));
window.addEventListener("touchstart", input.handleTouchDown.bind(input));
window.addEventListener("touchend", input.handleTouchUp.bind(input));
window.addEventListener("touchmove", input.handleTouchMove.bind(input));
window.addEventListener("touchcancel", input.handleTouchUp.bind(input));
window.addEventListener("touchleave", input.handleTouchUp.bind(input));
if(Device.supports.onkeydown) {
window.addEventListener("keydown", input.handleKeyDown.bind(input));
}
if(Device.supports.onkeyup) {
window.addEventListener("keyup", input.handleKeyUp.bind(input));
}
};
const loadIgnoreKeys = (input) => {
input.ignoreKeys = {};
input.ignoreKeys[8] = 1;
input.ignoreKeys[9] = 1;
input.ignoreKeys[13] = 1;
input.ignoreKeys[17] = 1;
input.ignoreKeys[91] = 1;
input.ignoreKeys[38] = 1;
input.ignoreKeys[39] = 1;
input.ignoreKeys[40] = 1;
input.ignoreKeys[37] = 1;
input.ignoreKeys[124] = 1;
input.ignoreKeys[125] = 1;
input.ignoreKeys[126] = 1;
input.cmdKeys[91] = 1;
input.cmdKeys[17] = 1;
input.iframeKeys[37] = 1;
input.iframeKeys[38] = 1;
input.iframeKeys[39] = 1;
input.iframeKeys[40] = 1;
};
const ignoreFKeys = (input, value) => {
for(let n = 112; n <= 123; n++) {
input.ignoreKeys[n] = value;
}
};
Input.Event = function() {
this.domEvent = null;
this.x = 0;
this.y = 0;
this.deltaX = 0;
this.deltaY = 0;
this.screenX = 0;
this.screenY = 0;
this.keyCode = 0;
this.entity = null;
};
const instance = new Input();
modules[7] = instance;
})();
//# sourceURL=src/Input.js
"use strict";
(function() {
var Device = modules[1];
function GamepadInfo(gamepad) {
const buttons = gamepad.buttons;
this.buttons = new Array(buttons.length);
for(let n = 0; n < buttons.length; n++) {
this.buttons[n] = buttons[n].pressed;
}
this.axes = gamepad.axes;
this.axesDefault = gamepad.axes;
}
function Gamepad() {
this.watchers = {};
this.gamepads = new Array(null, null, null, null);
this.updateFunc = this.update.bind(this);
window.addEventListener("gamepadconnected", this.handleConnected.bind(this));
window.addEventListener("gamepaddisconnected", this.handleDisconnected.bind(this));
requestAnimationFrame(this.updateFunc);
}
Gamepad.prototype = {
update: function() {
const gamepads = navigator.getGamepads();
for(let n = 0; n < gamepads.length; n++) {
const gamepad = gamepads[n];
if(!gamepad) {
continue;
}
const gamepadInfo = this.gamepads[n];
if(!gamepadInfo) {
this.gamepads[n] = new GamepadInfo(gamepad);
this.emit("connected", n);
}
else {
if(!Device.visible) {
continue;
}
const prevButtons = gamepadInfo.buttons;
const currButtons = gamepad.buttons;
for(let i = 0; i < currButtons.length; i++) {
const currButton = currButtons[i];
if(prevButtons[i] !== currButton.pressed) {
prevButtons[i] = currButton.pressed;
if(currButton.pressed) {
this.emit("down", i, n);
}
else {
this.emit("up", i, n);
}
}
}
let changed = false;
const axes = gamepad.axes;
const prevAxes = gamepadInfo.axes;
const defaultAxes = gamepadInfo.axesDefault;
for(let i = 0; i < axes.length; i++) {
let value = axes[i];
const defaultValue = defaultAxes[i];
if(value === defaultValue) {
value = 0;
}
if(prevAxes[i] !== value) {
prevAxes[i] = value;
this.emit("axis", i, n, value);
changed = true;
}
}
if(changed) {
this.emit("axes", prevAxes, n);
}
}
}
requestAnimationFrame(this.updateFunc);
},
handleConnected: function(event) {
const gamepad = event.gamepad;
if(!this.gamepads[gamepad.index]) {
this.gamepads[gamepad.index] = new GamepadInfo(gamepad);
this.emit("connected", gamepad.index);
}
},
handleDisconnected: function(event) {
const index = event.gamepad.index;
this.gamepads[index] = null;
this.emit("disconnected", index);
},
on: function(event, func) {
const buffer = this.watchers[event];
if(!buffer) {
this.watchers[event] = [ func ];
}
else {
buffer.push(func);
}
},
off: function(event, func) {
const buffer = this.watchers[event];
if(!buffer) {
return ;
}
const index = buffer.indexOf(func);
buffer[index] = buffer[buffer.length - 1];
buffer.pop();
},
emit: function(event, key, index, value) {
const buffer = this.watchers[event];
if(!buffer) {
return ;
}
for(let n = 0; n < buffer.length; n++) {
buffer[n](key, index, value);
}
},
pressed: function(key, index) {
const gamepad = this.gamepads[index];
return gamepad ? gamepad.buttons[key].pressed : false;
},
axis: function(key, index) {
const gamepad = this.gamepads[index];
if(!gamepad) {
return 0;
}
const value = gamepad.axes[key];
if(value === gamepad.axesDefault[key]) {
return 0;
}
return value;
}
};
const instance = new Gamepad();
modules[9] = instance;
})();
//# sourceURL=src/Gamepad.js
"use strict";
(function() {
var Resources = modules[5];
function Resource(config) {
this._loaded = false;
this._loading = false;
if(config) {
this.setup(config);
}
}
Resource.prototype = {
set loaded(value) {
if(value) {
if(!this._loaded) {
this._loaded = true;
this.loading = false;
}
}
else {
if(this._loaded) {
this._loaded = false;
}
}
},
get loaded() {
return this._loaded;
},
set loading(value) {
if(value) {
if(!this._loading) {
this._loading = true;
this._loaded = false;
Resources.resourceLoading(this);
}
}
else {
if(this._loading) {
this._loading = false;
this._loaded = true;
Resources.resourceLoaded(this);
}
}
},
get loading() {
return this._loading;
}
};
Resources.Resource = Resource;
modules[10] = Resource;
})();
//# sourceURL=src/resources/Resource.js
"use strict";
(function() {
const isPowerOf2 = (value) => {
return (value & (value - 1)) == 0;
};
const onDomLoad = (func) => {
if((document.readyState === "interactive") || (document.readyState === "complete")) {
func();
return ;
}
const callbackFunc = (event) => {
func();
window.removeEventListener("DOMContentLoaded", callbackFunc);
};
window.addEventListener("DOMContentLoaded", callbackFunc);
};
modules[12] = { isPowerOf2: isPowerOf2, onDomLoad: onDomLoad };
})();
//# sourceURL=src/Utils.js
"use strict";
(function() {
var Engine = modules[2];
var isPowerOf2 = modules[12].isPowerOf2;
var Resource = modules[10];
const greenPixel = new Uint8Array([ 0, 255, 0, 255 ]);
function Texture(config) {
Resource.call(this, config);
this.instance = Engine.gl.createTexture();
this.width = 0;
this.height = 0;
if(config) {
this.setup(config);
}
}
Texture.prototype = {
setup: function(config) {
this.loadFromPath(config.path);
},
loadFromPath: function(path) {
this.loading = true;
const image = new Image();
image.onload = () => {
this.loadFromImage(image);
};
image.onfailed = () => {
this.loadEmpty();
};
image.src = path;
},
loadEmpty: function() {
const gl = Engine.gl;
this.width = 1;
this.height = 1;
gl.bindTexture(gl.TEXTURE_2D, this.instance);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, greenPixel);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
this.loaded = true;
},
loadFromImage: function(image) {
const gl = Engine.gl;
this.width = image.width;
this.height = image.height;
gl.bindTexture(gl.TEXTURE_2D, this.instance);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
if(isPowerOf2(image.width) && isPowerOf2(image.height)) {
gl.generateMipmap(gl.TEXTURE_2D);
}
else {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
}
this.loading = false;
},
loadFromCanvas: function(canvas) {
const gl = Engine.gl;
this.width = canvas.width;
this.height = canvas.height;
gl.bindTexture(gl.TEXTURE_2D, this.instance);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas);
if(isPowerOf2(canvas.width) && isPowerOf2(canvas.height)) {
gl.generateMipmap(gl.TEXTURE_2D);
}
else {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
}
this.loaded = true;
},
frame: function() {
return this.frameData;
},
use: function() {
const gl = Engine.gl;
gl.bindTexture(gl.TEXTURE_2D, this.instance);
}
};
_inherits(Texture, Resource);
modules[11] = Texture;
})();
//# sourceURL=src/resources/Texture.js
"use strict";
(function() {
var Engine = modules[2];
var Resource = modules[10];
const requestTextFunc = (request) => {
return request.text();
};
function Attrib(name, loc) {
this.name = name;
this.loc = loc;
}
function Uniform(name, loc, type) {
this.name = name;
this.loc = loc;
this.type = type;
}
function Material(config) {
Resource.call(this, config);
this.program = null;
this.attrib = null;
this.attribData = null;
this.uniform = null;
this.uniformData = null;
this.numAttribs = 0;
this.uniforms = {};
if(config) {
this.setup(config);
}
}
Material.prototype = {
setup: function(config) {
if(config.vertexSourcePath) {
this.loading = true;
fetch(config.vertexSourcePath).then(requestTextFunc).then((vertexSource) => {
if(config.fragmentSourcePath) {
fetch(config.vertexSourcePath).then(requestTextFunc).then((fragmentSource) => {
this.createProgram(vertexSource, fragmentSource);
});
}
else {
this.createProgram(vertexSource, config.fragmentSource);
}
});
}
else if(config.fragmentSourcePath) {
fetch(config.vertexSourcePath).then(requestTextFunc).then((fragmentSource) => {
this.createProgram(config.vertexSource, fragmentSource);
});
}
else {
this.createProgram(config.vertexSource, config.fragmentSource);
}
},
loadShader: function(type, source) {
const gl = Engine.gl;
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if(!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
let shaderType;
switch(type) {
case gl.VERTEX_SHADER:
shaderType = "VERTEX_SHADER";
break;
case gl.FRAGMENT_SHADER:
shaderType = "FRAGMENT_SHADER";
break;
}
console.error("" + shaderType + ": " + gl.getShaderInfoLog(shader) + "");
gl.deleteShader(shader);
return null;
}
return shader;
},
createProgram: function(vertexSource, fragmentSource) {
const gl = Engine.gl;
const vertexShader = this.loadShader(gl.VERTEX_SHADER, vertexSource);
const fragmentShader = this.loadShader(gl.FRAGMENT_SHADER, fragmentSource);
this.program = gl.createProgram();
gl.attachShader(this.program, vertexShader);
gl.attachShader(this.program, fragmentShader);
gl.linkProgram(this.program);
if(!gl.getProgramParameter(this.program, gl.LINK_STATUS)) {
console.error("Unable to initialize the shader program: " + gl.getProgramInfoLog(this.program) + "");
gl.deleteProgram(this.program);
gl.deleteShader(vertexShader);
gl.deleteShader(fragmentShader);
return ;
}
this.extractAttribs();
this.extractUniforms();
this.loading = false;
},
extractAttribs: function() {
this.attrib = {};
this.attribData = [];
const gl = Engine.gl;
this.numAttribs = gl.getProgramParameter(this.program, gl.ACTIVE_ATTRIBUTES);
for(let n = 0; n < this.numAttribs; n++) {
const attrib = gl.getActiveAttrib(this.program, n);
const attribLoc = gl.getAttribLocation(this.program, attrib.name);
this.attrib[attrib.name] = attribLoc;
this.attribData.push(new Attrib(attrib.name, attribLoc));
}
},
extractUniforms: function() {
this.uniform = {};
this.uniformData = [];
const gl = Engine.gl;
const num = gl.getProgramParameter(this.program, gl.ACTIVE_UNIFORMS);
for(let n = 0; n < num; n++) {
const uniform = gl.getActiveUniform(this.program, n);
const name = uniform.name.replace("[0]", "");
const loc = gl.getUniformLocation(this.program, name);
this.uniform[name] = loc;
this.uniformData.push(new Uniform(name, loc, uniform.type));
}
}
};
_inherits(Material, Resource);
modules[13] = Material;
})();
//# sourceURL=src/resources/Material.js
"use strict";
(function() {
const radians = (degrees) => {
return (degrees * Math.PI) / 180;
};
const degrees = (ra