source: opengl-game/opengl-game.cpp@ e1f88a9

feature/imgui-sdl
Last change on this file since e1f88a9 was 5a23277, checked in by Dmitry Portnoy <dmp1488@…>, 5 years ago

Replace the key event in game-gui with distinct key up and key down events

  • Property mode set to 100644
File size: 10.3 KB
RevLine 
[d02c25f]1#include "opengl-game.hpp"
2
3#include <iostream>
4
[5edbd58]5#include "consts.hpp"
[c559904]6#include "logger.hpp"
[5edbd58]7
[83b5b4b]8#include "utils.hpp"
9
[d02c25f]10using namespace std;
11
12OpenGLGame::OpenGLGame() {
[d8cb15e]13 gui = nullptr;
14 window = nullptr;
[d02c25f]15}
16
17OpenGLGame::~OpenGLGame() {
18}
19
[b6e60b4]20void OpenGLGame::run(int width, int height, unsigned char guiFlags) {
[2e77b3f]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
[c559904]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
[5edbd58]38 if (initWindow(width, height, guiFlags) == RTWO_ERROR) {
[d8cb15e]39 return;
40 }
[b6e60b4]41
[d8cb15e]42 initOpenGL();
43 mainLoop();
44 cleanup();
[c559904]45
46 close_log();
[d8cb15e]47}
48
[c559904]49// TODO: Make some more initi functions, or call this initUI if the
50// amount of things initialized here keeps growing
[b6e60b4]51bool OpenGLGame::initWindow(int width, int height, unsigned char guiFlags) {
[c559904]52 // TODO: Put all fonts, textures, and images in the assets folder
[d8cb15e]53 gui = new GameGui_GLFW();
54
[b6e60b4]55 if (gui->init() == RTWO_ERROR) {
[c559904]56 // TODO: Also print these sorts of errors to the log
[d8cb15e]57 cout << "UI library could not be initialized!" << endl;
[b6e60b4]58 cout << gui->getError() << endl;
[d8cb15e]59 return RTWO_ERROR;
60 }
61 cout << "GUI init succeeded" << endl;
62
[b6e60b4]63 window = (GLFWwindow*) gui->createWindow("OpenGL Game", width, height, guiFlags & GUI_FLAGS_WINDOW_FULLSCREEN);
[d8cb15e]64 if (window == nullptr) {
65 cout << "Window could not be created!" << endl;
[ed7c953]66 cout << gui->getError() << endl;
[d8cb15e]67 return RTWO_ERROR;
68 }
69
[83b5b4b]70 viewport = { 0, 0, gui->getWindowWidth(), gui->getWindowHeight() };
71
[b6e60b4]72 cout << "Target window size: (" << width << ", " << height << ")" << endl;
[83b5b4b]73 cout << "Actual window size: (" << viewport.width << ", " << viewport.height << ")" << endl;
[b6e60b4]74
[d8cb15e]75 return RTWO_SUCCESS;
76}
77
78void OpenGLGame::initOpenGL() {
[92cbc6a]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 }
[f133da0]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();
[3de31cf]109
[0b1b52d]110 graphicsPipelines.push_back(GraphicsPipeline_OpenGL(viewport));
111
112 graphicsPipelines.back().addVaryingAttribute(ATTRIB_POINT_VARYING, 3, GL_FLOAT,
113 offset_of(&SceneObject::points));
114 graphicsPipelines.back().addVaryingAttribute(ATTRIB_POINT_VARYING, 3, GL_FLOAT,
115 offset_of(&SceneObject::colors));
116 graphicsPipelines.back().addVaryingAttribute(ATTRIB_POINT_VARYING, 3, GL_FLOAT,
117 offset_of(&SceneObject::normals));
118 graphicsPipelines.back().addVaryingAttribute(ATTRIB_OBJECT_VARYING, 1, GL_UNSIGNED_INT,
119 offset_of(&SceneObject::ubo_offset));
120
[3de31cf]121 graphicsPipelines.back().createPipeline("gl-shaders/ship.vert", "gl-shaders/ship.frag");
122
[0b1b52d]123 graphicsPipelines.push_back(GraphicsPipeline_OpenGL(viewport));
124
125 graphicsPipelines.back().addVaryingAttribute(ATTRIB_POINT_VARYING, 3, GL_FLOAT,
126 offset_of(&SceneObject::points));
127 graphicsPipelines.back().addVaryingAttribute(ATTRIB_POINT_VARYING, 3, GL_FLOAT,
128 offset_of(&SceneObject::colors));
129 graphicsPipelines.back().addVaryingAttribute(ATTRIB_POINT_VARYING, 3, GL_FLOAT,
130 offset_of(&SceneObject::normals));
131 graphicsPipelines.back().addVaryingAttribute(ATTRIB_OBJECT_VARYING, 1, GL_UNSIGNED_INT,
132 offset_of(&SceneObject::ubo_offset));
133
[3de31cf]134 graphicsPipelines.back().createPipeline("gl-shaders/asteroid.vert", "gl-shaders/asteroid.frag");
135
[0b1b52d]136 graphicsPipelines.push_back(GraphicsPipeline_OpenGL(viewport));
137
138 graphicsPipelines.back().addVaryingAttribute(ATTRIB_POINT_VARYING, 3, GL_FLOAT,
139 offset_of(&SceneObject::points));
140 graphicsPipelines.back().addVaryingAttribute(ATTRIB_POINT_VARYING, 2, GL_FLOAT,
141 offset_of(&SceneObject::texcoords));
142 graphicsPipelines.back().addVaryingAttribute(ATTRIB_OBJECT_VARYING, 1, GL_UNSIGNED_INT,
143 offset_of(&SceneObject::ubo_offset));
144
[3de31cf]145 graphicsPipelines.back().createPipeline("gl-shaders/laser.vert", "gl-shaders/laser.frag");
146
[0b1b52d]147 graphicsPipelines.push_back(GraphicsPipeline_OpenGL(viewport));
148
149 graphicsPipelines.back().addVaryingAttribute(ATTRIB_POINT_VARYING, 3, GL_FLOAT,
150 offset_of(&ParticleEffect::particleVelocities));
151 graphicsPipelines.back().addVaryingAttribute(ATTRIB_POINT_VARYING, 1, GL_FLOAT,
152 offset_of(&ParticleEffect::particleTimes));
153 graphicsPipelines.back().addVaryingAttribute(ATTRIB_OBJECT_VARYING, 1, GL_UNSIGNED_INT,
154 offset_of(&ParticleEffect::ubo_offset));
155
[3de31cf]156 graphicsPipelines.back().createPipeline("gl-shaders/explosion.vert", "gl-shaders/explosion.frag");
157
158 cout << "Created " << graphicsPipelines.size() << " graphics pipelines" << endl;
[d8cb15e]159}
160
161void OpenGLGame::mainLoop() {
[c61323a]162 UIEvent e;
163 bool quit = false;
[7bf5433]164
[c61323a]165 while (!quit) {
[7bf5433]166 gui->processEvents();
167
[c61323a]168 while (gui->pollEvent(&e)) {
169 switch (e.type) {
170 case UI_EVENT_QUIT:
171 cout << "Quit event detected" << endl;
172 quit = true;
173 break;
[5a23277]174 case UI_EVENT_KEYDOWN:
[c61323a]175 if (e.key.keycode == GLFW_KEY_ESCAPE) {
176 quit = true;
177 } else {
178 cout << "Key event detected" << endl;
179 }
180 break;
[a0da009]181 case UI_EVENT_WINDOWRESIZE:
182 cout << "Window resize event detected" << endl;
[83b5b4b]183 viewport.width = e.windowResize.width;
184 viewport.height = e.windowResize.height;
[a0da009]185 break;
[c61323a]186 default:
187 cout << "Unhandled UI event: " << e.type << endl;
188 }
[1ce9afe]189 }
190
[92cbc6a]191 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
192
193 // Anton's book suggests placing this here, after glClear(). Check it's impact on framerate
194 // TODO: This doesn't seem to work correctly when in the loop. DO some research
195 // max viewport dims are clamped to glGet(GL_MAX_VIEWPORT_DIMS)
196 //glViewport(0, 0, gui->getWindowWidth(), gui->getWindowHeight());
197
[f133da0]198 renderScene();
199 renderUI();
200
[d8cb15e]201 glfwSwapBuffers(window);
202 }
203}
204
[f133da0]205void OpenGLGame::renderScene() {
206
207}
208
209void OpenGLGame::renderUI() {
210 ImGui_ImplGlfwGL3_NewFrame();
211
212 {
213 int padding = 4;
214 ImGui::SetNextWindowPos(ImVec2(-padding, -padding), ImGuiCond_Once);
215 ImGui::SetNextWindowSize(ImVec2(gui->getWindowWidth() + 2 * padding, gui->getWindowHeight() + 2 * padding), ImGuiCond_Always);
216 ImGui::Begin("WndMain", NULL,
217 ImGuiWindowFlags_NoTitleBar |
218 ImGuiWindowFlags_NoResize |
219 ImGuiWindowFlags_NoMove);
220
221 ImGui::InvisibleButton("", ImVec2(10, 80));
222 ImGui::InvisibleButton("", ImVec2(285, 18));
223 ImGui::SameLine();
224 ImGui::Button("New Game");
225
226 ImGui::InvisibleButton("", ImVec2(10, 15));
227 ImGui::InvisibleButton("", ImVec2(300, 18));
228 ImGui::SameLine();
229 ImGui::Button("Quit");
230
231 ImGui::End();
232 }
233
234 ImGui::Render();
235 ImGui_ImplGlfwGL3_RenderDrawData(ImGui::GetDrawData());
236}
237
[d8cb15e]238void OpenGLGame::cleanup() {
[f133da0]239 ImGui_ImplGlfwGL3_Shutdown();
240 ImGui::DestroyContext();
241
[b6e60b4]242 gui->destroyWindow();
243 gui->shutdown();
[d8cb15e]244 delete gui;
[92cbc6a]245}
246
247void APIENTRY opengl_debug_callback(
248 GLenum source,
249 GLenum type,
250 GLuint id,
251 GLenum severity,
252 GLsizei length,
253 const GLchar* message,
254 const void* userParam
255) {
256 string strMessage(message);
257
258 // TODO: Use C++ strings directly and see if there are other ways to clean
259 // this function up
260 char source_str[2048];
261 char type_str[2048];
262 char severity_str[2048];
263
264 switch (source) {
265 case 0x8246:
266 strcpy(source_str, "API");
267 break;
268 case 0x8247:
269 strcpy(source_str, "WINDOW_SYSTEM");
270 break;
271 case 0x8248:
272 strcpy(source_str, "SHADER_COMPILER");
273 break;
274 case 0x8249:
275 strcpy(source_str, "THIRD_PARTY");
276 break;
277 case 0x824A:
278 strcpy(source_str, "APPLICATION");
279 break;
280 case 0x824B:
281 strcpy(source_str, "OTHER");
282 break;
283 default:
284 strcpy(source_str, "undefined");
285 break;
286 }
287
288 switch (type) {
289 case 0x824C:
290 strcpy(type_str, "ERROR");
291 break;
292 case 0x824D:
293 strcpy(type_str, "DEPRECATED_BEHAVIOR");
294 break;
295 case 0x824E:
296 strcpy(type_str, "UNDEFINED_BEHAVIOR");
297 break;
298 case 0x824F:
299 strcpy(type_str, "PORTABILITY");
300 break;
301 case 0x8250:
302 strcpy(type_str, "PERFORMANCE");
303 break;
304 case 0x8251:
305 strcpy(type_str, "OTHER");
306 break;
307 case 0x8268:
308 strcpy(type_str, "MARKER");
309 break;
310 case 0x8269:
311 strcpy(type_str, "PUSH_GROUP");
312 break;
313 case 0x826A:
314 strcpy(type_str, "POP_GROUP");
315 break;
316 default:
317 strcpy(type_str, "undefined");
318 break;
319 }
320 switch (severity) {
321 case 0x9146:
322 strcpy(severity_str, "HIGH");
323 break;
324 case 0x9147:
325 strcpy(severity_str, "MEDIUM");
326 break;
327 case 0x9148:
328 strcpy(severity_str, "LOW");
329 break;
330 case 0x826B:
331 strcpy(severity_str, "NOTIFICATION");
332 break;
333 default:
334 strcpy(severity_str, "undefined");
335 break;
336 }
337
338 if (string(severity_str) != "NOTIFICATION") {
339 cout << "OpenGL Error!!!" << endl;
340 cout << "Source: " << string(source_str) << endl;
341 cout << "Type: " << string(type_str) << endl;
342 cout << "Severity: " << string(severity_str) << endl;
343 cout << strMessage << endl;
344 }
[d02c25f]345}
Note: See TracBrowser for help on using the repository browser.