gpu.js/lib/WebCLGLUtils.class.js
2016-01-23 18:35:35 +08:00

252 lines
6.8 KiB
JavaScript

/**
* Utilities
* @class
* @constructor
*/
WebCLGLUtils = function() {
};
/** @private */
WebCLGLUtils.prototype.isPowerOfTwo = function(x) {
return (x & (x - 1)) == 0;
};
/** @private */
WebCLGLUtils.prototype.nextHighestPowerOfTwo = function(x) {
--x;
for (var i = 1; i < 32; i <<= 1) {
x = x | x >> i;
}
return x + 1;
};
/**
* @private
*/
WebCLGLUtils.prototype.loadQuad = function(node, length, height) {
var l=(length==undefined)?0.5:length;
var h=(height==undefined)?0.5:height;
this.vertexArray = [-l, -h, 0.0,
l, -h, 0.0,
l, h, 0.0,
-l, h, 0.0];
this.textureArray = [0.0, 0.0, 0.0,
1.0, 0.0, 0.0,
1.0, 1.0, 0.0,
0.0, 1.0, 0.0];
this.indexArray = [0, 1, 2, 0, 2, 3];
var meshObject = new Object;
meshObject.vertexArray = this.vertexArray;
meshObject.vertexItemSize = this.vertexItemSize;
meshObject.vertexNumItems = this.vertexNumItems;
meshObject.textureArray = this.textureArray;
meshObject.textureItemSize = this.textureItemSize;
meshObject.textureNumItems = this.textureNumItems;
meshObject.indexArray = this.indexArray;
meshObject.indexItemSize = this.indexItemSize;
meshObject.indexNumItems = this.indexNumItems;
return meshObject;
};
/** @private **/
WebCLGLUtils.prototype.getWebGLContextFromCanvas = function(canvas, ctxOpt) {
var gl;
try {
if(ctxOpt == undefined) gl = canvas.getContext("webgl");
else gl = canvas.getContext("webgl", ctxOpt);
} catch(e) {
gl = null;
}
if(gl == null) {
try {
if(ctxOpt == undefined) gl = canvas.getContext("experimental-webgl");
else gl = canvas.getContext("experimental-webgl", ctxOpt);
} catch(e) {
gl = null;
}
}
if(gl == null) gl = false;
return gl;
};
/**
* @private
*/
WebCLGLUtils.prototype.createShader = function(gl, name, sourceVertex, sourceFragment, shaderProgram) {
var _sv = false, _sf = false;
var makeDebug = (function(infoLog, shader) {
console.log(infoLog);
var arrErrors = [];
var errors = infoLog.split("\n");
for(var n = 0, f = errors.length; n < f; n++) {
if(errors[n].match(/^ERROR/gim) != null) {
var expl = errors[n].split(':');
var line = parseInt(expl[2]);
arrErrors.push([line,errors[n]]);
}
}
var sour = gl.getShaderSource(shader).split("\n");
sour.unshift("");
for(var n = 0, f = sour.length; n < f; n++) {
var lineWithError = false;
var errorStr = '';
for(var e = 0, fe = arrErrors.length; e < fe; e++) {
if(n == arrErrors[e][0]) {
lineWithError = true;
errorStr = arrErrors[e][1];
break;
}
}
if(lineWithError == false) {
console.log("%c"+n+' %c'+sour[n], "color:black", "color:blue");
} else {
console.log('%c►►%c'+n+' %c'+sour[n]+'\n%c'+errorStr, "color:red", "color:black", "color:blue", "color:red");
}
}
}).bind(this);
var shaderVertex = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(shaderVertex, sourceVertex);
gl.compileShader(shaderVertex);
if (!gl.getShaderParameter(shaderVertex, gl.COMPILE_STATUS)) {
alert(name+' ERROR (vertex program). See console.');
var infoLog = gl.getShaderInfoLog(shaderVertex);
console.log("%c"+name+' ERROR (vertex program)', "color:red");
if(infoLog != undefined)
makeDebug(infoLog, shaderVertex);
} else {
gl.attachShader(shaderProgram, shaderVertex);
_sv = true;
}
var shaderFragment = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(shaderFragment, sourceFragment);
gl.compileShader(shaderFragment);
if (!gl.getShaderParameter(shaderFragment, gl.COMPILE_STATUS)) {
alert(name+' ERROR (fragment program). See console.');
var infoLog = gl.getShaderInfoLog(shaderFragment);
console.log("%c"+name+' ERROR (fragment program)', "color:red");
if(infoLog != undefined)
makeDebug(infoLog, shaderFragment);
} else {
gl.attachShader(shaderProgram, shaderFragment);
_sf = true;
}
if(_sv == true && _sf == true) {
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert('Error in shader '+name);
console.log('Error shader program '+name+':\n ');
if(gl.getProgramInfoLog(shaderProgram) != undefined) {
console.log(gl.getProgramInfoLog(shaderProgram));
}
return false;
} else {
return true;
}
} else {
return false;
}
};
/**
* Get Uint8Array from HTMLImageElement
* @returns {Uint8Array}
* @param {HTMLImageElement} imageElement
*/
WebCLGLUtils.prototype.getUint8ArrayFromHTMLImageElement = function(imageElement) {
var e = document.createElement('canvas');
e.width = imageElement.width;
e.height = imageElement.height;
var ctx2D_tex = e.getContext("2d");
ctx2D_tex.drawImage(imageElement, 0, 0);
var arrayTex = ctx2D_tex.getImageData(0, 0, imageElement.width, imageElement.height);
return arrayTex.data;
};
/**
* Dot product vector4float
* @private
*/
WebCLGLUtils.prototype.dot4 = function(vector4A,vector4B) {
return vector4A[0]*vector4B[0] + vector4A[1]*vector4B[1] + vector4A[2]*vector4B[2] + vector4A[3]*vector4B[3];
};
/**
* Compute the fractional part of the argument. fract(pi)=0.14159265...
* @private
*/
WebCLGLUtils.prototype.fract = function(number) {
return number - Math.floor(number);
};
/**
* Pack 1float (0.0-1.0) to 4float rgba (0.0-1.0, 0.0-1.0, 0.0-1.0, 0.0-1.0)
* @private
*/
WebCLGLUtils.prototype.pack = function(v) {
var bias = [1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0, 0.0];
var r = v;
var g = this.fract(r * 255.0);
var b = this.fract(g * 255.0);
var a = this.fract(b * 255.0);
var colour = [r, g, b, a];
var dd = [colour[1]*bias[0],colour[2]*bias[1],colour[3]*bias[2],colour[3]*bias[3]];
return [colour[0]-dd[0],colour[1]-dd[1],colour[2]-dd[2],colour[3]-dd[3] ];
};
/**
* Unpack 4float rgba (0.0-1.0, 0.0-1.0, 0.0-1.0, 0.0-1.0) to 1float (0.0-1.0)
* @private
*/
WebCLGLUtils.prototype.unpack = function(colour) {
var bitShifts = [1.0, 1.0/255.0, 1.0/(255.0*255.0), 1.0/(255.0*255.0*255.0)];
return this.dot4(colour, bitShifts);
};
/**
* Get pack GLSL function string
* @returns {String}
*/
WebCLGLUtils.prototype.packGLSLFunctionString = function() {
return 'vec4 pack (float depth) {\n'+
'const vec4 bias = vec4(1.0 / 255.0,\n'+
'1.0 / 255.0,\n'+
'1.0 / 255.0,\n'+
'0.0);\n'+
'float r = depth;\n'+
'float g = fract(r * 255.0);\n'+
'float b = fract(g * 255.0);\n'+
'float a = fract(b * 255.0);\n'+
'vec4 colour = vec4(r, g, b, a);\n'+
'return colour - (colour.yzww * bias);\n'+
'}\n';
};
/**
* Get unpack GLSL function string
* @returns {String}
*/
WebCLGLUtils.prototype.unpackGLSLFunctionString = function() {
return 'float unpack (vec4 colour) {\n'+
'const vec4 bitShifts = vec4(1.0,\n'+
'1.0 / 255.0,\n'+
'1.0 / (255.0 * 255.0),\n'+
'1.0 / (255.0 * 255.0 * 255.0));\n'+
'return dot(colour, bitShifts);\n'+
'}\n';
};