UNPKG

ts-game-engine

Version:

Simple WebGL game/render engine written in TypeScript

105 lines (104 loc) 5.78 kB
"use strict"; 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;