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 160, 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::vertex_array, 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::vertex_array, 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