./
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
0 / 237
0.0%
Branches:
0 / 413
0.0%
Functions:
0 / 18
0.0%

libs/render/src/eu/render/renderer.cc
Line Branch Exec Source
1 #include "eu/render/renderer.h"
2
3 #include <algorithm>
4
5 #include "eu/log/log.h"
6
7 #include "eu/render/camera.h"
8 #include "eu/render/fullscreen.h"
9 #include "eu/core/geom.builder.h"
10 #include "eu/core/geom.h"
11 #include "eu/render/opengl_utils.h"
12 #include "eu/render/renderer.pimpl.h"
13 #include "eu/render/state.h"
14 #include "eu/render/constants.h"
15
16 namespace eu::render
17 {
18
19 ✗ Renderer::Renderer(State* states, Assets* default_assets, const RenderSettings& set)
20 ✗ : assets(default_assets)
21 ✗ , settings(set)
22
0/4
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 9 not taken.
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 7 not taken.
✗ , pimpl(std::make_unique<RendererPimpl>(states, *assets, set, FullScreenGeom{}))
23 {
24 ✗ }
25
26 ✗ Renderer::~Renderer() = default;
27
28 ✗ Skybox Renderer::make_skybox(std::shared_ptr<TextureCubemap> texture) const
29 {
30 ✗ constexpr float size = 1.0f;
31
32
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 51 not taken.
✗ const auto layout = pimpl->shaders_resources.skybox_shader.geom_layout;
33
34
0/4
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 34 not taken.
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 32 not taken.
✗ const auto triangle = core::geom::create_box(size, size, size, core::geom::NormalsFacing::In, colors::white).to_geom();
35
0/4
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 37 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 35 not taken.
✗ auto geom = compile_geom(USE_DEBUG_LABEL_MANY("skybox") triangle, layout);
36
37
0/6
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 45 not taken.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 43 not taken.
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 41 not taken.
✗ LOG_INFO("Created skybox");
38 ✗ return {geom, std::move(texture)};
39
0/2
✗ Branch 22 → 23 not taken.
✗ Branch 22 → 24 not taken.
✗ }
40
41 struct TransparentMesh
42 {
43 std::shared_ptr<MeshInstance> mesh;
44 float squared_distance_to_camera;
45 };
46
47 ✗ std::shared_ptr<UnlitMaterial> Renderer::make_unlit_material() const
48 {
49 ✗ return std::make_shared<UnlitMaterial>(pimpl->shaders_resources);
50 }
51
52 ✗ std::shared_ptr<DefaultMaterial> Renderer::make_default_material() const
53 {
54 ✗ return std::make_shared<DefaultMaterial>(pimpl->shaders_resources);
55 }
56
57 ✗ core::CompiledGeomVertexAttributes Renderer::unlit_geom_layout() const
58 {
59 ✗ return pimpl->shaders_resources.unlit_shader_container.geom_layout;
60 }
61
62 ✗ core::CompiledGeomVertexAttributes Renderer::default_geom_layout() const
63 {
64 ✗ return pimpl->shaders_resources.default_shader_container.geom_layout;
65 }
66
67 ✗ bool Renderer::is_loaded() const
68 {
69
0/4
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 9 not taken.
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 9 not taken.
✗ return pimpl->shaders_resources.is_loaded() && pimpl->debug_drawer.is_loaded();
70 }
71
72 ✗ m4 transform_from_rotation(const v3& position, const Ypr& ypr)
73 {
74
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 10 not taken.
✗ const auto translation = m4::from_translation(position);
75
0/4
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 9 not taken.
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 9 not taken.
✗ const auto rotation = m4::from(Q::from(ypr));
76
0/2
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 10 not taken.
✗ return translation * rotation;
77 }
78 ✗ m4 transform_from_billboard(const v3& position, Billboarding billboarding, const CompiledCamera& cc)
79 {
80 ✗ const auto calc_fixed_right = [](const n3& normal, const n3& up)
81 {
82
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 10 not taken.
✗ const auto right = normal.cross_norm(up).value_or(kk::right);
83
0/2
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 11 not taken.
✗ const auto new_up = right.cross_norm(normal).value_or(kk::up);
84
0/2
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 12 not taken.
✗ return m4::from_basis(right, new_up, normal);
85 };
86
87 ✗ const auto calc_fixed_up = [](const n3& normal, const n3& up)
88 {
89
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 10 not taken.
✗ const auto right = normal.cross_norm(up).value_or(kk::right);
90
0/2
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 11 not taken.
✗ const auto new_normal = right.cross_norm(up).value_or(kk::up);
91
0/2
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 12 not taken.
✗ return m4::from_basis(right, up, new_normal);
92 };
93
94
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 49 not taken.
✗ const auto translation = m4::from_translation(position);
95
96 // todo(Gustav): verify that the billboards are oriented correctly, grass in example 3 is twosided...
97
0/5
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 11 not taken.
✗ Branch 3 → 15 not taken.
✗ Branch 3 → 22 not taken.
✗ Branch 3 → 26 not taken.
✗ switch (billboarding)
98 {
99 ✗ case Billboarding::screen:
100 {
101
0/6
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 35 not taken.
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 35 not taken.
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 35 not taken.
✗ const auto rotation = calc_fixed_right(v3::from_to(cc.position, position).get_normalized().value_or(kk::in), kk::up);
102
0/2
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 38 not taken.
✗ return translation * rotation;
103 }
104 ✗ case Billboarding::screen_fast:
105 {
106 // todo(Gustav): move to precalculated or remove?
107
0/2
✗ Branch 11 → 12 not taken.
✗ Branch 11 → 39 not taken.
✗ const auto rotation = calc_fixed_right(cc.in, kk::up);
108
0/2
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 39 not taken.
✗ return translation * rotation;
109 }
110 ✗ case Billboarding::axial_y:
111 {
112
0/6
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 40 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 40 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 40 not taken.
✗ const auto rotation = calc_fixed_up(v3::from_to(cc.position, position).get_normalized().value_or(kk::in), kk::up);
113
0/2
✗ Branch 19 → 20 not taken.
✗ Branch 19 → 43 not taken.
✗ return translation * rotation;
114 }
115 ✗ case Billboarding::axial_y_fast:
116 {
117 // todo(Gustav): move to precalculated or remove?
118
0/2
✗ Branch 22 → 23 not taken.
✗ Branch 22 → 44 not taken.
✗ const auto rotation = calc_fixed_up(cc.in, kk::up);
119
0/2
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 44 not taken.
✗ return translation * rotation;
120 }
121 ✗ default:
122 {
123
0/2
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 45 not taken.
✗ DIE("invalid billboarding");
124
0/2
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 48 not taken.
✗ const auto rotation = calc_fixed_up(cc.in, kk::up);
125
0/2
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 48 not taken.
✗ return translation * rotation;
126 }
127
128 }
129 };
130
131 ✗ void batch_lines(LineDrawer* drawer, const std::vector<DebugLine>& debug_lines, float gamma)
132 {
133
0/2
✗ Branch 17 → 4 not taken.
✗ Branch 17 → 18 not taken.
✗ for (const auto& line: debug_lines)
134 {
135
0/4
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 20 not taken.
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 20 not taken.
✗ drawer->line(line.from, line.to, linear_from_srgb(line.color, gamma));
136 }
137 ✗ drawer->submit();
138 ✗ }
139
140 ✗ void render_debug_lines(const std::vector<DebugLine>& debug_lines, State* states, LineDrawer* drawer, const CompiledCamera& compiled_camera, const Size& window_size, float gamma)
141 {
142
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
✗ if (debug_lines.empty())
143 {
144 ✗ return;
145 }
146
147 ✗ drawer->shader.use();
148 ✗ drawer->set_camera(compiled_camera);
149
150
0/6
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 21 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 21 not taken.
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 21 not taken.
✗ StateChanger{states}.depth_func(Compare::less_equal).depth_test(true);
151 ✗ drawer->set_line_to_solid();
152 ✗ batch_lines(drawer, debug_lines, gamma);
153
154
0/6
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 22 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 22 not taken.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 22 not taken.
✗ StateChanger{states}.depth_func(Compare::greater).depth_test(true);
155
0/2
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 23 not taken.
✗ drawer->set_line_to_dash({float_from_int(window_size.width), float_from_int(window_size.height)}, 20.0f, 20.0f);
156 ✗ batch_lines(drawer, debug_lines, gamma);
157 }
158
159 ✗ void Renderer::render_world(const Size& window_size, const World& world, const CompiledCamera& compiled_camera, const ShadowContext& shadow_context)
160 {
161
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 348 not taken.
✗ SCOPED_DEBUG_GROUP("render world call"sv);
162
0/2
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 346 not taken.
✗ const auto has_outlined_meshes = std::ranges::any_of(world.meshes,
163 ✗ [](const auto& mesh) { return mesh->outline.has_value(); }
164 );
165
0/2
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 292 not taken.
✗ StateChanger{pimpl->states}
166
0/2
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 292 not taken.
✗ .cull_face(true)
167
0/2
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 292 not taken.
✗ .cull_face_mode(CullFace::back)
168
0/2
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 292 not taken.
✗ .stencil_mask(0xFF)
169
0/2
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 292 not taken.
✗ .stencil_test(has_outlined_meshes)
170
0/2
✗ Branch 11 → 12 not taken.
✗ Branch 11 → 292 not taken.
✗ .depth_test(true)
171
0/2
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 292 not taken.
✗ .depth_mask(true)
172
0/2
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 292 not taken.
✗ .stencil_op(StencilAction::keep, StencilAction::replace, StencilAction::replace)
173
0/2
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 292 not taken.
✗ .blend_mode(Blend::src_alpha, Blend::one_minus_src_alpha);
174
175
0/2
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 346 not taken.
✗ const auto clear_color = linear_from_srgb(world.clear_color, settings.gamma);
176
0/2
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 346 not taken.
✗ glClearColor(clear_color.r, clear_color.g, clear_color.b, 1.0f);
177
0/2
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 346 not taken.
✗ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
178
179
0/2
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 346 not taken.
✗ auto bound_camera_buffer = BoundUniformBuffer{pimpl->camera_uniform_buffer.buffer.get()};
180
0/2
✗ Branch 22 → 23 not taken.
✗ Branch 22 → 344 not taken.
✗ pimpl->camera_uniform_buffer.set_props(compiled_camera);
181
182 ✗ std::vector<TransparentMesh> transparent_meshes;
183
184 // render solids
185 {
186
0/2
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 94 not taken.
✗ if (world.meshes.empty() == false)
187 {
188
0/2
✗ Branch 26 → 27 not taken.
✗ Branch 26 → 308 not taken.
✗ SCOPED_DEBUG_GROUP("render basic geom"sv);
189
0/2
✗ Branch 91 → 29 not taken.
✗ Branch 91 → 92 not taken.
✗ for (const auto& mesh: world.meshes)
190 {
191 const auto not_transparent_context
192 ✗ = RenderContext{TransformSource::uniform, UseTransparency::no, settings.gamma, &shadow_context};
193
194
0/4
✗ Branch 34 → 35 not taken.
✗ Branch 34 → 304 not taken.
✗ Branch 35 → 36 not taken.
✗ Branch 35 → 46 not taken.
✗ if (mesh->material->is_transparent())
195 {
196 ✗ transparent_meshes.emplace_back(
197
0/4
✗ Branch 41 → 42 not taken.
✗ Branch 41 → 293 not taken.
✗ Branch 297 → 298 not taken.
✗ Branch 297 → 299 not taken.
✗ TransparentMesh{
198 .mesh = mesh,
199
0/6
✗ Branch 38 → 39 not taken.
✗ Branch 38 → 295 not taken.
✗ Branch 39 → 40 not taken.
✗ Branch 39 → 295 not taken.
✗ Branch 43 → 44 not taken.
✗ Branch 43 → 45 not taken.
✗ .squared_distance_to_camera = v3::from_to(compiled_camera.position, mesh->transform.get_translation()).get_length_squared()
200 }
201 );
202
203 ✗ continue;
204 }
205
0/2
✗ Branch 47 → 48 not taken.
✗ Branch 47 → 301 not taken.
✗ StateChanger{pimpl->states}
206
0/2
✗ Branch 48 → 49 not taken.
✗ Branch 48 → 301 not taken.
✗ .depth_test(true)
207
0/2
✗ Branch 49 → 50 not taken.
✗ Branch 49 → 301 not taken.
✗ .depth_mask(true)
208
0/2
✗ Branch 50 → 51 not taken.
✗ Branch 50 → 301 not taken.
✗ .depth_func(Compare::less)
209
0/2
✗ Branch 51 → 52 not taken.
✗ Branch 51 → 301 not taken.
✗ .blending(false)
210
0/2
✗ Branch 52 → 53 not taken.
✗ Branch 52 → 301 not taken.
✗ .stencil_mask(0x0)
211
0/2
✗ Branch 53 → 54 not taken.
✗ Branch 53 → 301 not taken.
✗ .stencil_func(Compare::always, 1, 0xFF);
212
213
0/2
✗ Branch 56 → 57 not taken.
✗ Branch 56 → 62 not taken.
✗ if (mesh->outline)
214 {
215
0/6
✗ Branch 58 → 59 not taken.
✗ Branch 58 → 302 not taken.
✗ Branch 59 → 60 not taken.
✗ Branch 59 → 302 not taken.
✗ Branch 60 → 61 not taken.
✗ Branch 60 → 302 not taken.
✗ StateChanger{pimpl->states}.stencil_func(Compare::always, 1, 0xFF).stencil_mask(0xFF);
216 }
217
0/2
✗ Branch 64 → 65 not taken.
✗ Branch 64 → 304 not taken.
✗ mesh->material->use_shader(not_transparent_context);
218
0/2
✗ Branch 69 → 70 not taken.
✗ Branch 69 → 303 not taken.
✗ mesh->material->set_uniforms(
219 ✗ not_transparent_context, compiled_camera, mesh->transform
220 );
221
0/2
✗ Branch 73 → 74 not taken.
✗ Branch 73 → 304 not taken.
✗ mesh->material->bind_textures(not_transparent_context, pimpl->states, assets);
222
0/2
✗ Branch 77 → 78 not taken.
✗ Branch 77 → 304 not taken.
✗ mesh->material->apply_lights(not_transparent_context, world.lights, settings, pimpl->states, assets);
223
224
0/2
✗ Branch 80 → 81 not taken.
✗ Branch 80 → 304 not taken.
✗ render_geom(*mesh->geom);
225 }
226 ✗ }
227
228
0/2
✗ Branch 95 → 96 not taken.
✗ Branch 95 → 140 not taken.
✗ if (world.instances.empty() == false)
229 {
230
0/2
✗ Branch 97 → 98 not taken.
✗ Branch 97 → 315 not taken.
✗ SCOPED_DEBUG_GROUP("render instances"sv);
231
0/2
✗ Branch 137 → 100 not taken.
✗ Branch 137 → 138 not taken.
✗ for (const auto& instance: world.instances)
232 {
233 ✗ const auto not_transparent_context = RenderContext{TransformSource::instanced_mat4, UseTransparency::no, settings.gamma, &shadow_context};
234
235
0/2
✗ Branch 104 → 105 not taken.
✗ Branch 104 → 309 not taken.
✗ StateChanger{pimpl->states}
236
0/2
✗ Branch 105 → 106 not taken.
✗ Branch 105 → 309 not taken.
✗ .depth_test(true)
237
0/2
✗ Branch 106 → 107 not taken.
✗ Branch 106 → 309 not taken.
✗ .depth_mask(true)
238
0/2
✗ Branch 107 → 108 not taken.
✗ Branch 107 → 309 not taken.
✗ .depth_func(Compare::less)
239
0/2
✗ Branch 108 → 109 not taken.
✗ Branch 108 → 309 not taken.
✗ .blending(false)
240
0/2
✗ Branch 109 → 110 not taken.
✗ Branch 109 → 309 not taken.
✗ .stencil_mask(0x0)
241
0/2
✗ Branch 110 → 111 not taken.
✗ Branch 110 → 309 not taken.
✗ .stencil_func(Compare::always, 1, 0xFF);
242
0/2
✗ Branch 113 → 114 not taken.
✗ Branch 113 → 311 not taken.
✗ instance->material->use_shader(not_transparent_context);
243
0/2
✗ Branch 117 → 118 not taken.
✗ Branch 117 → 310 not taken.
✗ instance->material->set_uniforms(
244 // todo(Gustav): should we really set the model matrix for instanced meshes?
245 not_transparent_context,
246 compiled_camera,
247 ✗ std::nullopt
248 );
249
0/2
✗ Branch 121 → 122 not taken.
✗ Branch 121 → 311 not taken.
✗ instance->material->bind_textures(not_transparent_context, pimpl->states, assets);
250 ✗ instance->material->apply_lights(
251
0/2
✗ Branch 125 → 126 not taken.
✗ Branch 125 → 311 not taken.
✗ not_transparent_context, world.lights, settings, pimpl->states, assets
252 );
253
254
0/2
✗ Branch 127 → 128 not taken.
✗ Branch 127 → 311 not taken.
✗ render_geom_instanced(*instance);
255 }
256 ✗ }
257
258
0/2
✗ Branch 141 → 142 not taken.
✗ Branch 141 → 149 not taken.
✗ if (debug.lines.empty() == false)
259 {
260
0/2
✗ Branch 143 → 144 not taken.
✗ Branch 143 → 318 not taken.
✗ SCOPED_DEBUG_GROUP("render debug lines"sv);
261 ✗ render_debug_lines(
262
0/2
✗ Branch 146 → 147 not taken.
✗ Branch 146 → 316 not taken.
✗ debug.lines, pimpl->states, &pimpl->debug_drawer, compiled_camera, window_size, settings.gamma
263 );
264 ✗ }
265 }
266
267 // todo(Gustav): should this be done at the start of the update so the renderer can be "const"
268 ✗ debug.lines.clear();
269
270 // render skybox
271
0/8
✗ Branch 151 → 152 not taken.
✗ Branch 151 → 159 not taken.
✗ Branch 154 → 155 not taken.
✗ Branch 154 → 159 not taken.
✗ Branch 157 → 158 not taken.
✗ Branch 157 → 159 not taken.
✗ Branch 160 → 161 not taken.
✗ Branch 160 → 183 not taken.
✗ if (world.skybox && world.skybox->cubemap != nullptr && world.skybox->geom != nullptr)
272 {
273
0/2
✗ Branch 162 → 163 not taken.
✗ Branch 162 → 322 not taken.
✗ SCOPED_DEBUG_GROUP("render skybox"sv);
274
0/2
✗ Branch 164 → 165 not taken.
✗ Branch 164 → 319 not taken.
✗ StateChanger{pimpl->states}
275
0/2
✗ Branch 165 → 166 not taken.
✗ Branch 165 → 319 not taken.
✗ .depth_test(true)
276
0/2
✗ Branch 166 → 167 not taken.
✗ Branch 166 → 319 not taken.
✗ .depth_mask(false)
277
0/2
✗ Branch 167 → 168 not taken.
✗ Branch 167 → 319 not taken.
✗ .depth_func(Compare::less_equal)
278
0/2
✗ Branch 168 → 169 not taken.
✗ Branch 168 → 319 not taken.
✗ .blending(false)
279
0/2
✗ Branch 169 → 170 not taken.
✗ Branch 169 → 319 not taken.
✗ .stencil_mask(0x0)
280
0/2
✗ Branch 170 → 171 not taken.
✗ Branch 170 → 319 not taken.
✗ .stencil_func(Compare::always, 1, 0xFF);
281
282 ✗ auto& shader = pimpl->shaders_resources.skybox_shader;
283
284
0/2
✗ Branch 173 → 174 not taken.
✗ Branch 173 → 320 not taken.
✗ shader.program->use();
285
0/2
✗ Branch 177 → 178 not taken.
✗ Branch 177 → 320 not taken.
✗ bind_texture_cubemap(pimpl->states, shader.tex_skybox_uniform, *world.skybox->cubemap);
286
287
0/2
✗ Branch 180 → 181 not taken.
✗ Branch 180 → 320 not taken.
✗ render_geom(*world.skybox->geom);
288 ✗ }
289
290
0/2
✗ Branch 185 → 186 not taken.
✗ Branch 185 → 342 not taken.
✗ std::sort(
291 transparent_meshes.begin(),
292 transparent_meshes.end(),
293 ✗ [](const auto& lhs, const auto& rhs) { return lhs.squared_distance_to_camera > rhs.squared_distance_to_camera; }
294 );
295
296
0/2
✗ Branch 187 → 188 not taken.
✗ Branch 187 → 242 not taken.
✗ if (transparent_meshes.empty() == false)
297 {
298
0/2
✗ Branch 189 → 190 not taken.
✗ Branch 189 → 330 not taken.
✗ SCOPED_DEBUG_GROUP("render transparent meshes"sv);
299
0/2
✗ Branch 239 → 192 not taken.
✗ Branch 239 → 240 not taken.
✗ for (auto& transparent_mesh: transparent_meshes)
300 {
301 ✗ const auto transparent_context = RenderContext{TransformSource::uniform, UseTransparency::yes, settings.gamma, &shadow_context};
302
303 ✗ const auto& mesh = transparent_mesh.mesh;
304
0/2
✗ Branch 196 → 197 not taken.
✗ Branch 196 → 323 not taken.
✗ StateChanger{pimpl->states}
305
0/2
✗ Branch 197 → 198 not taken.
✗ Branch 197 → 323 not taken.
✗ .depth_test(true)
306
0/2
✗ Branch 198 → 199 not taken.
✗ Branch 198 → 323 not taken.
✗ .depth_mask(true)
307
0/2
✗ Branch 199 → 200 not taken.
✗ Branch 199 → 323 not taken.
✗ .depth_func(Compare::less)
308
0/2
✗ Branch 200 → 201 not taken.
✗ Branch 200 → 323 not taken.
✗ .blending(true)
309
0/2
✗ Branch 201 → 202 not taken.
✗ Branch 201 → 323 not taken.
✗ .stencil_mask(0x0)
310
0/2
✗ Branch 202 → 203 not taken.
✗ Branch 202 → 323 not taken.
✗ .stencil_func(Compare::always, 1, 0xFF);
311
312
0/2
✗ Branch 205 → 206 not taken.
✗ Branch 205 → 211 not taken.
✗ if (mesh->outline)
313 {
314
0/6
✗ Branch 207 → 208 not taken.
✗ Branch 207 → 324 not taken.
✗ Branch 208 → 209 not taken.
✗ Branch 208 → 324 not taken.
✗ Branch 209 → 210 not taken.
✗ Branch 209 → 324 not taken.
✗ StateChanger{pimpl->states}.stencil_func(Compare::always, 1, 0xFF).stencil_mask(0xFF);
315 }
316
0/2
✗ Branch 213 → 214 not taken.
✗ Branch 213 → 326 not taken.
✗ mesh->material->use_shader(transparent_context);
317
0/2
✗ Branch 218 → 219 not taken.
✗ Branch 218 → 325 not taken.
✗ mesh->material->set_uniforms(transparent_context, compiled_camera, mesh->transform);
318
0/2
✗ Branch 222 → 223 not taken.
✗ Branch 222 → 326 not taken.
✗ mesh->material->bind_textures(transparent_context, pimpl->states, assets);
319
0/2
✗ Branch 226 → 227 not taken.
✗ Branch 226 → 326 not taken.
✗ mesh->material->apply_lights(transparent_context, world.lights, settings, pimpl->states, assets);
320
321
0/2
✗ Branch 229 → 230 not taken.
✗ Branch 229 → 326 not taken.
✗ render_geom(*mesh->geom);
322 }
323 ✗ }
324
325 // render outline over all other meshes
326
0/2
✗ Branch 242 → 243 not taken.
✗ Branch 242 → 288 not taken.
✗ if (has_outlined_meshes)
327 {
328
0/2
✗ Branch 244 → 245 not taken.
✗ Branch 244 → 341 not taken.
✗ SCOPED_DEBUG_GROUP("render outline meshes"sv);
329
0/2
✗ Branch 285 → 247 not taken.
✗ Branch 285 → 286 not taken.
✗ for (const auto& mesh: world.meshes)
330 {
331
0/2
✗ Branch 251 → 252 not taken.
✗ Branch 251 → 276 not taken.
✗ if (const auto& mesh_outline = mesh->outline)
332 {
333
0/2
✗ Branch 253 → 254 not taken.
✗ Branch 253 → 331 not taken.
✗ StateChanger{pimpl->states}
334
0/2
✗ Branch 254 → 255 not taken.
✗ Branch 254 → 331 not taken.
✗ .stencil_func(Compare::not_equal, 1, 0xFF)
335
0/2
✗ Branch 255 → 256 not taken.
✗ Branch 255 → 331 not taken.
✗ .stencil_mask(0x00)
336
0/2
✗ Branch 256 → 257 not taken.
✗ Branch 256 → 331 not taken.
✗ .depth_test(false);
337
0/2
✗ Branch 258 → 259 not taken.
✗ Branch 258 → 332 not taken.
✗ const m4 small_scale_mat = m4::from_scale(v3{ kk::outline_scale, kk::outline_scale, kk::outline_scale});
338
339 ✗ auto& shader = pimpl->shaders_resources.single_color_shader;
340
0/2
✗ Branch 261 → 262 not taken.
✗ Branch 261 → 337 not taken.
✗ shader.program->use();
341
0/8
✗ Branch 264 → 265 not taken.
✗ Branch 264 → 333 not taken.
✗ Branch 265 → 266 not taken.
✗ Branch 265 → 333 not taken.
✗ Branch 266 → 267 not taken.
✗ Branch 266 → 333 not taken.
✗ Branch 267 → 268 not taken.
✗ Branch 267 → 333 not taken.
✗ shader.program->set_vec4(shader.tint_color_uni, v4{vec_from_lin(linear_from_srgb(*mesh_outline, settings.gamma)), 1});
342
343
0/4
✗ Branch 270 → 271 not taken.
✗ Branch 270 → 336 not taken.
✗ Branch 271 → 272 not taken.
✗ Branch 271 → 336 not taken.
✗ shader.program->set_mat(shader.world_from_local_uni, mesh->transform * small_scale_mat);
344
345
0/2
✗ Branch 274 → 275 not taken.
✗ Branch 274 → 337 not taken.
✗ render_geom(*mesh->geom);
346 }
347 }
348 ✗ }
349 ✗ }
350
351 ✗ void Renderer::render_shadows(const Size& window_size, const World& world, const CompiledCamera& compiled_camera) const
352 {
353 // todo(Gustav): bind less colors and use depth only shaders
354
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 140 not taken.
✗ SCOPED_DEBUG_GROUP("render shadows call"sv);
355
0/2
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 117 not taken.
✗ StateChanger{pimpl->states}
356
0/2
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 117 not taken.
✗ .cull_face(true)
357
0/2
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 117 not taken.
✗ .cull_face_mode(CullFace::back)
358
0/2
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 117 not taken.
✗ .depth_test(true)
359
0/2
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 117 not taken.
✗ .depth_mask(true);
360
361
0/2
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 138 not taken.
✗ glClear(GL_DEPTH_BUFFER_BIT);
362
363
0/2
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 138 not taken.
✗ auto bound_camera_buffer = BoundUniformBuffer{pimpl->camera_uniform_buffer.buffer.get()};
364
0/2
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 136 not taken.
✗ pimpl->camera_uniform_buffer.set_props(compiled_camera);
365
366 // todo(Gustav): change shader to something that doesn't write color
367
368
0/2
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 118 not taken.
✗ StateChanger{pimpl->states}
369
0/2
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 118 not taken.
✗ .depth_test(true)
370
0/2
✗ Branch 19 → 20 not taken.
✗ Branch 19 → 118 not taken.
✗ .depth_mask(true)
371
0/2
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 118 not taken.
✗ .depth_func(Compare::less)
372
0/2
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 118 not taken.
✗ .blending(false)
373
0/2
✗ Branch 22 → 23 not taken.
✗ Branch 22 → 118 not taken.
✗ .stencil_mask(0x0)
374
0/2
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 118 not taken.
✗ .stencil_func(Compare::always, 1, 0xFF);
375
376 // render solids
377 {
378
0/2
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 72 not taken.
✗ if (world.meshes.empty() == false)
379 {
380
0/2
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 125 not taken.
✗ SCOPED_DEBUG_GROUP("render basic geom"sv);
381
0/2
✗ Branch 69 → 30 not taken.
✗ Branch 69 → 70 not taken.
✗ for (const auto& mesh: world.meshes)
382 {
383
0/4
✗ Branch 34 → 35 not taken.
✗ Branch 34 → 122 not taken.
✗ Branch 35 → 36 not taken.
✗ Branch 35 → 37 not taken.
✗ if (mesh->material->is_transparent())
384 {
385 ✗ continue;
386 }
387
388 ✗ auto& shader = pimpl->shaders_resources.depth_transform_uniform;
389
0/2
✗ Branch 39 → 40 not taken.
✗ Branch 39 → 122 not taken.
✗ shader.program->use();
390
391 // todo(Gustav): the depth shader should not be a shared type between transform uniform and instanced, this should be verified at compile time with different types
392
0/8
✗ Branch 41 → 42 not taken.
✗ Branch 41 → 48 not taken.
✗ Branch 42 → 43 not taken.
✗ Branch 42 → 122 not taken.
✗ Branch 43 → 44 not taken.
✗ Branch 43 → 48 not taken.
✗ Branch 45 → 46 not taken.
✗ Branch 45 → 119 not taken.
✗ ASSERT(shader.world_from_local_uni.has_value());
393
0/2
✗ Branch 49 → 50 not taken.
✗ Branch 49 → 54 not taken.
✗ if (shader.world_from_local_uni)
394 {
395
0/2
✗ Branch 53 → 54 not taken.
✗ Branch 53 → 122 not taken.
✗ shader.program->set_mat(*shader.world_from_local_uni, mesh->transform);
396 }
397
398
0/2
✗ Branch 55 → 56 not taken.
✗ Branch 55 → 57 not taken.
✗ if (mesh->billboarding != Billboarding::none)
399 {
400 ✗ continue;
401 }
402
0/2
✗ Branch 59 → 60 not taken.
✗ Branch 59 → 122 not taken.
✗ render_geom(*mesh->geom);
403 }
404 ✗ }
405
406
0/2
✗ Branch 73 → 74 not taken.
✗ Branch 73 → 105 not taken.
✗ if (world.instances.empty() == false)
407 {
408
0/2
✗ Branch 75 → 76 not taken.
✗ Branch 75 → 132 not taken.
✗ SCOPED_DEBUG_GROUP("render instances"sv);
409
0/2
✗ Branch 102 → 78 not taken.
✗ Branch 102 → 103 not taken.
✗ for (const auto& instance: world.instances)
410 {
411 ✗ auto& shader = pimpl->shaders_resources.depth_transform_instanced_mat4;
412
0/2
✗ Branch 82 → 83 not taken.
✗ Branch 82 → 129 not taken.
✗ shader.program->use();
413
0/8
✗ Branch 84 → 85 not taken.
✗ Branch 84 → 91 not taken.
✗ Branch 85 → 86 not taken.
✗ Branch 85 → 129 not taken.
✗ Branch 86 → 87 not taken.
✗ Branch 86 → 91 not taken.
✗ Branch 88 → 89 not taken.
✗ Branch 88 → 126 not taken.
✗ ASSERT(shader.world_from_local_uni.has_value() == false);
414
415
0/2
✗ Branch 92 → 93 not taken.
✗ Branch 92 → 129 not taken.
✗ render_geom_instanced(*instance);
416 }
417 ✗ }
418
419
0/2
✗ Branch 106 → 107 not taken.
✗ Branch 106 → 114 not taken.
✗ if (debug.lines.empty() == false)
420 {
421
0/2
✗ Branch 108 → 109 not taken.
✗ Branch 108 → 135 not taken.
✗ SCOPED_DEBUG_GROUP("render debug lines"sv);
422 ✗ render_debug_lines(
423
0/2
✗ Branch 111 → 112 not taken.
✗ Branch 111 → 133 not taken.
✗ debug.lines, pimpl->states, &pimpl->debug_drawer, compiled_camera, window_size, settings.gamma
424 );
425 ✗ }
426 }
427 ✗ }
428
429 } // namespace eu::render
430