source: opengl-game/new-game.cpp@ dba67b2

feature/imgui-sdl points-test
Last change on this file since dba67b2 was dba67b2, checked in by Dmitry Portnoy <dmp1488@…>, 6 years ago

Update the project to GLM 0.9.9, add the README to the Visual Studio project, and update the Windows build instructions in the README.

  • Property mode set to 100644
File size: 55.4 KB
Line 
1#include "logger.h"
2
3#include "stb_image.h"
4
5// I think this was for the OpenGL 4 book font file tutorial
6//#define STB_IMAGE_WRITE_IMPLEMENTATION
7//#include "stb_image_write.h"
8
9#define _USE_MATH_DEFINES
10
11#include <glm/mat4x4.hpp>
12#include <glm/gtc/matrix_transform.hpp>
13#include <glm/gtc/type_ptr.hpp>
14
15#include "IMGUI/imgui.h"
16#include "imgui_impl_glfw_gl3.h"
17
18#include <GL/glew.h>
19#include <GLFW/glfw3.h>
20
21#include <cstdio>
22#include <cstdlib>
23#include <ctime>
24#include <iostream>
25#include <fstream>
26#include <cmath>
27#include <string>
28#include <array>
29#include <vector>
30#include <queue>
31#include <map>
32
33using namespace std;
34using namespace glm;
35
36struct SceneObject {
37 unsigned int id;
38 mat4 model_mat, model_base, model_transform;
39 GLuint shader_program;
40 unsigned int num_points;
41 GLuint vertex_vbo_offset;
42 GLuint ubo_offset;
43 vector<GLfloat> points;
44 vector<GLfloat> colors;
45 vector<GLfloat> texcoords;
46 vector<GLfloat> normals;
47 vector<GLfloat> selected_colors;
48 bool deleted;
49};
50
51struct BufferInfo {
52 unsigned int vbo_base;
53 unsigned int vbo_offset;
54 unsigned int vbo_capacity;
55 unsigned int ubo_base;
56 unsigned int ubo_offset;
57 unsigned int ubo_capacity;
58};
59
60enum State {
61 STATE_MAIN_MENU,
62 STATE_GAME,
63};
64
65enum Event {
66 EVENT_GO_TO_MAIN_MENU,
67 EVENT_GO_TO_GAME,
68 EVENT_QUIT,
69};
70
71void glfw_error_callback(int error, const char* description);
72
73void mouse_button_callback(GLFWwindow* window, int button, int action, int mods);
74void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
75
76bool faceClicked(array<vec3, 3> points, SceneObject* obj, vec4 world_ray, vec4 cam, vec4& click_point);
77bool insideTriangle(vec3 p, array<vec3, 3> triangle_points);
78
79GLuint loadShader(GLenum type, string file);
80GLuint loadShaderProgram(string vertexShaderPath, string fragmentShaderPath);
81unsigned char* loadImage(string file_name, int* x, int* y);
82
83void printVector(string label, vec3 v);
84void print4DVector(string label, vec4 v);
85
86void addObjectToSceneDuringInit(SceneObject& obj);
87void addObjectToScene(SceneObject& obj, map<GLuint, BufferInfo>& shaderBufferInfo,
88 GLuint points_vbo,
89 GLuint colors_vbo,
90 GLuint selected_colors_vbo,
91 GLuint texcoords_vbo,
92 GLuint normals_vbo,
93 GLuint ubo,
94 GLuint model_mat_idx_vbo);
95void removeObjectFromScene(int objectId, GLuint ubo);
96
97void initializeBuffers(
98 GLuint* points_vbo,
99 GLuint* colors_vbo,
100 GLuint* selected_colors_vbo,
101 GLuint* texcoords_vbo,
102 GLuint* normals_vbo,
103 GLuint* ubo,
104 GLuint* model_mat_idx_vbo);
105
106void populateBuffers(vector<SceneObject>& objects,
107 map<GLuint, BufferInfo>& shaderBufferInfo,
108 GLuint points_vbo,
109 GLuint colors_vbo,
110 GLuint selected_colors_vbo,
111 GLuint texcoords_vbo,
112 GLuint normals_vbo,
113 GLuint ubo,
114 GLuint model_mat_idx_vbo);
115
116void copyObjectDataToBuffers(SceneObject& obj,
117 map<GLuint, BufferInfo>& shaderBufferInfo,
118 GLuint points_vbo,
119 GLuint colors_vbo,
120 GLuint selected_colors_vbo,
121 GLuint texcoords_vbo,
122 GLuint normals_vbo,
123 GLuint ubo,
124 GLuint model_mat_idx_vbo);
125
126void transformObject(SceneObject& obj, const mat4& transform, GLuint ubo);
127
128void renderMainMenu();
129void renderMainMenuGui();
130
131void renderScene(vector<SceneObject>& objects,
132 GLuint color_sp, GLuint texture_sp,
133 GLuint vao1, GLuint vao2,
134 GLuint points_vbo, GLuint normals_vbo,
135 GLuint colors_vbo, GLuint texcoords_vbo, GLuint selected_colors_vbo,
136 SceneObject* selectedObject,
137 map<GLuint, BufferInfo>& shaderBufferInfo);
138void renderSceneGui();
139
140void spawnAsteroid(vec3 pos, GLuint shader,
141 map<GLuint, BufferInfo>& shaderBufferInfo,
142 GLuint points_vbo,
143 GLuint colors_vbo,
144 GLuint selected_colors_vbo,
145 GLuint texcoords_vbo,
146 GLuint normals_vbo,
147 GLuint ubo,
148 GLuint model_mat_idx_vbo);
149
150float getRandomNum(float low, float high);
151
152#define NUM_KEYS (512)
153#define ONE_DEG_IN_RAD ((2.0f * M_PI) / 360.0f) // 0.017444444 (maybe make this a const instead)
154
155const int KEY_STATE_UNCHANGED = -1;
156const bool FULLSCREEN = false;
157const bool SHOW_FPS = false;
158const bool DISABLE_VSYNC = false; // disable vsync to see real framerate
159unsigned int MAX_UNIFORMS = 0; // Requires OpenGL constants only available at runtime, so it can't be const
160
161int key_state[NUM_KEYS];
162bool key_pressed[NUM_KEYS];
163
164int width = 640;
165int height = 480;
166
167double fps;
168
169vec3 cam_pos;
170
171mat4 view_mat;
172mat4 proj_mat;
173
174// TODO: Consider using a list instead since it will make element deletion more efficient
175vector<SceneObject> objects;
176queue<Event> events;
177
178SceneObject* clickedObject = NULL;
179SceneObject* selectedObject = NULL;
180
181float NEAR_CLIP = 0.1f;
182float FAR_CLIP = 100.0f;
183
184// Should really have some array or struct of UI-related variables
185bool isRunning = true;
186
187ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
188
189int main(int argc, char* argv[]) {
190 cout << "New OpenGL Game" << endl;
191
192 if (!restart_gl_log()) {}
193 gl_log("starting GLFW\n%s\n", glfwGetVersionString());
194
195 glfwSetErrorCallback(glfw_error_callback);
196 if (!glfwInit()) {
197 fprintf(stderr, "ERROR: could not start GLFW3\n");
198 return 1;
199 }
200
201#ifdef __APPLE__
202 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
203 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
204 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
205 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
206#endif
207
208 glfwWindowHint(GLFW_SAMPLES, 4);
209
210 GLFWwindow* window = NULL;
211 GLFWmonitor* mon = NULL;
212
213 if (FULLSCREEN) {
214 mon = glfwGetPrimaryMonitor();
215 const GLFWvidmode* vmode = glfwGetVideoMode(mon);
216
217 width = vmode->width;
218 height = vmode->height;
219 cout << "Fullscreen resolution " << vmode->width << "x" << vmode->height << endl;
220 }
221 window = glfwCreateWindow(width, height, "New OpenGL Game", mon, NULL);
222
223 if (!window) {
224 fprintf(stderr, "ERROR: could not open window with GLFW3\n");
225 glfwTerminate();
226 return 1;
227 }
228
229 glfwMakeContextCurrent(window);
230 glewExperimental = GL_TRUE;
231 glewInit();
232
233 srand(time(0));
234
235 /*
236 * RENDERING ALGORITHM NOTES:
237 *
238 * Basically, I need to split my objects into groups, so that each group fits into
239 * GL_MAX_UNIFORM_BLOCK_SIZE. I need to have an offset and a size for each group.
240 * Getting the offset is straitforward. The size may as well be GL_MAX_UNIFORM_BLOCK_SIZE
241 * for each group, since it seems that smaller sizes just round up to the nearest GL_MAX_UNIFORM_BLOCK_SIZE
242 *
243 * I'll need to have a loop inside my render loop that calls glBindBufferRange(GL_UNIFORM_BUFFER, ...
244 * for every 1024 objects and then draws all those objects with one glDraw call.
245 *
246 * Since I currently have very few objects, I'll wait to implement this until I have
247 * a reasonable number of objects always using the same shader.
248 */
249
250 GLint UNIFORM_BUFFER_OFFSET_ALIGNMENT, MAX_UNIFORM_BLOCK_SIZE;
251 glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &UNIFORM_BUFFER_OFFSET_ALIGNMENT);
252 glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &MAX_UNIFORM_BLOCK_SIZE);
253
254 MAX_UNIFORMS = MAX_UNIFORM_BLOCK_SIZE / sizeof(mat4);
255
256 cout << "UNIFORM_BUFFER_OFFSET_ALIGNMENT: " << UNIFORM_BUFFER_OFFSET_ALIGNMENT << endl;
257 cout << "MAX_UNIFORMS: " << MAX_UNIFORMS << endl;
258
259 // Setup Dear ImGui binding
260 IMGUI_CHECKVERSION();
261 ImGui::CreateContext();
262 ImGuiIO& io = ImGui::GetIO(); (void)io;
263 //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
264 //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
265 ImGui_ImplGlfwGL3_Init(window, true);
266
267 // Setup style
268 ImGui::StyleColorsDark();
269 //ImGui::StyleColorsClassic();
270
271 glfwSetMouseButtonCallback(window, mouse_button_callback);
272 glfwSetKeyCallback(window, key_callback);
273
274 const GLubyte* renderer = glGetString(GL_RENDERER);
275 const GLubyte* version = glGetString(GL_VERSION);
276 printf("Renderer: %s\n", renderer);
277 printf("OpenGL version supported %s\n", version);
278
279 glEnable(GL_DEPTH_TEST);
280 glDepthFunc(GL_LESS);
281
282 glEnable(GL_CULL_FACE);
283 // glCullFace(GL_BACK);
284 // glFrontFace(GL_CW);
285
286 int x, y;
287 unsigned char* texImage = loadImage("test.png", &x, &y);
288 if (texImage) {
289 cout << "Yay, I loaded an image!" << endl;
290 cout << x << endl;
291 cout << y << endl;
292 printf("first 4 bytes are: %i %i %i %i\n", texImage[0], texImage[1], texImage[2], texImage[3]);
293 }
294
295 GLuint tex = 0;
296 glGenTextures(1, &tex);
297 glActiveTexture(GL_TEXTURE0);
298 glBindTexture(GL_TEXTURE_2D, tex);
299 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, texImage);
300
301 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
302 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
303 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
304 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
305
306 /* RENDERING ALGORITHM
307 *
308 * Create a separate vbo for each of the following things:
309 * - points
310 * - colors
311 * - texture coordinates
312 * - selected colors
313 * - normals
314 * - indices into a ubo that stores a model matrix for each object
315 *
316 * Also, make a model matrix ubo, the entirety of which will be passed to the vertex shader.
317 * The vbo containing the correct index into the ubo (mentioned above) will be used to select
318 * the right model matrix for each point. The index in the vbo will be the saem for all points
319 * of any given object.
320 *
321 * There will be two shader programs for now, one for draing colored objects, and another for
322 * drawing textured ones. The points, normals, and model mat ubo indices will be passed to both
323 * shaders, while the colors vbo will only be passed to the colors shader, and the texcoords vbo
324 * only to the texture shader.
325 *
326 * Right now, the currently selected object is drawn using one color (specified in the selected
327 * colors vbo) regardless of whether it is normally rendering using colors or a texture. The selected
328 * object is rendering by binding the selected colors vbo in place of the colors vbo and using the colors
329 * shader. Then, the selected object is redrawn along with all other objects, but the depth buffer test
330 * prevents the unselected version of the object from appearing on the screen. This lets me render all the
331 * objects that use a particular shader using one glDrawArrays() call.
332 */
333
334 map<GLuint, BufferInfo> shaderBufferInfo;
335
336 GLuint color_sp = loadShaderProgram("./color.vert", "./color.frag");
337 GLuint texture_sp = loadShaderProgram("./texture.vert", "./texture.frag");
338
339 shaderBufferInfo[color_sp] = BufferInfo();
340 shaderBufferInfo[texture_sp] = BufferInfo();
341
342 SceneObject obj;
343 mat4 T_model, R_model;
344
345 /*
346 // triangle
347 obj = SceneObject();
348 obj.shader_program = color_sp;
349 obj.points = {
350 0.0f, 0.5f, 0.0f,
351 -0.5f, -0.5f, 0.0f,
352 0.5f, -0.5f, 0.0f,
353 0.5f, -0.5f, 0.0f,
354 -0.5f, -0.5f, 0.0f,
355 0.0f, 0.5f, 0.0f,
356 };
357 obj.colors = {
358 1.0f, 0.0f, 0.0f,
359 0.0f, 0.0f, 1.0f,
360 0.0f, 1.0f, 0.0f,
361 0.0f, 1.0f, 0.0f,
362 0.0f, 0.0f, 1.0f,
363 1.0f, 0.0f, 0.0f,
364 };
365 obj.texcoords = { 0.0f };
366 obj.selected_colors = {
367 0.0f, 1.0f, 0.0f,
368 0.0f, 1.0f, 0.0f,
369 0.0f, 1.0f, 0.0f,
370 0.0f, 1.0f, 0.0f,
371 0.0f, 1.0f, 0.0f,
372 0.0f, 1.0f, 0.0f,
373 };
374
375 T_model = translate(mat4(1.0f), vec3(0.45f, -1.5f, 0.0f));
376 R_model = rotate(mat4(1.0f), 0.0f, vec3(0.0f, 1.0f, 0.0f));
377 obj.model_base = T_model*R_model;
378
379 addObjectToSceneDuringInit(obj);
380
381 // square
382 obj = SceneObject();
383 obj.shader_program = texture_sp;
384 obj.points = {
385 0.5f, 0.5f, 0.0f,
386 -0.5f, 0.5f, 0.0f,
387 -0.5f, -0.5f, 0.0f,
388 0.5f, 0.5f, 0.0f,
389 -0.5f, -0.5f, 0.0f,
390 0.5f, -0.5f, 0.0f,
391 };
392 obj.colors = { 0.0f };
393 obj.texcoords = {
394 1.0f, 1.0f,
395 0.0f, 1.0f,
396 0.0f, 0.0f,
397 1.0f, 1.0f,
398 0.0f, 0.0f,
399 1.0f, 0.0f
400 };
401 obj.selected_colors = {
402 0.0f, 0.6f, 0.9f,
403 0.0f, 0.6f, 0.9f,
404 0.0f, 0.6f, 0.9f,
405 0.0f, 0.6f, 0.9f,
406 0.0f, 0.6f, 0.9f,
407 0.0f, 0.6f, 0.9f,
408 };
409
410 T_model = translate(mat4(1.0f), vec3(-0.5f, -1.5f, -1.00f));
411 R_model = rotate(mat4(1.0f), 0.5f, vec3(0.0f, 1.0f, 0.0f));
412 obj.model_base = T_model*R_model;
413
414 addObjectToSceneDuringInit(obj);
415 */
416
417 // player ship
418 obj = SceneObject();
419 obj.shader_program = color_sp;
420 obj.points = {
421 //back
422 -0.5f, 0.3f, 0.0f,
423 -0.5f, 0.0f, 0.0f,
424 0.5f, 0.0f, 0.0f,
425 -0.5f, 0.3f, 0.0f,
426 0.5f, 0.0f, 0.0f,
427 0.5f, 0.3f, 0.0f,
428
429 // left back
430 -0.5f, 0.3f, -2.0f,
431 -0.5f, 0.0f, -2.0f,
432 -0.5f, 0.0f, 0.0f,
433 -0.5f, 0.3f, -2.0f,
434 -0.5f, 0.0f, 0.0f,
435 -0.5f, 0.3f, 0.0f,
436
437 // right back
438 0.5f, 0.3f, 0.0f,
439 0.5f, 0.0f, 0.0f,
440 0.5f, 0.0f, -2.0f,
441 0.5f, 0.3f, 0.0f,
442 0.5f, 0.0f, -2.0f,
443 0.5f, 0.3f, -2.0f,
444
445 // left mid
446 -0.25f, 0.3f, -3.0f,
447 -0.25f, 0.0f, -3.0f,
448 -0.5f, 0.0f, -2.0f,
449 -0.25f, 0.3f, -3.0f,
450 -0.5f, 0.0f, -2.0f,
451 -0.5f, 0.3f, -2.0f,
452
453 // right mid
454 0.5f, 0.3f, -2.0f,
455 0.5f, 0.0f, -2.0f,
456 0.25f, 0.0f, -3.0f,
457 0.5f, 0.3f, -2.0f,
458 0.25f, 0.0f, -3.0f,
459 0.25f, 0.3f, -3.0f,
460
461 // left front
462 0.0f, 0.0f, -3.5f,
463 -0.25f, 0.0f, -3.0f,
464 -0.25f, 0.3f, -3.0f,
465
466 // right front
467 0.25f, 0.3f, -3.0f,
468 0.25f, 0.0f, -3.0f,
469 0.0f, 0.0f, -3.5f,
470
471 // top back
472 -0.5f, 0.3f, -2.0f,
473 -0.5f, 0.3f, 0.0f,
474 0.5f, 0.3f, 0.0f,
475 -0.5f, 0.3f, -2.0f,
476 0.5f, 0.3f, 0.0f,
477 0.5f, 0.3f, -2.0f,
478
479 // bottom back
480 -0.5f, 0.0f, 0.0f,
481 -0.5f, 0.0f, -2.0f,
482 0.5f, 0.0f, 0.0f,
483 0.5f, 0.0f, 0.0f,
484 -0.5f, 0.0f, -2.0f,
485 0.5f, 0.0f, -2.0f,
486
487 // top mid
488 -0.25f, 0.3f, -3.0f,
489 -0.5f, 0.3f, -2.0f,
490 0.5f, 0.3f, -2.0f,
491 -0.25f, 0.3f, -3.0f,
492 0.5f, 0.3f, -2.0f,
493 0.25f, 0.3f, -3.0f,
494
495 // bottom mid
496 -0.5f, 0.0f, -2.0f,
497 -0.25f, 0.0f, -3.0f,
498 0.5f, 0.0f, -2.0f,
499 0.5f, 0.0f, -2.0f,
500 -0.25f, 0.0f, -3.0f,
501 0.25f, 0.0f, -3.0f,
502
503 // top front
504 -0.25f, 0.3f, -3.0f,
505 0.25f, 0.3f, -3.0f,
506 0.0f, 0.0f, -3.5f,
507
508 // bottom front
509 0.25f, 0.0f, -3.0f,
510 -0.25f, 0.0f, -3.0f,
511 0.0f, 0.0f, -3.5f,
512
513 // left wing start back
514 -1.5f, 0.3f, 0.0f,
515 -1.5f, 0.0f, 0.0f,
516 -0.5f, 0.0f, 0.0f,
517 -1.5f, 0.3f, 0.0f,
518 -0.5f, 0.0f, 0.0f,
519 -0.5f, 0.3f, 0.0f,
520
521 // left wing start top
522 -0.5f, 0.3f, -0.3f,
523 -1.3f, 0.3f, -0.3f,
524 -1.5f, 0.3f, 0.0f,
525 -0.5f, 0.3f, -0.3f,
526 -1.5f, 0.3f, 0.0f,
527 -0.5f, 0.3f, 0.0f,
528
529 // left wing start front
530 -0.5f, 0.3f, -0.3f,
531 -0.5f, 0.0f, -0.3f,
532 -1.3f, 0.0f, -0.3f,
533 -0.5f, 0.3f, -0.3f,
534 -1.3f, 0.0f, -0.3f,
535 -1.3f, 0.3f, -0.3f,
536
537 // left wing start bottom
538 -0.5f, 0.0f, 0.0f,
539 -1.5f, 0.0f, 0.0f,
540 -1.3f, 0.0f, -0.3f,
541 -0.5f, 0.0f, 0.0f,
542 -1.3f, 0.0f, -0.3f,
543 -0.5f, 0.0f, -0.3f,
544
545 // left wing end outside
546 -1.5f, 0.3f, 0.0f,
547 -2.2f, 0.15f, -0.8f,
548 -1.5f, 0.0f, 0.0f,
549
550 // left wing end top
551 -1.3f, 0.3f, -0.3f,
552 -2.2f, 0.15f, -0.8f,
553 -1.5f, 0.3f, 0.0f,
554
555 // left wing end front
556 -1.3f, 0.0f, -0.3f,
557 -2.2f, 0.15f, -0.8f,
558 -1.3f, 0.3f, -0.3f,
559
560 // left wing end bottom
561 -1.5f, 0.0f, 0.0f,
562 -2.2f, 0.15f, -0.8f,
563 -1.3f, 0.0f, -0.3f,
564
565 // right wing start back
566 1.5f, 0.0f, 0.0f,
567 1.5f, 0.3f, 0.0f,
568 0.5f, 0.0f, 0.0f,
569 0.5f, 0.0f, 0.0f,
570 1.5f, 0.3f, 0.0f,
571 0.5f, 0.3f, 0.0f,
572
573 // right wing start top
574 1.3f, 0.3f, -0.3f,
575 0.5f, 0.3f, -0.3f,
576 1.5f, 0.3f, 0.0f,
577 1.5f, 0.3f, 0.0f,
578 0.5f, 0.3f, -0.3f,
579 0.5f, 0.3f, 0.0f,
580
581 // right wing start front
582 0.5f, 0.0f, -0.3f,
583 0.5f, 0.3f, -0.3f,
584 1.3f, 0.0f, -0.3f,
585 1.3f, 0.0f, -0.3f,
586 0.5f, 0.3f, -0.3f,
587 1.3f, 0.3f, -0.3f,
588
589 // right wing start bottom
590 1.5f, 0.0f, 0.0f,
591 0.5f, 0.0f, 0.0f,
592 1.3f, 0.0f, -0.3f,
593 1.3f, 0.0f, -0.3f,
594 0.5f, 0.0f, 0.0f,
595 0.5f, 0.0f, -0.3f,
596
597 // right wing end outside
598 2.2f, 0.15f, -0.8f,
599 1.5f, 0.3f, 0.0f,
600 1.5f, 0.0f, 0.0f,
601
602 // right wing end top
603 2.2f, 0.15f, -0.8f,
604 1.3f, 0.3f, -0.3f,
605 1.5f, 0.3f, 0.0f,
606
607 // right wing end front
608 2.2f, 0.15f, -0.8f,
609 1.3f, 0.0f, -0.3f,
610 1.3f, 0.3f, -0.3f,
611
612 // right wing end bottom
613 2.2f, 0.15f, -0.8f,
614 1.5f, 0.0f, 0.0f,
615 1.3f, 0.0f, -0.3f,
616 };
617 obj.colors = {
618 0.0f, 0.0f, 0.3f,
619 0.0f, 0.0f, 0.3f,
620 0.0f, 0.0f, 0.3f,
621 0.0f, 0.0f, 0.3f,
622 0.0f, 0.0f, 0.3f,
623 0.0f, 0.0f, 0.3f,
624
625 0.0f, 0.0f, 0.3f,
626 0.0f, 0.0f, 0.3f,
627 0.0f, 0.0f, 0.3f,
628 0.0f, 0.0f, 0.3f,
629 0.0f, 0.0f, 0.3f,
630 0.0f, 0.0f, 0.3f,
631
632 0.0f, 0.0f, 0.3f,
633 0.0f, 0.0f, 0.3f,
634 0.0f, 0.0f, 0.3f,
635 0.0f, 0.0f, 0.3f,
636 0.0f, 0.0f, 0.3f,
637 0.0f, 0.0f, 0.3f,
638
639 0.0f, 0.0f, 0.3f,
640 0.0f, 0.0f, 0.3f,
641 0.0f, 0.0f, 0.3f,
642 0.0f, 0.0f, 0.3f,
643 0.0f, 0.0f, 0.3f,
644 0.0f, 0.0f, 0.3f,
645
646 0.0f, 0.0f, 0.3f,
647 0.0f, 0.0f, 0.3f,
648 0.0f, 0.0f, 0.3f,
649 0.0f, 0.0f, 0.3f,
650 0.0f, 0.0f, 0.3f,
651 0.0f, 0.0f, 0.3f,
652
653 0.0f, 0.0f, 1.0f,
654 0.0f, 0.0f, 1.0f,
655 0.0f, 0.0f, 1.0f,
656
657 0.0f, 0.0f, 1.0f,
658 0.0f, 0.0f, 1.0f,
659 0.0f, 0.0f, 1.0f,
660
661 0.0f, 0.0f, 1.0f,
662 0.0f, 0.0f, 1.0f,
663 0.0f, 0.0f, 1.0f,
664 0.0f, 0.0f, 1.0f,
665 0.0f, 0.0f, 1.0f,
666 0.0f, 0.0f, 1.0f,
667
668 0.0f, 0.0f, 1.0f,
669 0.0f, 0.0f, 1.0f,
670 0.0f, 0.0f, 1.0f,
671 0.0f, 0.0f, 1.0f,
672 0.0f, 0.0f, 1.0f,
673 0.0f, 0.0f, 1.0f,
674
675 0.0f, 0.0f, 1.0f,
676 0.0f, 0.0f, 1.0f,
677 0.0f, 0.0f, 1.0f,
678 0.0f, 0.0f, 1.0f,
679 0.0f, 0.0f, 1.0f,
680 0.0f, 0.0f, 1.0f,
681
682 0.0f, 0.0f, 1.0f,
683 0.0f, 0.0f, 1.0f,
684 0.0f, 0.0f, 1.0f,
685 0.0f, 0.0f, 1.0f,
686 0.0f, 0.0f, 1.0f,
687 0.0f, 0.0f, 1.0f,
688
689 0.0f, 0.0f, 0.3f,
690 0.0f, 0.0f, 0.3f,
691 0.0f, 0.0f, 0.3f,
692
693 0.0f, 0.0f, 0.3f,
694 0.0f, 0.0f, 0.3f,
695 0.0f, 0.0f, 0.3f,
696
697 0.0f, 0.0f, 0.3f,
698 0.0f, 0.0f, 0.3f,
699 0.0f, 0.0f, 0.3f,
700 0.0f, 0.0f, 0.3f,
701 0.0f, 0.0f, 0.3f,
702 0.0f, 0.0f, 0.3f,
703
704 0.0f, 0.0f, 0.3f,
705 0.0f, 0.0f, 0.3f,
706 0.0f, 0.0f, 0.3f,
707 0.0f, 0.0f, 0.3f,
708 0.0f, 0.0f, 0.3f,
709 0.0f, 0.0f, 0.3f,
710
711 0.0f, 0.0f, 0.3f,
712 0.0f, 0.0f, 0.3f,
713 0.0f, 0.0f, 0.3f,
714 0.0f, 0.0f, 0.3f,
715 0.0f, 0.0f, 0.3f,
716 0.0f, 0.0f, 0.3f,
717
718 0.0f, 0.0f, 0.3f,
719 0.0f, 0.0f, 0.3f,
720 0.0f, 0.0f, 0.3f,
721 0.0f, 0.0f, 0.3f,
722 0.0f, 0.0f, 0.3f,
723 0.0f, 0.0f, 0.3f,
724
725 0.0f, 0.0f, 0.3f,
726 0.0f, 0.0f, 0.3f,
727 0.0f, 0.0f, 0.3f,
728
729 0.0f, 0.0f, 0.3f,
730 0.0f, 0.0f, 0.3f,
731 0.0f, 0.0f, 0.3f,
732
733 0.0f, 0.0f, 0.3f,
734 0.0f, 0.0f, 0.3f,
735 0.0f, 0.0f, 0.3f,
736
737 0.0f, 0.0f, 0.3f,
738 0.0f, 0.0f, 0.3f,
739 0.0f, 0.0f, 0.3f,
740
741 0.0f, 0.0f, 0.3f,
742 0.0f, 0.0f, 0.3f,
743 0.0f, 0.0f, 0.3f,
744 0.0f, 0.0f, 0.3f,
745 0.0f, 0.0f, 0.3f,
746 0.0f, 0.0f, 0.3f,
747
748 0.0f, 0.0f, 0.3f,
749 0.0f, 0.0f, 0.3f,
750 0.0f, 0.0f, 0.3f,
751 0.0f, 0.0f, 0.3f,
752 0.0f, 0.0f, 0.3f,
753 0.0f, 0.0f, 0.3f,
754
755 0.0f, 0.0f, 0.3f,
756 0.0f, 0.0f, 0.3f,
757 0.0f, 0.0f, 0.3f,
758 0.0f, 0.0f, 0.3f,
759 0.0f, 0.0f, 0.3f,
760 0.0f, 0.0f, 0.3f,
761
762 0.0f, 0.0f, 0.3f,
763 0.0f, 0.0f, 0.3f,
764 0.0f, 0.0f, 0.3f,
765 0.0f, 0.0f, 0.3f,
766 0.0f, 0.0f, 0.3f,
767 0.0f, 0.0f, 0.3f,
768
769 0.0f, 0.0f, 0.3f,
770 0.0f, 0.0f, 0.3f,
771 0.0f, 0.0f, 0.3f,
772
773 0.0f, 0.0f, 0.3f,
774 0.0f, 0.0f, 0.3f,
775 0.0f, 0.0f, 0.3f,
776
777 0.0f, 0.0f, 0.3f,
778 0.0f, 0.0f, 0.3f,
779 0.0f, 0.0f, 0.3f,
780
781 0.0f, 0.0f, 0.3f,
782 0.0f, 0.0f, 0.3f,
783 0.0f, 0.0f, 0.3f,
784 };
785 obj.texcoords = { 0.0f };
786 obj.selected_colors = { 0.0f };
787
788 T_model = translate(mat4(1.0f), vec3(0.0f, -1.2f, 1.8f));
789 R_model = rotate(mat4(1.0f), 20.0f * (float)ONE_DEG_IN_RAD, vec3(1.0f, 0.0f, 0.0f));
790 R_model = mat4(1.0f);
791 obj.model_base = T_model * R_model * scale(mat4(1.0f), vec3(0.1f, 0.1f, 0.1f));
792
793 addObjectToSceneDuringInit(obj);
794
795 vector<SceneObject>::iterator obj_it;
796
797 GLuint points_vbo, colors_vbo, selected_colors_vbo, texcoords_vbo,
798 normals_vbo, ubo, model_mat_idx_vbo;
799
800 initializeBuffers(
801 &points_vbo,
802 &colors_vbo,
803 &selected_colors_vbo,
804 &texcoords_vbo,
805 &normals_vbo,
806 &ubo,
807 &model_mat_idx_vbo);
808
809 populateBuffers(objects,
810 shaderBufferInfo,
811 points_vbo,
812 colors_vbo,
813 selected_colors_vbo,
814 texcoords_vbo,
815 normals_vbo,
816 ubo,
817 model_mat_idx_vbo);
818
819 /*
820 spawnAsteroid(vec3(0.0f, -1.2f, -21.5f), color_sp,
821 shaderBufferInfo,
822 points_vbo,
823 colors_vbo,
824 selected_colors_vbo,
825 texcoords_vbo,
826 normals_vbo,
827 ubo,
828 model_mat_idx_vbo);
829 spawnAsteroid(vec3(1.0f, -1.2f, -21.5f), color_sp,
830 shaderBufferInfo,
831 points_vbo,
832 colors_vbo,
833 selected_colors_vbo,
834 texcoords_vbo,
835 normals_vbo,
836 ubo,
837 model_mat_idx_vbo);
838 spawnAsteroid(vec3(-0.5f, -1.2f, -20.8f), color_sp,
839 shaderBufferInfo,
840 points_vbo,
841 colors_vbo,
842 selected_colors_vbo,
843 texcoords_vbo,
844 normals_vbo,
845 ubo,
846 model_mat_idx_vbo);
847 spawnAsteroid(vec3(-0.3f, -1.2f, -20.8f), color_sp,
848 shaderBufferInfo,
849 points_vbo,
850 colors_vbo,
851 selected_colors_vbo,
852 texcoords_vbo,
853 normals_vbo,
854 ubo,
855 model_mat_idx_vbo);
856 spawnAsteroid(vec3(-0.1f, -1.2f, -20.8f), color_sp,
857 shaderBufferInfo,
858 points_vbo,
859 colors_vbo,
860 selected_colors_vbo,
861 texcoords_vbo,
862 normals_vbo,
863 ubo,
864 model_mat_idx_vbo);
865 */
866
867 GLuint vao = 0;
868 glGenVertexArrays(1, &vao);
869 glBindVertexArray(vao);
870
871 glEnableVertexAttribArray(0);
872 glEnableVertexAttribArray(1);
873 glEnableVertexAttribArray(2);
874 glEnableVertexAttribArray(3);
875
876 glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
877 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
878
879 glBindBuffer(GL_ARRAY_BUFFER, normals_vbo);
880 glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, 0);
881
882 glBindBuffer(GL_ARRAY_BUFFER, model_mat_idx_vbo);
883 glVertexAttribIPointer(3, 1, GL_UNSIGNED_INT, 0, 0);
884
885 GLuint vao2 = 0;
886 glGenVertexArrays(1, &vao2);
887 glBindVertexArray(vao2);
888
889 glEnableVertexAttribArray(0);
890 glEnableVertexAttribArray(1);
891 glEnableVertexAttribArray(2);
892 glEnableVertexAttribArray(3);
893
894 glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
895 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
896
897 glBindBuffer(GL_ARRAY_BUFFER, texcoords_vbo);
898 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
899
900 glBindBuffer(GL_ARRAY_BUFFER, normals_vbo);
901 glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, 0);
902
903 glBindBuffer(GL_ARRAY_BUFFER, model_mat_idx_vbo);
904 glVertexAttribIPointer(3, 1, GL_UNSIGNED_INT, 0, 0);
905
906 float cam_speed = 1.0f;
907 float cam_yaw_speed = 60.0f*ONE_DEG_IN_RAD;
908 float cam_pitch_speed = 60.0f*ONE_DEG_IN_RAD;
909
910 // glm::lookAt can create the view matrix
911 // glm::perspective can create the projection matrix
912
913 cam_pos = vec3(0.0f, 0.0f, 2.0f);
914 //cam_pos = vec3(-2.1f, -1.5f, -1.5f); // Good position for checking ship faces
915 float cam_yaw = 0.0f * 2.0f * 3.14159f / 360.0f;
916 float cam_pitch = -50.0f * 2.0f * 3.14159f / 360.0f;
917
918 mat4 T = translate(mat4(1.0f), vec3(-cam_pos.x, -cam_pos.y, -cam_pos.z));
919 mat4 yaw_mat = rotate(mat4(1.0f), -cam_yaw, vec3(0.0f, 1.0f, 0.0f));
920 mat4 pitch_mat = rotate(mat4(1.0f), -cam_pitch, vec3(1.0f, 0.0f, 0.0f));
921 mat4 R = pitch_mat * yaw_mat;
922 view_mat = R*T;
923
924 float fov = 67.0f * ONE_DEG_IN_RAD;
925 float aspect = (float)width / (float)height;
926
927 float range = tan(fov * 0.5f) * NEAR_CLIP;
928 float Sx = NEAR_CLIP / (range * aspect);
929 float Sy = NEAR_CLIP / range;
930 float Sz = -(FAR_CLIP + NEAR_CLIP) / (FAR_CLIP - NEAR_CLIP);
931 float Pz = -(2.0f * FAR_CLIP * NEAR_CLIP) / (FAR_CLIP - NEAR_CLIP);
932
933 float proj_arr[] = {
934 Sx, 0.0f, 0.0f, 0.0f,
935 0.0f, Sy, 0.0f, 0.0f,
936 0.0f, 0.0f, Sz, -1.0f,
937 0.0f, 0.0f, Pz, 0.0f,
938 };
939 proj_mat = make_mat4(proj_arr);
940
941 GLuint ub_binding_point = 0;
942
943 GLuint view_test_loc = glGetUniformLocation(color_sp, "view");
944 GLuint proj_test_loc = glGetUniformLocation(color_sp, "proj");
945 GLuint color_sp_ub_index = glGetUniformBlockIndex(color_sp, "models");
946
947 GLuint view_mat_loc = glGetUniformLocation(texture_sp, "view");
948 GLuint proj_mat_loc = glGetUniformLocation(texture_sp, "proj");
949 GLuint texture_sp_ub_index = glGetUniformBlockIndex(texture_sp, "models");
950
951 glUseProgram(color_sp);
952 glUniformMatrix4fv(view_test_loc, 1, GL_FALSE, value_ptr(view_mat));
953 glUniformMatrix4fv(proj_test_loc, 1, GL_FALSE, value_ptr(proj_mat));
954
955 glUniformBlockBinding(color_sp, color_sp_ub_index, ub_binding_point);
956 glBindBufferRange(GL_UNIFORM_BUFFER, ub_binding_point, ubo, 0, GL_MAX_UNIFORM_BLOCK_SIZE);
957
958 glUseProgram(texture_sp);
959 glUniformMatrix4fv(view_mat_loc, 1, GL_FALSE, value_ptr(view_mat));
960 glUniformMatrix4fv(proj_mat_loc, 1, GL_FALSE, value_ptr(proj_mat));
961
962 glUniformBlockBinding(texture_sp, texture_sp_ub_index, ub_binding_point);
963 glBindBufferRange(GL_UNIFORM_BUFFER, ub_binding_point, ubo, 0, GL_MAX_UNIFORM_BLOCK_SIZE);
964
965 bool cam_moved = false;
966
967 int frame_count = 0;
968 double elapsed_seconds_fps = 0.0f;
969 double elapsed_seconds_spawn = 0.0f;
970 double previous_seconds = glfwGetTime();
971
972 // This draws wireframes. Useful for seeing separate faces and occluded objects.
973 //glPolygonMode(GL_FRONT, GL_LINE);
974
975 if (DISABLE_VSYNC && SHOW_FPS) {
976 glfwSwapInterval(0);
977 }
978
979 State curState = STATE_MAIN_MENU;
980
981 while (!glfwWindowShouldClose(window) && isRunning) {
982 double current_seconds = glfwGetTime();
983 double elapsed_seconds = current_seconds - previous_seconds;
984 previous_seconds = current_seconds;
985
986 if (SHOW_FPS) {
987 elapsed_seconds_fps += elapsed_seconds;
988 if (elapsed_seconds_fps > 0.25f) {
989 fps = (double)frame_count / elapsed_seconds_fps;
990 cout << "FPS: " << fps << endl;
991
992 frame_count = 0;
993 elapsed_seconds_fps = 0.0f;
994 }
995
996 frame_count++;
997 }
998
999 elapsed_seconds_spawn += elapsed_seconds;
1000 if (elapsed_seconds_spawn > 0.5f) {
1001 spawnAsteroid(vec3(getRandomNum(-1.3f, 1.3f), getRandomNum(-3.0f, -1.0f), getRandomNum(-5.5f, -4.5f)), color_sp,
1002 shaderBufferInfo,
1003 points_vbo,
1004 colors_vbo,
1005 selected_colors_vbo,
1006 texcoords_vbo,
1007 normals_vbo,
1008 ubo,
1009 model_mat_idx_vbo);
1010
1011 elapsed_seconds_spawn = 0.0f;
1012 }
1013
1014 // Handle events
1015
1016 clickedObject = NULL;
1017
1018 // reset the all key states to KEY_STATE_UNCHANGED (something the GLFW key callback can never return)
1019 // so that GLFW_PRESS and GLFW_RELEASE are only detected once
1020 // TODO: Change this if we ever need to act on GLFW_REPEAT (which is when a key is held down
1021 // continuously for a period of time)
1022 fill(key_state, key_state + NUM_KEYS, KEY_STATE_UNCHANGED);
1023
1024 glfwPollEvents();
1025
1026 while (!events.empty()) {
1027 switch (events.front()) {
1028 case EVENT_GO_TO_MAIN_MENU:
1029 curState = STATE_MAIN_MENU;
1030 break;
1031 case EVENT_GO_TO_GAME:
1032 curState = STATE_GAME;
1033 break;
1034 case EVENT_QUIT:
1035 isRunning = false;
1036 break;
1037 }
1038 events.pop();
1039 }
1040
1041 if (curState == STATE_GAME) {
1042 /*
1043 if (clickedObject == &objects[0]) {
1044 selectedObject = &objects[0];
1045 }
1046 if (clickedObject == &objects[1]) {
1047 selectedObject = &objects[1];
1048 }
1049 */
1050
1051 /*
1052 if (key_state[GLFW_KEY_SPACE] == GLFW_PRESS) {
1053 transformObject(objects[1], translate(mat4(1.0f), vec3(0.3f, 0.0f, 0.0f)), ubo);
1054 }
1055 if (key_pressed[GLFW_KEY_RIGHT]) {
1056 transformObject(objects[2], translate(mat4(1.0f), vec3(0.01f, 0.0f, 0.0f)), ubo);
1057 }
1058 if (key_pressed[GLFW_KEY_LEFT]) {
1059 transformObject(objects[2], translate(mat4(1.0f), vec3(-0.01f, 0.0f, 0.0f)), ubo);
1060 }
1061 */
1062
1063 if (key_pressed[GLFW_KEY_RIGHT]) {
1064 transformObject(objects[0], translate(mat4(1.0f), vec3(0.01f, 0.0f, 0.0f)), ubo);
1065 }
1066 if (key_pressed[GLFW_KEY_LEFT]) {
1067 transformObject(objects[0], translate(mat4(1.0f), vec3(-0.01f, 0.0f, 0.0f)), ubo);
1068 }
1069
1070 for (int i = 1; i < objects.size(); i++) {
1071 if (!objects[i].deleted) {
1072 transformObject(objects[i], translate(mat4(1.0f), vec3(0.0f, 0.0f, 0.04f)), ubo);
1073 }
1074 }
1075
1076 if (key_state[GLFW_KEY_SPACE] == GLFW_PRESS) {
1077 removeObjectFromScene(0, ubo);
1078 }
1079 }
1080
1081 if (key_state[GLFW_KEY_ESCAPE] == GLFW_PRESS) {
1082 glfwSetWindowShouldClose(window, 1);
1083 }
1084
1085 float dist = cam_speed * elapsed_seconds;
1086 if (key_pressed[GLFW_KEY_A]) {
1087 vec3 dir = vec3(inverse(R) * vec4(-1.0f, 0.0f, 0.0f, 1.0f));
1088 cam_pos += dir * dist;
1089
1090 cam_moved = true;
1091 }
1092 if (key_pressed[GLFW_KEY_D]) {
1093 vec3 dir = vec3(inverse(R) * vec4(1.0f, 0.0f, 0.0f, 1.0f));
1094 cam_pos += dir * dist;
1095
1096 cam_moved = true;
1097 }
1098 if (key_pressed[GLFW_KEY_W]) {
1099 vec3 dir = vec3(inverse(R) * vec4(0.0f, 0.0f, -1.0f, 1.0f));
1100 cam_pos += dir * dist;
1101
1102 cam_moved = true;
1103 }
1104 if (key_pressed[GLFW_KEY_S]) {
1105 vec3 dir = vec3(inverse(R) * vec4(0.0f, 0.0f, 1.0f, 1.0f));
1106 cam_pos += dir * dist;
1107
1108 cam_moved = true;
1109 }
1110 /*
1111 if (key_pressed[GLFW_KEY_LEFT]) {
1112 cam_yaw += cam_yaw_speed * elapsed_seconds;
1113 cam_moved = true;
1114 }
1115 if (key_pressed[GLFW_KEY_RIGHT]) {
1116 cam_yaw -= cam_yaw_speed * elapsed_seconds;
1117 cam_moved = true;
1118 }
1119 if (key_pressed[GLFW_KEY_UP]) {
1120 cam_pitch += cam_pitch_speed * elapsed_seconds;
1121 cam_moved = true;
1122 }
1123 if (key_pressed[GLFW_KEY_DOWN]) {
1124 cam_pitch -= cam_pitch_speed * elapsed_seconds;
1125 cam_moved = true;
1126 }
1127 */
1128 if (cam_moved) {
1129 T = translate(mat4(1.0f), vec3(-cam_pos.x, -cam_pos.y, -cam_pos.z));
1130
1131 mat4 yaw_mat = rotate(mat4(1.0f), -cam_yaw, vec3(0.0f, 1.0f, 0.0f));
1132 mat4 pitch_mat = rotate(mat4(1.0f), -cam_pitch, vec3(1.0f, 0.0f, 0.0f));
1133 R = pitch_mat * yaw_mat;
1134
1135 view_mat = R * T;
1136
1137 //printVector("cam pos", cam_pos);
1138
1139 glUseProgram(color_sp);
1140 glUniformMatrix4fv(view_test_loc, 1, GL_FALSE, value_ptr(view_mat));
1141
1142 glUseProgram(texture_sp);
1143 glUniformMatrix4fv(view_mat_loc, 1, GL_FALSE, value_ptr(view_mat));
1144
1145 cam_moved = false;
1146 }
1147
1148 // Render scene
1149
1150 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1151
1152 switch (curState) {
1153 case STATE_MAIN_MENU:
1154 renderMainMenu();
1155 renderMainMenuGui();
1156 break;
1157 case STATE_GAME:
1158 renderScene(objects,
1159 color_sp, texture_sp,
1160 vao, vao2,
1161 points_vbo, normals_vbo,
1162 colors_vbo, texcoords_vbo, selected_colors_vbo,
1163 selectedObject,
1164 shaderBufferInfo);
1165 renderSceneGui();
1166 break;
1167 }
1168
1169 glfwSwapBuffers(window);
1170 }
1171
1172 ImGui_ImplGlfwGL3_Shutdown();
1173 ImGui::DestroyContext();
1174
1175 glfwDestroyWindow(window);
1176 glfwTerminate();
1177
1178 return 0;
1179}
1180
1181void glfw_error_callback(int error, const char* description) {
1182 gl_log_err("GLFW ERROR: code %i msg: %s\n", error, description);
1183}
1184
1185void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) {
1186 double mouse_x, mouse_y;
1187 glfwGetCursorPos(window, &mouse_x, &mouse_y);
1188
1189 if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) {
1190 cout << "Mouse clicked (" << mouse_x << "," << mouse_y << ")" << endl;
1191 selectedObject = NULL;
1192
1193 float x = (2.0f*mouse_x) / width - 1.0f;
1194 float y = 1.0f - (2.0f*mouse_y) / height;
1195
1196 cout << "x: " << x << ", y: " << y << endl;
1197
1198 vec4 ray_clip = vec4(x, y, -1.0f, 1.0f);
1199 vec4 ray_eye = inverse(proj_mat) * ray_clip;
1200 ray_eye = vec4(vec2(ray_eye), -1.0f, 1.0f);
1201 vec4 ray_world = inverse(view_mat) * ray_eye;
1202
1203 vec4 cam_pos_temp = vec4(cam_pos, 1.0f);
1204
1205 vec4 click_point;
1206 vec3 closest_point = vec3(0.0f, 0.0f, -FAR_CLIP); // Any valid point will be closer than the far clipping plane, so initial value to that
1207 SceneObject* closest_object = NULL;
1208
1209 for (vector<SceneObject>::iterator it = objects.begin(); it != objects.end(); it++) {
1210 for (unsigned int p_idx = 0; p_idx < it->points.size(); p_idx += 9) {
1211 if (faceClicked(
1212 {
1213 vec3(it->points[p_idx], it->points[p_idx + 1], it->points[p_idx + 2]),
1214 vec3(it->points[p_idx + 3], it->points[p_idx + 4], it->points[p_idx + 5]),
1215 vec3(it->points[p_idx + 6], it->points[p_idx + 7], it->points[p_idx + 8]),
1216 },
1217 &*it, ray_world, cam_pos_temp, click_point
1218 )) {
1219 click_point = view_mat * click_point;
1220
1221 if (-NEAR_CLIP >= click_point.z && click_point.z > -FAR_CLIP && click_point.z > closest_point.z) {
1222 closest_point = vec3(click_point);
1223 closest_object = &*it;
1224 }
1225 }
1226 }
1227 }
1228
1229 if (closest_object == NULL) {
1230 cout << "No object was clicked" << endl;
1231 } else {
1232 clickedObject = closest_object;
1233 cout << "Clicked object: " << clickedObject->id << endl;
1234 }
1235 }
1236}
1237
1238void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
1239 key_state[key] = action;
1240
1241 // should be true for GLFW_PRESS and GLFW_REPEAT
1242 key_pressed[key] = (action != GLFW_RELEASE);
1243}
1244
1245
1246GLuint loadShader(GLenum type, string file) {
1247 cout << "Loading shader from file " << file << endl;
1248
1249 ifstream shaderFile(file);
1250 GLuint shaderId = 0;
1251
1252 if (shaderFile.is_open()) {
1253 string line, shaderString;
1254
1255 while(getline(shaderFile, line)) {
1256 shaderString += line + "\n";
1257 }
1258 shaderFile.close();
1259 const char* shaderCString = shaderString.c_str();
1260
1261 shaderId = glCreateShader(type);
1262 glShaderSource(shaderId, 1, &shaderCString, NULL);
1263 glCompileShader(shaderId);
1264
1265 cout << "Loaded successfully" << endl;
1266 } else {
1267 cout << "Failed to load the file" << endl;
1268 }
1269
1270 return shaderId;
1271}
1272
1273GLuint loadShaderProgram(string vertexShaderPath, string fragmentShaderPath) {
1274 GLuint vs = loadShader(GL_VERTEX_SHADER, vertexShaderPath);
1275 GLuint fs = loadShader(GL_FRAGMENT_SHADER, fragmentShaderPath);
1276
1277 GLuint shader_program = glCreateProgram();
1278 glAttachShader(shader_program, vs);
1279 glAttachShader(shader_program, fs);
1280
1281 glLinkProgram(shader_program);
1282
1283 return shader_program;
1284}
1285
1286unsigned char* loadImage(string file_name, int* x, int* y) {
1287 int n;
1288 int force_channels = 4; // This forces RGBA (4 bytes per pixel)
1289 unsigned char* image_data = stbi_load(file_name.c_str(), x, y, &n, force_channels);
1290
1291 int width_in_bytes = *x * 4;
1292 unsigned char *top = NULL;
1293 unsigned char *bottom = NULL;
1294 unsigned char temp = 0;
1295 int half_height = *y / 2;
1296
1297 // flip image upside-down to account for OpenGL treating lower-left as (0, 0)
1298 for (int row = 0; row < half_height; row++) {
1299 top = image_data + row * width_in_bytes;
1300 bottom = image_data + (*y - row - 1) * width_in_bytes;
1301 for (int col = 0; col < width_in_bytes; col++) {
1302 temp = *top;
1303 *top = *bottom;
1304 *bottom = temp;
1305 top++;
1306 bottom++;
1307 }
1308 }
1309
1310 if (!image_data) {
1311 fprintf(stderr, "ERROR: could not load %s\n", file_name.c_str());
1312 }
1313
1314 // Not Power-of-2 check
1315 if ((*x & (*x - 1)) != 0 || (*y & (*y - 1)) != 0) {
1316 fprintf(stderr, "WARNING: texture %s is not power-of-2 dimensions\n", file_name.c_str());
1317 }
1318
1319 return image_data;
1320}
1321
1322bool faceClicked(array<vec3, 3> points, SceneObject* obj, vec4 world_ray, vec4 cam, vec4& click_point) {
1323 // LINE EQUATION: P = O + Dt
1324 // O = cam
1325 // D = ray_world
1326
1327 // PLANE EQUATION: P dot n + d = 0
1328 // n is the normal vector
1329 // d is the offset from the origin
1330
1331 // Take the cross-product of two vectors on the plane to get the normal
1332 vec3 v1 = points[1] - points[0];
1333 vec3 v2 = points[2] - points[0];
1334
1335 vec3 normal = vec3(v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x);
1336
1337 vec3 local_ray = vec3(inverse(obj->model_mat) * world_ray);
1338 vec3 local_cam = vec3(inverse(obj->model_mat) * cam);
1339
1340 local_ray = local_ray - local_cam;
1341
1342 float d = -glm::dot(points[0], normal);
1343 float t = -(glm::dot(local_cam, normal) + d) / glm::dot(local_ray, normal);
1344
1345 vec3 intersection = local_cam + t*local_ray;
1346
1347 if (insideTriangle(intersection, points)) {
1348 click_point = obj->model_mat * vec4(intersection, 1.0f);
1349 return true;
1350 } else {
1351 return false;
1352 }
1353}
1354
1355bool insideTriangle(vec3 p, array<vec3, 3> triangle_points) {
1356 vec3 v21 = triangle_points[1] - triangle_points[0];
1357 vec3 v31 = triangle_points[2] - triangle_points[0];
1358 vec3 pv1 = p - triangle_points[0];
1359
1360 float y = (pv1.y*v21.x - pv1.x*v21.y) / (v31.y*v21.x - v31.x*v21.y);
1361 float x = (pv1.x-y*v31.x) / v21.x;
1362
1363 return x > 0.0f && y > 0.0f && x+y < 1.0f;
1364}
1365
1366void printVector(string label, vec3 v) {
1367 cout << label << " -> (" << v.x << "," << v.y << "," << v.z << ")" << endl;
1368}
1369
1370void print4DVector(string label, vec4 v) {
1371 cout << label << " -> (" << v.x << "," << v.y << "," << v.z << "," << v.w << ")" << endl;
1372}
1373
1374void addObjectToSceneDuringInit(SceneObject& obj) {
1375 obj.id = objects.size(); // currently unused
1376 obj.num_points = obj.points.size() / 3;
1377 obj.model_transform = mat4(1.0f);
1378 obj.deleted = false;
1379
1380 obj.normals.reserve(obj.points.size());
1381 for (int i = 0; i < obj.points.size(); i += 9) {
1382 vec3 point1 = vec3(obj.points[i], obj.points[i + 1], obj.points[i + 2]);
1383 vec3 point2 = vec3(obj.points[i + 3], obj.points[i + 4], obj.points[i + 5]);
1384 vec3 point3 = vec3(obj.points[i + 6], obj.points[i + 7], obj.points[i + 8]);
1385
1386 vec3 normal = normalize(cross(point2 - point1, point3 - point1));
1387
1388 // Add the same normal for all 3 points
1389 for (int j = 0; j < 3; j++) {
1390 obj.normals.push_back(normal.x);
1391 obj.normals.push_back(normal.y);
1392 obj.normals.push_back(normal.z);
1393 }
1394 }
1395
1396 objects.push_back(obj);
1397}
1398
1399void addObjectToScene(SceneObject& obj,
1400 map<GLuint, BufferInfo>& shaderBufferInfo,
1401 GLuint points_vbo,
1402 GLuint colors_vbo,
1403 GLuint selected_colors_vbo,
1404 GLuint texcoords_vbo,
1405 GLuint normals_vbo,
1406 GLuint ubo,
1407 GLuint model_mat_idx_vbo) {
1408 addObjectToSceneDuringInit(obj);
1409
1410 BufferInfo* bufferInfo = &shaderBufferInfo[obj.shader_program];
1411
1412 // Check if the buffers aren't large enough to fit the new object and, if so, print an error and quit.
1413 // This is a temporary sanity check to make sure things are working as expected
1414 if (bufferInfo->vbo_capacity < (bufferInfo->ubo_offset + obj.num_points) ||
1415 bufferInfo->ubo_capacity < (bufferInfo->ubo_offset + 1)) {
1416 populateBuffers(objects, shaderBufferInfo,
1417 points_vbo,
1418 colors_vbo,
1419 selected_colors_vbo,
1420 texcoords_vbo,
1421 normals_vbo,
1422 ubo,
1423 model_mat_idx_vbo);
1424 } else {
1425 copyObjectDataToBuffers(objects.back(), shaderBufferInfo,
1426 points_vbo,
1427 colors_vbo,
1428 selected_colors_vbo,
1429 texcoords_vbo,
1430 normals_vbo,
1431 ubo,
1432 model_mat_idx_vbo);
1433 }
1434}
1435
1436void removeObjectFromScene(int objectId, GLuint ubo) {
1437 SceneObject& obj = objects[objectId];
1438
1439 if (!obj.deleted) {
1440 // Move the object outside the render bounds of the scene so it doesn't get rendered
1441 // TODO: Find a better way of hiding the object until the next time buffers are repopulated
1442 transformObject(obj, translate(mat4(1.0f), vec3(0.0f, 0.0f, FAR_CLIP * 1000.0f)), ubo);
1443 obj.deleted = true;
1444 }
1445}
1446
1447void initializeBuffers(
1448 GLuint* points_vbo,
1449 GLuint* colors_vbo,
1450 GLuint* selected_colors_vbo,
1451 GLuint* texcoords_vbo,
1452 GLuint* normals_vbo,
1453 GLuint* ubo,
1454 GLuint* model_mat_idx_vbo) {
1455 *points_vbo = 0;
1456 glGenBuffers(1, points_vbo);
1457
1458 *colors_vbo = 0;
1459 glGenBuffers(1, colors_vbo);
1460
1461 *selected_colors_vbo = 0;
1462 glGenBuffers(1, selected_colors_vbo);
1463
1464 *texcoords_vbo = 0;
1465 glGenBuffers(1, texcoords_vbo);
1466
1467 *normals_vbo = 0;
1468 glGenBuffers(1, normals_vbo);
1469
1470 *ubo = 0;
1471 glGenBuffers(1, ubo);
1472
1473 *model_mat_idx_vbo = 0;
1474 glGenBuffers(1, model_mat_idx_vbo);
1475}
1476
1477void populateBuffers(vector<SceneObject>& objects,
1478 map<GLuint, BufferInfo>& shaderBufferInfo,
1479 GLuint points_vbo,
1480 GLuint colors_vbo,
1481 GLuint selected_colors_vbo,
1482 GLuint texcoords_vbo,
1483 GLuint normals_vbo,
1484 GLuint ubo,
1485 GLuint model_mat_idx_vbo) {
1486 GLsizeiptr points_buffer_size = 0;
1487 GLsizeiptr textures_buffer_size = 0;
1488 GLsizeiptr ubo_buffer_size = 0;
1489 GLsizeiptr model_mat_idx_buffer_size = 0;
1490
1491 map<GLuint, unsigned int> shaderCounts;
1492 map<GLuint, unsigned int> shaderUboCounts;
1493
1494 vector<SceneObject>::iterator it;
1495
1496 /* Find all shaders that need to be used and the number of objects and
1497 * number of points for each shader. Construct a map from shader id to count
1498 * of points being drawn using that shader (for thw model matrix ubo, we
1499 * need object counts instead). These will be used to get offsets into the
1500 * vertex buffer for each shader.
1501 */
1502 for (it = objects.begin(); it != objects.end();) {
1503 if (it->deleted) {
1504 it = objects.erase(it);
1505 } else {
1506 points_buffer_size += it->num_points * sizeof(GLfloat) * 3;
1507 textures_buffer_size += it->num_points * sizeof(GLfloat) * 2;
1508 ubo_buffer_size += 16 * sizeof(GLfloat);
1509 model_mat_idx_buffer_size += it->num_points * sizeof(GLuint);
1510
1511 if (shaderCounts.count(it->shader_program) == 0) {
1512 shaderCounts[it->shader_program] = it->num_points;
1513 shaderUboCounts[it->shader_program] = 1;
1514 } else {
1515 shaderCounts[it->shader_program] += it->num_points;
1516 shaderUboCounts[it->shader_program]++;
1517 }
1518
1519 it++;
1520 }
1521 }
1522
1523 // double the buffer sizes to leave room for new objects
1524 points_buffer_size *= 2;
1525 textures_buffer_size *= 2;
1526 ubo_buffer_size *= 2;
1527 model_mat_idx_buffer_size *= 2;
1528
1529 map<GLuint, unsigned int>::iterator shaderIt;
1530 unsigned int lastShaderCount = 0;
1531 unsigned int lastShaderUboCount = 0;
1532
1533 /*
1534 * The counts calculated above can be used to get the starting offset of
1535 * each shader in the vertex buffer. Create a map of base offsets to mark
1536 * where the data for the first object using a given shader begins. Also,
1537 * create a map of current offsets to mark where to copy data for the next
1538 * object being added.
1539 */
1540 for (shaderIt = shaderCounts.begin(); shaderIt != shaderCounts.end(); shaderIt++) {
1541 shaderBufferInfo[shaderIt->first].vbo_base = lastShaderCount * 2;
1542 shaderBufferInfo[shaderIt->first].ubo_base = lastShaderUboCount * 2;
1543 cout << "shader: " << shaderIt->first << endl;
1544 cout << "point counts: " << shaderCounts[shaderIt->first] << endl;
1545 cout << "object counts: " << shaderUboCounts[shaderIt->first] << endl;
1546 cout << "vbo_base: " << shaderBufferInfo[shaderIt->first].vbo_base << endl;
1547 cout << "ubo_base: " << shaderBufferInfo[shaderIt->first].ubo_base << endl;
1548
1549 shaderBufferInfo[shaderIt->first].vbo_offset = 0;
1550 shaderBufferInfo[shaderIt->first].ubo_offset = 0;
1551
1552 shaderBufferInfo[shaderIt->first].vbo_capacity = shaderCounts[shaderIt->first] * 2;
1553 shaderBufferInfo[shaderIt->first].ubo_capacity = shaderUboCounts[shaderIt->first] * 2;
1554
1555 lastShaderCount += shaderCounts[shaderIt->first];
1556 lastShaderUboCount += shaderUboCounts[shaderIt->first];
1557 }
1558
1559 // Allocate all the buffers using the counts calculated above
1560
1561 glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
1562 glBufferData(GL_ARRAY_BUFFER, points_buffer_size, NULL, GL_DYNAMIC_DRAW);
1563
1564 glBindBuffer(GL_ARRAY_BUFFER, colors_vbo);
1565 glBufferData(GL_ARRAY_BUFFER, points_buffer_size, NULL, GL_DYNAMIC_DRAW);
1566
1567 glBindBuffer(GL_ARRAY_BUFFER, selected_colors_vbo);
1568 glBufferData(GL_ARRAY_BUFFER, points_buffer_size, NULL, GL_DYNAMIC_DRAW);
1569
1570 glBindBuffer(GL_ARRAY_BUFFER, texcoords_vbo);
1571 glBufferData(GL_ARRAY_BUFFER, textures_buffer_size, NULL, GL_DYNAMIC_DRAW);
1572
1573 glBindBuffer(GL_ARRAY_BUFFER, normals_vbo);
1574 glBufferData(GL_ARRAY_BUFFER, points_buffer_size, NULL, GL_DYNAMIC_DRAW);
1575
1576 glBindBuffer(GL_UNIFORM_BUFFER, ubo);
1577 glBufferData(GL_UNIFORM_BUFFER, ubo_buffer_size, NULL, GL_DYNAMIC_DRAW);
1578
1579 glBindBuffer(GL_ARRAY_BUFFER, model_mat_idx_vbo);
1580 glBufferData(GL_ARRAY_BUFFER, model_mat_idx_buffer_size, NULL, GL_DYNAMIC_DRAW);
1581
1582 for (it = objects.begin(); it != objects.end(); it++) {
1583 copyObjectDataToBuffers(*it, shaderBufferInfo,
1584 points_vbo,
1585 colors_vbo,
1586 selected_colors_vbo,
1587 texcoords_vbo,
1588 normals_vbo,
1589 ubo,
1590 model_mat_idx_vbo);
1591 }
1592}
1593
1594void copyObjectDataToBuffers(SceneObject& obj,
1595 map<GLuint, BufferInfo>& shaderBufferInfo,
1596 GLuint points_vbo,
1597 GLuint colors_vbo,
1598 GLuint selected_colors_vbo,
1599 GLuint texcoords_vbo,
1600 GLuint normals_vbo,
1601 GLuint ubo,
1602 GLuint model_mat_idx_vbo) {
1603 BufferInfo* bufferInfo = &shaderBufferInfo[obj.shader_program];
1604
1605 obj.vertex_vbo_offset = bufferInfo->vbo_base + bufferInfo->vbo_offset;
1606 obj.ubo_offset = bufferInfo->ubo_base + bufferInfo->ubo_offset;
1607
1608 glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
1609 glBufferSubData(GL_ARRAY_BUFFER, obj.vertex_vbo_offset * sizeof(GLfloat) * 3, obj.points.size() * sizeof(GLfloat), &obj.points[0]);
1610
1611 glBindBuffer(GL_ARRAY_BUFFER, colors_vbo);
1612 glBufferSubData(GL_ARRAY_BUFFER, obj.vertex_vbo_offset * sizeof(GLfloat) * 3, obj.colors.size() * sizeof(GLfloat), &obj.colors[0]);
1613
1614 glBindBuffer(GL_ARRAY_BUFFER, selected_colors_vbo);
1615 glBufferSubData(GL_ARRAY_BUFFER, obj.vertex_vbo_offset * sizeof(GLfloat) * 3, obj.selected_colors.size() * sizeof(GLfloat), &obj.selected_colors[0]);
1616
1617 glBindBuffer(GL_ARRAY_BUFFER, texcoords_vbo);
1618 glBufferSubData(GL_ARRAY_BUFFER, obj.vertex_vbo_offset * sizeof(GLfloat) * 2, obj.texcoords.size() * sizeof(GLfloat), &obj.texcoords[0]);
1619
1620 glBindBuffer(GL_ARRAY_BUFFER, normals_vbo);
1621 glBufferSubData(GL_ARRAY_BUFFER, obj.vertex_vbo_offset * sizeof(GLfloat) * 3, obj.normals.size() * sizeof(GLfloat), &obj.normals[0]);
1622
1623 glBindBuffer(GL_ARRAY_BUFFER, model_mat_idx_vbo);
1624 for (int i = 0; i < obj.num_points; i++) {
1625 glBufferSubData(GL_ARRAY_BUFFER, (obj.vertex_vbo_offset + i) * sizeof(GLuint), sizeof(GLuint), &obj.ubo_offset);
1626 }
1627
1628 obj.model_mat = obj.model_base * obj.model_transform;
1629 glBindBuffer(GL_UNIFORM_BUFFER, ubo);
1630 glBufferSubData(GL_UNIFORM_BUFFER, obj.ubo_offset * sizeof(mat4), sizeof(mat4), value_ptr(obj.model_mat));
1631
1632 bufferInfo->vbo_offset += obj.num_points;
1633 bufferInfo->ubo_offset++;
1634}
1635
1636void transformObject(SceneObject& obj, const mat4& transform, GLuint ubo) {
1637 obj.model_transform = obj.model_transform * transform;
1638 obj.model_mat = obj.model_transform * obj.model_base;
1639
1640 glBindBuffer(GL_UNIFORM_BUFFER, ubo);
1641 glBufferSubData(GL_UNIFORM_BUFFER, obj.ubo_offset * sizeof(mat4), sizeof(mat4), value_ptr(obj.model_mat));
1642}
1643
1644void renderScene(vector<SceneObject>& objects,
1645 GLuint color_sp, GLuint texture_sp,
1646 GLuint vao1, GLuint vao2,
1647 GLuint points_vbo, GLuint normals_vbo,
1648 GLuint colors_vbo, GLuint texcoords_vbo, GLuint selected_colors_vbo,
1649 SceneObject* selectedObject,
1650 map<GLuint, BufferInfo>& shaderBufferInfo) {
1651
1652 glUseProgram(color_sp);
1653 glBindVertexArray(vao1);
1654
1655 if (selectedObject != NULL) {
1656 glBindBuffer(GL_ARRAY_BUFFER, selected_colors_vbo);
1657 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
1658
1659 glDrawArrays(GL_TRIANGLES, selectedObject->vertex_vbo_offset, selectedObject->num_points);
1660 }
1661
1662 glBindBuffer(GL_ARRAY_BUFFER, colors_vbo);
1663 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
1664
1665 glDrawArrays(GL_TRIANGLES, shaderBufferInfo[color_sp].vbo_base, shaderBufferInfo[color_sp].vbo_offset);
1666
1667 glUseProgram(texture_sp);
1668 glBindVertexArray(vao2);
1669
1670 glDrawArrays(GL_TRIANGLES, shaderBufferInfo[texture_sp].vbo_base, shaderBufferInfo[texture_sp].vbo_offset);
1671}
1672
1673void renderSceneGui() {
1674 ImGui_ImplGlfwGL3_NewFrame();
1675
1676 // 1. Show a simple window.
1677 // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets automatically appears in a window called "Debug".
1678 /*
1679 {
1680 static float f = 0.0f;
1681 static int counter = 0;
1682 ImGui::Text("Hello, world!"); // Display some text (you can use a format string too)
1683 ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
1684 ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
1685
1686 ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our windows open/close state
1687 ImGui::Checkbox("Another Window", &show_another_window);
1688
1689 if (ImGui::Button("Button")) // Buttons return true when clicked (NB: most widgets return true when edited/activated)
1690 counter++;
1691 ImGui::SameLine();
1692 ImGui::Text("counter = %d", counter);
1693
1694 ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
1695 }
1696 */
1697
1698 {
1699 ImGui::SetNextWindowSize(ImVec2(85, 22), ImGuiCond_Once);
1700 ImGui::SetNextWindowPos(ImVec2(10, 50), ImGuiCond_Once);
1701 ImGui::Begin("WndStats", NULL,
1702 ImGuiWindowFlags_NoTitleBar |
1703 ImGuiWindowFlags_NoResize |
1704 ImGuiWindowFlags_NoMove);
1705 ImGui::Text("Score: ???");
1706 ImGui::End();
1707 }
1708
1709 {
1710 ImGui::SetNextWindowPos(ImVec2(380, 10), ImGuiCond_Once);
1711 ImGui::SetNextWindowSize(ImVec2(250, 35), ImGuiCond_Once);
1712 ImGui::Begin("WndMenubar", NULL,
1713 ImGuiWindowFlags_NoTitleBar |
1714 ImGuiWindowFlags_NoResize |
1715 ImGuiWindowFlags_NoMove);
1716 ImGui::InvisibleButton("", ImVec2(155, 18));
1717 ImGui::SameLine();
1718 if (ImGui::Button("Main Menu")) {
1719 events.push(EVENT_GO_TO_MAIN_MENU);
1720 }
1721 ImGui::End();
1722 }
1723
1724 ImGui::Render();
1725 ImGui_ImplGlfwGL3_RenderDrawData(ImGui::GetDrawData());
1726}
1727
1728void renderMainMenu() {
1729}
1730
1731void renderMainMenuGui() {
1732 ImGui_ImplGlfwGL3_NewFrame();
1733
1734 {
1735 int padding = 4;
1736 ImGui::SetNextWindowPos(ImVec2(-padding, -padding), ImGuiCond_Once);
1737 ImGui::SetNextWindowSize(ImVec2(width + 2 * padding, height + 2 * padding), ImGuiCond_Once);
1738 ImGui::Begin("WndMain", NULL,
1739 ImGuiWindowFlags_NoTitleBar |
1740 ImGuiWindowFlags_NoResize |
1741 ImGuiWindowFlags_NoMove);
1742
1743 ImGui::InvisibleButton("", ImVec2(10, 80));
1744 ImGui::InvisibleButton("", ImVec2(285, 18));
1745 ImGui::SameLine();
1746 if (ImGui::Button("New Game")) {
1747 events.push(EVENT_GO_TO_GAME);
1748 }
1749
1750 ImGui::InvisibleButton("", ImVec2(10, 15));
1751 ImGui::InvisibleButton("", ImVec2(300, 18));
1752 ImGui::SameLine();
1753 if (ImGui::Button("Quit")) {
1754 events.push(EVENT_QUIT);
1755 }
1756
1757 ImGui::End();
1758 }
1759
1760 ImGui::Render();
1761 ImGui_ImplGlfwGL3_RenderDrawData(ImGui::GetDrawData());
1762}
1763
1764void spawnAsteroid(vec3 pos, GLuint shader,
1765 map<GLuint, BufferInfo>& shaderBufferInfo,
1766 GLuint points_vbo,
1767 GLuint colors_vbo,
1768 GLuint selected_colors_vbo,
1769 GLuint texcoords_vbo,
1770 GLuint normals_vbo,
1771 GLuint ubo,
1772 GLuint model_mat_idx_vbo) {
1773 SceneObject obj = SceneObject();
1774 obj.shader_program = shader;
1775
1776 obj.points = {
1777 // front
1778 1.0f, 1.0f, 1.0f,
1779 -1.0f, 1.0f, 1.0f,
1780 -1.0f, -1.0f, 1.0f,
1781 1.0f, 1.0f, 1.0f,
1782 -1.0f, -1.0f, 1.0f,
1783 1.0f, -1.0f, 1.0f,
1784
1785 // top
1786 1.0f, 1.0f, -1.0f,
1787 -1.0f, 1.0f, -1.0f,
1788 -1.0f, 1.0f, 1.0f,
1789 1.0f, 1.0f, -1.0f,
1790 -1.0f, 1.0f, 1.0f,
1791 1.0f, 1.0f, 1.0f,
1792
1793 // bottom
1794 1.0f, -1.0f, 1.0f,
1795 -1.0f, -1.0f, 1.0f,
1796 -1.0f, -1.0f, -1.0f,
1797 1.0f, -1.0f, 1.0f,
1798 -1.0f, -1.0f, -1.0f,
1799 1.0f, -1.0f, -1.0f,
1800
1801 // back
1802 1.0f, 1.0f, -1.0f,
1803 -1.0f, -1.0f, -1.0f,
1804 -1.0f, 1.0f, -1.0f,
1805 1.0f, 1.0f, -1.0f,
1806 1.0f, -1.0f, -1.0f,
1807 -1.0f, -1.0f, -1.0f,
1808
1809 // right
1810 1.0f, 1.0f, -1.0f,
1811 1.0f, 1.0f, 1.0f,
1812 1.0f, -1.0f, 1.0f,
1813 1.0f, 1.0f, -1.0f,
1814 1.0f, -1.0f, 1.0f,
1815 1.0f, -1.0f, -1.0f,
1816
1817 // left
1818 -1.0f, 1.0f, 1.0f,
1819 -1.0f, 1.0f, -1.0f,
1820 -1.0f, -1.0f, -1.0f,
1821 -1.0f, 1.0f, 1.0f,
1822 -1.0f, -1.0f, -1.0f,
1823 -1.0f, -1.0f, 1.0f,
1824 };
1825 obj.colors = {
1826 // front
1827 0.8f, 0.0f, 0.0f,
1828 0.8f, 0.0f, 0.0f,
1829 0.8f, 0.0f, 0.0f,
1830 0.8f, 0.0f, 0.0f,
1831 0.8f, 0.0f, 0.0f,
1832 0.8f, 0.0f, 0.0f,
1833
1834 // top
1835 0.8f, 0.0f, 0.0f,
1836 0.8f, 0.0f, 0.0f,
1837 0.8f, 0.0f, 0.0f,
1838 0.8f, 0.0f, 0.0f,
1839 0.8f, 0.0f, 0.0f,
1840 0.8f, 0.0f, 0.0f,
1841
1842 // bottom
1843 0.8f, 0.0f, 0.0f,
1844 0.8f, 0.0f, 0.0f,
1845 0.8f, 0.0f, 0.0f,
1846 0.8f, 0.0f, 0.0f,
1847 0.8f, 0.0f, 0.0f,
1848 0.8f, 0.0f, 0.0f,
1849
1850 // back
1851 0.8f, 0.0f, 0.0f,
1852 0.8f, 0.0f, 0.0f,
1853 0.8f, 0.0f, 0.0f,
1854 0.8f, 0.0f, 0.0f,
1855 0.8f, 0.0f, 0.0f,
1856 0.8f, 0.0f, 0.0f,
1857
1858 // right
1859 0.8f, 0.0f, 0.0f,
1860 0.8f, 0.0f, 0.0f,
1861 0.8f, 0.0f, 0.0f,
1862 0.8f, 0.0f, 0.0f,
1863 0.8f, 0.0f, 0.0f,
1864 0.8f, 0.0f, 0.0f,
1865
1866 // left
1867 0.8f, 0.0f, 0.0f,
1868 0.8f, 0.0f, 0.0f,
1869 0.8f, 0.0f, 0.0f,
1870 0.8f, 0.0f, 0.0f,
1871 0.8f, 0.0f, 0.0f,
1872 0.8f, 0.0f, 0.0f,
1873 };
1874 obj.texcoords = { 0.0f };
1875 obj.selected_colors = { 0.0f };
1876
1877 mat4 T = translate(mat4(1.0f), pos);
1878 mat4 R = rotate(mat4(1.0f), 60.0f * (float)ONE_DEG_IN_RAD, vec3(1.0f, 1.0f, -1.0f));
1879 obj.model_base = T * R * scale(mat4(1.0f), vec3(0.1f, 0.1f, 0.1f));
1880
1881 addObjectToScene(obj, shaderBufferInfo,
1882 points_vbo,
1883 colors_vbo,
1884 selected_colors_vbo,
1885 texcoords_vbo,
1886 normals_vbo,
1887 ubo,
1888 model_mat_idx_vbo);
1889}
1890
1891float getRandomNum(float low, float high) {
1892 return low + ((float)rand()/RAND_MAX) * (high-low);
1893}
Note: See TracBrowser for help on using the repository browser.