./
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
0 / 119
0.0%
Branches:
0 / 266
0.0%
Functions:
0 / 2
0.0%

libs/mrgui/examples/main.cc
Line Branch Exec Source
1 // todo(Gustav): look into glad support
2 #define SDL_FUNCTION_POINTER_IS_VOID_POINTER
3
4 #include "SDL.h"
5 #include "SDL_timer.h"
6
7 #include <cassert>
8 #include <optional>
9 #include <vector>
10 #include <unordered_map>
11 #include <string>
12 #include <algorithm>
13 #include <cstdint>
14
15 #include "dependency_glad.h"
16 #include "OpenSans-Regular.ttf.h"
17 #include "uv-texture.png.h"
18 #include "spritesheet.png.h"
19
20 #include "eu/log/log.h"
21 #include "eu/base/memorychunk.h"
22
23 #include "eu/render/canvas.h"
24 #include "eu/render/state.h"
25 #include "eu/render/font.h"
26 #include "eu/render/opengl_utils.h"
27 #include "eu/render/texture.io.h"
28 #include "eu/render/enable_high_performance_graphics.h"
29
30 #include "data/spritesheet.h"
31
32 #include "eu/mrgui/widgets.h"
33
34 using namespace eu::mrgui;
35
36 ENABLE_HIGH_PERFORMANCE_GRAPHICS
37
38 ✗ static eu::MemoryChunk chunk_from_embed(const embedded_binary& binary)
39 {
40 return
41 {
42 ✗ .bytes = reinterpret_cast<const char*>(binary.data),
43 ✗ .size = binary.size
44 ✗ };
45 }
46
47 ✗ int main(int, char**)
48 {
49 ✗ int window_width = 1280;
50 ✗ int window_height = 720;
51
52
0/4
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 432 not taken.
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 10 not taken.
✗ if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) == false) {
53
0/8
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 432 not taken.
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 260 not taken.
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 259 not taken.
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 257 not taken.
✗ LOG_ERR("Error initializing SDL: {}", SDL_GetError());
54 ✗ return -1;
55 }
56
57
58 #ifdef __APPLE__
59 // GL 3.2 Core + GLSL 150
60 const char* glsl_version = "#version 150";
61 SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); // Always required on Mac
62 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
63 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
64 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
65 #else
66 // GL 3.0 + GLSL 130
67 // const char* glsl_version = "#version 130";
68
0/2
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 432 not taken.
✗ SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
69
0/2
✗ Branch 11 → 12 not taken.
✗ Branch 11 → 432 not taken.
✗ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
70
0/2
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 432 not taken.
✗ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
71
0/2
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 432 not taken.
✗ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); // was 0 in dear imgui example??
72 #endif
73
74
0/2
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 432 not taken.
✗ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
75
0/2
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 432 not taken.
✗ SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
76
77
0/2
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 432 not taken.
✗ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
78
0/2
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 432 not taken.
✗ SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
79
80
0/2
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 432 not taken.
✗ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
81
0/2
✗ Branch 19 → 20 not taken.
✗ Branch 19 → 432 not taken.
✗ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
82
0/2
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 432 not taken.
✗ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
83
0/2
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 432 not taken.
✗ SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
84
85
0/2
✗ Branch 22 → 23 not taken.
✗ Branch 22 → 432 not taken.
✗ SDL_Window* window = SDL_CreateWindow("mrgui sample",
86 window_width, window_height, SDL_WINDOW_OPENGL | SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_RESIZABLE);
87
0/2
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 30 not taken.
✗ if (window == nullptr) {
88
0/8
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 432 not taken.
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 265 not taken.
✗ Branch 26 → 27 not taken.
✗ Branch 26 → 264 not taken.
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 262 not taken.
✗ LOG_ERR("Error creating window: {}", SDL_GetError());
89 ✗ return -1;
90 }
91
92
0/2
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 432 not taken.
✗ auto* gl_context = SDL_GL_CreateContext(window);
93
0/2
✗ Branch 31 → 32 not taken.
✗ Branch 31 → 432 not taken.
✗ SDL_GetWindowSize(window, &window_width, &window_height);
94
0/2
✗ Branch 32 → 33 not taken.
✗ Branch 32 → 39 not taken.
✗ if (gl_context == nullptr) {
95
0/8
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 432 not taken.
✗ Branch 34 → 35 not taken.
✗ Branch 34 → 270 not taken.
✗ Branch 35 → 36 not taken.
✗ Branch 35 → 269 not taken.
✗ Branch 36 → 37 not taken.
✗ Branch 36 → 267 not taken.
✗ LOG_ERR("Error creating gl context: {}", SDL_GetError());
96 ✗ return -1;
97 }
98
99 /* OpenGL setup */
100
0/2
✗ Branch 39 → 40 not taken.
✗ Branch 39 → 432 not taken.
✗ const int glad_result = gladLoadGLLoader(SDL_GL_GetProcAddress);
101
0/2
✗ Branch 40 → 41 not taken.
✗ Branch 40 → 46 not taken.
✗ if (glad_result == 0)
102 {
103
0/6
✗ Branch 41 → 42 not taken.
✗ Branch 41 → 432 not taken.
✗ Branch 42 → 43 not taken.
✗ Branch 42 → 274 not taken.
✗ Branch 43 → 44 not taken.
✗ Branch 43 → 272 not taken.
✗ LOG_ERR("Failed to init glad, error: {0}", glad_result);
104 ✗ return -1;
105 }
106
107 {
108
0/4
✗ Branch 48 → 49 not taken.
✗ Branch 48 → 276 not taken.
✗ Branch 49 → 50 not taken.
✗ Branch 49 → 276 not taken.
✗ const std::string gl_vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
109
0/4
✗ Branch 53 → 54 not taken.
✗ Branch 53 → 279 not taken.
✗ Branch 54 → 55 not taken.
✗ Branch 54 → 279 not taken.
✗ const std::string gl_renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
110
0/4
✗ Branch 58 → 59 not taken.
✗ Branch 58 → 282 not taken.
✗ Branch 59 → 60 not taken.
✗ Branch 59 → 282 not taken.
✗ const std::string gl_version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
111
0/4
✗ Branch 63 → 64 not taken.
✗ Branch 63 → 285 not taken.
✗ Branch 64 → 65 not taken.
✗ Branch 64 → 285 not taken.
✗ const std::string gl_shading_language_version = reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION));
112
113
0/6
✗ Branch 66 → 67 not taken.
✗ Branch 66 → 304 not taken.
✗ Branch 67 → 68 not taken.
✗ Branch 67 → 290 not taken.
✗ Branch 68 → 69 not taken.
✗ Branch 68 → 288 not taken.
✗ LOG_INFO("Vendor: {0}", gl_vendor);
114
0/6
✗ Branch 70 → 71 not taken.
✗ Branch 70 → 304 not taken.
✗ Branch 71 → 72 not taken.
✗ Branch 71 → 294 not taken.
✗ Branch 72 → 73 not taken.
✗ Branch 72 → 292 not taken.
✗ LOG_INFO("Renderer: {0}", gl_renderer);
115
0/6
✗ Branch 74 → 75 not taken.
✗ Branch 74 → 304 not taken.
✗ Branch 75 → 76 not taken.
✗ Branch 75 → 298 not taken.
✗ Branch 76 → 77 not taken.
✗ Branch 76 → 296 not taken.
✗ LOG_INFO("Version OpenGL: {0}", gl_version);
116
0/6
✗ Branch 78 → 79 not taken.
✗ Branch 78 → 304 not taken.
✗ Branch 79 → 80 not taken.
✗ Branch 79 → 302 not taken.
✗ Branch 80 → 81 not taken.
✗ Branch 80 → 300 not taken.
✗ LOG_INFO("Version GLSL: {0}", gl_shading_language_version);
117 ✗ }
118
119 ✗ eu::render::State states;
120
0/2
✗ Branch 86 → 87 not taken.
✗ Branch 86 → 432 not taken.
✗ eu::render::Render2 render{ &states };
121
122
0/2
✗ Branch 87 → 88 not taken.
✗ Branch 87 → 430 not taken.
✗ UiState uistate;
123 ✗ const IdStack idstack;
124
0/2
✗ Branch 89 → 90 not taken.
✗ Branch 89 → 313 not taken.
✗ eu::render::DrawableFont font{chunk_from_embed(OPENSANS_REGULAR_TTF)};
125
126
0/2
✗ Branch 92 → 93 not taken.
✗ Branch 92 → 316 not taken.
✗ const auto sample_texture = eu::render::load_image_from_embedded(SEND_DEBUG_LABEL_MANY("uv-texture.png") UV_TEXTURE_PNG,
127
0/2
✗ Branch 93 → 94 not taken.
✗ Branch 93 → 314 not taken.
✗ eu::render::TextureEdge::clamp, eu::render::TextureRenderStyle::linear, eu::render::Transparency::exclude, eu::render::ColorData::color_data);
128
129
0/2
✗ Branch 98 → 99 not taken.
✗ Branch 98 → 322 not taken.
✗ const auto spritesheet = eu::render::load_image_from_embedded(SEND_DEBUG_LABEL_MANY("spritesheet.png") SPRITESHEET_PNG,
130
0/2
✗ Branch 99 → 100 not taken.
✗ Branch 99 → 320 not taken.
✗ eu::render::TextureEdge::repeat, eu::render::TextureRenderStyle::linear, eu::render::Transparency::include, eu::render::ColorData::color_data);
131
132 ✗ bool running = true;
133
0/2
✗ Branch 104 → 105 not taken.
✗ Branch 104 → 326 not taken.
✗ std::string editable_text = "Editable text";
134
135
0/6
✗ Branch 106 → 107 not taken.
✗ Branch 106 → 420 not taken.
✗ Branch 107 → 108 not taken.
✗ Branch 107 → 331 not taken.
✗ Branch 108 → 109 not taken.
✗ Branch 108 → 329 not taken.
✗ LOG_INFO("Mrgui sample started");
136
0/2
✗ Branch 241 → 111 not taken.
✗ Branch 241 → 242 not taken.
✗ while (running)
137 {
138 // events
139 SDL_Event e;
140
0/4
✗ Branch 136 → 137 not taken.
✗ Branch 136 → 415 not taken.
✗ Branch 137 → 112 not taken.
✗ Branch 137 → 138 not taken.
✗ while (SDL_PollEvent(&e))
141 {
142
0/8
✗ Branch 112 → 113 not taken.
✗ Branch 112 → 115 not taken.
✗ Branch 112 → 118 not taken.
✗ Branch 112 → 121 not taken.
✗ Branch 112 → 127 not taken.
✗ Branch 112 → 129 not taken.
✗ Branch 112 → 133 not taken.
✗ Branch 112 → 134 not taken.
✗ switch (e.type)
143 {
144 ✗ case SDL_EVENT_MOUSE_MOTION:
145 ✗ uistate.mouse = { e.motion.x, static_cast<float>(window_height) - e.motion.y };
146 ✗ break;
147 ✗ case SDL_EVENT_MOUSE_BUTTON_DOWN:
148
0/2
✗ Branch 115 → 116 not taken.
✗ Branch 115 → 117 not taken.
✗ if (e.button.button == 1)
149 {
150 ✗ uistate.mousedown = true;
151 }
152 ✗ break;
153 ✗ case SDL_EVENT_MOUSE_BUTTON_UP:
154
0/2
✗ Branch 118 → 119 not taken.
✗ Branch 118 → 120 not taken.
✗ if (e.button.button == 1)
155 {
156 ✗ uistate.mousedown = false;
157 }
158 ✗ break;
159 ✗ case SDL_EVENT_WINDOW_RESIZED:
160 case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
161
0/6
✗ Branch 121 → 122 not taken.
✗ Branch 121 → 415 not taken.
✗ Branch 122 → 123 not taken.
✗ Branch 122 → 335 not taken.
✗ Branch 123 → 124 not taken.
✗ Branch 123 → 333 not taken.
✗ LOG_INFO("Resized");
162
0/2
✗ Branch 125 → 126 not taken.
✗ Branch 125 → 415 not taken.
✗ SDL_GetWindowSize(window, &window_width, &window_height);
163 ✗ break;
164 ✗ case SDL_EVENT_KEY_DOWN:
165 ✗ uistate.key = KeyboardInput {.key = e.key.key, .mod = e.key.mod };
166 ✗ break;
167 ✗ case SDL_EVENT_TEXT_INPUT:
168 {
169 // todo(Gustav): handle unicode
170 ✗ const char first_char = e.text.text[0];
171
0/2
✗ Branch 129 → 130 not taken.
✗ Branch 129 → 132 not taken.
✗ if ((first_char & 0xFF80) == 0)
172 {
173 ✗ uistate.keychar = static_cast<char>(first_char & 0x7f);
174 }
175 }
176 ✗ break;
177 ✗ case SDL_EVENT_QUIT: running = false; break;
178 ✗ default:
179 // ignore other events
180 ✗ break;
181 }
182 }
183
184 // render
185 {
186 ✗ const eu::render::RenderCommand cmd {.states = &states, .render = &render, .size = {.width = window_width, .height = window_height} };
187
188 // todo(Gustav): provide a pixel layout
189 ✗ const auto screen = eu::render::LayoutData{ .style = eu::render::ViewportStyle::extended,
190 ✗ .requested_width = static_cast<float>(window_width), .requested_height = static_cast<float>(window_height) };
191
192
0/2
✗ Branch 138 → 139 not taken.
✗ Branch 138 → 414 not taken.
✗ cmd.clear(eu::colors::blue_sky, screen);
193
194
0/2
✗ Branch 139 → 140 not taken.
✗ Branch 139 → 414 not taken.
✗ auto layer = eu::render::with_layer2(cmd, screen);
195
0/4
✗ Branch 143 → 144 not taken.
✗ Branch 143 → 337 not taken.
✗ Branch 144 → 145 not taken.
✗ Branch 144 → 337 not taken.
✗ eu::render::Quad{ .tint = eu::colors::green_bluish }.draw(layer.batch, layer.viewport_aabb_in_worldspace.get_bottom(50));
196
197 static eu::An rotation = eu::no_rotation;
198 static float slider_a = 0.5f;
199 static float slider_b = 0.5f;
200
201 ✗ eu::render::Quad{
202 ✗ .texture = &sample_texture,
203 // select bottom right of the texture, assuming it is split in 4 smaller rects
204
0/2
✗ Branch 148 → 149 not taken.
✗ Branch 148 → 343 not taken.
✗ .texturecoord = eu::Rect::from_bottom_left_size({0.5f, 0}, {0.5f, 0.5f}),
205 ✗ .rotation = eu::render::RotateQuad{.angle = rotation, .center = {slider_a, slider_b} }
206
0/4
✗ Branch 155 → 156 not taken.
✗ Branch 155 → 339 not taken.
✗ Branch 156 → 157 not taken.
✗ Branch 156 → 339 not taken.
✗ }.draw(layer.batch, eu::Rect::from_bottom_left_size({ 300, 300 }, { 300, 300 }));
207
208 ✗ const auto button_size = eu::v2{ 64, 64 };
209
210
0/2
✗ Branch 157 → 158 not taken.
✗ Branch 157 → 412 not taken.
✗ uistate.begin();
211
0/10
✗ Branch 159 → 160 not taken.
✗ Branch 159 → 354 not taken.
✗ Branch 162 → 163 not taken.
✗ Branch 162 → 350 not taken.
✗ Branch 163 → 164 not taken.
✗ Branch 163 → 348 not taken.
✗ Branch 164 → 165 not taken.
✗ Branch 164 → 348 not taken.
✗ Branch 167 → 168 not taken.
✗ Branch 167 → 171 not taken.
✗ if (basic_button(idstack.get("a"), eu::Rect::from_bottom_left_size({ 100, 100 }, button_size), uistate, layer.batch))
212 {
213
0/4
✗ Branch 168 → 169 not taken.
✗ Branch 168 → 356 not taken.
✗ Branch 169 → 170 not taken.
✗ Branch 169 → 356 not taken.
✗ rotation -= eu::An::from_degrees(15.0f);
214 }
215
0/10
✗ Branch 172 → 173 not taken.
✗ Branch 172 → 363 not taken.
✗ Branch 175 → 176 not taken.
✗ Branch 175 → 359 not taken.
✗ Branch 176 → 177 not taken.
✗ Branch 176 → 357 not taken.
✗ Branch 177 → 178 not taken.
✗ Branch 177 → 357 not taken.
✗ Branch 180 → 181 not taken.
✗ Branch 180 → 184 not taken.
✗ if (basic_button(idstack.get("b"), eu::Rect::from_bottom_left_size({ 200, 100 }, button_size), uistate, layer.batch))
216 {
217
0/4
✗ Branch 181 → 182 not taken.
✗ Branch 181 → 365 not taken.
✗ Branch 182 → 183 not taken.
✗ Branch 182 → 365 not taken.
✗ rotation += eu::An::from_degrees(15.0f);
218 }
219
0/10
✗ Branch 185 → 186 not taken.
✗ Branch 185 → 372 not taken.
✗ Branch 188 → 189 not taken.
✗ Branch 188 → 368 not taken.
✗ Branch 189 → 190 not taken.
✗ Branch 189 → 366 not taken.
✗ Branch 190 → 191 not taken.
✗ Branch 190 → 366 not taken.
✗ Branch 193 → 194 not taken.
✗ Branch 193 → 195 not taken.
✗ if (basic_button(idstack.get("c"), eu::Rect::from_bottom_left_size({ 300, 100 }, button_size), uistate, layer.batch))
220 {
221 ✗ rotation = eu::no_rotation;
222 }
223
0/8
✗ Branch 196 → 197 not taken.
✗ Branch 196 → 380 not taken.
✗ Branch 199 → 200 not taken.
✗ Branch 199 → 376 not taken.
✗ Branch 200 → 201 not taken.
✗ Branch 200 → 374 not taken.
✗ Branch 201 → 202 not taken.
✗ Branch 201 → 374 not taken.
✗ button_texture(idstack.get("d"), eu::Rect::from_bottom_left_size({ 400, 100 }, button_size), uistate, layer.batch, &spritesheet,
224 ::spritesheet::button_square_flat,
225 ::spritesheet::button_square_depth_flat,
226 ::spritesheet::button_square_depth_gradient
227 );
228
229 ✗ const auto slider_size = eu::v2{ 256, 25 };
230
0/8
✗ Branch 205 → 206 not taken.
✗ Branch 205 → 388 not taken.
✗ Branch 208 → 209 not taken.
✗ Branch 208 → 384 not taken.
✗ Branch 209 → 210 not taken.
✗ Branch 209 → 382 not taken.
✗ Branch 210 → 211 not taken.
✗ Branch 210 → 382 not taken.
✗ slider(idstack.get("slider_a"), &slider_a, eu::Rect::from_bottom_left_size({ 100, 200 }, slider_size), uistate, layer.batch);
231
0/8
✗ Branch 214 → 215 not taken.
✗ Branch 214 → 396 not taken.
✗ Branch 217 → 218 not taken.
✗ Branch 217 → 392 not taken.
✗ Branch 218 → 219 not taken.
✗ Branch 218 → 390 not taken.
✗ Branch 219 → 220 not taken.
✗ Branch 219 → 390 not taken.
✗ slider(idstack.get("slider_b"), &slider_b, eu::Rect::from_bottom_left_size({ 100, 250 }, slider_size), uistate, layer.batch);
232
0/6
✗ Branch 225 → 226 not taken.
✗ Branch 225 → 400 not taken.
✗ Branch 226 → 227 not taken.
✗ Branch 226 → 398 not taken.
✗ Branch 227 → 228 not taken.
✗ Branch 227 → 398 not taken.
✗ textfield(idstack.get("textfield"), &editable_text, &font, 20, {100, 300}, uistate, layer.batch);
233
0/2
✗ Branch 230 → 231 not taken.
✗ Branch 230 → 412 not taken.
✗ uistate.end();
234
235
0/4
✗ Branch 234 → 235 not taken.
✗ Branch 234 → 407 not taken.
✗ Branch 235 → 236 not taken.
✗ Branch 235 → 405 not taken.
✗ draw_text(layer.batch, &font, "Hello world", 60, {200, 400 + 200}, eu::colors::black);
236 ✗ }
237
0/2
✗ Branch 239 → 240 not taken.
✗ Branch 239 → 415 not taken.
✗ SDL_GL_SwapWindow(window);
238 }
239
240
0/6
✗ Branch 242 → 243 not taken.
✗ Branch 242 → 420 not taken.
✗ Branch 243 → 244 not taken.
✗ Branch 243 → 418 not taken.
✗ Branch 244 → 245 not taken.
✗ Branch 244 → 416 not taken.
✗ LOG_INFO("Shutting down");
241
0/2
✗ Branch 246 → 247 not taken.
✗ Branch 246 → 420 not taken.
✗ SDL_GL_DestroyContext(gl_context);
242
0/2
✗ Branch 247 → 248 not taken.
✗ Branch 247 → 420 not taken.
✗ SDL_DestroyWindow(window);
243
0/2
✗ Branch 248 → 249 not taken.
✗ Branch 248 → 420 not taken.
✗ SDL_Quit();
244
245 ✗ return 0;
246 ✗ }
247