1 | #include <iostream> |
2 |
|
3 | #include "ZydecoCommon.hpp" |
4 | #include "CommonSDL2.hpp" |
5 | #include "EventHandlerSDL2.hpp" |
6 | #include "WindowSDL2.hpp" |
7 | #include "TimerSDL2.hpp" |
8 | #include "Renderer.hpp" |
9 | #include "Engine.hpp" |
10 |
|
11 |
|
12 | static Logger LOGGER("main"); |
13 |
|
14 | static const char *ZYDECO_TERMOUT[] = { |
15 | "Zydeco v0.1.0 Copyright (c) Joshua Stockin 2023", |
16 | "<https://joshstock.in> <josh@joshstock.in>", |
17 | }; |
18 |
|
19 |
|
20 | void on_terminate(void) |
21 | { |
22 | ZydecoFault("PROGRAM TERMINATED UNEXPECTEDLY."); |
23 | } |
24 |
|
25 | int main(int argc, char *argv[]) |
26 | { |
27 | // Print boilerplate copyright output |
28 | for (const char *line : ZYDECO_TERMOUT) |
29 | { |
30 | std::cout << line << std::endl; |
31 | } |
32 |
|
33 | // Runtime environment setup |
34 | std::set_terminate(static_cast<std::terminate_handler>(on_terminate)); |
35 |
|
36 | // Initialize logging |
37 | Logger::InitializeLogging(Logger::DEBUG, &std::cout); |
38 | LOGGER.Log(Logger::INFO, "main(): Logging initialized"); |
39 |
|
40 | // Initialize SDL environment |
41 | LOGGER.Log(Logger::INFO, "main(): Initializing SDL..."); |
42 | SDL_CallErrorReturningFunction(SDL_Init, SDL_INIT_VIDEO | SDL_INIT_EVENTS); |
43 | LOGGER.Log(Logger::INFO, "main(): SDL initialized"); |
44 |
|
45 | // Load ImGui |
46 | LOGGER.Log(Logger::INFO, "main(): Loading ImGui..."); |
47 | IMGUI_CHECKVERSION(); |
48 | ImGui::CreateContext(); |
49 | ImGuiIO& imgui_io = ImGui::GetIO(); |
50 | imgui_io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; |
51 | //imgui_io.ConfigDockingWithShift = false; |
52 |
|
53 | // Create subsystems |
54 | LOGGER.Log(Logger::INFO, "main(): Creating subsystems..."); |
55 | EventHandlerSDL2 sdl_event_handler {}; |
56 | WindowSDL2 sdl_window {"Zydeco", SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE}; |
57 | TimerSDL2 sdl_core_timer {}; |
58 |
|
59 | // Load OpenGL |
60 | LOGGER.Log(Logger::INFO, "main(): Loading OpenGL with GL3W..."); |
61 |
|
62 | sdl_window.MakeContextCurrent(); |
63 | int gl3wRes = gl3wInit(); |
64 | if (gl3wRes != 0) |
65 | { |
66 | ZydecoFault("gl3wInit failed ({})", gl3wRes); |
67 | } |
68 |
|
69 | if (!gl3wIsSupported(GL_VERSION_MAJOR, GL_VERSION_MINOR)) |
70 | { |
71 | ZydecoFault("OpenGL/GL3W {}.{} not supported", GL_VERSION_MAJOR, GL_VERSION_MINOR); |
72 | } |
73 |
|
74 | LOGGER.Log(Logger::DEBUG, "main(): OpenGL {}, GLSL {}", glGetString(GL_VERSION), glGetString(GL_SHADING_LANGUAGE_VERSION)); |
75 | LOGGER.Log(Logger::DEBUG, "main(): Renderer: {}", glGetString(GL_RENDERER)); |
76 | LOGGER.Log(Logger::INFO, "main(): OpenGL loaded with GL3W"); |
77 |
|
78 | TimerSDL2 sdl_renderer_timer {}; |
79 | Renderer gl_renderer {sdl_event_handler, sdl_window, sdl_renderer_timer}; |
80 |
|
81 | LOGGER.Log(Logger::INFO, "main(): Subsystems created"); |
82 |
|
83 | // Constructor implictly creates a GL context and makes it current. Context must be current to load GL and ascertain |
84 | // capabilities. GL doesn't thread well, so we can't have that context be current here after initialization. |
85 | sdl_window.MakeNullCurrent(); |
86 |
|
87 | // Create engine |
88 | LOGGER.Log(Logger::INFO, "main(): Creating engine..."); |
89 | Engine engine {sdl_event_handler, sdl_window, sdl_core_timer, gl_renderer}; |
90 | LOGGER.Log(Logger::INFO, "main(): Engine created"); |
91 |
|
92 | // Enter loop |
93 | LOGGER.Log(Logger::INFO, "main(): Entering engine loop"); |
94 | engine.Execute(); |
95 |
|
96 | // Engine exited |
97 | LOGGER.Log(Logger::INFO, "main(): Engine exited"); |
98 |
|
99 | // Quit ImGui |
100 | LOGGER.Log(Logger::INFO, "main(): Quitting ImGui"); |
101 | ImGui_ImplOpenGL3_Shutdown(); |
102 | ImGui_ImplSDL2_Shutdown(); |
103 | ImGui::DestroyContext(); |
104 |
|
105 | // Quit SDL |
106 | LOGGER.Log(Logger::INFO, "main(): Quitting SDL"); |
107 | SDL_Quit(); |
108 |
|
109 | // Exiting program |
110 | LOGGER.Log(Logger::INFO, "main(): Exiting"); |
111 | return 0; |
112 | } |
113 |
|