GCC Code Coverage Report


./
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
0 of 133, 0 excluded
0.0%
Functions:
0 of 4, 0 excluded
0.0%
Branches:
0 of 271, 0 excluded
0.0%

apps/editor/src/eu/editor/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
6 #include <cassert>
7 #include <string>
8
9 #include "OpenSans-Regular.ttf.h"
10
11 #include "eu/log/log.h"
12 #include "eu/base/memorychunk.h"
13
14 #include "eu/render/canvas.h"
15 #include "eu/render/state.h"
16 #include "eu/render/font.h"
17 #include "eu/render/opengl_utils.h"
18 #include "eu/render/texture.io.h"
19
20 #include "eu/render/enable_high_performance_graphics.h"
21
22 #include "dear_imgui/imgui.h"
23 #include "dear_imgui/imgui_internal.h"
24
25 #include "dear_imgui/backends/imgui_impl_sdl3.h"
26 #include "dear_imgui/backends/imgui_impl_opengl3.h"
27
28 ENABLE_HIGH_PERFORMANCE_GRAPHICS
29
30 namespace imgui
31 {
32 void label(const char* label)
33 {
34 ImGuiWindow* window = ImGui::GetCurrentWindow();
35 float fullWidth = ImGui::GetContentRegionAvail().x;
36 float itemWidth = fullWidth * 0.6f;
37 ImVec2 textSize = ImGui::CalcTextSize(label);
38 ImRect textRect;
39 textRect.Min = ImGui::GetCursorScreenPos();
40 textRect.Max = textRect.Min;
41 textRect.Max.x += fullWidth - itemWidth;
42 textRect.Max.y += textSize.y;
43
44 ImGui::AlignTextToFramePadding();
45 textRect.Min.y += window->DC.CurrLineTextBaseOffset;
46 textRect.Max.y += window->DC.CurrLineTextBaseOffset;
47
48 ImGui::ItemSize(textRect);
49 if (ImGui::ItemAdd(textRect, window->GetID(label)))
50 {
51 const float ellipsis_max = 3.0f;
52 ImGui::RenderTextEllipsis(ImGui::GetWindowDrawList(), textRect.Min, textRect.Max, ellipsis_max, label, nullptr, &textSize);
53
54 if (textRect.GetWidth() < textSize.x && ImGui::IsItemHovered())
55 ImGui::SetTooltip("%s", label);
56 }
57 ImGui::SameLine();
58 ImGui::SetNextItemWidth(-1);
59 }
60
61 bool centered_button(const char* label)
62 {
63 const auto window_width = ImGui::GetContentRegionAvail().x;
64 const auto text_width = ImGui::CalcTextSize(label).x;
65 const auto padding_hor = ImGui::GetStyle().FramePadding.x * 2; // padding on both sides
66 const auto whitespace = window_width - text_width - padding_hor;
67 const float x = whitespace * 0.5f;
68 ImGui::SetCursorPosX(x);
69 return ImGui::Button(label);
70 }
71 }
72
73 eu::MemoryChunk chunk_from_embed(const embedded_binary& binary)
74 {
75 return { .bytes = reinterpret_cast<const char*>(binary.data), .size = binary.size };
76 }
77
78 int main(int, char**)
79 {
80 int window_width = 1280;
81 int window_height = 720;
82 const char* glsl_version = "#version 130";
83
84 SDL_SetAppMetadata("Euphoria editor", "v0.1", "com.madeso.euphoria");
85
86 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) == false)
87 {
88 LOG_ERR("Error initializing SDL: {}", SDL_GetError());
89 return -1;
90 }
91
92 #if defined(__APPLE__)
93 // GL 3.2 Core + GLSL 150
94 const char* glsl_version = "#version 150";
95 SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); // Always required on Mac
96 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
97 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
98 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
99 #else
100 // GL 3.0 + GLSL 130
101 // const char* glsl_version = "#version 130";
102 SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
103 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
104 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
105 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); // was 0 in dear imgui example??
106 #endif
107
108 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
109 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
110
111 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
112 SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
113
114 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
115 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
116 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
117 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
118
119 SDL_Window* window = SDL_CreateWindow("Editor sample",
120 window_width, window_height, SDL_WINDOW_OPENGL | SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_RESIZABLE);
121 if (!window) {
122 LOG_ERR("Error creating window: {}", SDL_GetError());
123 return -1;
124 }
125
126 auto* glContext = SDL_GL_CreateContext(window);
127 SDL_GetWindowSize(window, &window_width, &window_height);
128 if (!glContext) {
129 LOG_ERR("Error creating gl context: {}", SDL_GetError());
130 return -1;
131 }
132
133 /* OpenGL setup */
134 const int glad_result = gladLoadGLLoader(SDL_GL_GetProcAddress);
135 if (glad_result == 0)
136 {
137 LOG_ERR("Failed to init glad, error: {0}", glad_result);
138 return -1;
139 }
140
141 IMGUI_CHECKVERSION();
142 ImGui::CreateContext();
143 ImGuiIO& io = ImGui::GetIO(); (void)io;
144 ImGui::StyleColorsDark();
145 ImGui_ImplSDL3_InitForOpenGL(window, glContext);
146 ImGui_ImplOpenGL3_Init(glsl_version);
147
148 bool show_demo_window = true;
149
150 {
151 const std::string gl_vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
152 const std::string gl_renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
153 const std::string gl_version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
154 const std::string gl_shading_language_version = reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION));
155
156 LOG_INFO("Vendor: {0}", gl_vendor);
157 LOG_INFO("Renderer: {0}", gl_renderer);
158 LOG_INFO("Version OpenGL: {0}", gl_version);
159 LOG_INFO("Version GLSL: {0}", gl_shading_language_version);
160 }
161
162 ImFontConfig config;
163 config.FontDataOwnedByAtlas = false;
164 ImFont* font = io.Fonts->AddFontFromMemoryTTF(
165 const_cast<void*>(static_cast<const void*>(OPENSANS_REGULAR_TTF_data)),
166 OPENSANS_REGULAR_TTF_size,
167 18.0f,
168 &config
169 );
170 IM_ASSERT(font != nullptr);
171
172 eu::render::State states;
173 eu::render::Render2 render{ &states };
174
175 bool running = true;
176
177 LOG_INFO("Editor started");
178 while (running)
179 {
180 SDL_Event e;
181 while (SDL_PollEvent(&e) != 0)
182 {
183 ImGui_ImplSDL3_ProcessEvent(&e);
184 switch (e.type)
185 {
186 case SDL_EVENT_WINDOW_RESIZED:
187 LOG_INFO("Resized");
188 SDL_GetWindowSize(window, &window_width, &window_height);
189 break;
190 case SDL_EVENT_QUIT: running = false; break;
191 default:
192 // ignore other events
193 break;
194 }
195 }
196
197 ImGui_ImplOpenGL3_NewFrame();
198 ImGui_ImplSDL3_NewFrame();
199 ImGui::NewFrame();
200
201 if (show_demo_window)
202 {
203 ImGui::ShowDemoWindow(&show_demo_window);
204 }
205
206 if (ImGui::Begin("Properties"))
207 {
208 static eu::v3 pos = {0,0,0};
209 static eu::v3 rot = {0, 0, 0};
210 static eu::v3 scale = {1, 1, 1};
211
212 imgui::label("Position");
213 ImGui::DragFloat3("##Position", pos.get_data_ptr());
214
215 imgui::label("Rotation");
216 ImGui::DragFloat3("##Rotation", rot.get_data_ptr());
217
218 imgui::label("Scale");
219 ImGui::DragFloat3("##Scale", scale.get_data_ptr());
220
221 imgui::centered_button("Add component");
222 }
223 ImGui::End();
224
225 {
226 eu::render::RenderCommand cmd {.states = &states, .render = &render, .size = {.width = window_width, .height = window_height} };
227
228 // todo(Gustav): provide a pixel layout
229 const auto screen = eu::render::LayoutData{ .style = eu::render::ViewportStyle::extended,
230 .requested_width = static_cast<float>(window_width), .requested_height = static_cast<float>(window_height) };
231
232 cmd.clear(eu::colors::blue_sky, screen);
233
234 auto layer = eu::render::with_layer2(cmd, screen);
235 eu::render::Quad{ .tint = eu::colors::green_bluish }.draw(layer.batch, layer.viewport_aabb_in_worldspace.get_bottom(50));
236 }
237
238 ImGui::Render();
239 ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
240 SDL_GL_SwapWindow(window);
241 }
242
243 ImGui_ImplOpenGL3_Shutdown();
244 ImGui_ImplSDL3_Shutdown();
245 ImGui::DestroyContext();
246
247 LOG_INFO("Shutting down");
248 SDL_GL_DestroyContext(glContext);
249 SDL_DestroyWindow(window);
250 SDL_Quit();
251
252 return 0;
253 }
254