source: opengl-game/new-game.cpp@ 92b1e90

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

Add a type field to SceneObject and mostly integrate lasers into the pipeline for creating and rendering objects to the scene (Lasers currently still use their own VBOs).

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