void move(mat4 & e, vec3 & pos) { //e_position -= vec3(getPosition().v[0],0,getPosition().v[2]) * getDelta() * e_speed; if(e_isAlive) { e = scale(e, vec3(1.5,1.5,1.5)); e_direction = vec3(getPosition() - e_cs.center); e_direction = normalise(e_direction); e_rotation.v[1] = std::acos(e_direction.v[2]); if(e_direction.v[0] > 0) e_rotation.v[1] =-e_rotation.v[1]; e = rotate_x_deg(e, e_rotation.v[0]); e = rotate_y_deg(e, (-e_rotation.v[1] * (180/M_PI))); e = rotate_z_deg(e, e_rotation.v[2]); } if(e_isAlive) { vec3 newpos(e_cs.center); newpos += e_direction * e_speed; // newpos.v[1] -= 0.3; setE_Position(newpos); e = translate(e,getE_Position()); } // e_position = getPosition() - e_position; // temp -= getPosition() * getDelta() * e_speed;//vec3(getPosition().v[0],0,getPosition().v[2]);// * getDelta() * e_speed; }
// Maintain translations and rotations. inline void updateView() { mat4 T = translate (identity_mat4 (), vec3 (-cam_pos[0], -cam_pos[1], -cam_pos[2])); // cam translation mat4 R = rotate_z_deg(identity_mat4(), -cam_zaw) * rotate_y_deg(identity_mat4(), -cam_yaw) * rotate_x_deg(identity_mat4(), -cam_xaw); mat4 view_mat = T * R; glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, view_mat.m); }
int main () { restart_gl_log (); // use GLFW and GLEW to start GL context. see gl_utils.cpp for details start_gl (); // tell GL to only draw onto a pixel if the shape is closer to the viewer glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" /* OTHER STUFF GOES HERE NEXT */ GLfloat points[] = { -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, 0.5f, 0.5f, 0.0f, 0.5f, 0.5f, 0.0f, -0.5f, 0.5f, 0.0f, -0.5f, -0.5f, 0.0f }; // 2^16 = 65536 GLfloat texcoords[] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; GLuint points_vbo; glGenBuffers (1, &points_vbo); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glBufferData (GL_ARRAY_BUFFER, 18 * sizeof (GLfloat), points, GL_STATIC_DRAW); GLuint texcoords_vbo; glGenBuffers (1, &texcoords_vbo); glBindBuffer (GL_ARRAY_BUFFER, texcoords_vbo); glBufferData (GL_ARRAY_BUFFER, 12 * sizeof (GLfloat), texcoords, GL_STATIC_DRAW); GLuint vao; glGenVertexArrays (1, &vao); glBindVertexArray (vao); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glBindBuffer (GL_ARRAY_BUFFER, texcoords_vbo); glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 0, NULL); // normalise! glEnableVertexAttribArray (0); glEnableVertexAttribArray (1); GLuint shader_programme = create_programme_from_files ( "test_vs.glsl", "test_fs.glsl"); #define ONE_DEG_IN_RAD (2.0 * M_PI) / 360.0 // 0.017444444 // input variables float near = 0.1f; // clipping plane float far = 100.0f; // clipping plane float fov = 67.0f * ONE_DEG_IN_RAD; // convert 67 degrees to radians float aspect = (float)g_gl_width / (float)g_gl_height; // aspect ratio // matrix components float range = tan (fov * 0.5f) * near; float Sx = (2.0f * near) / (range * aspect + range * aspect); float Sy = near / range; float Sz = -(far + near) / (far - near); float Pz = -(2.0f * far * near) / (far - near); GLfloat proj_mat[] = { Sx, 0.0f, 0.0f, 0.0f, 0.0f, Sy, 0.0f, 0.0f, 0.0f, 0.0f, Sz, -1.0f, 0.0f, 0.0f, Pz, 0.0f }; float cam_speed = 1.0f; // 1 unit per second float cam_yaw_speed = 10.0f; // 10 degrees per second float cam_pos[] = {0.0f, 0.0f, 2.0f}; // don't start at zero, or we will be too close float cam_yaw = 0.0f; // y-rotation in degrees mat4 T = translate (identity_mat4 (), vec3 (-cam_pos[0], -cam_pos[1], -cam_pos[2])); mat4 R = rotate_y_deg (identity_mat4 (), -cam_yaw); mat4 view_mat = R * T; int view_mat_location = glGetUniformLocation (shader_programme, "view"); glUseProgram (shader_programme); glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, view_mat.m); int proj_mat_location = glGetUniformLocation (shader_programme, "proj"); glUseProgram (shader_programme); glUniformMatrix4fv (proj_mat_location, 1, GL_FALSE, proj_mat); // load texture GLuint tex; assert (load_texture ("skulluvmap.png", &tex)); glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CCW); // GL_CCW for counter clock-wise while (!glfwWindowShouldClose (g_window)) { static double previous_seconds = glfwGetTime (); double current_seconds = glfwGetTime (); double elapsed_seconds = current_seconds - previous_seconds; previous_seconds = current_seconds; _update_fps_counter (g_window); // wipe the drawing surface clear glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport (0, 0, g_gl_width, g_gl_height); glUseProgram (shader_programme); glBindVertexArray (vao); // draw points 0-3 from the currently bound VAO with current in-use shader glDrawArrays (GL_TRIANGLES, 0, 6); // update other events like input handling glfwPollEvents (); // control keys bool cam_moved = false; if (glfwGetKey (g_window, GLFW_KEY_A)) { cam_pos[0] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_D)) { cam_pos[0] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_PAGE_UP)) { cam_pos[1] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_PAGE_DOWN)) { cam_pos[1] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_W)) { cam_pos[2] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_S)) { cam_pos[2] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_LEFT)) { cam_yaw += cam_yaw_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_RIGHT)) { cam_yaw -= cam_yaw_speed * elapsed_seconds; cam_moved = true; } // update view matrix if (cam_moved) { mat4 T = translate (identity_mat4 (), vec3 (-cam_pos[0], -cam_pos[1], -cam_pos[2])); // cam translation mat4 R = rotate_y_deg (identity_mat4 (), -cam_yaw); // mat4 view_mat = R * T; glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, view_mat.m); } if (GLFW_PRESS == glfwGetKey (g_window, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (g_window, 1); } // put the stuff we've been drawing onto the display glfwSwapBuffers (g_window); } // close GL context and any other GLFW resources glfwTerminate(); return 0; }
int main () { GLFWwindow* window = NULL; const GLubyte* renderer; const GLubyte* version; GLuint shader_programme; GLuint vao; // // Start OpenGL using helper libraries // -------------------------------------------------------------------------- if (!glfwInit ()) { fprintf (stderr, "ERROR: could not start GLFW3\n"); return 1; } /* change to 3.2 if on Apple OS X glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 0); glfwWindowHint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); */ window = glfwCreateWindow (gl_width, gl_height, "Spinning Cube", NULL, NULL); if (!window) { fprintf (stderr, "ERROR: opening OS window\n"); return 1; } glfwMakeContextCurrent (window); glewExperimental = GL_TRUE; glewInit (); /* get version info */ renderer = glGetString (GL_RENDERER); /* get renderer string */ version = glGetString (GL_VERSION); /* version as a string */ printf ("Renderer: %s\n", renderer); printf ("OpenGL version supported %s\n", version); int point_count = 0; // // Set up vertex buffers and vertex array object // -------------------------------------------------------------------------- { GLfloat* vp = NULL; // array of vertex points GLfloat* vn = NULL; // array of vertex normals (we haven't used these yet) GLfloat* vt = NULL; // array of texture coordinates (or these) assert (load_obj_file ("cube.obj", vp, vt, vn, point_count)); GLuint points_vbo, texcoord_vbo; glGenBuffers (1, &points_vbo); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); // copy our points from the header file into our VBO on graphics hardware glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 3 * point_count, vp, GL_STATIC_DRAW); // and grab the normals glGenBuffers (1, &texcoord_vbo); glBindBuffer (GL_ARRAY_BUFFER, texcoord_vbo); glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 2 * point_count, vt, GL_STATIC_DRAW); glGenVertexArrays (1, &vao); glBindVertexArray (vao); glEnableVertexAttribArray (0); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (1); glBindBuffer (GL_ARRAY_BUFFER, texcoord_vbo); glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 0, NULL); free (vp); free (vn); free (vt); } // // Load shaders from files // -------------------------------------------------------------------------- { char* vertex_shader_str; char* fragment_shader_str; // allocate some memory to store shader strings vertex_shader_str = (char*)malloc (81920); fragment_shader_str = (char*)malloc (81920); // load shader strings from text files assert (parse_file_into_str ("teapot.vert", vertex_shader_str, 81920)); assert (parse_file_into_str ("teapot.frag", fragment_shader_str, 81920)); GLuint vs, fs; vs = glCreateShader (GL_VERTEX_SHADER); fs = glCreateShader (GL_FRAGMENT_SHADER); glShaderSource (vs, 1, (const char**)&vertex_shader_str, NULL); glShaderSource (fs, 1, (const char**)&fragment_shader_str, NULL); // free memory free (vertex_shader_str); free (fragment_shader_str); glCompileShader (vs); glCompileShader (fs); shader_programme = glCreateProgram (); glAttachShader (shader_programme, fs); glAttachShader (shader_programme, vs); glLinkProgram (shader_programme); /* TODO NOTE: you should check for errors and print logs after compiling and also linking shaders */ } // // Create some matrices // -------------------------------------------------------------------------- mat4 M, V, P; M = identity_mat4 ();//scale (identity_mat4 (), vec3 (0.05, 0.05, 0.05)); vec3 cam_pos (0.0, 0.0, 5.0); vec3 targ_pos (0.0, 0.0, 0.0); vec3 up (0.0, 1.0, 0.0); V = look_at (cam_pos, targ_pos, up); P = perspective (67.0f, (float)gl_width / (float)gl_height, 0.1, 1000.0); int M_loc = glGetUniformLocation (shader_programme, "M"); int V_loc = glGetUniformLocation (shader_programme, "V"); int P_loc = glGetUniformLocation (shader_programme, "P"); // send matrix values to shader immediately glUseProgram (shader_programme); glUniformMatrix4fv (M_loc, 1, GL_FALSE, M.m); glUniformMatrix4fv (V_loc, 1, GL_FALSE, V.m); glUniformMatrix4fv (P_loc, 1, GL_FALSE, P.m); int dt_pixel_c = 16 * 16; char* dt_data = (char*)malloc (4 * dt_pixel_c); if (!dt_data) { fprintf (stderr, "ERROR: out of memory. malloc default texture\n"); return 1; } for (int i = 0; i < dt_pixel_c * 4; i += 4) { int sq_ac = i / 16; if ((sq_ac / 2) * 2 == sq_ac) { dt_data[i] = 0; dt_data[i + 1] = 0; dt_data[i + 2] = 0; dt_data[i + 3] = (char)255; } else { dt_data[i] = (char)255; dt_data[i + 1] = 0; dt_data[i + 2] = (char)255; dt_data[i + 3] = (char)255; } int sq_dn = i / (16 * 16); if ((sq_dn / 2) * 2 == sq_dn) { dt_data[i] = (char)255 - dt_data[i]; dt_data[i + 2] = (char)255 - dt_data[i + 2]; } } GLuint tex; glGenTextures (1, &tex); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, tex); int x,y,n; unsigned char *data = stbi_load ("move_me.png", &x, &y, &n, 4); if (!data) { fprintf (stderr, "ERROR: could not load image 'move_me.png'. using default texture\n"); glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, dt_data ); } else { glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data ); stbi_image_free(data); data = NULL; printf ("loaded image with [%i,%i] res and %i chans\n", x, y, n); } glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); free (dt_data); dt_data = NULL; // */ // // Start rendering // -------------------------------------------------------------------------- // tell GL to only draw onto a pixel if the fragment is closer to the viewer glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" glClearColor (0.01, 0.01, 0.25, 1.0); float a = 0.0f; double prev = glfwGetTime (); while (!glfwWindowShouldClose (window)) { glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // just the default viewport, covering the whole render area glViewport (0, 0, gl_width, gl_height); double curr = glfwGetTime (); double elapsed = curr - prev; prev = curr; glUseProgram (shader_programme); glBindVertexArray (vao); a += sinf (elapsed * 50.0f); M = rotate_y_deg (identity_mat4 (), a); glUniformMatrix4fv (M_loc, 1, GL_FALSE, M.m); glDrawArrays (GL_TRIANGLES, 0, point_count); /* this just updates window events and keyboard input events (not used yet) */ glfwPollEvents (); glfwSwapBuffers (window); } return 0; }
int main () { restart_gl_log (); start_gl (); glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CCW); // set counter-clock-wise vertex order to mean the front glClearColor (0.2, 0.2, 0.2, 1.0); // grey background to help spot mistakes glViewport (0, 0, g_gl_width, g_gl_height); /* load the mesh using assimp */ GLuint monkey_vao; int monkey_point_count = 0; assert (load_mesh (MESH_FILE, &monkey_vao, &monkey_point_count)); /*-------------------------------CREATE SHADERS-------------------------------*/ GLuint shader_programme = create_programme_from_files ( VERTEX_SHADER_FILE, FRAGMENT_SHADER_FILE ); #define ONE_DEG_IN_RAD (2.0 * M_PI) / 360.0 // 0.017444444 // input variables float near = 0.1f; // clipping plane float far = 100.0f; // clipping plane float fov = 67.0f * ONE_DEG_IN_RAD; // convert 67 degrees to radians float aspect = (float)g_gl_width / (float)g_gl_height; // aspect ratio // matrix components float range = tan (fov * 0.5f) * near; float Sx = (2.0f * near) / (range * aspect + range * aspect); float Sy = near / range; float Sz = -(far + near) / (far - near); float Pz = -(2.0f * far * near) / (far - near); GLfloat proj_mat[] = { Sx, 0.0f, 0.0f, 0.0f, 0.0f, Sy, 0.0f, 0.0f, 0.0f, 0.0f, Sz, -1.0f, 0.0f, 0.0f, Pz, 0.0f }; float cam_speed = 1.0f; // 1 unit per second float cam_yaw_speed = 10.0f; // 10 degrees per second float cam_pos[] = {0.0f, 0.0f, 5.0f}; // don't start at zero, or we will be too close float cam_yaw = 0.0f; // y-rotation in degrees mat4 T = translate (identity_mat4 (), vec3 (-cam_pos[0], -cam_pos[1], -cam_pos[2])); mat4 R = rotate_y_deg (identity_mat4 (), -cam_yaw); mat4 view_mat = R * T; int view_mat_location = glGetUniformLocation (shader_programme, "view"); glUseProgram (shader_programme); glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, view_mat.m); int proj_mat_location = glGetUniformLocation (shader_programme, "proj"); glUseProgram (shader_programme); glUniformMatrix4fv (proj_mat_location, 1, GL_FALSE, proj_mat); while (!glfwWindowShouldClose (g_window)) { static double previous_seconds = glfwGetTime (); double current_seconds = glfwGetTime (); double elapsed_seconds = current_seconds - previous_seconds; previous_seconds = current_seconds; _update_fps_counter (g_window); // wipe the drawing surface clear glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport (0, 0, g_gl_width, g_gl_height); glUseProgram (shader_programme); glBindVertexArray (monkey_vao); glDrawArrays (GL_TRIANGLES, 0, monkey_point_count); // update other events like input handling glfwPollEvents (); // control keys bool cam_moved = false; if (glfwGetKey (g_window, GLFW_KEY_A)) { cam_pos[0] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_D)) { cam_pos[0] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_PAGE_UP)) { cam_pos[1] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_PAGE_DOWN)) { cam_pos[1] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_W)) { cam_pos[2] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_S)) { cam_pos[2] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_LEFT)) { cam_yaw += cam_yaw_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_RIGHT)) { cam_yaw -= cam_yaw_speed * elapsed_seconds; cam_moved = true; } // update view matrix if (cam_moved) { mat4 T = translate (identity_mat4 (), vec3 (-cam_pos[0], -cam_pos[1], -cam_pos[2])); // cam translation mat4 R = rotate_y_deg (identity_mat4 (), -cam_yaw); // mat4 view_mat = R * T; glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, view_mat.m); } if (GLFW_PRESS == glfwGetKey (g_window, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (g_window, 1); } // put the stuff we've been drawing onto the display glfwSwapBuffers (g_window); } // close GL context and any other GLFW resources glfwTerminate(); return 0; }
int main () { // start GL context and O/S window using the GLFW helper library if (!glfwInit ()) { fprintf (stderr, "ERROR: could not start GLFW3\n"); return 1; } // uncomment these lines if on Apple OS X glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); GLFWwindow* window = glfwCreateWindow (640, 480, "Cube to Sphere", NULL, NULL); if (!window) { fprintf (stderr, "ERROR: could not open window with GLFW3\n"); glfwTerminate(); return 1; } GLFWwindow* window2 = glfwCreateWindow (640, 480, "Just checking", NULL, NULL); if (!window2) { fprintf (stderr, "ERROR: could not open window with GLFW3\n"); glfwTerminate(); return 1; } glfwMakeContextCurrent (window); //start GLEW extension handler glewExperimental = GL_TRUE; glewInit (); // get version info const GLubyte* renderer = glGetString (GL_RENDERER); // get renderer string const GLubyte* version = glGetString (GL_VERSION); // version as a string printf ("Renderer: %s\n", renderer); printf ("OpenGL version supported %s\n", version); //CLGLUtils::init(); boost::compute::context context; try { context = boost::compute::opengl_create_shared_context(); } catch (std::exception e) { std::cerr<<"Failed to initialize a CLGL context"<<e.what()<<std::endl; exit(0); } // tell GL to only draw onto a pixel if the shape is closer to the viewer glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" // OTHER STUFF GOES HERE NEXT float points[] = { -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f }; GLuint vbo; glGenBuffers (1, &vbo); glBindBuffer (GL_ARRAY_BUFFER, vbo); glBufferData (GL_ARRAY_BUFFER, 3 * 36 * sizeof (float), &points, GL_STATIC_DRAW); GLuint vao; glGenVertexArrays (1, &vao); glBindVertexArray (vao); glEnableVertexAttribArray (0); glBindBuffer (GL_ARRAY_BUFFER, vbo); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); //Create Cube map GLuint cube_map_texture; create_cube_map ((resource_dir+"negz.jpg").c_str(), (resource_dir+"posz.jpg").c_str(), (resource_dir+"posy.jpg").c_str(), (resource_dir+"negy.jpg").c_str(), (resource_dir+"negx.jpg").c_str(), (resource_dir+"posx.jpg").c_str(), &cube_map_texture); boost::shared_ptr<boost::compute::opengl_texture> cl_cube_map_texture; try { cl_cube_map_texture = boost::shared_ptr<boost::compute::opengl_texture>(new boost::compute::opengl_texture(context,GL_TEXTURE_2D_ARRAY,0,cube_map_texture,boost::compute::memory_object::mem_flags::read_only)); } catch ( const std::exception& e ) { std::cerr << e.what() << std::endl; } const char* vertex_shader = "#version 400\n" "in vec3 vp;" "uniform mat4 P, V;" // "uniform vec3 vertOut;" "out vec3 texcoords;" "vec3 newP;" "void main () {" " texcoords = vp;" // " vertOut = vp;" " gl_Position = P * V * vec4 (vp, 1.0);" "}"; const char* fragment_shader = loadShader(resource_dir+"fragmentShader.frag").c_str(); /*"#version 400\n" "in vec3 texcoords;" "uniform samplerCube cube_texture;" "out vec4 frag_colour;" "vec4 cubeToLatLon(samplerCube cubemap, vec3 inUV) {" "vec3 cubmapTexCoords;" //"cubmapTexCoords.x = inUV.x*sqrt(1 - ( (inUV.y * inUV.y)/2 ) - ( (inUV.z * inUV.z)/2 ) + ( ( (inUV.y * inUV.y) * (inUV.z * inUV.z))/3));" "cubmapTexCoords.x = inUV.x;" //"cubmapTexCoords.y= inUV.y*sqrt(1 - ( (inUV.z * inUV.z)/2 ) - ( (inUV.x * inUV.x)/2 ) + ( ( (inUV.z * inUV.z) * (inUV.x * inUV.x))/3));" "cubmapTexCoords.y = inUV.y;" "cubmapTexCoords.z = inUV.z*sqrt(1 - ( (inUV.x * inUV.x)/2 ) - ( (inUV.y * inUV.y)/2 ) + ( ( (inUV.x * inUV.x) * (inUV.y * inUV.y))/3));" //"cubmapTexCoords.z = inUV.z;" "return texture(cubemap, cubmapTexCoords);" "}" "void main () {" //" frag_colour = texture (cube_texture, texcoords);" " frag_colour = cubeToLatLon (cube_texture, texcoords);" "}";*/ GLuint vs = glCreateShader (GL_VERTEX_SHADER); glShaderSource (vs, 1, &vertex_shader, NULL); glCompileShader (vs); GLuint fs = glCreateShader (GL_FRAGMENT_SHADER); glShaderSource (fs, 1, &fragment_shader, NULL); glCompileShader (fs); GLuint cube_sp = glCreateProgram (); glAttachShader (cube_sp, fs); glAttachShader (cube_sp, vs); glLinkProgram (cube_sp); //*-----------------------------Compile Shaders for second window - square --------*/ glfwMakeContextCurrent(window2); //start GLEW extension handler glewExperimental = GL_TRUE; glewInit (); glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" float squarePoints[] = { -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f }; GLfloat texcoords[] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; GLuint vbo_square; glGenBuffers (1, &vbo_square); glBindBuffer (GL_ARRAY_BUFFER, vbo_square); glBufferData (GL_ARRAY_BUFFER, 3 * 6 * sizeof (float), &squarePoints, GL_STATIC_DRAW); GLuint texcoords_vbo; glGenBuffers (1, &texcoords_vbo); glBindBuffer (GL_ARRAY_BUFFER, texcoords_vbo); glBufferData (GL_ARRAY_BUFFER, 12 * sizeof (GLfloat), texcoords, GL_STATIC_DRAW); GLuint vao_square; glGenVertexArrays (1, &vao_square); glBindVertexArray (vao_square); glBindBuffer (GL_ARRAY_BUFFER, vbo_square); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glBindBuffer (GL_ARRAY_BUFFER, texcoords_vbo); glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 0, NULL); // normalise! glEnableVertexAttribArray (0); glEnableVertexAttribArray (1); GLuint square_sp = create_programme_from_files((resource_dir+"square.vert").c_str(), (resource_dir+"square.frag").c_str()); GLuint tex; assert (load_texture ((resource_dir+"negz.jpg").c_str(), &tex)); //*----------------------------------------------------------------------------------*/ glfwMakeContextCurrent (window); int cube_V_location = glGetUniformLocation (cube_sp, "V"); int cube_P_location = glGetUniformLocation (cube_sp, "P"); //int cube_vertOut = glGetUniformLocation (cube_sp, "vertOut"); /*-------------------------------CREATE GLOBAL CAMERA--------------------------------*/ #define ONE_DEG_IN_RAD (2.0 * M_PI) / 360.0 // 0.017444444 // input variables float near = 0.1f; // clipping plane float far = 100.0f; // clipping plane float fovy = 80.0f; // 67 degrees float aspect = (float)g_gl_width / (float)g_gl_height; // aspect ratio proj_mat = perspective (fovy, aspect, near, far); float cam_speed = 3.0f; // 1 unit per second float cam_heading_speed = 50.0f; // 30 degrees per second float cam_heading = 0.0f; // y-rotation in degrees mat4 T = translate (identity_mat4 (), vec3 (-cam_pos.v[0], -cam_pos.v[1], -cam_pos.v[2])); mat4 R = rotate_y_deg (identity_mat4 (), -cam_heading); versor q = quat_from_axis_deg (-cam_heading, 0.0f, 1.0f, 0.0f); view_mat = R * T; // keep track of some useful vectors that can be used for keyboard movement vec4 fwd (0.0f, 0.0f, -1.0f, 0.0f); vec4 rgt (1.0f, 0.0f, 0.0f, 0.0f); vec4 up (0.0f, 1.0f, 0.0f, 0.0f); /*---------------------------SET RENDERING DEFAULTS---------------------------*/ glUseProgram (cube_sp); glUniformMatrix4fv (cube_V_location, 1, GL_FALSE, R.m); glUniformMatrix4fv (cube_P_location, 1, GL_FALSE, proj_mat.m); // unique model matrix for each sphere mat4 model_mat = identity_mat4 (); glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CCW); // set counter-clock-wise vertex order to mean the front glClearColor (0.2, 0.2, 0.2, 1.0); // grey background to help spot mistakes glViewport (0, 0, g_gl_width, g_gl_height); while (!glfwWindowShouldClose (window) && !glfwWindowShouldClose (window2)) { // update timers static double previous_seconds = glfwGetTime (); double current_seconds = glfwGetTime (); double elapsed_seconds = current_seconds - previous_seconds; previous_seconds = current_seconds; //_update_fps_counter (window); // wipe the drawing surface clear glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // render a sky-box using the cube-map texture glDepthMask (GL_FALSE); glUseProgram (cube_sp); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_CUBE_MAP, cube_map_texture); glBindVertexArray (vao); glDrawArrays (GL_TRIANGLES, 0, 36); glDepthMask (GL_TRUE); //*---------------------------------Display for second window-------------------*/ glfwMakeContextCurrent (window2); glUseProgram (square_sp); int cubemap_vert = glGetUniformLocation (square_sp, "cubeMap_texcoords"); glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CCW); // set counter-clock-wise vertex order to mean the front glClearColor (0.3, 0.2, 0.3, 1.0); // grey background to help spot mistakes glViewport (0, 0, g_gl_width, g_gl_height); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDepthMask (GL_FALSE); glUseProgram (square_sp); glBindVertexArray (vao_square); glDrawArrays (GL_TRIANGLES, 0, 6); glDepthMask (GL_TRUE); //*------------------------------GO back to cubemap window--------------------*/ glfwMakeContextCurrent (window); // update other events like input handling glfwPollEvents (); // control keys bool cam_moved = false; vec3 move (0.0, 0.0, 0.0); float cam_yaw = 0.0f; // y-rotation in degrees float cam_pitch = 0.0f; float cam_roll = 0.0; if (glfwGetKey (window, GLFW_KEY_A)) { move.v[0] -= cam_speed * elapsed_seconds; cam_moved = true; print(move); } if (glfwGetKey (window, GLFW_KEY_D)) { move.v[0] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_Q)) { move.v[1] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_E)) { move.v[1] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_W)) { move.v[2] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_S)) { move.v[2] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_LEFT)) { cam_yaw += cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_yaw = quat_from_axis_deg ( cam_yaw, up.v[0], up.v[1], up.v[2] ); q = q_yaw * q; } if (glfwGetKey (window, GLFW_KEY_RIGHT)) { cam_yaw -= cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_yaw = quat_from_axis_deg ( cam_yaw, up.v[0], up.v[1], up.v[2] ); q = q_yaw * q; } if (glfwGetKey (window, GLFW_KEY_UP)) { cam_pitch += cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_pitch = quat_from_axis_deg ( cam_pitch, rgt.v[0], rgt.v[1], rgt.v[2] ); q = q_pitch * q; } if (glfwGetKey (window, GLFW_KEY_DOWN)) { cam_pitch -= cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_pitch = quat_from_axis_deg ( cam_pitch, rgt.v[0], rgt.v[1], rgt.v[2] ); q = q_pitch * q; } if (glfwGetKey (window, GLFW_KEY_Z)) { cam_roll -= cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_roll = quat_from_axis_deg ( cam_roll, fwd.v[0], fwd.v[1], fwd.v[2] ); q = q_roll * q; } if (glfwGetKey (window, GLFW_KEY_C)) { cam_roll += cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_roll = quat_from_axis_deg ( cam_roll, fwd.v[0], fwd.v[1], fwd.v[2] ); q = q_roll * q; } // update view matrix if (cam_moved) { cam_heading += cam_yaw; // re-calculate local axes so can move fwd in dir cam is pointing R = quat_to_mat4 (q); fwd = R * vec4 (0.0, 0.0, -1.0, 0.0); rgt = R * vec4 (1.0, 0.0, 0.0, 0.0); up = R * vec4 (0.0, 1.0, 0.0, 0.0); cam_pos = cam_pos + vec3 (fwd) * -move.v[2]; cam_pos = cam_pos + vec3 (up) * move.v[1]; cam_pos = cam_pos + vec3 (rgt) * move.v[0]; mat4 T = translate (identity_mat4 (), vec3 (cam_pos)); view_mat = inverse (R) * inverse (T); //std::cout<<inverse(R).m<<std::endl; // cube-map view matrix has rotation, but not translation glUseProgram (cube_sp); glUniformMatrix4fv (cube_V_location, 1, GL_FALSE, inverse (R).m); } if (GLFW_PRESS == glfwGetKey (window, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (window, 1); } if (GLFW_PRESS == glfwGetKey (window2, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (window2, 1); } // put the stuff we've been drawing onto the display glfwSwapBuffers (window); glfwMakeContextCurrent (window2); glfwSwapBuffers (window2); glfwMakeContextCurrent (window); } // close GL context and any other GLFW resources glfwTerminate(); return 0; }
int main () { restart_gl_log (); start_gl (); // tell GL to only draw onto a pixel if the shape is closer to the viewer glEnable (GL_DEPTH_TEST); // enable depth-testing // depth-testing interprets a smaller value as "closer" glDepthFunc (GL_LESS); assert (load_mesh ("monkey.obj")); GLuint vao; glGenVertexArrays (1, &vao); glBindVertexArray (vao); GLuint points_vbo; if (NULL != g_vp) { glGenBuffers (1, &points_vbo); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glBufferData (GL_ARRAY_BUFFER, 3 * g_point_count * sizeof (GLfloat), g_vp, GL_STATIC_DRAW); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (0); printf ("enabled points\n"); } GLuint normals_vbo; if (NULL != g_vn) { glGenBuffers (1, &normals_vbo); glBindBuffer (GL_ARRAY_BUFFER, normals_vbo); glBufferData (GL_ARRAY_BUFFER, 3 * g_point_count * sizeof (GLfloat), g_vn, GL_STATIC_DRAW); glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (1); printf ("enabled normals\n"); } GLuint texcoords_vbo; if (NULL != g_vt) { glGenBuffers (1, &texcoords_vbo); glBindBuffer (GL_ARRAY_BUFFER, texcoords_vbo); glBufferData (GL_ARRAY_BUFFER, 2 * g_point_count * sizeof (GLfloat), g_vt, GL_STATIC_DRAW); glVertexAttribPointer (2, 2, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (2); printf ("enabled texcoords\n"); } GLuint shader_programme = create_programme_from_files ("test_vs.glsl", "test_fs.glsl"); /* if converting to GLSL 410 do this to replace GLSL texture bindings: GLint diffuse_map_loc, specular_map_loc, ambient_map_loc, emission_map_loc; diffuse_map_loc = glGetUniformLocation (shader_programme, "diffuse_map"); specular_map_loc = glGetUniformLocation (shader_programme, "specular_map"); ambient_map_loc = glGetUniformLocation (shader_programme, "ambient_map"); emission_map_loc = glGetUniformLocation (shader_programme, "emission_map"); assert (diffuse_map_loc > -1); assert (specular_map_loc > -1); assert (ambient_map_loc > -1); assert (emission_map_loc > -1); glUseProgram (shader_programme); glUniform1i (diffuse_map_loc, 0); glUniform1i (specular_map_loc, 1); glUniform1i (ambient_map_loc, 2); glUniform1i (emission_map_loc, 3);*/ // load texture GLuint tex_diff, tex_spec, tex_amb, tex_emiss; glActiveTexture (GL_TEXTURE0); assert (load_texture ("boulder_diff.png", &tex_diff)); glActiveTexture (GL_TEXTURE1); assert (load_texture ("boulder_spec.png", &tex_spec)); glActiveTexture (GL_TEXTURE2); assert (load_texture ("ao.png", &tex_amb)); glActiveTexture (GL_TEXTURE3); assert (load_texture ("tileable9b_emiss.png", &tex_emiss)); #define ONE_DEG_IN_RAD (2.0 * M_PI) / 360.0 // 0.017444444 // input variables float near = 0.1f; // clipping plane float far = 100.0f; // clipping plane float fov = 67.0f * ONE_DEG_IN_RAD; // convert 67 degrees to radians float aspect = (float)g_gl_width / (float)g_gl_height; // aspect ratio // matrix components float range = tan (fov * 0.5f) * near; float Sx = (2.0f * near) / (range * aspect + range * aspect); float Sy = near / range; float Sz = -(far + near) / (far - near); float Pz = -(2.0f * far * near) / (far - near); GLfloat proj_mat[] = { Sx, 0.0f, 0.0f, 0.0f, 0.0f, Sy, 0.0f, 0.0f, 0.0f, 0.0f, Sz, -1.0f, 0.0f, 0.0f, Pz, 0.0f }; float cam_speed = 1.0f; // 1 unit per second float cam_yaw_speed = 90.0f; // 10 degrees per second // don't start at zero, or we will be too close float cam_pos[] = {0.0f, 0.0f, 5.0f}; float cam_yaw = 0.0f; // y-rotation in degrees mat4 T = translate (identity_mat4 (), vec3 (-cam_pos[0], -cam_pos[1], -cam_pos[2])); mat4 R = rotate_y_deg (identity_mat4 (), -cam_yaw); mat4 view_mat = R * T; int view_mat_location = glGetUniformLocation (shader_programme, "view"); glUseProgram (shader_programme); glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, view_mat.m); int proj_mat_location = glGetUniformLocation (shader_programme, "proj"); glUseProgram (shader_programme); glUniformMatrix4fv (proj_mat_location, 1, GL_FALSE, proj_mat); glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CCW); // GL_CCW for counter clock-wise while (!glfwWindowShouldClose (g_window)) { static double previous_seconds = glfwGetTime (); double current_seconds = glfwGetTime (); double elapsed_seconds = current_seconds - previous_seconds; previous_seconds = current_seconds; _update_fps_counter (g_window); // wipe the drawing surface clear glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport (0, 0, g_gl_width, g_gl_height); glUseProgram (shader_programme); glBindVertexArray (vao); // draw points 0-3 from the currently bound VAO with current in-use shader glDrawArrays (GL_TRIANGLES, 0, g_point_count); // update other events like input handling glfwPollEvents (); // control keys bool cam_moved = false; if (glfwGetKey (g_window, GLFW_KEY_A)) { cam_pos[0] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_D)) { cam_pos[0] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_PAGE_UP)) { cam_pos[1] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_PAGE_DOWN)) { cam_pos[1] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_W)) { cam_pos[2] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_S)) { cam_pos[2] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_LEFT)) { cam_yaw += cam_yaw_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_RIGHT)) { cam_yaw -= cam_yaw_speed * elapsed_seconds; cam_moved = true; } // update view matrix if (cam_moved) { mat4 T = translate (identity_mat4 (), vec3 (-cam_pos[0], -cam_pos[1], -cam_pos[2])); // cam translation mat4 R = rotate_y_deg (identity_mat4 (), -cam_yaw); // mat4 view_mat = R * T; glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, view_mat.m); } if (GLFW_PRESS == glfwGetKey (g_window, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (g_window, 1); } // put the stuff we've been drawing onto the display glfwSwapBuffers (g_window); } // close GL context and any other GLFW resources glfwTerminate(); return 0; }
int main () { restart_gl_log (); // use GLFW and GLEW to start GL context. see gl_utils.cpp for details start_gl (); /* create buffer of particle initial attributes and a VAO */ GLuint vao = gen_particles (); GLuint shader_programme = create_programme_from_files ( "test_vs.glsl", "test_fs.glsl"); #define ONE_DEG_IN_RAD (2.0 * M_PI) / 360.0 // 0.017444444 // input variables float near = 0.1f; // clipping plane float far = 100.0f; // clipping plane float fov = 67.0f * ONE_DEG_IN_RAD; // convert 67 degrees to radians float aspect = (float)g_gl_width / (float)g_gl_height; // aspect ratio // matrix components float range = tan (fov * 0.5f) * near; float Sx = (2.0f * near) / (range * aspect + range * aspect); float Sy = near / range; float Sz = -(far + near) / (far - near); float Pz = -(2.0f * far * near) / (far - near); GLfloat proj_mat[] = { Sx, 0.0f, 0.0f, 0.0f, 0.0f, Sy, 0.0f, 0.0f, 0.0f, 0.0f, Sz, -1.0f, 0.0f, 0.0f, Pz, 0.0f }; float cam_speed = 1.0f; // 1 unit per second float cam_yaw_speed = 10.0f; // 10 degrees per second float cam_pos[] = {0.0f, 0.0f, 2.0f}; // don't start at zero, or we will be too close float cam_yaw = 0.0f; // y-rotation in degrees mat4 T = translate (identity_mat4 (), vec3 (-cam_pos[0], -cam_pos[1], -cam_pos[2])); mat4 R = rotate_y_deg (identity_mat4 (), -cam_yaw); mat4 view_mat = R * T; /* make up a world position for the emitter */ vec3 emitter_world_pos (0.0f, 0.0f, 0.0f); // locations of view and projection matrices int V_loc = glGetUniformLocation (shader_programme, "V"); assert (V_loc > -1); int P_loc = glGetUniformLocation (shader_programme, "P"); assert (P_loc > -1); int emitter_pos_wor_loc = glGetUniformLocation (shader_programme, "emitter_pos_wor"); assert (emitter_pos_wor_loc > -1); int elapsed_system_time_loc = glGetUniformLocation (shader_programme, "elapsed_system_time"); assert (elapsed_system_time_loc > -1); glUseProgram (shader_programme); glUniformMatrix4fv (V_loc, 1, GL_FALSE, view_mat.m); glUniformMatrix4fv (P_loc, 1, GL_FALSE, proj_mat); glUniform3f (emitter_pos_wor_loc, emitter_world_pos.v[0], emitter_world_pos.v[1], emitter_world_pos.v[2]); // load texture GLuint tex; if (!load_texture ("Droplet.png", &tex)) { gl_log_err ("ERROR: loading Droplet.png texture\n"); return 1; } glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CCW); // GL_CCW for counter clock-wise glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" glEnable (GL_DEPTH_TEST); // enable depth-testing glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glClearColor (0.2, 0.2, 0.2, 1.0); /* MUST use this is in compatibility profile. doesn't exist in core glEnable(GL_POINT_SPRITE); */ while (!glfwWindowShouldClose (g_window)) { static double previous_seconds = glfwGetTime (); double current_seconds = glfwGetTime (); double elapsed_seconds = current_seconds - previous_seconds; previous_seconds = current_seconds; _update_fps_counter (g_window); // wipe the drawing surface clear glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport (0, 0, g_gl_width, g_gl_height); /* Render Particles. Enabling point re-sizing in vertex shader */ glEnable (GL_PROGRAM_POINT_SIZE); glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); glEnable (GL_BLEND); glDepthMask (GL_FALSE); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, tex); glUseProgram (shader_programme); /* update time in shaders */ glUniform1f (elapsed_system_time_loc, (GLfloat)current_seconds); glBindVertexArray (vao); // draw points 0-3 from the currently bound VAO with current in-use shader glDrawArrays (GL_POINTS, 0, PARTICLE_COUNT); glDisable (GL_BLEND); glDepthMask (GL_TRUE); glDisable (GL_PROGRAM_POINT_SIZE); // update other events like input handling glfwPollEvents (); // control keys bool cam_moved = false; if (glfwGetKey (g_window, GLFW_KEY_A)) { cam_pos[0] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_D)) { cam_pos[0] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_PAGE_UP)) { cam_pos[1] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_PAGE_DOWN)) { cam_pos[1] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_W)) { cam_pos[2] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_S)) { cam_pos[2] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_LEFT)) { cam_yaw += cam_yaw_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_RIGHT)) { cam_yaw -= cam_yaw_speed * elapsed_seconds; cam_moved = true; } // update view matrix if (cam_moved) { mat4 T = translate (identity_mat4 (), vec3 (-cam_pos[0], -cam_pos[1], -cam_pos[2])); // cam translation mat4 R = rotate_y_deg (identity_mat4 (), -cam_yaw); // mat4 view_mat = R * T; glUniformMatrix4fv (V_loc, 1, GL_FALSE, view_mat.m); } if (GLFW_PRESS == glfwGetKey (g_window, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (g_window, 1); } // put the stuff we've been drawing onto the display glfwSwapBuffers (g_window); } // close GL context and any other GLFW resources glfwTerminate(); return 0; }
int main () { //start logger system assert(restart_gl_log()); hardware = {}; //must initialize window before starting gl stuff //create our main window assert(start_gl()); cursor = {}; cursor.vertexData = new GLfloat[36 + (3 * 6)]; setCursorCoordinates(cursor.vertexData, &cursor); GLfloat*cursorColourData = new GLfloat[36 + (3 * 6)]; { for (int i = 0; i < 12; ++i) { cursorColourData[i * 3] = 0.5f; cursorColourData[i * 3 + 1] = 0.0f; cursorColourData[i * 3 + 2] = 0.5f; }; for (int j = 12; j < 17; ++j) { cursorColourData[j * 3] = 0.5f; cursorColourData[j * 3 + 1] = 0.5f; cursorColourData[j * 3 + 2] = 0.5f; } } grid = {}; grid.numberOfLines = 100; grid.heightValue = 0.0f; GLfloat *gridColourData = new GLfloat[100 * 2 * 3]; { int totalVerteces = 100 * 2; for (int i = 0; i < totalVerteces; ++i) { gridColourData[i * 3 ] = 0.5f; gridColourData[i * 3 + 1] = 0.0f; gridColourData[i * 3 + 2] = 0.5f; } } //Create our gridPoints coordinates GLfloat *gridVertexData = new GLfloat[grid.numberOfLines * 6]; { for (int i = 0; i < grid.numberOfLines; ++i) { //draw the lines parallel to the x axis if (i < 50) { gridVertexData[i * 6] = i - 25; // gridVertexData[i * 6 + 1] = grid.heightValue; gridVertexData[i * 6 + 2] = -100.f; gridVertexData[i * 6 + 3] = i - 25; // gridVertexData[i * 6 + 4] = grid.heightValue; gridVertexData[i * 6 + 5] = 100.0f; } //draw the lines parallel to the z axis; if (i >= 50) { gridVertexData[i * 6] = -100.0f; // gridVertexData[i * 6 + 1] = grid.heightValue; gridVertexData[i * 6 + 2] = i - 50 - 25.0f; gridVertexData[i * 6 + 3] = 100.0f; // gridVertexData[i * 6 + 4] = grid.heightValue; gridVertexData[i * 6 + 5] = i - 50 - 25.0f; } } } //create our wall items //2 triangles , 3 points each, 3 coordinate Wall wall = {}; wall.scale = vec3(1.0f, 0, 1.0f); wall.position = vec3(1.0f, 1.0f, 1.0f); GLfloat *wallVertexData = new GLfloat[2 * 3 * 3]; { wallVertexData[0] = wall.scale.v[0] * 0.5f; wallVertexData[1] = 0.0f; wallVertexData[2] = - wall.scale.v[2] * 0.5f; wallVertexData[3] = -wall.scale.v[0] * 0.5f; wallVertexData[4] = 0.0f; wallVertexData[5] = + wall.scale.v[2] * 0.5f; wallVertexData[6] = - wall.scale.v[0] * 0.5f; wallVertexData[7] = 0.0f; wallVertexData[8] = - wall.scale.v[2] * 0.5f; wallVertexData[9] = + wall.scale.v[0] * 0.5f; wallVertexData[10] = 0.0f; wallVertexData[11] = - wall.scale.v[2] * 0.5f; wallVertexData[12] = + wall.scale.v[0] * 0.5f; wallVertexData[13] = 0.0f; wallVertexData[14] = + wall.scale.v[2] * 0.5f; wallVertexData[15] = - wall.scale.v[0] * 0.5f; wallVertexData[16] = 0.0f; wallVertexData[17] = + wall.scale.v[2] * 0.5f; } GLfloat *wallColourData = new GLfloat[2 * 3 * 3]; { for (int i = 0; i < 6; ++i) { wallColourData[i * 3 + 0] = 0.8f; wallColourData[i * 3 + 1] = 0.8f; wallColourData[i * 3 + 2] = 0.8f; } } glfwSetCursorPosCallback(hardware.window,cursor_position_callback); glfwSetInputMode(hardware.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glfwSetKeyCallback(hardware.window, key_callback); glfwSetInputMode(hardware.window,GLFW_STICKY_KEYS, 1); GLuint shader_program = create_programme_from_files(VERTEX_SHADER, FRAGMENT_SHADER); /* get version info */ glEnable (GL_DEPTH_TEST); /* enable depth-testing */ glDepthFunc (GL_LESS); createVertexBufferObject(&wallColourVbo, 3 * 3 * 2 * sizeof(GLfloat), wallColourData); createVertexBufferObject(&wallVertexVbo, 3 * 3 * 2 * sizeof(GLfloat), wallVertexData); createVertexBufferObject(&grid.vertexVbo, grid.numberOfLines * 6 * sizeof(GLfloat), gridVertexData); createVertexBufferObject(&grid.colourVbo, grid.numberOfLines * 6 * sizeof(GLfloat), gridColourData); createVertexBufferObject(&cursor.vertexVbo, (36 + (3 * 6)) * sizeof(GLfloat), cursor.vertexData); createVertexBufferObject(&cursor.colourVbo, (36 + (3 * 6)) * sizeof(GLfloat), cursorColourData); createVertexArrayObjet(&wallVao, &wallVertexVbo, 3); createVertexArrayObjet(&grid.vao, &grid.vertexVbo, 3); createVertexArrayObjet(&cursor.vao, &cursor.vertexVbo, 3); cursor.colourAttributeIndex = 1; grid.colourAttributeIndex = 1; wallColourAttributeIndex = 1; setColourMesh(&cursor.vao, &cursor.colourVbo, 3, &cursor.colourAttributeIndex); setColourMesh(&grid.vao, &grid.colourVbo, 3, &grid.colourAttributeIndex); setColourMesh(&wallVao, &wallColourVbo, 3, &wallColourAttributeIndex); free(cursor.vertexData); free(cursorColourData); free(wallVertexData); free(wallColourData); // camera stuff #define PI 3.14159265359 #define DEG_TO_RAD (2.0 * PI) / 360.0 float near = 0.1f; float far = 100.0f; double fov = 67.0f * DEG_TO_RAD; float aspect = (float)hardware.vmode->width /(float)hardware.vmode->height; // matrix components double range = tan (fov * 0.5f) * near; double Sx = (2.0f * near) / (range * aspect + range * aspect); double Sy = near / range; float Sz = -(far + near) / (far - near); float Pz = -(2.0f * far * near) / (far - near); GLfloat proj_mat[] = { Sx, 0.0f, 0.0f, 0.0f, 0.0f, Sy, 0.0f, 0.0f, 0.0f, 0.0f, Sz, -1.0f, 0.0f, 0.0f, Pz, 0.0f }; camera = {}; //create view matrix camera.pos[0] = 0.0f; // don't start at zero, or we will be too close camera.pos[1] = 0.0f; // don't start at zero, or we will be too close camera.pos[2] = 0.5f; // don't start at zero, or we will be too close camera.T = translate (identity_mat4 (), vec3 (-camera.pos[0], -camera.pos[1], -camera.pos[2])); camera.Rpitch = rotate_y_deg (identity_mat4 (), -camera.yaw); camera.Ryaw = rotate_y_deg (identity_mat4 (), -camera.yaw); camera.viewMatrix = camera.Rpitch * camera.T; cursor.yaw = cursor.roll = cursor.pitch += 0.0f; calculateCursorRotations(&cursor); //create the viewmatrix of the wall wall.T= translate (identity_mat4 (), vec3 (2.0f, 2.0f, 2.0f)); glUseProgram(shader_program); camera.view_mat_location = glGetUniformLocation(shader_program, "view"); camera.proj_mat_location = glGetUniformLocation(shader_program, "proj"); glUniformMatrix4fv(camera.view_mat_location, 1, GL_FALSE, camera.viewMatrix.m); glUniformMatrix4fv(camera.proj_mat_location, 1, GL_FALSE, proj_mat); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); walls.push_back(wall); while (!glfwWindowShouldClose (hardware.window)) { updateMovement(&camera); calculateViewMatrices(&camera, &cursor); //set the new view matrix @ the shader level glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, hardware.vmode->width, hardware.vmode->height); glUseProgram(shader_program); //draw the cursor glUniformMatrix4fv(camera.view_mat_location, 1, GL_FALSE, cursor.viewMatrix.m); glBindVertexArray(cursor.vao); glDrawArrays(GL_TRIANGLES, 0, 18); //draw the walls in place //for each wall, draw it. //get view matrix for ( std::vector<Wall>::iterator it = walls.begin(); it != walls.end(); ++it) { Wall tempWall = *it; getTransformationMatrix(&tempWall); glUniformMatrix4fv(camera.view_mat_location, 1, GL_FALSE, tempWall.transformationMatrix.m); glBindVertexArray(wallVao); glDrawArrays(GL_TRIANGLES, 0, 6); } //draw the grid glUniformMatrix4fv(camera.view_mat_location, 1, GL_FALSE, camera.viewMatrix.m); glBindVertexArray(grid.vao); glDrawArrays(GL_LINES, 0, grid.numberOfLines* 2); glfwPollEvents(); if (GLFW_PRESS == glfwGetKey(hardware.window, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose(hardware.window, 1); } glfwSwapBuffers(hardware.window); } /* close GL context and any other GLFW resources */ glfwTerminate(); return 0; }
int main () { assert (restart_gl_log ()); assert (start_gl ()); glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CCW); // set counter-clock-wise vertex order to mean the front glClearColor (0.2, 0.2, 0.2, 1.0); // grey background to help spot mistakes glViewport (0, 0, g_gl_width, g_gl_height); /* load the mesh using assimp */ GLuint monkey_vao; mat4 monkey_bone_offset_matrices[MAX_BONES]; mat4 monkey_bone_animation_mats[MAX_BONES]; for (int i = 0; i < MAX_BONES; i++) { monkey_bone_animation_mats[i] = identity_mat4 (); monkey_bone_offset_matrices[i] = identity_mat4 (); monkey_bone_animation_mats[i] = identity_mat4 (); } int monkey_point_count = 0; int monkey_bone_count = 0; Skeleton_Node* monkey_root_node = NULL; double monkey_anim_duration = 0.0; assert (load_mesh ( MESH_FILE, &monkey_vao, &monkey_point_count, monkey_bone_offset_matrices, &monkey_bone_count, &monkey_root_node, &monkey_anim_duration )); printf ("monkey bone count %i\n", monkey_bone_count); /* create a buffer of bone positions for visualising the bones */ float bone_positions[3 * 256]; int c = 0; for (int i = 0; i < monkey_bone_count; i++) { //print (monkey_bone_offset_matrices[i]); // get the x y z translation elements from the last column in the array bone_positions[c++] = -monkey_bone_offset_matrices[i].m[12]; bone_positions[c++] = -monkey_bone_offset_matrices[i].m[13]; bone_positions[c++] = -monkey_bone_offset_matrices[i].m[14]; } GLuint bones_vao; glGenVertexArrays (1, &bones_vao); glBindVertexArray (bones_vao); GLuint bones_vbo; glGenBuffers (1, &bones_vbo); glBindBuffer (GL_ARRAY_BUFFER, bones_vbo); glBufferData ( GL_ARRAY_BUFFER, 3 * monkey_bone_count * sizeof (float), bone_positions, GL_STATIC_DRAW ); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (0); /*-------------------------------CREATE SHADERS-------------------------------*/ GLuint shader_programme = create_programme_from_files ( VERTEX_SHADER_FILE, FRAGMENT_SHADER_FILE ); GLuint bones_shader_programme = create_programme_from_files ( "bones.vert", "bones.frag" ); #define ONE_DEG_IN_RAD (2.0 * M_PI) / 360.0 // 0.017444444 // input variables float near = 0.1f; // clipping plane float far = 100.0f; // clipping plane float fov = 67.0f * ONE_DEG_IN_RAD; // convert 67 degrees to radians float aspect = (float)g_gl_width / (float)g_gl_height; // aspect ratio // matrix components float range = tan (fov * 0.5f) * near; float Sx = (2.0f * near) / (range * aspect + range * aspect); float Sy = near / range; float Sz = -(far + near) / (far - near); float Pz = -(2.0f * far * near) / (far - near); GLfloat proj_mat[] = { Sx, 0.0f, 0.0f, 0.0f, 0.0f, Sy, 0.0f, 0.0f, 0.0f, 0.0f, Sz, -1.0f, 0.0f, 0.0f, Pz, 0.0f }; float cam_speed = 5.0f; // 1 unit per second float cam_yaw_speed = 40.0f; // 10 degrees per second float cam_pos[] = {0.0f, 0.0f, 5.0f}; // don't start at zero, or we will be too close float cam_yaw = 0.0f; // y-rotation in degrees mat4 T = translate (identity_mat4 (), vec3 (-cam_pos[0], -cam_pos[1], -cam_pos[2])); mat4 R = rotate_y_deg (identity_mat4 (), -cam_yaw); mat4 view_mat = R * T; /* apply a model matrix that rotates our mesh up the correct way */ mat4 model_mat = identity_mat4 (); glUseProgram (shader_programme); int model_mat_location = glGetUniformLocation (shader_programme, "model"); glUniformMatrix4fv (model_mat_location, 1, GL_FALSE, model_mat.m); int view_mat_location = glGetUniformLocation (shader_programme, "view"); glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, view_mat.m); int proj_mat_location = glGetUniformLocation (shader_programme, "proj"); glUniformMatrix4fv (proj_mat_location, 1, GL_FALSE, proj_mat); int bone_matrices_locations[MAX_BONES]; // reset all the bone matrices char name[64]; for (int i = 0; i < MAX_BONES; i++) { sprintf (name, "bone_matrices[%i]", i); bone_matrices_locations[i] = glGetUniformLocation (shader_programme, name); glUniformMatrix4fv (bone_matrices_locations[i], 1, GL_FALSE, identity_mat4 ().m); } glUseProgram (bones_shader_programme); int bones_view_mat_location = glGetUniformLocation (bones_shader_programme, "view"); glUniformMatrix4fv (bones_view_mat_location, 1, GL_FALSE, view_mat.m); int bones_proj_mat_location = glGetUniformLocation (bones_shader_programme, "proj"); glUniformMatrix4fv (bones_proj_mat_location, 1, GL_FALSE, proj_mat); double anim_time = 0.0; while (!glfwWindowShouldClose (g_window)) { static double previous_seconds = glfwGetTime (); double current_seconds = glfwGetTime (); double elapsed_seconds = current_seconds - previous_seconds; previous_seconds = current_seconds; /* update animation timer and loop */ anim_time += elapsed_seconds * 0.5; if (anim_time >= monkey_anim_duration) { anim_time = monkey_anim_duration - anim_time; } _update_fps_counter (g_window); // wipe the drawing surface clear glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport (0, 0, g_gl_width, g_gl_height); glEnable (GL_DEPTH_TEST); glUseProgram (shader_programme); glBindVertexArray (monkey_vao); glDrawArrays (GL_TRIANGLES, 0, monkey_point_count); glDisable (GL_DEPTH_TEST); glEnable (GL_PROGRAM_POINT_SIZE); glUseProgram (bones_shader_programme); glBindVertexArray (bones_vao); glDrawArrays (GL_POINTS, 0, monkey_bone_count); glDisable (GL_PROGRAM_POINT_SIZE); // update other events like input handling glfwPollEvents (); // control keys bool cam_moved = false; if (glfwGetKey (g_window, GLFW_KEY_A)) { cam_pos[0] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_D)) { cam_pos[0] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_PAGE_UP)) { cam_pos[1] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_PAGE_DOWN)) { cam_pos[1] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_W)) { cam_pos[2] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_S)) { cam_pos[2] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_LEFT)) { cam_yaw += cam_yaw_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_RIGHT)) { cam_yaw -= cam_yaw_speed * elapsed_seconds; cam_moved = true; } // update view matrix if (cam_moved) { mat4 T = translate (identity_mat4 (), vec3 (-cam_pos[0], -cam_pos[1], -cam_pos[2])); // cam translation mat4 R = rotate_y_deg (identity_mat4 (), -cam_yaw); // mat4 view_mat = R * T; glUseProgram (shader_programme); glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, view_mat.m); glUseProgram (bones_shader_programme); glUniformMatrix4fv (bones_view_mat_location, 1, GL_FALSE, view_mat.m); } skeleton_animate ( monkey_root_node, anim_time, identity_mat4 (), monkey_bone_offset_matrices, monkey_bone_animation_mats ); glUseProgram (shader_programme); glUniformMatrix4fv ( bone_matrices_locations[0], monkey_bone_count, GL_FALSE, monkey_bone_animation_mats[0].m ); if (GLFW_PRESS == glfwGetKey (g_window, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (g_window, 1); } // put the stuff we've been drawing onto the display glfwSwapBuffers (g_window); } // close GL context and any other GLFW resources glfwTerminate(); return 0; }
int main () { GLFWwindow* window = NULL; const GLubyte* renderer; const GLubyte* version; GLuint shader_programme; GLuint vao; // // Start OpenGL using helper libraries // -------------------------------------------------------------------------- if (!glfwInit ()) { fprintf (stderr, "ERROR: could not start GLFW3\n"); return 1; } // change to 3.2 if on Apple OS X glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint (GLFW_SAMPLES, msaa); window = glfwCreateWindow (gl_width, gl_height, "Textured Mesh", NULL, NULL); if (!window) { fprintf (stderr, "ERROR: opening OS window\n"); return 1; } glfwMakeContextCurrent (window); glewExperimental = GL_TRUE; glewInit (); /* get version info */ renderer = glGetString (GL_RENDERER); /* get renderer string */ version = glGetString (GL_VERSION); /* version as a string */ printf ("Renderer: %s\n", renderer); printf ("OpenGL version supported %s\n", version); int point_count = 0; // // Set up vertex buffers and vertex array object // -------------------------------------------------------------------------- { GLfloat* vp = NULL; // array of vertex points GLfloat* vn = NULL; // array of vertex normals (we haven't used these yet) GLfloat* vt = NULL; // array of texture coordinates (or these) //assert (load_obj_file ("cube.obj", vp, vt, vn, point_count)); assert (load_obj_file ("monkey.obj", vp, vt, vn, point_count)); GLuint points_vbo, texcoord_vbo, normal_vbo; glGenBuffers (1, &points_vbo); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 3 * point_count, vp, GL_STATIC_DRAW); glGenBuffers (1, &texcoord_vbo); glBindBuffer (GL_ARRAY_BUFFER, texcoord_vbo); glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 2 * point_count, vt, GL_STATIC_DRAW); glGenBuffers (1, &normal_vbo); glBindBuffer (GL_ARRAY_BUFFER, normal_vbo); glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 3 * point_count, vn, GL_STATIC_DRAW); glGenVertexArrays (1, &vao); glBindVertexArray (vao); glEnableVertexAttribArray (0); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (1); glBindBuffer (GL_ARRAY_BUFFER, texcoord_vbo); glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (2); glBindBuffer (GL_ARRAY_BUFFER, normal_vbo); glVertexAttribPointer (2, 3, GL_FLOAT, GL_FALSE, 0, NULL); free (vp); free (vn); free (vt); } // // Load shaders from files // -------------------------------------------------------------------------- { char* vertex_shader_str; char* fragment_shader_str; // allocate some memory to store shader strings vertex_shader_str = (char*)malloc (81920); fragment_shader_str = (char*)malloc (81920); // load shader strings from text files assert (parse_file_into_str ("teapot.vert", vertex_shader_str, 81920)); assert (parse_file_into_str ("teapot.frag", fragment_shader_str, 81920)); GLuint vs, fs; vs = glCreateShader (GL_VERTEX_SHADER); fs = glCreateShader (GL_FRAGMENT_SHADER); glShaderSource (vs, 1, (const char**)&vertex_shader_str, NULL); glShaderSource (fs, 1, (const char**)&fragment_shader_str, NULL); // free memory free (vertex_shader_str); free (fragment_shader_str); int params = -1; glCompileShader (vs); glGetShaderiv (vs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { printf ("ERROR: GL shader index %i (teapot.vert) did not compile\n", vs); int max_length = 2048; int actual_length = 0; char log[2048]; glGetShaderInfoLog (vs, max_length, &actual_length, log); printf ("shader info log for GL index %u\n%s\n", vs, log); } glCompileShader (fs); glGetShaderiv (fs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { printf ("ERROR: GL shader index %i (teapot.frag) did not compile\n", fs); int max_length = 2048; int actual_length = 0; char log[2048]; glGetShaderInfoLog (fs, max_length, &actual_length, log); printf ("shader info log for GL index %u\n%s\n", vs, log); } shader_programme = glCreateProgram (); glAttachShader (shader_programme, fs); glAttachShader (shader_programme, vs); glBindAttribLocation (shader_programme, 0, "vp"); glBindAttribLocation (shader_programme, 1, "vt"); glBindAttribLocation (shader_programme, 2, "vn"); glLinkProgram (shader_programme); glGetProgramiv (shader_programme, GL_LINK_STATUS, ¶ms); if (GL_TRUE != params) { printf ("ERROR: could not link shader programme GL index %u\n", shader_programme); int max_length = 2048; int actual_length = 0; char log[2048]; glGetProgramInfoLog (shader_programme, max_length, &actual_length, log); printf ("program info log for GL index %u\n%s\n", shader_programme, log); } /* TODO NOTE: you should check for errors and print logs after compiling and also linking shaders */ } // // Create some matrices // -------------------------------------------------------------------------- mat4 M, V, P; M = identity_mat4 ();//scale (identity_mat4 (), vec3 (0.05, 0.05, 0.05)); vec3 cam_pos (0.0, 5.0, 5.0); vec3 targ_pos (0.0, 0.0, 0.0); vec3 up = normalise (vec3 (0.0, 1.0, -1.0)); V = look_at (cam_pos, targ_pos, up); P = perspective (67.0f, (float)gl_width / (float)gl_height, 0.1, 10.0); int M_loc = glGetUniformLocation (shader_programme, "M"); int V_loc = glGetUniformLocation (shader_programme, "V"); int P_loc = glGetUniformLocation (shader_programme, "P"); int ol_loc = glGetUniformLocation (shader_programme, "ol_mode"); int sm_loc = glGetUniformLocation (shader_programme, "sm_shaded"); // send matrix values to shader immediately glUseProgram (shader_programme); glUniformMatrix4fv (M_loc, 1, GL_FALSE, M.m); glUniformMatrix4fv (V_loc, 1, GL_FALSE, V.m); glUniformMatrix4fv (P_loc, 1, GL_FALSE, P.m); glUniform1f (ol_loc, 0.0f); glUniform1f (sm_loc, 0.0f); // // Start rendering // -------------------------------------------------------------------------- // tell GL to only draw onto a pixel if the fragment is closer to the viewer glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" glDepthFunc (GL_LESS); // depth-testing is to use a "less than" function glEnable (GL_CULL_FACE); // enable culling of faces glCullFace (GL_BACK); glFrontFace (GL_CCW); glClearColor (0.04, 0.04, 0.75, 1.0); bool multi_pass = true; GLuint fb, c_tex, d_tex;; { // fb glGenFramebuffers (1, &fb); glBindFramebuffer (GL_FRAMEBUFFER, fb); glGenTextures (1, &c_tex); glGenTextures (1, &d_tex); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, c_tex); glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, gl_width, gl_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, c_tex, 0); glBindTexture (GL_TEXTURE_2D, d_tex); glTexImage2D (GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, gl_width, gl_height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, d_tex, 0); glBindFramebuffer (GL_FRAMEBUFFER, 0); } GLuint quad_vao; { float quad_pts[] = {-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0}; GLuint quad_vbo; glGenBuffers (1, &quad_vbo); glGenVertexArrays (1, &quad_vao); glBindVertexArray (quad_vao); glEnableVertexAttribArray (0); glBindBuffer (GL_ARRAY_BUFFER, quad_vbo); glBufferData (GL_ARRAY_BUFFER, 8 * sizeof (float), quad_pts, GL_STATIC_DRAW); glVertexAttribPointer (0, 2, GL_FLOAT, GL_FALSE, 0, NULL); } GLuint post_sp; { char* vertex_shader_str; char* fragment_shader_str; // allocate some memory to store shader strings vertex_shader_str = (char*)malloc (81920); fragment_shader_str = (char*)malloc (81920); // load shader strings from text files assert (parse_file_into_str ("post.vert", vertex_shader_str, 81920)); assert (parse_file_into_str ("post.frag", fragment_shader_str, 81920)); GLuint vs, fs; vs = glCreateShader (GL_VERTEX_SHADER); fs = glCreateShader (GL_FRAGMENT_SHADER); glShaderSource (vs, 1, (const char**)&vertex_shader_str, NULL); glShaderSource (fs, 1, (const char**)&fragment_shader_str, NULL); // free memory free (vertex_shader_str); free (fragment_shader_str); int params = -1; glCompileShader (vs); glGetShaderiv (vs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { printf ("ERROR: GL shader index %i (post.vert) did not compile\n", vs); int max_length = 2048; int actual_length = 0; char log[2048]; glGetShaderInfoLog (vs, max_length, &actual_length, log); printf ("shader info log for GL index %u\n%s\n", vs, log); } glCompileShader (fs); glGetShaderiv (fs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { printf ("ERROR: GL shader index %i (post.frag) did not compile\n", fs); int max_length = 2048; int actual_length = 0; char log[2048]; glGetShaderInfoLog (fs, max_length, &actual_length, log); printf ("shader info log for GL index %u\n%s\n", vs, log); } post_sp = glCreateProgram (); glAttachShader (post_sp, fs); glAttachShader (post_sp, vs); glBindAttribLocation (post_sp, 0, "vp"); glLinkProgram (post_sp); glGetProgramiv (post_sp, GL_LINK_STATUS, ¶ms); if (GL_TRUE != params) { printf ("ERROR: could not link shader programme GL index %u\n", post_sp); int max_length = 2048; int actual_length = 0; char log[2048]; glGetProgramInfoLog (post_sp, max_length, &actual_length, log); printf ("program info log for GL index %u\n%s\n", post_sp, log); } } double a = 0.0f; double prev = glfwGetTime (); while (!glfwWindowShouldClose (window)) { if (multi_pass) { glBindFramebuffer (GL_FRAMEBUFFER, fb); } glViewport (0, 0, gl_width, gl_height); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, 0); double curr = glfwGetTime (); double elapsed = curr - prev; prev = curr; glUseProgram (shader_programme); glBindVertexArray (vao); a += elapsed * 50.0f; //float ang = (float)sin (a); M = rotate_y_deg (identity_mat4 (), a); glUniformMatrix4fv (M_loc, 1, GL_FALSE, M.m); glUniform1f (sm_loc, 1.0f); // smooth shaded or not (exception is flat-shaded, they might not be great // if non-cube anyway due to scaling) if (!multi_pass) { glFrontFace (GL_CW); glUniform1f (ol_loc, 1.0f); glDrawArrays (GL_TRIANGLES, 0, point_count); } glFrontFace (GL_CCW); glUniform1f (ol_loc, 0.0f); glDrawArrays (GL_TRIANGLES, 0, point_count); /* this just updates window events and keyboard input events (not used yet) */ if (multi_pass) { glFlush (); glFinish (); glBindFramebuffer (GL_FRAMEBUFFER, 0); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport (0, 0, gl_width, gl_height); glUseProgram (post_sp); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, d_tex); glBindVertexArray (quad_vao); glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); } glfwPollEvents (); glfwSwapBuffers (window); } return 0; }
int main () { assert (restart_gl_log ()); /*------------------------------start GL context------------------------------*/ assert (start_gl ()); /*------------------------------create geometry-------------------------------*/ GLfloat points[] = { 0.0f, 0.5f, 0.0f, 0.5f, -0.5f, 0.0f, -0.5f, -0.5f, 0.0f }; GLfloat colours[] = { 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f }; GLuint points_vbo; glGenBuffers (1, &points_vbo); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (GLfloat), points, GL_STATIC_DRAW); GLuint colours_vbo; glGenBuffers (1, &colours_vbo); glBindBuffer (GL_ARRAY_BUFFER, colours_vbo); glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (GLfloat), colours, GL_STATIC_DRAW); GLuint vao; glGenVertexArrays (1, &vao); glBindVertexArray (vao); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glBindBuffer (GL_ARRAY_BUFFER, colours_vbo); glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (0); glEnableVertexAttribArray (1); /*------------------------------create shaders--------------------------------*/ char vertex_shader[1024 * 256]; char fragment_shader[1024 * 256]; assert (parse_file_into_str ("Shaders/test_vs.glsl", vertex_shader, 1024 * 256)); assert (parse_file_into_str ("Shaders/test_fs.glsl", fragment_shader, 1024 * 256)); GLuint vs = glCreateShader (GL_VERTEX_SHADER); const GLchar* p = (const GLchar*)vertex_shader; glShaderSource (vs, 1, &p, NULL); glCompileShader (vs); // check for compile errors int params = -1; glGetShaderiv (vs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { fprintf (stderr, "ERROR: GL shader index %i did not compile\n", vs); print_shader_info_log (vs); return 1; // or exit or something } GLuint fs = glCreateShader (GL_FRAGMENT_SHADER); p = (const GLchar*)fragment_shader; glShaderSource (fs, 1, &p, NULL); glCompileShader (fs); // check for compile errors glGetShaderiv (fs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { fprintf (stderr, "ERROR: GL shader index %i did not compile\n", fs); print_shader_info_log (fs); return 1; // or exit or something } GLuint shader_programme = glCreateProgram (); glAttachShader (shader_programme, fs); glAttachShader (shader_programme, vs); glLinkProgram (shader_programme); glGetProgramiv (shader_programme, GL_LINK_STATUS, ¶ms); if (GL_TRUE != params) { fprintf ( stderr, "ERROR: could not link shader programme GL index %i\n", shader_programme ); print_programme_info_log (shader_programme); return false; } /*--------------------------create camera matrices----------------------------*/ /* create PROJECTION MATRIX */ #define ONE_DEG_IN_RAD (2.0 * M_PI) / 360.0 // 0.017444444 // input variables float near = 0.1f; // clipping plane float far = 100.0f; // clipping plane float fov = 67.0f * ONE_DEG_IN_RAD; // convert 67 degrees to radians float aspect = (float)g_gl_width / (float)g_gl_height; // aspect ratio // matrix components float range = tan (fov * 0.5f) * near; float Sx = (2.0f * near) / (range * aspect + range * aspect); float Sy = near / range; float Sz = -(far + near) / (far - near); float Pz = -(2.0f * far * near) / (far - near); GLfloat proj_mat[] = { Sx, 0.0f, 0.0f, 0.0f, 0.0f, Sy, 0.0f, 0.0f, 0.0f, 0.0f, Sz, -1.0f, 0.0f, 0.0f, Pz, 0.0f }; /* create VIEW MATRIX */ float cam_speed = 1.0f; // 1 unit per second float cam_yaw_speed = 10.0f; // 10 degrees per second float cam_pos[] = {0.0f, 0.0f, 2.0f}; // don't start at zero, or we will be too close float cam_yaw = 0.0f; // y-rotation in degrees mat4 T = translate (identity_mat4 (), vec3 (-cam_pos[0], -cam_pos[1], -cam_pos[2])); mat4 R = rotate_y_deg (identity_mat4 (), -cam_yaw); mat4 view_mat = R * T; /* get location numbers of matrices in shader programme */ GLint view_mat_location = glGetUniformLocation (shader_programme, "view"); GLint proj_mat_location = glGetUniformLocation (shader_programme, "proj"); /* use program (make current in state machine) and set default matrix values*/ glUseProgram (shader_programme); glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, view_mat.m); glUniformMatrix4fv (proj_mat_location, 1, GL_FALSE, proj_mat); /*------------------------------rendering loop--------------------------------*/ /* some rendering defaults */ glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CW); // GL_CCW for counter clock-wise while (!glfwWindowShouldClose (g_window)) { static double previous_seconds = glfwGetTime (); double current_seconds = glfwGetTime (); double elapsed_seconds = current_seconds - previous_seconds; previous_seconds = current_seconds; _update_fps_counter (g_window); // wipe the drawing surface clear glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport (0, 0, g_gl_width, g_gl_height); glUseProgram (shader_programme); glBindVertexArray (vao); // draw points 0-3 from the currently bound VAO with current in-use shader glDrawArrays (GL_TRIANGLES, 0, 3); // update other events like input handling glfwPollEvents (); /*-----------------------------move camera here-------------------------------*/ // control keys bool cam_moved = false; if (glfwGetKey (g_window, GLFW_KEY_A)) { cam_pos[0] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_D)) { cam_pos[0] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_PAGE_UP)) { cam_pos[1] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_PAGE_DOWN)) { cam_pos[1] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_W)) { cam_pos[2] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_S)) { cam_pos[2] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_LEFT)) { cam_yaw += cam_yaw_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_RIGHT)) { cam_yaw -= cam_yaw_speed * elapsed_seconds; cam_moved = true; } /* update view matrix */ if (cam_moved) { mat4 T = translate (identity_mat4 (), vec3 (-cam_pos[0], -cam_pos[1], -cam_pos[2])); // cam translation mat4 R = rotate_y_deg (identity_mat4 (), -cam_yaw); // mat4 view_mat = R * T; glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, view_mat.m); } if (GLFW_PRESS == glfwGetKey (g_window, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (g_window, 1); } // put the stuff we've been drawing onto the display glfwSwapBuffers (g_window); } // close GL context and any other GLFW resources glfwTerminate(); return 0; }
int main () { /*--------------------------------START OPENGL--------------------------------*/ assert (restart_gl_log ()); // start GL context and O/S window using the GLFW helper library assert (start_gl ()); // set a function to be called when the mouse is clicked glfwSetMouseButtonCallback (g_window, glfw_mouse_click_callback); /*------------------------------CREATE GEOMETRY-------------------------------*/ GLfloat* vp = NULL; // array of vertex points GLfloat* vn = NULL; // array of vertex normals GLfloat* vt = NULL; // array of texture coordinates int g_point_count = 0; assert (load_obj_file (MESH_FILE, vp, vt, vn, g_point_count)); GLuint vao; glGenVertexArrays (1, &vao); glBindVertexArray (vao); GLuint points_vbo; if (NULL != vp) { glGenBuffers (1, &points_vbo); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glBufferData ( GL_ARRAY_BUFFER, 3 * g_point_count * sizeof (GLfloat), vp, GL_STATIC_DRAW ); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (0); } /*-------------------------------CREATE SHADERS-------------------------------*/ GLuint shader_programme = create_programme_from_files ( VERTEX_SHADER_FILE, FRAGMENT_SHADER_FILE ); int model_mat_location = glGetUniformLocation (shader_programme, "model"); int view_mat_location = glGetUniformLocation (shader_programme, "view"); int proj_mat_location = glGetUniformLocation (shader_programme, "proj"); int blue_location = glGetUniformLocation (shader_programme, "blue"); /*-------------------------------CREATE CAMERA--------------------------------*/ #define ONE_DEG_IN_RAD (2.0 * M_PI) / 360.0 // 0.017444444 // input variables float near = 0.1f; // clipping plane float far = 100.0f; // clipping plane float fovy = 67.0f; // 67 degrees float aspect = (float)g_gl_width / (float)g_gl_height; // aspect ratio proj_mat = perspective (fovy, aspect, near, far); float cam_speed = 3.0f; // 1 unit per second float cam_heading_speed = 50.0f; // 30 degrees per second float cam_heading = 0.0f; // y-rotation in degrees mat4 T = translate ( identity_mat4 (), vec3 (-cam_pos.v[0], -cam_pos.v[1], -cam_pos.v[2]) ); mat4 R = rotate_y_deg (identity_mat4 (), -cam_heading); versor q = quat_from_axis_deg (-cam_heading, 0.0f, 1.0f, 0.0f); view_mat = R * T; // keep track of some useful vectors that can be used for keyboard movement vec4 fwd (0.0f, 0.0f, -1.0f, 0.0f); vec4 rgt (1.0f, 0.0f, 0.0f, 0.0f); vec4 up (0.0f, 1.0f, 0.0f, 0.0f); /*---------------------------SET RENDERING DEFAULTS---------------------------*/ glUseProgram (shader_programme); glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, view_mat.m); glUniformMatrix4fv (proj_mat_location, 1, GL_FALSE, proj_mat.m); // unique model matrix for each sphere mat4 model_mats[NUM_SPHERES]; for (int i = 0; i < NUM_SPHERES; i++) { model_mats[i] = translate (identity_mat4 (), sphere_pos_wor[i]); } glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CCW); // set counter-clock-wise vertex order to mean the front glClearColor (0.2, 0.2, 0.2, 1.0); // grey background to help spot mistakes glViewport (0, 0, g_gl_width, g_gl_height); /*-------------------------------RENDERING LOOP-------------------------------*/ while (!glfwWindowShouldClose (g_window)) { // update timers static double previous_seconds = glfwGetTime (); double current_seconds = glfwGetTime (); double elapsed_seconds = current_seconds - previous_seconds; previous_seconds = current_seconds; _update_fps_counter (g_window); // wipe the drawing surface clear glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram (shader_programme); glBindVertexArray (vao); for (int i = 0; i < NUM_SPHERES; i++) { if (g_selected_sphere == i) { glUniform1f (blue_location, 1.0f); } else { glUniform1f (blue_location, 0.0f); } glUniformMatrix4fv (model_mat_location, 1, GL_FALSE, model_mats[i].m); glDrawArrays (GL_TRIANGLES, 0, g_point_count); } // update other events like input handling glfwPollEvents (); // control keys bool cam_moved = false; vec3 move (0.0, 0.0, 0.0); float cam_yaw = 0.0f; // y-rotation in degrees float cam_pitch = 0.0f; float cam_roll = 0.0; if (glfwGetKey (g_window, GLFW_KEY_A)) { move.v[0] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_D)) { move.v[0] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_Q)) { move.v[1] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_E)) { move.v[1] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_W)) { move.v[2] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_S)) { move.v[2] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_LEFT)) { cam_yaw += cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_yaw = quat_from_axis_deg ( cam_yaw, up.v[0], up.v[1], up.v[2] ); q = q_yaw * q; } if (glfwGetKey (g_window, GLFW_KEY_RIGHT)) { cam_yaw -= cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_yaw = quat_from_axis_deg ( cam_yaw, up.v[0], up.v[1], up.v[2] ); q = q_yaw * q; } if (glfwGetKey (g_window, GLFW_KEY_UP)) { cam_pitch += cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_pitch = quat_from_axis_deg ( cam_pitch, rgt.v[0], rgt.v[1], rgt.v[2] ); q = q_pitch * q; } if (glfwGetKey (g_window, GLFW_KEY_DOWN)) { cam_pitch -= cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_pitch = quat_from_axis_deg ( cam_pitch, rgt.v[0], rgt.v[1], rgt.v[2] ); q = q_pitch * q; } if (glfwGetKey (g_window, GLFW_KEY_Z)) { cam_roll -= cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_roll = quat_from_axis_deg ( cam_roll, fwd.v[0], fwd.v[1], fwd.v[2] ); q = q_roll * q; } if (glfwGetKey (g_window, GLFW_KEY_C)) { cam_roll += cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_roll = quat_from_axis_deg ( cam_roll, fwd.v[0], fwd.v[1], fwd.v[2] ); q = q_roll * q; } // update view matrix if (cam_moved) { // re-calculate local axes so can move fwd in dir cam is pointing R = quat_to_mat4 (q); fwd = R * vec4 (0.0, 0.0, -1.0, 0.0); rgt = R * vec4 (1.0, 0.0, 0.0, 0.0); up = R * vec4 (0.0, 1.0, 0.0, 0.0); cam_pos = cam_pos + vec3 (fwd) * -move.v[2]; cam_pos = cam_pos + vec3 (up) * move.v[1]; cam_pos = cam_pos + vec3 (rgt) * move.v[0]; mat4 T = translate (identity_mat4 (), vec3 (cam_pos)); view_mat = inverse (R) * inverse (T); glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, view_mat.m); } if (GLFW_PRESS == glfwGetKey (g_window, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (g_window, 1); } // put the stuff we've been drawing onto the display glfwSwapBuffers (g_window); } // close GL context and any other GLFW resources glfwTerminate(); return 0; }