source: opengl-game/opengl-game.cpp@ 0b1b52d

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

In openglgame, port over the functionality to specify and initialize varying attributes

  • Property mode set to 100644
File size: 10.3 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(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
121 graphicsPipelines.back().createPipeline("gl-shaders/ship.vert", "gl-shaders/ship.frag");
122
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
134 graphicsPipelines.back().createPipeline("gl-shaders/asteroid.vert", "gl-shaders/asteroid.frag");
135
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
145 graphicsPipelines.back().createPipeline("gl-shaders/laser.vert", "gl-shaders/laser.frag");
146
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
156 graphicsPipelines.back().createPipeline("gl-shaders/explosion.vert", "gl-shaders/explosion.frag");
157
158 cout << "Created " << graphicsPipelines.size() << " graphics pipelines" << endl;
159}
160
161void OpenGLGame::mainLoop() {
162 UIEvent e;
163 bool quit = false;
164
165 while (!quit) {
166 gui->processEvents();
167
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;
174 case UI_EVENT_KEY:
175 if (e.key.keycode == GLFW_KEY_ESCAPE) {
176 quit = true;
177 } else {
178 cout << "Key event detected" << endl;
179 }
180 break;
181 case UI_EVENT_WINDOWRESIZE:
182 cout << "Window resize event detected" << endl;
183 viewport.width = e.windowResize.width;
184 viewport.height = e.windowResize.height;
185 break;
186 default:
187 cout << "Unhandled UI event: " << e.type << endl;
188 }
189 }
190
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
198 renderScene();
199 renderUI();
200
201 glfwSwapBuffers(window);
202 }
203}
204
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
238void OpenGLGame::cleanup() {
239 ImGui_ImplGlfwGL3_Shutdown();
240 ImGui::DestroyContext();
241
242 gui->destroyWindow();
243 gui->shutdown();
244 delete gui;
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 }
345}
Note: See TracBrowser for help on using the repository browser.