source: opengl-game/new-game.cpp@ 147ac6d

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

Remove the clicked field of the SceneObject and instead use a clickedObject variable to keep track of which object was just clicked.

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