summaryrefslogtreecommitdiff
path: root/honey/ecs/render.lua
blob: 8cca6cff2fd89eac5cb8ff76ffc5cbe713f6d43c (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
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

local gl = honey.gl
local glfw = honey.glfw

local node = require 'honey.ecs.node'

local module = {}
setmetatable(module, {__index=_G})
setfenv(1, module)

--===== rendering =====--

local function drawMesh(program, uniforms, matrices, vao, count)
	gl.UseProgram(program)

	-- bind matrices
	shader.configure(program, {
		matrix={
			model = matrices.model,
			view = matrices.view,
			projection = matrices.projection,
		},
	})

	-- 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


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
		
		-- 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