Initial commit
This commit is contained in:
188
C#/TSEngine/Core/GL/glBuffer.ts
Normal file
188
C#/TSEngine/Core/GL/glBuffer.ts
Normal file
@@ -0,0 +1,188 @@
|
||||
///<reference path="gl.ts"/>
|
||||
|
||||
namespace TSE {
|
||||
|
||||
/** Represents the Information needed for a GLBuffer Attribute. */
|
||||
export class AttributeInfo {
|
||||
/** The location of this Attribute */
|
||||
public location: number;
|
||||
|
||||
/** The size (number of elements) in this Attribute (i.e Vector3 = 3). */
|
||||
public size: number;
|
||||
|
||||
/** The number of Elements from the beginning of the Buffer. */
|
||||
public offset: number;
|
||||
|
||||
public constructor(location: number, size: number) {
|
||||
this.location = location;
|
||||
this.size = size;
|
||||
this.offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** Represents a WebGLBuffer */
|
||||
export class GLBuffer {
|
||||
|
||||
private _hasAttributeLocation: boolean = false;
|
||||
private _elementSize: number;
|
||||
private _stride: number;
|
||||
private _buffer: WebGLBuffer;
|
||||
|
||||
private _targetBufferType: number;
|
||||
private _dataType: number;
|
||||
private _mode: number;
|
||||
private _typeSize: number;
|
||||
|
||||
private _data: number[] = [];
|
||||
private _attributes: AttributeInfo[] = [];
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new GLBuffer.
|
||||
* @param elementSize The size of each Element in this Buffer.
|
||||
* @param dataType The data type of this Buffer. Default: FLOAT
|
||||
* @param targetBufferType The Buffer target type. ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER. Default: ARRAY_BUFFER
|
||||
* @param mode The drawing mode of this Buffer. TRIANGLES, LINES. Default: TRIANGLES
|
||||
*/
|
||||
public constructor(dataType: number = gl.FLOAT, targetBufferType: number = gl.ARRAY_BUFFER, mode: number = gl.TRIANGLES) {
|
||||
this._elementSize = 0;
|
||||
this._dataType = dataType;
|
||||
this._targetBufferType = targetBufferType;
|
||||
this._mode = mode;
|
||||
|
||||
// Determine Byte size
|
||||
switch (this._dataType) {
|
||||
case gl.FLOAT:
|
||||
case gl.INT:
|
||||
case gl.UNSIGNED_INT:
|
||||
this._typeSize = 4;
|
||||
break;
|
||||
|
||||
case gl.SHORT:
|
||||
case gl.UNSIGNED_SHORT:
|
||||
this._typeSize = 2;
|
||||
break;
|
||||
|
||||
case gl.BYTE:
|
||||
case gl.UNSIGNED_BYTE:
|
||||
this._typeSize = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error("Unrecognized data type: " + dataType.toString());
|
||||
}
|
||||
|
||||
this._buffer = gl.createBuffer();
|
||||
}
|
||||
|
||||
/** Destroys this Buffer. */
|
||||
public destroy(): void {
|
||||
gl.deleteBuffer(this._buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds this Buffer.
|
||||
* @param normalized Indecates if the BufferData should be normalized. Default: false
|
||||
*/
|
||||
public bind(normalized: boolean = false): void {
|
||||
gl.bindBuffer(this._targetBufferType, this._buffer);
|
||||
|
||||
if (this._hasAttributeLocation) {
|
||||
for (let it of this._attributes) {
|
||||
gl.vertexAttribPointer(it.location, it.size, this._dataType, normalized, this._stride, it.offset * this._typeSize);
|
||||
gl.enableVertexAttribArray(it.location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Unbinds this Buffer. */
|
||||
public unbind(): void {
|
||||
if (this._hasAttributeLocation) {
|
||||
for (let it of this._attributes) {
|
||||
gl.disableVertexAttribArray(it.location);
|
||||
}
|
||||
}
|
||||
|
||||
gl.bindBuffer(this._targetBufferType, undefined);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an Attribute with the provided info to this Buffer.
|
||||
* @param info The Attribute Information.
|
||||
*/
|
||||
public addAttributeLocation(info: AttributeInfo): void {
|
||||
this._hasAttributeLocation = true;
|
||||
info.offset = this._elementSize;
|
||||
this._attributes.push(info);
|
||||
this._elementSize += info.size;
|
||||
this._stride = this._elementSize * this._typeSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Data to this Buffer.
|
||||
* @param data The Data for this Buffer.
|
||||
*/
|
||||
public pushBackData(data: number[]): void {
|
||||
for (let d of data)
|
||||
this._data.push(d);
|
||||
}
|
||||
|
||||
public clearData(): void {
|
||||
this._data.length = 0;
|
||||
}
|
||||
|
||||
public setData(data: number[]): void {
|
||||
this.clearData();
|
||||
this.pushBackData(data);
|
||||
}
|
||||
|
||||
/** Upload the BufferData to the GPU */
|
||||
public upload(): void {
|
||||
gl.bindBuffer(this._targetBufferType, this._buffer);
|
||||
|
||||
let bufferData: ArrayBuffer;
|
||||
switch (this._dataType) {
|
||||
case gl.FLOAT:
|
||||
bufferData = new Float32Array(this._data);
|
||||
break;
|
||||
|
||||
case gl.INT:
|
||||
bufferData = new Int32Array(this._data);
|
||||
break;
|
||||
|
||||
case gl.UNSIGNED_INT:
|
||||
bufferData = new Uint32Array(this._data);
|
||||
break;
|
||||
|
||||
case gl.SHORT:
|
||||
bufferData = new Int16Array(this._data);
|
||||
break;
|
||||
|
||||
case gl.UNSIGNED_SHORT:
|
||||
bufferData = new Uint16Array(this._data);
|
||||
break;
|
||||
|
||||
case gl.BYTE:
|
||||
bufferData = new Int8Array(this._data);
|
||||
break;
|
||||
|
||||
case gl.UNSIGNED_BYTE:
|
||||
bufferData = new Uint8Array(this._data);
|
||||
break;
|
||||
}
|
||||
|
||||
gl.bufferData(this._targetBufferType, bufferData, gl.STATIC_DRAW);
|
||||
}
|
||||
|
||||
/** Draws this Buffer. */
|
||||
public draw(): void {
|
||||
if (this._targetBufferType === gl.ARRAY_BUFFER)
|
||||
gl.drawArrays(this._mode, 0, this._data.length / this._elementSize);
|
||||
|
||||
if (this._targetBufferType === gl.ELEMENT_ARRAY_BUFFER)
|
||||
gl.drawElements(this._mode, this._data.length, this._dataType, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user