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

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