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

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

Restrucutre code to enable easier click testing of different triangles, start using 3d vec3 arrays to pass triangles around more conveniently, and make an algorithm for click testing all the triangles in the scene.

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