local module = {} local gl = honey.gl setmetatable(module, {__index=_G}) setfenv(1, module) local function printVertex(vertices, i) print(string.format( "p(%f, %f, %f), n(%f, %f, %f), t(%f, %f)", vertices[i+0], vertices[i+1], vertices[i+2], vertices[i+3], vertices[i+4], vertices[i+5], vertices[i+5], vertices[i+6] )) end local function insertVertex(vertices, attrib, vertex, debug) if debug then print() end local pos = 3*vertex.v_idx for i=1,3 do table.insert(vertices, attrib.vertices[pos+i]) if debug then print(vertices[#vertices]) end end local normal = 3*vertex.vn_idx for i=1,3 do table.insert(vertices, attrib.normals[normal+i]) if debug then print(vertices[#vertices]) end end local tex = 2*vertex.vt_idx for i=1,2 do table.insert(vertices, attrib.texcoords[tex+i]) if debug then print(vertices[#vertices]) end end if debug then for i=1,#attrib.texcoords do print(i, attrib.texcoords[i]) end end end function loadShape(shape, attrib, debug) local vertices = {} local indices = {} local start = shape.face_offset local finish = start + shape.length for i=start,finish-1 do assert(attrib.face_num_verts[i+1] == 3, "non-triangular face!") for j=0,2 do local vertex = attrib.faces[(3*i) + j + 1] insertVertex(vertices, attrib, vertex, debug) table.insert(indices, #indices) end end return vertices, indices end function loadFile(filename, debug) local flags = honey.tinyobj.FLAG_TRIANGULATE if debug then print("load file:", filename) end local attrib, shapes, materials = honey.tinyobj.parse_obj(filename, flags) local meshes = {} for _, shape in ipairs(shapes) do local vertices, indices = loadShape(shape, attrib, debug) table.insert(meshes, Mesh(vertices, indices)) end if debug then print("finished file:", filename) end return meshes end cache = {} function loadCached(filename, index, debug) if not cache[filename] then cache[filename] = loadFile(filename, debug) end return cache[filename][index] end Mesh = {} Mesh.__index = Mesh function Mesh.new(_, vertices, indices) local self = {} setmetatable(self, Mesh) self.vertexArray = gl.GenVertexArrays() self.vertexBuffer = gl.GenBuffers() self.elementBuffer = gl.GenBuffers() self.vertexCount = #indices gl.BindVertexArray(self.vertexArray) gl.BindBuffer(gl.ARRAY_BUFFER, self.vertexBuffer) gl.BufferData(gl.ARRAY_BUFFER, gl.FLOAT, vertices, gl.STATIC_DRAW) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.elementBuffer) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, gl.UNSIGNED_INT, indices, gl.STATIC_DRAW) gl.VertexAttribPointer(0, 3, false, 8, 0) gl.EnableVertexAttribArray(0) gl.VertexAttribPointer(1, 3, false, 8, 3) gl.EnableVertexAttribArray(1) gl.VertexAttribPointer(2, 2, false, 8, 6) gl.EnableVertexAttribArray(2) return self end setmetatable(Mesh, {__call=Mesh.new}) function Mesh.drawElements(self) gl.BindVertexArray(self.vertexArray) gl.DrawElements(gl.TRIANGLES, self.vertexCount, gl.UNSIGNED_INT, 0) end --===== builtin meshes =====-- function createBuiltins() cache["builtin.quad"] = {Mesh( { 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1 }, { 0, 1, 3, 0, 3, 2 } )} end return module