GCC Code Coverage Report


./
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
0 of 143, 0 excluded
0.0%
Functions:
0 of 14, 0 excluded
0.0%
Branches:
0 of 146, 0 excluded
0.0%

libs/render/src/eu/render/world.cc
Line Branch Exec Source
1 #include "eu/render/world.h"
2
3 #include "eu/assert/assert.h"
4
5
6 #include "eu/core/geom.extract.h"
7 #include "eu/render/opengl_utils.h"
8 #include "eu/render/shader.h"
9 #include "eu/core/vertex_layout.h"
10
11 #include <utility>
12
13 namespace eu::render
14 {
15
16 CompiledGeom::CompiledGeom(u32 b, u32 a, u32 e, const core::CompiledGeomVertexAttributes& att, i32 tc)
17 : vbo(b)
18 , vao(a)
19 , ebo(e)
20 , number_of_triangles(tc)
21 , debug_types(att.debug_types.begin(), att.debug_types.end())
22
23 {
24 }
25
26 CompiledGeom_TransformInstance::CompiledGeom_TransformInstance(
27 u32 iv, std::size_t mi, u32 b, u32 a, u32 e, const core::CompiledGeomVertexAttributes& att, i32 tc
28 )
29 : instance_vbo(iv)
30 , max_instances(mi)
31 , vbo(b)
32 , vao(a)
33 , ebo(e)
34 , number_of_triangles(tc)
35 , debug_types(att.debug_types.begin(), att.debug_types.end())
36
37 {
38 }
39
40 std::shared_ptr<MeshInstance> make_mesh_instance(std::shared_ptr<CompiledGeom> geom, std::shared_ptr<Material> mat)
41 {
42 auto instance = std::make_shared<MeshInstance>();
43 instance->geom = std::move(geom);
44 instance->material = std::move(mat);
45 return instance;
46 }
47
48 std::shared_ptr<MeshInstance_TransformInstanced> make_mesh_instance(
49 std::shared_ptr<CompiledGeom_TransformInstance> geom, std::shared_ptr<Material> mat
50 )
51 {
52 auto instance = std::make_shared<MeshInstance_TransformInstanced>();
53 instance->geom = std::move(geom);
54 instance->material = std::move(mat);
55 return instance;
56 }
57
58 std::shared_ptr<CompiledGeom> compile_geom(DEBUG_LABEL_ARG_MANY const core::Geom& geom, const core::CompiledGeomVertexAttributes& geom_layout)
59 {
60 const auto ex = extract_geom(geom, geom_layout);
61
62 const auto vao = create_vertex_array();
63 glBindVertexArray(vao);
64 SET_DEBUG_LABEL_NAMED(vao, DebugLabelFor::VertexArray, fmt::format("VERT {}", debug_label));
65
66 const auto vbo = create_buffer();
67 glBindBuffer(GL_ARRAY_BUFFER, vbo);
68 SET_DEBUG_LABEL_NAMED(vbo, DebugLabelFor::Buffer, fmt::format("ARR BUF {}", debug_label));
69 glBufferData(GL_ARRAY_BUFFER, glsizeiptr_from_sizet(ex.data.size()), ex.data.data(), GL_STATIC_DRAW);
70
71 const auto get_type = [](const core::ExtractedAttribute& extracted) -> GLenum
72 {
73 switch (extracted.type)
74 {
75 case core::ExtractedAttributeType::Float: return GL_FLOAT;
76 default: DIE("invalid extracted attribute"); return GL_FLOAT;
77 }
78 };
79
80 const auto stride = ex.stride;
81 int attrib_location = 0;
82 std::size_t offset = 0;
83 for (const auto& att: ex.attributes)
84 {
85 constexpr auto normalize = false;
86 glVertexAttribPointer(
87 gluint_from_int(attrib_location),
88 att.count,
89 get_type(att),
90 normalize ? GL_TRUE : GL_FALSE,
91 glsizei_from_sizet(stride),
92 reinterpret_cast<void*>(offset)
93 );
94 glEnableVertexAttribArray(gluint_from_int(attrib_location));
95
96 attrib_location += 1;
97 offset += att.size;
98 }
99
100
101 const auto ebo = create_buffer();
102 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
103 SET_DEBUG_LABEL_NAMED(ebo, DebugLabelFor::Buffer, fmt::format("IND BUF {}", debug_label));
104
105 glBufferData(
106 GL_ELEMENT_ARRAY_BUFFER,
107 glsizeiptr_from_sizet(sizeof(u32) * ex.indices.size()),
108 ex.indices.data(),
109 GL_STATIC_DRAW
110 );
111
112 return std::make_shared<CompiledGeom>(vbo, vao, ebo, geom_layout, ex.face_size);
113 }
114
115 CompiledGeom::~CompiledGeom()
116 {
117 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
118 destroy_buffer(ebo);
119
120 glBindBuffer(GL_ARRAY_BUFFER, 0);
121 destroy_buffer(vbo);
122
123 glBindVertexArray(0);
124 destroy_vertex_array(vao);
125 }
126
127 std::shared_ptr<CompiledGeom_TransformInstance> compile_geom_with_transform_instance(
128 DEBUG_LABEL_ARG_MANY
129 const core::Geom& geom, const core::CompiledGeomVertexAttributes& geom_layout, std::size_t max_instances
130 )
131 {
132 const auto ex = extract_geom(geom, geom_layout);
133
134 const auto vao = create_vertex_array();
135 glBindVertexArray(vao);
136 SET_DEBUG_LABEL_NAMED(vao, DebugLabelFor::VertexArray, fmt::format("VERT (in) {}", debug_label));
137
138 const auto vbo = create_buffer();
139 glBindBuffer(GL_ARRAY_BUFFER, vbo);
140 SET_DEBUG_LABEL_NAMED(vbo, DebugLabelFor::Buffer, fmt::format("ARR BUF (in) {}", debug_label));
141 glBufferData(GL_ARRAY_BUFFER, glsizeiptr_from_sizet(ex.data.size()), ex.data.data(), GL_STATIC_DRAW);
142
143 const auto get_type = [](const core::ExtractedAttribute& extracted) -> GLenum
144 {
145 switch (extracted.type)
146 {
147 case core::ExtractedAttributeType::Float: return GL_FLOAT;
148 default: DIE("invalid extracted attribute"); return GL_FLOAT;
149 }
150 };
151
152 const auto stride = ex.stride;
153 int attrib_location = 0;
154 std::size_t offset = 0;
155 for (const auto& att: ex.attributes)
156 {
157 constexpr auto normalize = false;
158 glVertexAttribPointer(
159 gluint_from_int(attrib_location),
160 att.count,
161 get_type(att),
162 normalize ? GL_TRUE : GL_FALSE,
163 glsizei_from_sizet(stride),
164 reinterpret_cast<void*>(offset)
165 );
166 glEnableVertexAttribArray(gluint_from_int(attrib_location));
167
168 attrib_location += 1;
169 offset += att.size;
170 }
171
172 // finally bind instance_vbo data, use a dummy data since the data will be uploaded before rendering
173 // todo(Gustav): is dynamic draw correct?
174 const auto instance_vbo = create_buffer();
175 glBindBuffer(GL_ARRAY_BUFFER, instance_vbo);
176 SET_DEBUG_LABEL_NAMED(instance_vbo, DebugLabelFor::Buffer, fmt::format("ARRAY BUF (trans in) {}", debug_label));
177 constexpr auto instance_size = sizeof(float) * 16;
178 glBufferData(GL_ARRAY_BUFFER, glsizeiptr_from_sizet(instance_size * max_instances), nullptr, GL_DYNAMIC_DRAW);
179
180 for (int matrix = 0; matrix < 4; matrix += 1)
181 {
182 const auto attribute = gluint_from_int(attrib_location + matrix);
183 glVertexAttribPointer(
184 attribute,
185 4,
186 GL_FLOAT,
187 GL_FALSE,
188 instance_size,
189 reinterpret_cast<void*>(sizeof(v4) * static_cast<std::size_t>(matrix))
190 );
191 glEnableVertexAttribArray(attribute);
192 glVertexAttribDivisor(attribute, 1);
193 }
194
195 const auto ebo = create_buffer();
196 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
197 SET_DEBUG_LABEL_NAMED(ebo, DebugLabelFor::Buffer, fmt::format("IND BUF (in) {}", debug_label));
198 glBufferData(
199 GL_ELEMENT_ARRAY_BUFFER,
200 glsizeiptr_from_sizet(sizeof(u32) * ex.indices.size()),
201 ex.indices.data(),
202 GL_STATIC_DRAW
203 );
204
205 return std::make_shared<CompiledGeom_TransformInstance>(
206 instance_vbo, max_instances, vbo, vao, ebo, geom_layout, ex.face_size
207 );
208 }
209
210 LocalAxis MeshInstance::get_local_axis() const
211 {
212 // todo(Gustav): this this work with the matrix now including both rotation ADN translation? is it used anymore?
213 return {
214 .x = transform.get_transformed_vec(v3{1, 0, 0}),
215 .y = transform.get_transformed_vec(v3{0, 1, 0}),
216 .z = transform.get_transformed_vec(v3{0, 0, 1})
217 };
218 }
219
220 void render_geom(const CompiledGeom& geom)
221 {
222 ASSERT(is_bound_for_shader(geom.debug_types));
223 glBindVertexArray(geom.vao);
224 glDrawElements(GL_TRIANGLES, geom.number_of_triangles * 3, GL_UNSIGNED_INT, nullptr);
225 }
226
227 void render_geom_instanced(const MeshInstance_TransformInstanced& instanced)
228 {
229 auto* geom = instanced.geom.get();
230 ASSERT(is_bound_for_shader(geom->debug_types));
231 ASSERT(! instanced.world_from_locals.empty());
232
233 for (std::size_t start_index = 0; start_index < instanced.world_from_locals.size();
234 start_index += instanced.geom->max_instances)
235 {
236 const std::size_t step_size
237 = std::min(instanced.world_from_locals.size() - start_index, instanced.geom->max_instances);
238 glBindBuffer(GL_ARRAY_BUFFER, instanced.geom->instance_vbo);
239 glBufferSubData(
240 GL_ARRAY_BUFFER, 0, glsizeiptr_from_sizet(sizeof(m4) * step_size), &instanced.world_from_locals[start_index]
241 );
242
243 glBindVertexArray(geom->vao);
244 glDrawElementsInstanced(
245 GL_TRIANGLES,
246 geom->number_of_triangles * 3,
247 GL_UNSIGNED_INT,
248 nullptr,
249 glsizei_from_sizet(instanced.world_from_locals.size())
250 );
251 }
252 }
253
254 CompiledGeom_TransformInstance::~CompiledGeom_TransformInstance()
255 {
256 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
257 destroy_buffer(ebo);
258
259 glBindBuffer(GL_ARRAY_BUFFER, 0);
260 destroy_buffer(vbo);
261 destroy_buffer(instance_vbo);
262
263 glBindVertexArray(0);
264 destroy_vertex_array(vao);
265 }
266
267 CameraVectors create_vectors(const DirectionalLight& p)
268 {
269 return create_vectors(p.rotation);
270 }
271
272 } // namespace eu::render
273