ts-game-engine
Version:
Simple WebGL game/render engine written in TypeScript
105 lines (104 loc) • 5.78 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const Constants_1 = require("../Constants");
const Utils_1 = require("../Utils");
const BoundingBox_1 = require("../Math/BoundingBox");
exports.VERTEX_POSITION_SIZE = 3; // X, Y, Z
exports.VERTEX_COLOR_SIZE = 4; // R, G, B, A
exports.VERTEX_NORMAL_SIZE = 3; // X, Y, Z
exports.VERTEX_UV_SIZE = 2; // X, Y
exports.ATTRIBUTE_INFO = [
{ vertexFormat: 1 /* Position */, name: Constants_1.POSITION_ATTRIBUTE, location: Constants_1.POSITION_ATTRIBUTE_LOCATION, size: exports.VERTEX_POSITION_SIZE },
{ vertexFormat: 2 /* Color */, name: Constants_1.COLOR_ATTRIBUTE, location: Constants_1.COLOR_ATTRIBUTE_LOCATION, size: exports.VERTEX_COLOR_SIZE },
{ vertexFormat: 4 /* Normal */, name: Constants_1.NORMAL_ATTRIBUTE, location: Constants_1.NORMAL_ATTRIBUTE_LOCATION, size: exports.VERTEX_NORMAL_SIZE },
{ vertexFormat: 8 /* UV0 */, name: Constants_1.UV0_ATTRIBUTE, location: Constants_1.UV0_ATTRIBUTE_LOCATION, size: exports.VERTEX_UV_SIZE },
{ vertexFormat: 16 /* UV1 */, name: Constants_1.UV1_ATTRIBUTE, location: Constants_1.UV1_ATTRIBUTE_LOCATION, size: exports.VERTEX_UV_SIZE }
];
class Mesh {
constructor(scene) {
this.context = scene.Game.GraphicsSystem.Context;
this.pipelineState = scene.Game.GraphicsSystem.PipelineState;
this.isLoaded = false;
const vertexBuffer = this.context.createBuffer();
if (vertexBuffer === null)
throw new Error("Unable to create position buffer");
this.vertexBuffer = vertexBuffer;
Utils_1.Utils.DebugName(this.vertexBuffer, `${this.constructor.name} vertex buffer`);
this.vertexFormat = 1 /* Position */;
this.indexFormat = 0 /* UInt16 */;
this.meshTopology = 4 /* Triangles */;
this.vertexCount = 0;
this.indexCount = 0;
this.boundingBox = new BoundingBox_1.BoundingBox();
this.isVertexBufferDynamic = false;
}
get IsLoaded() { return this.isLoaded; }
get VertexBuffer() { return this.vertexBuffer; }
get IndexBuffer() { return this.indexBuffer; }
get VertexFormat() { return this.vertexFormat; }
get IndexFormat() { return this.indexFormat; }
get MeshTopology() { return this.meshTopology; }
get VertexCount() { return this.vertexCount; }
get IndexCount() { return this.indexCount; }
get BoundingBox() { return this.boundingBox; }
Dispose() {
this.isLoaded = false;
if (this.vertexBuffer)
this.context.deleteBuffer(this.vertexBuffer);
if (this.indexBuffer)
this.context.deleteBuffer(this.indexBuffer);
}
SetVertexData(vertexFormat, meshTopology, vertexCount, vertexData, isDynamic) {
let stride = 0;
if ((vertexFormat & 1 /* Position */) !== 0)
stride += exports.VERTEX_POSITION_SIZE;
if ((vertexFormat & 2 /* Color */) !== 0)
stride += exports.VERTEX_COLOR_SIZE;
if ((vertexFormat & 4 /* Normal */) !== 0)
stride += exports.VERTEX_NORMAL_SIZE;
if ((vertexFormat & 8 /* UV0 */) !== 0)
stride += exports.VERTEX_UV_SIZE;
if ((vertexFormat & 16 /* UV1 */) !== 0)
stride += exports.VERTEX_UV_SIZE;
if (vertexCount * stride !== vertexData.length)
throw new Error("Vertex count, vertex format and vertex data size don't match.");
this.vertexFormat = vertexFormat;
this.meshTopology = meshTopology;
this.vertexCount = vertexCount;
// It's not necessary to unbind the current VAO, as binding an array buffer won't modify the
// array buffer/s of the current VAO. They are referenced in the vertexAttribPointer calls, not in the VAO.
this.context.bindBuffer(WebGL2RenderingContext.ARRAY_BUFFER, this.vertexBuffer);
this.context.bufferData(WebGL2RenderingContext.ARRAY_BUFFER, vertexData, isDynamic ? WebGL2RenderingContext.DYNAMIC_DRAW : WebGL2RenderingContext.STATIC_DRAW);
this.isVertexBufferDynamic = isDynamic;
}
UpdateVertexData(vertexData) {
if (!this.isVertexBufferDynamic) {
console.error(`${this.constructor.name}'s vertex buffer is not dynamic.`);
return;
}
// It's not necessary to unbind the current VAO, as binding an array buffer won't modify the
// array buffer/s of the current VAO. They are referenced in the vertexAttribPointer calls, not in the VAO.
this.context.bindBuffer(WebGL2RenderingContext.ARRAY_BUFFER, this.vertexBuffer);
this.context.bufferSubData(WebGL2RenderingContext.ARRAY_BUFFER, 0, vertexData);
}
SetIndexData(indices) {
if (!this.indexBuffer) {
const indexBuffer = this.context.createBuffer();
if (indexBuffer === null)
throw new Error("Unable to create index buffer.");
this.indexBuffer = indexBuffer;
Utils_1.Utils.DebugName(this.indexBuffer, `${this.constructor.name} index buffer`);
}
// Make sure current VAO is null so we don't accidentally modify the element buffer of other VAO.
// Unlike array buffers, element buffers are actually referenced directly in the VAO.
this.pipelineState.CurrentVAO = null;
this.indexCount = indices.length;
this.context.bindBuffer(WebGL2RenderingContext.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
this.context.bufferData(WebGL2RenderingContext.ELEMENT_ARRAY_BUFFER, indices, WebGL2RenderingContext.STATIC_DRAW);
}
SetBounds(min, max) {
this.boundingBox.min = min;
this.boundingBox.max = max;
}
}
exports.Mesh = Mesh;