3dexperiments/src/engine/mesh/index.js

97 lines
2.5 KiB
JavaScript

class Mesh {
static loadToBuffer (gl, type, data, drawtype = gl.STATIC_DRAW) {
let id = gl.createBuffer()
gl.bindBuffer(type, id)
gl.bufferData(type, data, drawtype)
return id
}
static construct (gl, vertices, indices, uvs, normals) {
// VBO for model vertices
let pos = Mesh.loadToBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(vertices))
// Indices Buffer
let ebo = Mesh.loadToBuffer(gl, gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices))
// Create the mesh, as we have the most important data already buffered
let mesh = new Mesh()
mesh.posBuffer = pos
mesh.ebo = ebo
mesh.vertices = vertices
mesh.indices = indices
// VBO for model UVs
if (uvs) {
mesh.uv = uvs
mesh.uvs = Mesh.loadToBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(uvs))
}
// Normals buffer
if (normals) {
mesh.normals = normals
mesh.nms = Mesh.loadToBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(normals))
}
gl.bindBuffer(gl.ARRAY_BUFFER, null)
return mesh
}
bindBuffers (gl, shader) {
gl.bindBuffer(gl.ARRAY_BUFFER, this.posBuffer)
shader.setAttribute(gl, 'aVertexPosition', 3, false, 3 * Float32Array.BYTES_PER_ELEMENT, 0)
if (this.nms && shader.hasAttribute(gl, 'aNormal')) {
gl.bindBuffer(gl.ARRAY_BUFFER, this.nms)
shader.setAttribute(gl, 'aNormal', 3, false, 3 * Float32Array.BYTES_PER_ELEMENT, 0)
}
if (this.uvs && shader.hasAttribute(gl, 'aTexCoords')) {
gl.bindBuffer(gl.ARRAY_BUFFER, this.uvs)
shader.setAttribute(gl, 'aTexCoords', 2, false, 2 * Float32Array.BYTES_PER_ELEMENT, 0)
}
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.ebo)
}
prepare (gl, shader) {
// Bind attrib arrays
this.bindBuffers(gl, shader)
// Give materials to shader
if (this.material) {
this.material.apply(gl, shader)
}
}
draw (gl, shader, mode = gl.TRIANGLES) {
if (this.indices) {
gl.drawElements(mode, this.indices.length, gl.UNSIGNED_SHORT, 0)
} else {
gl.drawArrays(mode, 0, this.vertices.length)
}
}
// Make sure no data floats around in memory
dispose (gl) {
gl.deleteBuffer(this.posBuffer)
gl.deleteBuffer(this.ebo)
this.uvs && gl.deleteBuffer(this.uvs)
this.nms && gl.deleteBuffer(this.nms)
this.vertices = null
this.indices = null
this.uv = null
this.normals = null
}
recreate (gl) {
let msh = Mesh.construct(gl, this.vertices, this.indices, this.uv, this.normals)
if (!msh) return null
this.dispose(gl)
return msh
}
}
export { Mesh }