summaryrefslogtreecommitdiff
path: root/honey
diff options
context:
space:
mode:
Diffstat (limited to 'honey')
-rw-r--r--honey/init.lua29
-rw-r--r--honey/mat4.lua144
-rw-r--r--honey/mesh.lua95
-rw-r--r--honey/std.lua10
-rw-r--r--honey/vec3.lua170
-rw-r--r--honey/window.lua3
6 files changed, 449 insertions, 2 deletions
diff --git a/honey/init.lua b/honey/init.lua
new file mode 100644
index 0000000..c3dda37
--- /dev/null
+++ b/honey/init.lua
@@ -0,0 +1,29 @@
+local glfw = honey.glfw
+local gl = honey.gl
+local window = require 'honey.window'
+
+local hinit = {}
+setmetatable(hinit, {__index=_G})
+setfenv(1, hinit)
+
+
+function init(width, height, title)
+ local width = width or 640
+ local height = height or 480
+ local title = title or "honey3d"
+
+ glfw.Init()
+ local window = honey.Window(width, height, title)
+ glfw.MakeContextCurrent(window.win)
+ gl.InitGlad()
+
+ return window
+end
+
+
+function terminate()
+ glfw.Terminate()
+end
+
+
+return hinit
diff --git a/honey/mat4.lua b/honey/mat4.lua
new file mode 100644
index 0000000..a97129c
--- /dev/null
+++ b/honey/mat4.lua
@@ -0,0 +1,144 @@
+local glm = honey.glm
+local Vec3 = require 'honey.vec3'
+
+local module = {}
+setmetatable(module, {__index=_G})
+setfenv(1, module)
+
+local RowLookup = {}
+function RowLookup.new(_, row, data)
+ local self = {
+ row=row,
+ data=data,
+ }
+ setmetatable(self, RowLookup)
+ return self
+end
+setmetatable(RowLookup, {__call=RowLookup.new})
+function RowLookup.__index(self, col)
+ return glm.mat4_get(self.data, col-1, self.row-1)
+end
+function RowLookup.__newindex(self, col, value)
+ return glm.mat4_set(self.data, col-1, self.row-1, value)
+end
+
+
+
+Mat4 = {}
+
+function Mat4.new(_, self, values)
+ local self = {}
+ self.type = "mat4"
+ self.data = glm.mat4_create()
+ setmetatable(self, Mat4)
+ if values then
+ self[1][1] = values[1]
+ self[1][2] = values[2]
+ self[1][3] = values[3]
+ self[1][4] = values[4]
+
+ self[2][1] = values[5]
+ self[2][2] = values[6]
+ self[2][3] = values[7]
+ self[2][4] = values[8]
+
+ self[3][1] = values[9]
+ self[3][2] = values[10]
+ self[3][3] = values[11]
+ self[3][4] = values[12]
+
+ self[4][1] = values[13]
+ self[4][2] = values[14]
+ self[4][3] = values[15]
+ self[4][4] = values[16]
+ end
+ return self
+end
+setmetatable(Mat4, {__call=Mat4.new})
+
+
+function Mat4.__index(self, key)
+ if type(key) == "number" then
+ return RowLookup(key, self.data)
+ else
+ return Mat4[key]
+ end
+end
+
+
+function Mat4.__tostring(self)
+ return string.format(
+ "/ %0.4f, %0.4f, %0.4f, %0.4f \\\n" ..
+ "| %0.4f, %0.4f, %0.4f, %0.4f |\n" ..
+ "| %0.4f, %0.4f, %0.4f, %0.4f |\n" ..
+ "\\ %0.4f, %0.4f, %0.4f, %0.4f /",
+ self[1][1], self[1][2], self[1][3], self[1][4],
+ self[2][1], self[2][2], self[2][3], self[2][4],
+ self[3][1], self[3][2], self[3][3], self[3][4],
+ self[4][1], self[4][2], self[4][3], self[4][4]
+ )
+end
+
+
+function Mat4.__mul(self, other)
+ if other.type == "mat4" then
+ local dest = Mat4()
+ glm.mat4_mul(self.data, other.data, dest.data)
+ return dest
+ elseif other.type == "vec4" then
+ -- todo
+ elseif other.type == "vec3" then
+ local dest = Vec3()
+ glm.mat4_mulv3(self.data, other.data, 1.0, dest.data)
+ return dest
+ else
+ error(string.format("cannot multiply Mat4 by %s", type(other)))
+ end
+end
+
+
+function Mat4.copyTo(self, dest)
+ glm.mat4_copy(self.data, dest.data)
+end
+
+
+function Mat4.identity(self)
+ glm.mat4_identity(self.data)
+end
+
+
+function Mat4.zero(self)
+ glm.mat4_zero(self.data)
+end
+
+
+function Mat4.translate(self, vec)
+ glm.translate(self.data, vec.data)
+end
+
+
+function Mat4.rotateX(self, angle)
+ glm.rotate_x(self.data, angle, self.data)
+end
+function Mat4.rotateY(self, angle)
+ glm.rotate_y(self.data, angle, self.data)
+end
+function Mat4.rotateZ(self, angle)
+ glm.rotate_z(self.data, angle, self.data)
+end
+
+
+function Mat4.scale(self, vec)
+ glm.scale(self.data, vec.data)
+end
+
+
+function Mat4.perspective(self, fovy, aspect, near, far)
+ glm.perspective(fovy, aspect, near, far, self.data)
+end
+function Mat4.perspectiveResize(self, aspect)
+ glm.perspective_resize(aspect, self.data)
+end
+
+
+return module.Mat4
diff --git a/honey/mesh.lua b/honey/mesh.lua
new file mode 100644
index 0000000..430d5c3
--- /dev/null
+++ b/honey/mesh.lua
@@ -0,0 +1,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
diff --git a/honey/std.lua b/honey/std.lua
index 923c66a..78b2525 100644
--- a/honey/std.lua
+++ b/honey/std.lua
@@ -1,3 +1,13 @@
+local init = require 'honey.init'
local window = require 'honey.window'
+local mesh = require 'honey.mesh'
+local Vec3 = require 'honey.vec3'
+local Mat4 = require 'honey.mat4'
+
+honey.init = init.init
+honey.terminate = init.terminate
honey.Window = window.Window
+honey.mesh = mesh
+honey.Vec3 = Vec3
+honey.Mat4 = Mat4
diff --git a/honey/vec3.lua b/honey/vec3.lua
new file mode 100644
index 0000000..af9ac4b
--- /dev/null
+++ b/honey/vec3.lua
@@ -0,0 +1,170 @@
+local glm = honey.glm
+
+local vec3 = {}
+setmetatable(vec3, {__index=_G})
+setfenv(1, vec3)
+
+
+Vec3 = {}
+
+function Vec3.new(_, values)
+ local self = {}
+ self.data = glm.vec3_create()
+ setmetatable(self, Vec3)
+ if values then
+ self[1] = values[1]
+ self[2] = values[2]
+ self[3] = values[3]
+ end
+ return self
+end
+setmetatable(Vec3, {__call=Vec3.new})
+
+
+function Vec3.__index(self, key)
+ if type(key) == 'number' then
+ return glm.vec3_get(self.data, key-1)
+ else
+ return Vec3[key]
+ end
+end
+
+
+function Vec3.__newindex(self, key, value)
+ glm.vec3_set(self.data, key-1, value)
+end
+
+
+function Vec3.__tostring(self)
+ return string.format("[%.4f, %.4f, %.4f]", self[1], self[2], self[3])
+end
+
+
+--===== arithmetic =====--
+
+local function swapIfNumber(self, other)
+ if type(self) == "number" and type(other) == "table" then
+ return other, self
+ else
+ return self, other
+ end
+end
+
+
+function Vec3.__add(self, other)
+ local self, other = swapIfNumber(self, other)
+
+ local dest = Vec3()
+ if type(other) == "number" then
+ glm.vec3_adds(self.data, other, dest.data)
+ elseif type(other) == "table" then
+ glm.vec3_add(self.data, other.data, dest.data)
+ else
+ error(string.format("cannot add %s to Vec3", type(other)))
+ end
+ return dest
+end
+
+
+function Vec3.__sub(self, other)
+ local dest = Vec3()
+ if type(other) == "number" then
+ glm.vec3_subs(self.data, other, dest.data)
+ elseif type(other) == "table" then
+ glm.vec3_sub(self.data, other.data, dest.data)
+ else
+ error(string.format("cannot subtract %s from Vec3", type(other)))
+ end
+ return dest
+end
+
+
+function Vec3.__mul(self, other)
+ local self, other = swapIfNumber(self, other)
+ local dest = Vec3()
+ if type(other) == "number" then
+ glm.vec3_scale(self.data, other, dest.data)
+ elseif type(other) == "table" then
+ glm.vec3_mul(self.data, other.data, dest.data)
+ else
+ error(string.format("cannot multiply %s and Vec3", type(other)))
+ end
+ return dest
+end
+
+
+function Vec3.__div(self, other)
+ local dest = Vec3()
+ if type(other) == "number" then
+ glm.vec3_divs(self.data, other, dest.data)
+ elseif type(other) == "table" then
+ glm.vec3_div(self.data, other.data, dest.data)
+ else
+ error(string.format("cannot divide Vec3 by %s", type(other)))
+ end
+ return dest
+end
+
+
+
+
+function Vec3.copyTo(self, dest)
+ glm.vec3_copy(self.data, dest.data)
+end
+
+
+function Vec3.zero(self)
+ glm.vec3_zero(self.data)
+end
+
+
+function Vec3.zero(self)
+ glm.vec3_zero(self.data)
+end
+function Vec3.one(self)
+ glm.vec3_one(self.data)
+end
+
+
+function Vec3.dot(self, other)
+ return glm.vec3_dot(self.data, other.data)
+end
+
+
+function Vec3.crossTo(self, other, dest)
+ glm.vec3_cross(self.data, other.data, dest.data)
+end
+function Vec3.cross(self, other)
+ local dest = Vec3()
+ self:crossTo(other, dest)
+ return dest
+end
+
+
+function Vec3.crossnTo(self, other, dest)
+ glm.vec3_crossn(self.data, other.data, dest.data)
+end
+function Vec3.crossn(self, other)
+ local dest = Vec3()
+ self:crossTo(other, dest)
+ return dest
+end
+
+
+function Vec3.norm2(self)
+ return glm.vec3_norm2(self.data)
+end
+function Vec3.norm(self)
+ return glm.vec3_norm(self.data)
+end
+
+
+function Vec3.normalize(self)
+ glm.vec3_normalize(self.data)
+end
+function Vec3.normalizeTo(self, dest)
+ glm.vec3_normalize_to(self.data, dest.data)
+end
+
+
+return vec3.Vec3
diff --git a/honey/window.lua b/honey/window.lua
index 204f8e4..35e04ac 100644
--- a/honey/window.lua
+++ b/honey/window.lua
@@ -17,7 +17,6 @@ function Window.new(_, width, height, title, monitor, share)
self.win = glfw.CreateWindow(width, height, title, monitor, share)
self.__gc = honey.util.gc_canary(function()
- print("destroying window " .. tostring(self.win))
glfw.DestroyWindow(self.win)
end)
@@ -149,7 +148,7 @@ function Window.setContentScaleCallback(self, cb)
end
-function Window.SwapBuffers(self)
+function Window.swapBuffers(self)
glfw.SwapBuffers(self.win)
end