source: opengl-game/opengl-game.cpp@ 83b5b4b

feature/imgui-sdl points-test
Last change on this file since 83b5b4b was 83b5b4b, checked in by Dmitry Portnoy <dmitry.portnoy@…>, 5 years ago

Handle window resize events in openglgame

  • Property mode set to 100644
File size: 8.5 KB
Line 
1#include "opengl-game.hpp"
2
3#include <iostream>
4
5#include "consts.hpp"
6#include "logger.hpp"
7
8#include "utils.hpp"
9
10using namespace std;
11
12OpenGLGame::OpenGLGame() {
13 gui = nullptr;
14 window = nullptr;
15}
16
17OpenGLGame::~OpenGLGame() {
18}
19
20void OpenGLGame::run(int width, int height, unsigned char guiFlags) {
21#ifdef NDEBUG
22 cout << "DEBUGGING IS OFF" << endl;
23#else
24 cout << "DEBUGGING IS ON" << endl;
25#endif
26
27 cout << "OpenGL Game" << endl;
28
29 // TODO: Refactor the logger api to be more flexible,
30 // esp. since gl_log() and gl_log_err() have issues printing anything besides stirngs
31 restart_gl_log();
32 gl_log("starting GLFW\n%s", glfwGetVersionString());
33
34 open_log();
35 get_log() << "starting GLFW" << endl;
36 get_log() << glfwGetVersionString() << endl;
37
38 if (initWindow(width, height, guiFlags) == RTWO_ERROR) {
39 return;
40 }
41
42 initOpenGL();
43 mainLoop();
44 cleanup();
45
46 close_log();
47}
48
49// TODO: Make some more initi functions, or call this initUI if the
50// amount of things initialized here keeps growing
51bool OpenGLGame::initWindow(int width, int height, unsigned char guiFlags) {
52 // TODO: Put all fonts, textures, and images in the assets folder
53 gui = new GameGui_GLFW();
54
55 if (gui->init() == RTWO_ERROR) {
56 // TODO: Also print these sorts of errors to the log
57 cout << "UI library could not be initialized!" << endl;
58 cout << gui->getError() << endl;
59 return RTWO_ERROR;
60 }
61 cout << "GUI init succeeded" << endl;
62
63 window = (GLFWwindow*) gui->createWindow("OpenGL Game", width, height, guiFlags & GUI_FLAGS_WINDOW_FULLSCREEN);
64 if (window == nullptr) {
65 cout << "Window could not be created!" << endl;
66 cout << gui->getError() << endl;
67 return RTWO_ERROR;
68 }
69
70 viewport = { 0, 0, gui->getWindowWidth(), gui->getWindowHeight() };
71
72 cout << "Target window size: (" << width << ", " << height << ")" << endl;
73 cout << "Actual window size: (" << viewport.width << ", " << viewport.height << ")" << endl;
74
75 return RTWO_SUCCESS;
76}
77
78void OpenGLGame::initOpenGL() {
79 glfwMakeContextCurrent(window);
80 glViewport(0, 0, gui->getWindowWidth(), gui->getWindowHeight());
81
82 glewExperimental = GL_TRUE;
83 glewInit();
84
85 if (GLEW_KHR_debug) {
86 cout << "FOUND GLEW debug extension" << endl;
87 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
88 glDebugMessageCallback((GLDEBUGPROC)opengl_debug_callback, nullptr);
89 cout << "Bound debug callback" << endl;
90 } else {
91 cout << "OpenGL debug message callback is not supported" << endl;
92 }
93
94 // Setup Dear ImGui binding
95 IMGUI_CHECKVERSION();
96 ImGui::CreateContext();
97 ImGuiIO& io = ImGui::GetIO(); (void)io;
98 //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
99 //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
100 ImGui_ImplGlfwGL3_Init(window, true);
101
102 // Setup style
103 ImGui::StyleColorsDark();
104 //ImGui::StyleColorsClassic();
105
106 // The glfw event handlers have to be bound after ImGui is initialized.
107 // Otherwise, it seems they get overridden by ImGui
108 ((GameGui_GLFW*)gui)->bindEventHandlers();
109
110 graphicsPipelines.push_back(GraphicsPipeline_OpenGL());
111 graphicsPipelines.back().createPipeline("gl-shaders/ship.vert", "gl-shaders/ship.frag");
112
113 graphicsPipelines.push_back(GraphicsPipeline_OpenGL());
114 graphicsPipelines.back().createPipeline("gl-shaders/asteroid.vert", "gl-shaders/asteroid.frag");
115
116 graphicsPipelines.push_back(GraphicsPipeline_OpenGL());
117 graphicsPipelines.back().createPipeline("gl-shaders/laser.vert", "gl-shaders/laser.frag");
118
119 graphicsPipelines.push_back(GraphicsPipeline_OpenGL());
120 graphicsPipelines.back().createPipeline("gl-shaders/explosion.vert", "gl-shaders/explosion.frag");
121
122 cout << "Created " << graphicsPipelines.size() << " graphics pipelines" << endl;
123}
124
125void OpenGLGame::mainLoop() {
126 UIEvent e;
127 bool quit = false;
128
129 while (!quit) {
130 gui->processEvents();
131
132 while (gui->pollEvent(&e)) {
133 switch (e.type) {
134 case UI_EVENT_QUIT:
135 cout << "Quit event detected" << endl;
136 quit = true;
137 break;
138 case UI_EVENT_KEY:
139 if (e.key.keycode == GLFW_KEY_ESCAPE) {
140 quit = true;
141 } else {
142 cout << "Key event detected" << endl;
143 }
144 break;
145 case UI_EVENT_WINDOWRESIZE:
146 cout << "Window resize event detected" << endl;
147 viewport.width = e.windowResize.width;
148 viewport.height = e.windowResize.height;
149 break;
150 default:
151 cout << "Unhandled UI event: " << e.type << endl;
152 }
153 }
154
155 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
156
157 // Anton's book suggests placing this here, after glClear(). Check it's impact on framerate
158 // TODO: This doesn't seem to work correctly when in the loop. DO some research
159 // max viewport dims are clamped to glGet(GL_MAX_VIEWPORT_DIMS)
160 //glViewport(0, 0, gui->getWindowWidth(), gui->getWindowHeight());
161
162 renderScene();
163 renderUI();
164
165 glfwSwapBuffers(window);
166 }
167}
168
169void OpenGLGame::renderScene() {
170
171}
172
173void OpenGLGame::renderUI() {
174 ImGui_ImplGlfwGL3_NewFrame();
175
176 {
177 int padding = 4;
178 ImGui::SetNextWindowPos(ImVec2(-padding, -padding), ImGuiCond_Once);
179 ImGui::SetNextWindowSize(ImVec2(gui->getWindowWidth() + 2 * padding, gui->getWindowHeight() + 2 * padding), ImGuiCond_Always);
180 ImGui::Begin("WndMain", NULL,
181 ImGuiWindowFlags_NoTitleBar |
182 ImGuiWindowFlags_NoResize |
183 ImGuiWindowFlags_NoMove);
184
185 ImGui::InvisibleButton("", ImVec2(10, 80));
186 ImGui::InvisibleButton("", ImVec2(285, 18));
187 ImGui::SameLine();
188 ImGui::Button("New Game");
189
190 ImGui::InvisibleButton("", ImVec2(10, 15));
191 ImGui::InvisibleButton("", ImVec2(300, 18));
192 ImGui::SameLine();
193 ImGui::Button("Quit");
194
195 ImGui::End();
196 }
197
198 ImGui::Render();
199 ImGui_ImplGlfwGL3_RenderDrawData(ImGui::GetDrawData());
200}
201
202void OpenGLGame::cleanup() {
203 ImGui_ImplGlfwGL3_Shutdown();
204 ImGui::DestroyContext();
205
206 gui->destroyWindow();
207 gui->shutdown();
208 delete gui;
209}
210
211void APIENTRY opengl_debug_callback(
212 GLenum source,
213 GLenum type,
214 GLuint id,
215 GLenum severity,
216 GLsizei length,
217 const GLchar* message,
218 const void* userParam
219) {
220 string strMessage(message);
221
222 // TODO: Use C++ strings directly and see if there are other ways to clean
223 // this function up
224 char source_str[2048];
225 char type_str[2048];
226 char severity_str[2048];
227
228 switch (source) {
229 case 0x8246:
230 strcpy(source_str, "API");
231 break;
232 case 0x8247:
233 strcpy(source_str, "WINDOW_SYSTEM");
234 break;
235 case 0x8248:
236 strcpy(source_str, "SHADER_COMPILER");
237 break;
238 case 0x8249:
239 strcpy(source_str, "THIRD_PARTY");
240 break;
241 case 0x824A:
242 strcpy(source_str, "APPLICATION");
243 break;
244 case 0x824B:
245 strcpy(source_str, "OTHER");
246 break;
247 default:
248 strcpy(source_str, "undefined");
249 break;
250 }
251
252 switch (type) {
253 case 0x824C:
254 strcpy(type_str, "ERROR");
255 break;
256 case 0x824D:
257 strcpy(type_str, "DEPRECATED_BEHAVIOR");
258 break;
259 case 0x824E:
260 strcpy(type_str, "UNDEFINED_BEHAVIOR");
261 break;
262 case 0x824F:
263 strcpy(type_str, "PORTABILITY");
264 break;
265 case 0x8250:
266 strcpy(type_str, "PERFORMANCE");
267 break;
268 case 0x8251:
269 strcpy(type_str, "OTHER");
270 break;
271 case 0x8268:
272 strcpy(type_str, "MARKER");
273 break;
274 case 0x8269:
275 strcpy(type_str, "PUSH_GROUP");
276 break;
277 case 0x826A:
278 strcpy(type_str, "POP_GROUP");
279 break;
280 default:
281 strcpy(type_str, "undefined");
282 break;
283 }
284 switch (severity) {
285 case 0x9146:
286 strcpy(severity_str, "HIGH");
287 break;
288 case 0x9147:
289 strcpy(severity_str, "MEDIUM");
290 break;
291 case 0x9148:
292 strcpy(severity_str, "LOW");
293 break;
294 case 0x826B:
295 strcpy(severity_str, "NOTIFICATION");
296 break;
297 default:
298 strcpy(severity_str, "undefined");
299 break;
300 }
301
302 if (string(severity_str) != "NOTIFICATION") {
303 cout << "OpenGL Error!!!" << endl;
304 cout << "Source: " << string(source_str) << endl;
305 cout << "Type: " << string(type_str) << endl;
306 cout << "Severity: " << string(severity_str) << endl;
307 cout << strMessage << endl;
308 }
309}
Note: See TracBrowser for help on using the repository browser.