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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
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 =====--
--===== script system =====--
script = 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 = require(script.name)
f(self.db, id, dt)
end
end
}
end
return module
|