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