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

191 lines
7.5 KiB
JavaScript

/**
* WebCLGLBuffer Object
* @class
* @constructor
* @property {WebGLTexture} textureData
* @property {Array<Float>} inData Original array
* @property {Int} [offset=0] offset of buffer
*/
WebCLGLBufferItem = function(gl, length, type, offset, linear, mode) {
this.gl = gl;
if(length.constructor === Array) {
this.length = length[0]*length[1];
this.W = length[0];
this.H = length[1];
} else {
this.length = length;
this.W = Math.ceil(Math.sqrt(this.length));
this.H = this.W;
}
this.utils = new WebCLGLUtils();
this.type = (type != undefined) ? type : 'FLOAT';
this._supportFormat = this.gl.FLOAT;
//this._supportFormat = this.gl.UNSIGNED_BYTE;
this.offset = (offset != undefined) ? offset : 0;
this.linear = (linear != undefined && linear == true) ? true : false;
this.inData; // enqueueWriteBuffer user data
this.mode = (mode != undefined) ? mode : "FRAGMENT"; // "FRAGMENT", "VERTEX", "VERTEX_INDEX", "VERTEX_FROM_KERNEL", "VERTEX_AND_FRAGMENT"
// readPixel arrays
this.outArray4Uint8ArrayX = new Uint8Array((this.W*this.H)*4);
this.outArray4Uint8ArrayY = new Uint8Array((this.W*this.H)*4);
this.outArray4Uint8ArrayZ = new Uint8Array((this.W*this.H)*4);
this.outArray4Uint8ArrayW = new Uint8Array((this.W*this.H)*4);
/*this.outArray4x4Uint8Array = new Uint8Array((this.W*this.H)*4*4);*/
this.Packet4Uint8Array_Float = []; // [this.outArray4Uint8ArrayX]
this.Float = []; // [unpack(this.outArray4Uint8ArrayX)]
this.Packet4Uint8Array_Float4 = []; // [this.outArray4Uint8ArrayX, ..Y, ..Z, ..W]
this.Float4 = []; // [unpack(this.outArray4Uint8ArrayX), unpack(..Y), unpack(..Z), unpack(..W)]
// Create FrameBuffer & RenderBuffer
this.rBuffer = this.gl.createRenderbuffer();
this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, this.rBuffer);
this.gl.renderbufferStorage(this.gl.RENDERBUFFER, this.gl.DEPTH_COMPONENT16, this.W, this.H);
this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, null);
this.fBuffer = this.gl.createFramebuffer();
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.fBuffer);
this.gl.framebufferRenderbuffer(this.gl.FRAMEBUFFER, this.gl.DEPTH_ATTACHMENT, this.gl.RENDERBUFFER, this.rBuffer);
if(this.mode == "FRAGMENT" || this.mode == "VERTEX_FROM_KERNEL" || this.mode == "VERTEX_AND_FRAGMENT") {
// Create WebGLTexture buffer
this.textureData = this.createWebGLTextureBuffer();
}
if(this.mode == "VERTEX" || this.mode == "VERTEX_INDEX" || this.mode == "VERTEX_FROM_KERNEL" || this.mode == "VERTEX_AND_FRAGMENT") {
// Create WebGL buffer
this.vertexData0 = this.createWebGLBuffer();
}
};
/**
* Create the WebGLTexture buffer
* @type Void
*/
WebCLGLBufferItem.prototype.createWebGLTextureBuffer = function() {
this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, false);
this.gl.pixelStorei(this.gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
var textureData = this.gl.createTexture();
this.gl.bindTexture(this.gl.TEXTURE_2D, textureData);
if(this.linear != undefined && this.linear == true) {
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.W,this.H, 0, this.gl.RGBA, this._supportFormat, null);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR_MIPMAP_NEAREST);
this.gl.generateMipmap(this.gl.TEXTURE_2D);
} else {
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.W,this.H, 0, this.gl.RGBA, this._supportFormat, null);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
}
return textureData;
};
/**
* Create the WebGL buffer
* @type Void
*/
WebCLGLBufferItem.prototype.createWebGLBuffer = function() {
var vertexData = this.gl.createBuffer();
return vertexData;
};
/**
* Write WebGLTexture buffer
* @param {Array|Float32Array|Uint8Array|WebGLTexture|HTMLImageElement} array
* @param {Bool} [flip=false]
* @type Void
*/
WebCLGLBufferItem.prototype.writeWebGLTextureBuffer = function(arr, flip) {
this.inData = arr;
if(arr instanceof WebGLTexture) this.textureData = arr;
else {
if(flip == false || flip == undefined)
this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, false);
else
this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, true);
this.gl.pixelStorei(this.gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
this.gl.bindTexture(this.gl.TEXTURE_2D, this.textureData);
if(arr instanceof HTMLImageElement) {
this.inData = this.utils.getUint8ArrayFromHTMLImageElement(arr);
//texImage2D( target, level, internalformat, format, type, TexImageSource);
if(this.type == 'FLOAT4') {
this.gl.texImage2D( this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.FLOAT, arr);
}/* else if(this.type == 'INT4') {
this.gl.texImage2D( this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, arr);
}*/
} else {
//console.log("Write arr with length of "+arr.length+" in Buffer "+this.type+" with length of "+this.length+" (W: "+this.W+"; H: "+this.H+")");
if(this.type == 'FLOAT4') {
var arrt = new Float32Array((this.W*this.H)*4);
for(var n=0; n < arr.length; n++) arrt[n] = arr[n];
//texImage2D( target, level, internalformat, width, height, border, format, type, pixels);
if(arr instanceof Uint8Array) {
this.gl.texImage2D( this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.W, this.H, 0, this.gl.RGBA, this.gl.FLOAT, arrt);
} else if(arr instanceof Float32Array) {
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.W, this.H, 0, this.gl.RGBA, this.gl.FLOAT, arrt);
} else {
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.W, this.H, 0, this.gl.RGBA, this.gl.FLOAT, arrt);
}
} else if(this.type == 'FLOAT') {
var arrayTemp = new Float32Array(this.W*this.H*4);
for(var n = 0, f = this.W*this.H; n < f; n++) {
var idd = n*4;
arrayTemp[idd] = arr[n];
arrayTemp[idd+1] = 0.0;
arrayTemp[idd+2] = 0.0;
arrayTemp[idd+3] = 0.0;
}
arr = arrayTemp;
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.W, this.H, 0, this.gl.RGBA, this.gl.FLOAT, arr);
}
}
}
if(this.linear) this.gl.generateMipmap(this.gl.TEXTURE_2D);
};
/**
* Write WebGL buffer
* @param {Array|Float32Array|Uint8Array|WebGLTexture|HTMLImageElement} array
* @param {Bool} [flip=false]
* @type Void
*/
WebCLGLBufferItem.prototype.writeWebGLBuffer = function(arr, flip) {
this.inData = arr;
if(this.mode == "VERTEX_INDEX") { // "VERTEX_INDEX" ELEMENT_ARRAY_BUFFER
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.vertexData0);
this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(arr), this.gl.DYNAMIC_DRAW);
} else { // "VERTEX" || "VERTEX_AND_FRAGMENT" ARRAY_BUFFER
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexData0);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(arr), this.gl.DYNAMIC_DRAW);
}
};
/**
* Remove this buffer
* @type Void
*/
WebCLGLBufferItem.prototype.remove = function() {
this.gl.deleteRenderbuffer(this.rBuffer);
this.gl.deleteFramebuffer(this.fBuffer);
if(this.mode == "FRAGMENT" || this.mode == "VERTEX_FROM_KERNEL" || this.mode == "VERTEX_AND_FRAGMENT")
this.gl.deleteTexture(this.textureData);
if(this.mode == "VERTEX" || this.mode == "VERTEX_INDEX" || this.mode == "VERTEX_FROM_KERNEL" || this.mode == "VERTEX_AND_FRAGMENT")
this.gl.deleteBuffer(this.vertexData0);
};