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
|