97 lines
2.5 KiB
JavaScript
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 }
|