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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
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
|