summaryrefslogtreecommitdiff
path: root/honey/mesh.lua
blob: 430d5c300b7cbac1cf7975b6576dbf881cf778d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
local mesh = {}
local gl = honey.gl
setmetatable(mesh, {__index=_G})
setfenv(1, mesh)


local function insertVertex(vertices, attrib, vertex)
	local pos = 3*vertex.v_idx
	for i=1,3 do
		table.insert(vertices, attrib.vertices[pos+i])
	end

	local normal = 3*vertex.vn_idx
	for i=1,3 do
		table.insert(vertices, attrib.normals[normal+i])
	end

	local tex = 3*vertex.vt_idx
	for i=1,2 do
		table.insert(vertices, attrib.texcoords[tex+i])
	end
end


function loadShape(shape, attrib)
	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)
			table.insert(indices, #indices)
		end
	end

	return vertices, indices
end


function loadFile(filename)
	local flags = honey.tinyobj.FLAG_TRIANGULATE
	local attrib, shapes, materials = honey.tinyobj.parse_obj(filename, flags)
	
	local meshes = {}
	for _, shape in ipairs(shapes) do
		local vertices, indices = loadShape(shape, attrib)
		table.insert(meshes, Mesh(vertices, indices))
	end
	return meshes
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


return mesh