summaryrefslogtreecommitdiff
path: root/honey/ecs-systems.lua
blob: 18f50a8d6f2a1f2bf833e07000af44faba1efa28 (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
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
local ecs = require 'honey.ecs'
local gl = honey.gl
local glfw = honey.glfw


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



--===== transform cascading =====--

transform = function(params)
	return {
		db = params.db,
		update = function(self, dt)
			local entities = self.db:queryComponent("transform")
	
			-- prepare transforms
			for id, transform in pairs(entities) do
				transform._visited = false
			end
	
			-- helper function
			local function recursiveTransform(transform)
				if transform._visited then
					return transform._matrix
				end
	
				if not transform.parent then
					transform._matrix = transform.matrix
				else
					local parentTransform = self.db:getComponent(transform.parent, "transform")
					local parentMatrix = recursiveTransform(parentTransform)
					transform._matrix = parentMatrix * transform.matrix
				end
				transform._visited = true
				return transform._matrix
			end
	
			-- compute transforms
			for id, transform in pairs(entities) do
				recursiveTransform(transform)
			end
		end,
		priority = 0,
	}
end



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

function renderCamera(params) 
	return {
		camera = params.camera,
		db = params.db,
		priority = params.priority or 99,
		update = function(self, dt)
			local cameraParams = self.db:getComponent(self.camera, "camera")
			local cameraTransform = self.db:getComponent(self.camera, "transform")
			local view
			if cameraTransform then
				view = cameraTransform._matrix
			else
				view = Mat4():identity()
			end
	
			local entities = self.db:queryComponent("renderMesh")
			for entity, tbl in pairs(entities) do
				-- get shader
				local shader = honey.shader.loadShader(tbl.shader.vertex, tbl.shader.fragment)
				shader:use()
	
				-- bind textures
				local texOffset = 0
				for name, texTbl in pairs(tbl.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
				local query = self.db:getComponent(entity, "transform")
				local model = (query and query._matrix) or Mat4():identity()
				shader:configure{
					float={
						time=glfw.GetTime(),
					},
					matrix={
						view=view,
						projection=cameraParams.projection,
						model=model,
					},
				}
	
				-- draw mesh
				local mesh = honey.mesh.loadMesh(tbl.mesh.filename, tbl.mesh.index)
				mesh:drawElements()
	
				-- unbind textures
				for i=0,texOffset-1 do
					gl.BindTexture(gl.TEXTURE_2D + i, 0)
				end
			end
		end,
	}
end



--===== update functions =====--



return module