Archived
Private
Public Access
1
0
This repository has been archived on 2026-02-04. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
ProjectBackup/C#/TSEngine/Core/GL/glBuffer.ts
2022-09-04 12:45:01 +02:00

188 lines
5.9 KiB
TypeScript

///<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);
}
}
}