source: opengl-game/new-game.cpp@ 3d06b4e

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

Calculate the bounding box for each object

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