From 89572c1648128456822cf2dda07b13e78cfc2813 Mon Sep 17 00:00:00 2001 From: sanine Date: Mon, 13 Mar 2023 02:42:16 -0500 Subject: render all shapes --- honey/init.lua | 29 ++++++++++ honey/mat4.lua | 144 ++++++++++++++++++++++++++++++++++++++++++++++ honey/mesh.lua | 95 +++++++++++++++++++++++++++++++ honey/std.lua | 10 ++++ honey/vec3.lua | 170 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ honey/window.lua | 3 +- 6 files changed, 449 insertions(+), 2 deletions(-) create mode 100644 honey/init.lua create mode 100644 honey/mat4.lua create mode 100644 honey/mesh.lua create mode 100644 honey/vec3.lua (limited to 'honey') 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 -- cgit v1.2.1