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

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

Create SceneObject and ObjectFace structs, a list of objects, and a list of faces, and start using them in the rendering and click detection code to better encapsulate objects in the scene.

  • Property mode set to 100644
File size: 24.2 KB
Line 
1#include "logger.h"
2
3#include "stb_image.h"
4
5#define _USE_MATH_DEFINES
6#define GLM_SWIZZLE
7
8#include <glm/mat4x4.hpp>
9#include <glm/gtc/matrix_transform.hpp>
10#include <glm/gtc/type_ptr.hpp>
11
12#include <GL/glew.h>
13#include <GLFW/glfw3.h>
14
15#include <cstdio>
16#include <iostream>
17#include <fstream>
18#include <cmath>
19#include <string>
20#include <array>
21#include <vector>
22
23using namespace std;
24using namespace glm;
25
26#define ONE_DEG_IN_RAD (2.0 * M_PI) / 360.0 // 0.017444444
27
28struct SceneObject {
29 mat4 model_mat;
30 bool clicked;
31};
32
33struct ObjectFace {
34 unsigned int objectId;
35 array<vec3, 3> points;
36};
37
38const bool FULLSCREEN = false;
39int width = 640;
40int height = 480;
41
42vec3 cam_pos;
43
44int colors_i = 0;
45
46mat4 view_mat;
47mat4 proj_mat;
48
49vector<SceneObject> objects;
50vector<ObjectFace> faces;
51
52bool insideTriangle(vec3 p, ObjectFace* face);
53
54GLuint loadShader(GLenum type, string file);
55GLuint loadShaderProgram(string vertexShaderPath, string fragmentShaderPath);
56unsigned char* loadImage(string file_name, int* x, int* y);
57
58void printVector(string label, vec3 v);
59
60float NEAR_CLIP = 0.1f;
61float FAR_CLIP = 100.0f;
62
63void glfw_error_callback(int error, const char* description) {
64 gl_log_err("GLFW ERROR: code %i msg: %s\n", error, description);
65}
66
67void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) {
68 /*
69 double mouse_x, mouse_y;
70 glfwGetCursorPos(window, &mouse_x, &mouse_y);
71
72 if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) {
73 cout << "Mouse clicked (" << mouse_x << "," << mouse_y << ")" << endl;
74
75 float x = (2.0f*mouse_x) / width - 1.0f;
76 float y = 1.0f - (2.0f*mouse_y) / height;
77 cout << "x: " << x << ", y: " << y << endl;
78
79 // Since the projection matrix gets applied before the view matrix,
80 // treat the initial camera position (aka origin of the ray) as (0, 0, 0)
81
82 // When getting the ray direction, you can use near and fov to get the
83 // coordinates
84
85 vec4 ray_clip = vec4(x, y, -1.0f, 1.0f); // this should have a z equal to the near clipping plane
86 vec4 ray_eye = inverse(proj_mat) * ray_clip;
87 ray_eye = vec4(ray_eye.xy(), -1.0f, 0.0f);
88 vec3 ray_world = normalize((inverse(view_mat) * ray_eye).xyz());
89
90 / * LATEST NOTES:
91 *
92 * Normalizing the world ray caused issues, although it should make sense with the projection
93 * matrix, since the z coordinate has meaning there.
94 *
95 * Now, I need to figure out the correct intersection test in 2D space
96 * Also, need to check that the global triangle points are correct
97 * /
98
99 // since ray_world is the end result we want anyway, we probably don't need to add cam_pos to
100 // it, only to subtract it later
101
102 vec3 click_point = cam_pos + ray_world;
103
104 / * Now, we need to generate the constants for the equations describing
105 * a 3D line:
106 * (x - x0) / a = (y - y0) / b = (z - z0) / c
107 *
108 * The line goes through the camera position, so
109 * cam_pos = <x0, y0, z0>
110 * /
111
112 // upper right corner is 1, 1 in opengl
113
114 cout << "Converted -> (" << ray_world.x << "," << ray_world.y << "," << ray_world.z << ")" << endl << endl;;
115 cout << "Camera -> (" << cam_pos.x << "," << cam_pos.y << "," << cam_pos.z << ")" << endl;
116 cout << "Click point -> (" << click_point.x << "," << click_point.y << "," << click_point.z << ")" << endl;
117
118 float a = 1.0f;
119 float b = a * (click_point.y - cam_pos.y) / (click_point.x - cam_pos.x);
120 float c = a * (click_point.z - cam_pos.z) / (click_point.x - cam_pos.x);
121
122 cout << "(x - " << cam_pos.x << ") / " << a << " = ";
123 cout << "(y - " << cam_pos.y << ") / " << b << " = ";
124 cout << "(z - " << cam_pos.z << ") / " << c << endl;;
125
126 / * Now, we need to generate the constants for the equations describing
127 * a 3D plane:
128 * dx + ey +fz +g = 0
129 * /
130
131 vec3 fp1 = triangle_face[0];
132 vec3 fp2 = triangle_face[1];
133 vec3 fp3 = triangle_face[2];
134
135 cout << "Points on the plane" << endl;
136 cout << "(" << fp1.x << ", " << fp1.y << ", " << fp1.z << ")" << endl;
137 cout << "(" << fp2.x << ", " << fp2.y << ", " << fp2.z << ")" << endl;
138 cout << "(" << fp3.x << ", " << fp3.y << ", " << fp3.z << ")" << endl;
139
140 float pa = (fp2.y-fp1.y)*(fp3.z-fp1.z) - (fp3.y-fp1.y)*(fp2.z-fp1.z);
141 float pb = (fp2.z-fp1.z)*(fp3.x-fp1.x) - (fp3.z-fp1.z)*(fp2.x-fp1.x);
142 float pc = (fp2.x-fp1.x)*(fp3.y-fp1.y) - (fp3.x-fp1.x)*(fp2.y-fp1.y);
143 float pd = -(pa*fp1.x+pb*fp1.y+pc*fp1.z);
144
145 cout << pa << "x+" << pb << "y+" << pc << "z+" << pd << "=0" << endl;
146
147 // get intersection
148
149 // the intersection this computes is incorrect
150 // it doesn't match the equation of the plane
151 vec3 i;
152 i.z = -cam_pos.z - pc*pd/(pa*a+pb*b);
153 i.x = cam_pos.x + a * (i.z-cam_pos.z) / c;
154 i.y = cam_pos.y + b * (i.z-cam_pos.z) / c;
155
156 cout << "The holy grail?" << endl;
157 cout << "(" << i.x << "," << i.y << "," << i.z << ")" << endl;
158
159 clicked = insideTriangle(i, triangle_face);
160 cout << (clicked ? "true" : "false") << endl;
161 }
162 */
163}
164
165/* REFACTORING PLAN:
166 *
167 * Have an array of object structs
168 * Each object struct has:
169 * -a model matrix
170 * -a selected boolean
171 * Eventually, maybe also want to store a reference to the correct shader
172 * or whatever other info I need to properly render it
173 *
174 * Have an array of face structs
175 * Each face struct has
176 * -an object index indicating which object it is a part of
177 * -an array of three points
178 *
179 * The mouse button callback will:
180 * -Set all selected flags in the objects array to false
181 * -iterate through the faces array
182 * -For each face, it will call faceClicked() with the following params:
183 * -Probably a world ray created from the mouse click coordinates
184 * -An array of 3 points representing the face
185 * -The object struct represnting the object the face is a part of
186 *
187 * -Really, all I need to pass in are the world ray and an ObjectFace reference
188 * -The world ray will first need to be multiplied by the view and projection matrices before being passed in
189 */
190
191void mouse_button_callback_new(GLFWwindow* window, int button, int action, int mods) {
192 double mouse_x, mouse_y;
193 glfwGetCursorPos(window, &mouse_x, &mouse_y);
194
195 ObjectFace* face = &faces[0];
196 SceneObject* obj = &objects[face->objectId];
197
198 if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) {
199 cout << "Mouse clicked (" << mouse_x << "," << mouse_y << ")" << endl;
200
201 float x = (2.0f*mouse_x) / width - 1.0f;
202 float y = 1.0f - (2.0f*mouse_y) / height;
203
204 cout << "x: " << x << ", y: " << y << endl;
205
206 // Since the projection matrix gets applied before the view matrix,
207 // treat the initial camera position (aka origin of the ray) as (0, 0, 0)
208
209 // When getting the ray direction, you can use near and fov to get the
210 // coordinates
211
212 // vec4 ray_clip = vec4(x, y, -1.0f, 1.0f); // this should have a z equal to the near clipping plane
213 // vec4 ray_eye = inverse(proj_mat) * ray_clip;
214 // ray_eye = vec4(ray_eye.xy(), -1.0f, 0.0f);
215 // vec3 ray_world = normalize((inverse(view_mat) * ray_eye).xyz());
216
217 vec4 ray_clip = vec4(x, y, NEAR_CLIP, 1.0f); // this should have a z equal to the near clipping plane
218 vec4 ray_eye = ray_clip;
219 vec3 ray_world = (inverse(obj->model_mat) * inverse(view_mat) * ray_eye).xyz();
220
221 /* LATEST NOTES:
222 *
223 * Normalizing the world ray caused issues, although it should make sense with the projection
224 * matrix, since the z coordinate has meaning there.
225 * Plus, we really want to normalize it only once we recompute it below as the difference of two points,
226 * although doing so shouldn't effect the results. Check the book to see if there is a good reason for doing so.
227 */
228
229 printVector("Initial world ray:", ray_world);
230
231 vec4 cam_pos_origin = vec4(x, y, 0.0f, 1.0f);
232 vec3 cam_pos_temp = (inverse(obj->model_mat) * inverse(view_mat) * cam_pos_origin).xyz();
233
234 ray_world = ray_world-cam_pos_temp;
235
236 cout << "Ray clip -> (" << ray_clip.x << "," << ray_clip.y << "," << ray_clip.z << ")" << endl << endl;;
237 cout << "Ray world -> (" << ray_world.x << "," << ray_world.y << "," << ray_world.z << ")" << endl << endl;;
238 cout << "Camera -> (" << cam_pos_temp.x << "," << cam_pos_temp.y << "," << cam_pos_temp.z << ")" << endl;
239
240 vec3 fp1 = face->points[0];
241 vec3 fp2 = face->points[1];
242 vec3 fp3 = face->points[2];
243
244 cout << "Points on the plane" << endl;
245 cout << "(" << fp1.x << ", " << fp1.y << ", " << fp1.z << ")" << endl;
246 cout << "(" << fp2.x << ", " << fp2.y << ", " << fp2.z << ")" << endl;
247 cout << "(" << fp3.x << ", " << fp3.y << ", " << fp3.z << ")" << endl;
248
249 // LINE EQUATION: P = O + Dt
250 // O = cam_pos
251 // D = ray_world
252
253 // PLANE EQUATION: P dot n + d = 0 (n is the normal vector and d is the offset from the origin)
254
255 // Take the cross-product of two vectors on the plane to get the normal
256 vec3 v1 = fp2 - fp1;
257 vec3 v2 = fp3 - fp1;
258
259 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);
260 printVector("v1", v1);
261 printVector("v2", v2);
262 printVector("Cross", normal);
263 cout << "Test theory: " << glm::dot(cam_pos_temp, normal) << endl;
264 cout << "Test 2: " << glm::dot(ray_world, normal) << endl;
265
266 float d = -glm::dot(fp1, normal);
267 cout << "d: " << d << endl;
268
269 float t = - (glm::dot(cam_pos_temp, normal) + d) / glm::dot(ray_world, normal);
270 cout << "t: " << t << endl;
271
272 vec3 intersection = cam_pos_temp+t*ray_world;
273 printVector("Intersection", intersection);
274
275 obj->clicked = insideTriangle(intersection, face);
276 cout << (obj->clicked ? "true" : "false") << endl;
277 }
278}
279
280int main(int argc, char* argv[]) {
281 cout << "New OpenGL Game" << endl;
282
283 if (!restart_gl_log()) {}
284 gl_log("starting GLFW\n%s\n", glfwGetVersionString());
285
286 glfwSetErrorCallback(glfw_error_callback);
287 if (!glfwInit()) {
288 fprintf(stderr, "ERROR: could not start GLFW3\n");
289 return 1;
290 }
291
292#ifdef __APPLE__
293 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
294 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
295 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
296 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
297#endif
298
299 glfwWindowHint(GLFW_SAMPLES, 4);
300
301 GLFWwindow* window = NULL;
302
303 if (FULLSCREEN) {
304 GLFWmonitor* mon = glfwGetPrimaryMonitor();
305 const GLFWvidmode* vmode = glfwGetVideoMode(mon);
306
307 cout << "Fullscreen resolution " << vmode->width << "x" << vmode->height << endl;
308 window = glfwCreateWindow(vmode->width, vmode->height, "Extended GL Init", mon, NULL);
309
310 width = vmode->width;
311 height = vmode->height;
312 } else {
313 window = glfwCreateWindow(width, height, "Hello Triangle", NULL, NULL);
314 }
315
316 if (!window) {
317 fprintf(stderr, "ERROR: could not open window with GLFW3\n");
318 glfwTerminate();
319 return 1;
320 }
321
322 bool squareSelected = false;
323
324 glfwSetMouseButtonCallback(window, mouse_button_callback_new);
325
326 glfwMakeContextCurrent(window);
327 glewExperimental = GL_TRUE;
328 glewInit();
329
330 // Check if we might ever need this. If not, remove it.
331 // glViewport(0, 0, width*2, height*2);
332
333 const GLubyte* renderer = glGetString(GL_RENDERER);
334 const GLubyte* version = glGetString(GL_VERSION);
335 printf("Renderer: %s\n", renderer);
336 printf("OpenGL version supported %s\n", version);
337
338 glEnable(GL_DEPTH_TEST);
339 glDepthFunc(GL_LESS);
340
341 glEnable(GL_CULL_FACE);
342 // glCullFace(GL_BACK);
343 // glFrontFace(GL_CW);
344
345 int x, y;
346 unsigned char* texImage = loadImage("test.png", &x, &y);
347 if (texImage) {
348 cout << "Yay, I loaded an image!" << endl;
349 cout << x << endl;
350 cout << y << endl;
351 printf ("first 4 bytes are: %i %i %i %i\n", texImage[0], texImage[1], texImage[2], texImage[3]);
352 }
353
354 GLuint tex = 0;
355 glGenTextures(1, &tex);
356 glActiveTexture(GL_TEXTURE0);
357 glBindTexture(GL_TEXTURE_2D, tex);
358 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, texImage);
359
360 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
361 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
362 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
363 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
364
365 GLfloat points[] = {
366 0.0f, 0.5f, 0.0f,
367 -0.5f, -0.5f, 0.0f,
368 0.5f, -0.5f, 0.0f,
369 0.5f, -0.5f, 0.0f,
370 -0.5f, -0.5f, 0.0f,
371 0.0f, 0.5f, 0.0f,
372 };
373
374 GLfloat colors[] = {
375 1.0, 0.0, 0.0,
376 0.0, 0.0, 1.0,
377 0.0, 1.0, 0.0,
378 0.0, 1.0, 0.0,
379 0.0, 0.0, 1.0,
380 1.0, 0.0, 0.0,
381 };
382
383 GLfloat colors_new[] = {
384 0.0, 1.0, 0.0,
385 0.0, 1.0, 0.0,
386 0.0, 1.0, 0.0,
387 0.0, 1.0, 0.0,
388 0.0, 1.0, 0.0,
389 0.0, 1.0, 0.0,
390 };
391
392 // Each point is made of 3 floats
393 int numPoints = (sizeof(points) / sizeof(float)) / 3;
394
395 GLfloat points2[] = {
396 0.5f, 0.5f, 0.0f,
397 -0.5f, 0.5f, 0.0f,
398 -0.5f, -0.5f, 0.0f,
399 0.5f, 0.5f, 0.0f,
400 -0.5f, -0.5f, 0.0f,
401 0.5f, -0.5f, 0.0f,
402 };
403
404 GLfloat colors2[] = {
405 0.0, 0.9, 0.9,
406 0.0, 0.9, 0.9,
407 0.0, 0.9, 0.9,
408 0.0, 0.9, 0.9,
409 0.0, 0.9, 0.9,
410 0.0, 0.9, 0.9,
411 };
412
413 GLfloat texcoords[] = {
414 1.0f, 1.0f,
415 0.0f, 1.0f,
416 0.0, 0.0,
417 1.0, 1.0,
418 0.0, 0.0,
419 1.0, 0.0
420 };
421
422 // Each point is made of 3 floats
423 int numPoints2 = (sizeof(points2) / sizeof(float)) / 3;
424
425 // initialize global variables for click intersection tests
426
427 mat4 T_model, R_model;
428
429 // triangle
430 objects.push_back(SceneObject());
431 objects[0].clicked = false;
432
433 /*
434 mat4 R_model = rotate(mat4(), 4.0f, vec3(0.0f, 1.0f, 0.0f));
435 */
436 T_model = translate(mat4(), vec3(0.5f, 0.0f, 0.0f));
437 R_model = rotate(mat4(), 0.0f, vec3(0.0f, 1.0f, 0.0f));
438 objects[0].model_mat = T_model*R_model;
439
440 faces.push_back(ObjectFace());
441 faces[0].objectId = 0;
442 faces[0].points = {
443 vec3(points[0], points[1], points[2]),
444 vec3(points[3], points[4], points[5]),
445 vec3(points[6], points[7], points[8]),
446 };
447
448 // square
449 objects.push_back(SceneObject());
450 objects[1].clicked = false;
451
452 // mat4 T_model2 = translate(mat4(), vec3(-1.0f, 0.0f, 0.0f));
453 T_model = translate(mat4(), vec3(-0.5f, 0.0f, 0.0f));
454 R_model = rotate(mat4(), 0.0f, vec3(0.0f, 1.0f, 0.0f));
455 objects[1].model_mat = T_model*R_model;
456
457 faces.push_back(ObjectFace());
458 faces[1].objectId = 1;
459 faces[1].points = {
460 vec3(points2[0], points2[1], points2[2]),
461 vec3(points2[3], points2[4], points2[5]),
462 vec3(points2[6], points2[7], points2[8]),
463 };
464
465 faces.push_back(ObjectFace());
466 faces[2].objectId = 1;
467 faces[2].points = {
468 vec3(points2[9], points2[10], points2[11]),
469 vec3(points2[12], points2[13], points2[14]),
470 vec3(points2[15], points2[16], points2[17]),
471 };
472
473 GLuint points_vbo = 0;
474 glGenBuffers(1, &points_vbo);
475 glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
476 glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
477
478 GLuint colors_vbo = 0;
479 glGenBuffers(1, &colors_vbo);
480 glBindBuffer(GL_ARRAY_BUFFER, colors_vbo);
481 glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
482
483 GLuint vao = 0;
484 glGenVertexArrays(1, &vao);
485 glBindVertexArray(vao);
486 glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
487 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
488 glBindBuffer(GL_ARRAY_BUFFER, colors_vbo);
489 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
490
491 glEnableVertexAttribArray(0);
492 glEnableVertexAttribArray(1);
493
494 GLuint points2_vbo = 0;
495 glGenBuffers(1, &points2_vbo);
496 glBindBuffer(GL_ARRAY_BUFFER, points2_vbo);
497 glBufferData(GL_ARRAY_BUFFER, sizeof(points2), points2, GL_STATIC_DRAW);
498
499 GLuint colors2_vbo = 0;
500 glGenBuffers(1, &colors2_vbo);
501 glBindBuffer(GL_ARRAY_BUFFER, colors2_vbo);
502 glBufferData(GL_ARRAY_BUFFER, sizeof(colors2), colors2, GL_STATIC_DRAW);
503
504 GLuint vt_vbo;
505 glGenBuffers(1, &vt_vbo);
506 glBindBuffer(GL_ARRAY_BUFFER, vt_vbo);
507 glBufferData(GL_ARRAY_BUFFER, sizeof(texcoords), texcoords, GL_STATIC_DRAW);
508
509 GLuint vao2 = 0;
510 glGenVertexArrays(1, &vao2);
511 glBindVertexArray(vao2);
512 glBindBuffer(GL_ARRAY_BUFFER, points2_vbo);
513 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
514 // glBindBuffer(GL_ARRAY_BUFFER, colors2_vbo);
515 // glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
516 glBindBuffer(GL_ARRAY_BUFFER, vt_vbo);
517 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL);
518
519 glEnableVertexAttribArray(0);
520 glEnableVertexAttribArray(1);
521
522 GLuint shader_program = loadShaderProgram("./color.vert", "./color.frag");
523 GLuint shader_program2 = loadShaderProgram("./texture.vert", "./texture.frag");
524
525 float speed = 1.0f;
526 float last_position = 0.0f;
527
528 float cam_speed = 1.0f;
529 float cam_yaw_speed = 60.0f*ONE_DEG_IN_RAD;
530
531 //cam_pos = vec3(0.0f, 0.0f, 2.0f);
532 cam_pos = vec3(0.0f, 0.0f, 0.3f);
533 float cam_yaw = 0.0f * 2.0f * 3.14159f / 360.0f;
534
535 mat4 T = translate(mat4(), vec3(-cam_pos.x, -cam_pos.y, -cam_pos.z));
536 mat4 R = rotate(mat4(), -cam_yaw, vec3(0.0f, 1.0f, 0.0f));
537 /*
538 mat4 T = translate(mat4(), vec3(0.0f, 0.0f, 0.0f));
539 mat4 R = rotate(mat4(), 0.0f, vec3(0.0f, 1.0f, 0.0f));
540 */
541 view_mat = R*T;
542
543 float fov = 67.0f * ONE_DEG_IN_RAD;
544 float aspect = (float)width / (float)height;
545
546 float range = tan(fov * 0.5f) * NEAR_CLIP;
547 float Sx = NEAR_CLIP / (range * aspect);
548 float Sy = NEAR_CLIP / range;
549 float Sz = -(FAR_CLIP + NEAR_CLIP) / (FAR_CLIP - NEAR_CLIP);
550 float Pz = -(2.0f * FAR_CLIP * NEAR_CLIP) / (FAR_CLIP - NEAR_CLIP);
551
552 /*
553 float proj_arr[] = {
554 Sx, 0.0f, 0.0f, 0.0f,
555 0.0f, Sy, 0.0f, 0.0f,
556 0.0f, 0.0f, Sz, -1.0f,
557 0.0f, 0.0f, Pz, 0.0f,
558 };
559 */
560 float proj_arr[] = {
561 1.0f, 0.0f, 0.0f, 0.0f,
562 0.0f, 1.0f, 0.0f, 0.0f,
563 0.0f, 0.0f, 1.0f, 0.0f,
564 0.0f, 0.0f, 0.0f, 1.0f,
565 };
566 proj_mat = make_mat4(proj_arr);
567
568 GLint model_test_loc = glGetUniformLocation(shader_program, "model");
569 GLint view_test_loc = glGetUniformLocation(shader_program, "view");
570 GLint proj_test_loc = glGetUniformLocation(shader_program, "proj");
571
572 GLint model_mat_loc = glGetUniformLocation(shader_program2, "model");
573 GLint view_mat_loc = glGetUniformLocation(shader_program2, "view");
574 GLint proj_mat_loc = glGetUniformLocation(shader_program2, "proj");
575
576 glUseProgram(shader_program);
577 glUniformMatrix4fv(model_test_loc, 1, GL_FALSE, value_ptr(objects[0].model_mat));
578 glUniformMatrix4fv(view_test_loc, 1, GL_FALSE, value_ptr(view_mat));
579 glUniformMatrix4fv(proj_test_loc, 1, GL_FALSE, value_ptr(proj_mat));
580
581 glUseProgram(shader_program2);
582 glUniformMatrix4fv(model_mat_loc, 1, GL_FALSE, value_ptr(objects[1].model_mat));
583 glUniformMatrix4fv(view_mat_loc, 1, GL_FALSE, value_ptr(view_mat));
584 glUniformMatrix4fv(proj_mat_loc, 1, GL_FALSE, value_ptr(proj_mat));
585
586 bool cam_moved = false;
587
588 double previous_seconds = glfwGetTime();
589 while (!glfwWindowShouldClose(window)) {
590 double current_seconds = glfwGetTime();
591 double elapsed_seconds = current_seconds - previous_seconds;
592 previous_seconds = current_seconds;
593
594 if (fabs(last_position) > 1.0f) {
595 speed = -speed;
596 }
597
598 if (objects[0].clicked) {
599 glBindBuffer(GL_ARRAY_BUFFER, colors_vbo);
600
601 if (colors_i == 0) {
602 glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors_new, GL_STATIC_DRAW);
603 colors_i = 1;
604 } else {
605 glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
606 colors_i = 0;
607 }
608 }
609
610 /*
611 model[12] = last_position + speed*elapsed_seconds;
612 last_position = model[12];
613 */
614
615 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
616
617 glUseProgram(shader_program);
618
619 // this is temporary.
620 // It's needed to offset the code for the recoloring of the square working during click detection
621 glUniformMatrix4fv(model_test_loc, 1, GL_FALSE, value_ptr(objects[0].model_mat));
622
623 glBindVertexArray(vao);
624
625 glDrawArrays(GL_TRIANGLES, 0, numPoints);
626
627 if (objects[1].clicked) {
628 squareSelected = !squareSelected;
629 }
630
631 if (squareSelected) {
632 glUseProgram(shader_program);
633
634 // this is temporary.
635 // It's needed to get the recoloring of the square working during click detection
636 glUniformMatrix4fv(model_test_loc, 1, GL_FALSE, value_ptr(objects[1].model_mat));
637
638 glBindVertexArray(vao2);
639
640 glBindBuffer(GL_ARRAY_BUFFER, colors2_vbo);
641 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
642 } else {
643 glUseProgram(shader_program2);
644
645 glBindVertexArray(vao2);
646
647 glBindBuffer(GL_ARRAY_BUFFER, vt_vbo);
648 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL);
649 }
650
651 glDrawArrays(GL_TRIANGLES, 0, numPoints2);
652
653 for (vector<SceneObject>::iterator it = objects.begin(); it != objects.end(); it++) {
654 it->clicked = false;
655 }
656
657 glfwPollEvents();
658 glfwSwapBuffers(window);
659
660 if (GLFW_PRESS == glfwGetKey(window, GLFW_KEY_ESCAPE)) {
661 glfwSetWindowShouldClose(window, 1);
662 }
663
664 float dist = cam_speed * elapsed_seconds;
665 if (glfwGetKey(window, GLFW_KEY_A)) {
666 cam_pos.x -= cos(cam_yaw)*dist;
667 cam_pos.z += sin(cam_yaw)*dist;
668 cam_moved = true;
669 }
670 if (glfwGetKey(window, GLFW_KEY_D)) {
671 cam_pos.x += cos(cam_yaw)*dist;
672 cam_pos.z -= sin(cam_yaw)*dist;
673 cam_moved = true;
674 }
675 if (glfwGetKey(window, GLFW_KEY_W)) {
676 cam_pos.x -= sin(cam_yaw)*dist;
677 cam_pos.z -= cos(cam_yaw)*dist;
678 cam_moved = true;
679 }
680 if (glfwGetKey(window, GLFW_KEY_S)) {
681 cam_pos.x += sin(cam_yaw)*dist;
682 cam_pos.z += cos(cam_yaw)*dist;
683 cam_moved = true;
684 }
685 if (glfwGetKey(window, GLFW_KEY_LEFT)) {
686 cam_yaw += cam_yaw_speed * elapsed_seconds;
687 cam_moved = true;
688 }
689 if (glfwGetKey(window, GLFW_KEY_RIGHT)) {
690 cam_yaw -= cam_yaw_speed * elapsed_seconds;
691 cam_moved = true;
692 }
693 if (cam_moved) {
694 T = translate(mat4(), vec3(-cam_pos.x, -cam_pos.y, -cam_pos.z));
695 R = rotate(mat4(), -cam_yaw, vec3(0.0f, 1.0f, 0.0f));
696 // view_mat = R*T;
697
698 glUniformMatrix4fv(view_mat_loc, 1, GL_FALSE, value_ptr(view_mat));
699 cam_moved = false;
700 }
701 }
702
703 glfwTerminate();
704 return 0;
705}
706
707GLuint loadShader(GLenum type, string file) {
708 cout << "Loading shader from file " << file << endl;
709
710 ifstream shaderFile(file);
711 GLuint shaderId = 0;
712
713 if (shaderFile.is_open()) {
714 string line, shaderString;
715
716 while(getline(shaderFile, line)) {
717 shaderString += line + "\n";
718 }
719 shaderFile.close();
720 const char* shaderCString = shaderString.c_str();
721
722 shaderId = glCreateShader(type);
723 glShaderSource(shaderId, 1, &shaderCString, NULL);
724 glCompileShader(shaderId);
725
726 cout << "Loaded successfully" << endl;
727 } else {
728 cout << "Failed to loade the file" << endl;
729 }
730
731 return shaderId;
732}
733
734GLuint loadShaderProgram(string vertexShaderPath, string fragmentShaderPath) {
735 GLuint vs = loadShader(GL_VERTEX_SHADER, vertexShaderPath);
736 GLuint fs = loadShader(GL_FRAGMENT_SHADER, fragmentShaderPath);
737
738 GLuint shader_program = glCreateProgram();
739 glAttachShader(shader_program, vs);
740 glAttachShader(shader_program, fs);
741
742 glLinkProgram(shader_program);
743
744 return shader_program;
745}
746
747unsigned char* loadImage(string file_name, int* x, int* y) {
748 int n;
749 int force_channels = 4;
750 unsigned char* image_data = stbi_load(file_name.c_str(), x, y, &n, force_channels);
751 if (!image_data) {
752 fprintf(stderr, "ERROR: could not load %s\n", file_name.c_str());
753 }
754 return image_data;
755}
756
757bool insideTriangle(vec3 p, ObjectFace* face) {
758 vec3 v21 = face->points[1]- face->points[0];
759 vec3 v31 = face->points[2]- face->points[0];
760 vec3 pv1 = p- face->points[0];
761
762 float y = (pv1.y*v21.x - pv1.x*v21.y) / (v31.y*v21.x - v31.x*v21.y);
763 float x = (pv1.x-y*v31.x) / v21.x;
764
765 cout << "(" << x << ", " << y << ")" << endl;
766
767 return x > 0.0f && y > 0.0f && x+y < 1.0f;
768}
769
770void printVector(string label, vec3 v) {
771 cout << label << " -> (" << v.x << "," << v.y << "," << v.z << ")" << endl;
772}
Note: See TracBrowser for help on using the repository browser.