From 0d96ebc90c9740e7e66a70aa11168b11f49d220b Mon Sep 17 00:00:00 2001 From: sanine-a Date: Fri, 12 May 2023 14:10:48 -0500 Subject: run working program with refactored code --- honey/ecs/ecs.lua | 6 +-- honey/ecs/node.lua | 77 +++++++++++++-------------- honey/ecs/render.lua | 144 ++++++++++++++++++++++----------------------------- honey/ecs/script.lua | 28 +++++----- 4 files changed, 113 insertions(+), 142 deletions(-) (limited to 'honey/ecs') diff --git a/honey/ecs/ecs.lua b/honey/ecs/ecs.lua index d7eb4ac..0c84041 100644 --- a/honey/ecs/ecs.lua +++ b/honey/ecs/ecs.lua @@ -77,11 +77,9 @@ end -- load database from file function EntityDb.load(self, filename) - print(collectgarbage("count")) self.entities = {} self.components = {} collectgarbage() - print(collectgarbage("count")) local env = { Entity = function(id, components) self:createEntity(id) @@ -320,7 +318,6 @@ function SystemDb.update(self, dt) -- check for dangling dependencies local dangle = "" for dependency in pairs(self.dangling) do - print(dependency) dangle = dangle .. string.format( "unresolved dangling dependency: %s\n", dependency @@ -330,11 +327,10 @@ function SystemDb.update(self, dt) error(dangle) end - for _, name in ipairs(self.sort) do local system = self.systems[name] local params = self.params[name] - system.f(self.db, dt, params) + system.f(self.entityDb, dt, params) end end diff --git a/honey/ecs/node.lua b/honey/ecs/node.lua index 4953af5..6a47a1f 100644 --- a/honey/ecs/node.lua +++ b/honey/ecs/node.lua @@ -1,52 +1,47 @@ +local ecs = require 'honey.ecs.ecs' + local module = {} setmetatable(module, {__index=_G}) setfenv(1, module) --===== transform cascading =====-- -system = function(params) - return { - db = params.db, - - priority = 2, - update = function(self, dt) - local nodes = self.db:queryComponent("node") - - -- prepare nodes - for id, node in pairs(nodes) do - node._visited = false - node._child = nil - end - - -- helper function - local function recursiveTransform(id, node) - if node._visited then - return node._matrix - end - - if not node.parent then - node._matrix = node.matrix - else - local parentNode = self.db:getComponent(node.parent, "node") - local parentMatrix = recursiveTransform(node.parent, parentNode) - node._matrix = parentMatrix * node.matrix - if node.name then - if not parentNode._child then parentNode._child = {} end - parentNode._child[node.name] = honey.ecs.Accessor(self.db, id) - end - end - node._visited = true - return node._matrix - end - - -- compute nodes - for id, node in pairs(nodes) do - recursiveTransform(id, node) - end - end, - } +local function recursiveTransform(db, id, node) + if node._visited then + return node._matrix + end + + if not node.parent then + node._matrix = node.matrix + else + local parentNode = db:getComponent(node.parent, "node") + local parentMatrix = recursiveTransform(db, node.parent, parentNode) + node._matrix = parentMatrix * node.matrix + if node.name then + if not parentNode._child then parentNode._child = {} end + parentNode._child[node.name] = ecs.Accessor(db, id) + end + end + node._visited = true + return node._matrix end +system = {ecs.System("node", function(db, dt, params) + local nodes = db:queryComponent("node") + + -- prepare nodes + for id, node in pairs(nodes) do + node._visited = false + node._child = nil + end + + -- compute nodes + for id, node in pairs(nodes) do + recursiveTransform(db, id, node) + end +end)} + + return module diff --git a/honey/ecs/render.lua b/honey/ecs/render.lua index 1e41e7a..8cca6cf 100644 --- a/honey/ecs/render.lua +++ b/honey/ecs/render.lua @@ -1,3 +1,9 @@ +local ecs = require 'honey.ecs.ecs' + +local image = require 'honey.asset.image' +local shader = require 'honey.asset.shader' +local mesh = require 'honey.asset.mesh' + local glm = require 'honey.glm' local Vec3 = glm.Vec3 local Mat4 = glm.Mat4 @@ -5,103 +11,77 @@ local Mat4 = glm.Mat4 local gl = honey.gl local glfw = honey.glfw +local node = require 'honey.ecs.node' + local module = {} setmetatable(module, {__index=_G}) setfenv(1, module) --===== rendering =====-- -function draw(model, view, projection, textures, shader, mesh) - shader:use() +local function drawMesh(program, uniforms, matrices, vao, count) + gl.UseProgram(program) - -- bind textures - local texOffset = 0 - for name, texTbl in pairs(textures or {}) do - local texture = honey.image.loadImage(texTbl.filename, texTbl.params) - gl.BindTexture(gl.TEXTURE_2D + texOffset, texture.texture) - shader:setInt(name, texOffset) - texOffset = texOffset + 1 - end - - -- configure default uniforms - shader:configure{ - float={ - time=glfw.GetTime(), - }, + -- bind matrices + shader.configure(program, { matrix={ - view=view, - projection=projection, - model=model, + model = matrices.model, + view = matrices.view, + projection = matrices.projection, }, - } + }) - -- draw mesh - mesh:drawElements() - - -- unbind textures - for i=0,texOffset-1 do - gl.BindTexture(gl.TEXTURE_2D + i, 0) + -- bind textures + local offset = 0 + for name, tbl in pairs(uniforms.textures or {}) do + local tex = image.get(tbl.filename) + gl.BindTexture(gl.TEXTURE_2D + offset, tex) + shader.setInt(program, name, offset) + offset = offset+1 end + + -- configure additional uniforms + shader.configure(program, uniforms) + + -- render mesh + gl.BindVertexArray(vao) + gl.DrawElements(gl.TRIANGLES, count, gl.UNSIGNED_INT, 0) end -system = function(params) - return { - db = params.db, - priority = params.priority or 99, - update = function(self, dt) - for id, camera in pairs(self.db:queryComponent("camera")) do - local projection = camera.projection - local cameraTransform = self.db:getComponent(id, "node") - local view = Mat4() - if cameraTransform then - honey.glm.mat4_inv(cameraTransform._matrix.data, view.data) - else - view:identity() - end + +local render = ecs.System("render", function(db, dt, p) + for id, camera in pairs(db:queryComponent("camera")) do + -- get camera's view and projection matrices + local projection = camera.projection + local view = Mat4() + local node = db:getComponent(id, "node") + if node then + honey.glm.mat4_inv(node._matrix.data, view.data) + else + view:identity() + end - local entities = self.db:queryComponent("renderMesh") - for entity, tbl in pairs(entities) do - -- get model - local node = self.db:getComponent(entity, "node") - local model = - (node and node._matrix) or - Mat4():identity() - -- get shader - if not tbl.shader then - print(node) - print(node and node._matrix) - print(node and node.name) - print(node and node.parent) - for k, v in pairs(tbl) do - print(k, v) - end - end - local shader = honey.shader.loadShader( - tbl.shader.vertex, tbl.shader.fragment - ) - -- get mesh - local mesh = honey.mesh.loadCached( - tbl.mesh.filename, tbl.mesh.index, tbl.mesh.debug - ) - draw(model, view, projection, tbl.textures, shader, mesh) - end - - entities = self.db:queryComponent("renderQuad") - local quadmesh = honey.mesh.loadCached("builtin.quad", 1) - for entity, tbl in pairs(entities) do - -- get model - local model = Mat4():identity() - -- get shader - local shader = honey.shader.loadShader( - tbl.shader.vertex, tbl.shader.fragment - ) - draw(model, view, projection, tbl.textures, shader, quadmesh) - end - end - end, - } -end + -- iterate over all scene meshes + local meshes = db:queryComponent("renderMesh") + for id, tbl in pairs(meshes) do + -- get model matrix + local node = db:getComponent(id, "node") + local model = (node and node._matrix) or Mat4():identity() + + -- get shader program + local program = shader.get(tbl.shader) + + -- get mesh + local vao, count = mesh.get(tbl.mesh.filename, tbl.mesh.index) + + -- draw c: + drawMesh(program, tbl.uniforms or {}, {view=view, model=model, projection=projection}, vao, count) + end + end +end) +render:addDependencies(node.system) +system = {render} return module diff --git a/honey/ecs/script.lua b/honey/ecs/script.lua index 9ae7d72..46af4fa 100644 --- a/honey/ecs/script.lua +++ b/honey/ecs/script.lua @@ -1,3 +1,6 @@ +local ecs = require 'honey.ecs.ecs' +local node = require 'honey.ecs.node' + local module = {} setmetatable(module, {__index=_G}) setfenv(1, module) @@ -16,8 +19,8 @@ end --===== dispatch messages to handlers =====-- -dispatch = function(entities, msg, data) - local query = entities:queryComponent(msg) +dispatch = function(db, msg, data) + local query = db:queryComponent(msg) for id, handler in pairs(query) do local f = getFunction(handler) f(entities, id, data) @@ -26,19 +29,16 @@ end --===== script system =====-- -system = function(params) - return { - db=params.db, - update=function(self, dt) - local entities = self.db:queryComponent("script") - for id, script in pairs(entities) do - local f = getFunction(script) - f(self.db, id, dt) - end - end - } -end +local script = ecs.System("script", function(db, dt, params) + local entities = db:queryComponent("script") + for id, script in pairs(entities) do + local f = getFunction(script) + f(db, id, dt) + end +end) +script:addDependencies(node.system) +system = {script} return module -- cgit v1.2.1