void initializeOpenGL() { 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); }
int main () { double prev_time = 0.0; double accum_sim_time = 0.0; if (!start_gl (800, 800)) { fprintf (stderr, "ERROR: could not start opengl\n"); return 1; } init_cam (); init_terrain (); init_dash (); glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LESS); glClearColor (0.0, 0.5, 0.5, 1.0); prev_time = glfwGetTime (); while (!glfwWindowShouldClose (gl_window)) { // work out how much time has passed double curr_time = glfwGetTime (); double elapsed = curr_time - prev_time; prev_time = curr_time; accum_sim_time += elapsed; // work out simulation time steps while (accum_sim_time > TIME_STEP_SIZE) { accum_sim_time -= TIME_STEP_SIZE; update_player (TIME_STEP_SIZE); } glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport (0, 0, gl_width, gl_height); draw_terrain (); // i dont want the dashboard to ever intersect with background so // i do a clear of the depth buffer glClear (GL_DEPTH_BUFFER_BIT); draw_dash (); // can expect everything has updated camera matrices by now cam_P_dirty = false; cam_V_dirty = false; glfwPollEvents (); glfwSwapBuffers (gl_window); } return 0; }
int main () { assert (restart_gl_log ()); // all the start-up code for GLFW and GLEW is called here assert (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.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 }; glm::mat4 mvp = glm::mat4(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); glBufferData (GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data) * sizeof (GLfloat), g_vertex_buffer_data, GL_STATIC_DRAW); /* create a second VBO, containing the array of colours. note that we could also put them both into a single vertex buffer. in this case we would use the pointer and stride parameters of glVertexAttribPointer() to describe the different data layouts */ GLuint colours_vbo; glGenBuffers (1, &colours_vbo); glBindBuffer (GL_ARRAY_BUFFER, colours_vbo); // glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (GLfloat), colours, GL_STATIC_DRAW); glBufferData (GL_ARRAY_BUFFER, sizeof(g_color_buffer_data) * sizeof (GLfloat), g_color_buffer_data, GL_STATIC_DRAW); /* create the VAO. we bind each VBO in turn, and call glVertexAttribPointer() to indicate where the memory should be fetched for vertex shader input variables 0, and 1, respectively. we also have to explicitly enable both 'attribute' variables. 'attribute' is the older name for vertex shader 'in' variables. */ 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); char vertex_shader[1024 * 256]; char fragment_shader[1024 * 256]; assert (parse_file_into_str ("test_vs.glsl", vertex_shader, 1024 * 256)); assert (parse_file_into_str ("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); glBindAttribLocation(shader_programme, 0, "vertex_position"); glBindAttribLocation(shader_programme, 1, "vertex_colour"); 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; } //pass uniform GLint u = glGetUniformLocation(shader_programme, "mvp"); assert (u > -1); glUniformMatrix4fv(u, 1, GL_FALSE, &mvp[0][0]); 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)) { _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, 12* 3); // update other events like input handling glfwPollEvents (); 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; }
// The MAIN function, from here we start the application and run the game loop int main() { //////////////////////////////////////// BULLET /////////////////////////////////////////////////////////////////////////////////////////////////////////// // create the world parameters btBroadphaseInterface * broadphase = new btDbvtBroadphase(); btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration(); btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration); btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver; btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration); dynamicsWorld->setGravity(btVector3(0., GRAVITY, 0)); // Set up the sides btRigidBody* sides [6]; sides[0] = makeSide(dynamicsWorld, btVector3(0, 1, 0), btVector3(0, 0, 0)); sides[1] = makeSide(dynamicsWorld, btVector3(1, 0, 0), btVector3(-20, 0, 0)); sides[2] = makeSide(dynamicsWorld, btVector3(-1, 0, 0), btVector3(20, 0, 0)); sides[3] = makeSide(dynamicsWorld, btVector3(0, -1, 0), btVector3(0, 40, 0)); sides[4] = makeSide(dynamicsWorld, btVector3(0, 0, -1), btVector3(0, 0, 20)); sides[5] = makeSide(dynamicsWorld, btVector3(0, 0, 1), btVector3(0, 0, -20)); btRigidBody* sphere1 = makeSphere(dynamicsWorld, 1, 1, btVector3(0, 40, 0)); btRigidBody* sphere2 = makeSphere(dynamicsWorld, 1, 1, btVector3(0, 40, 0)); btRigidBody* cube = makeSphere(dynamicsWorld, 1, 1, btVector3(0, 35, 0)); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // start glfw and glew with default settings bool test = start_gl(); assert(test); // Build and compile our shader program Shader sphereShader("shaders/shader.vs", "shaders/shader.frag"); Shader cubeShader("shaders/shader.vs", "shaders/lamp.frag"); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// GLuint container_VAO, container_VBO, container_EBO; GLfloat verts[] = { -0.5f, -0.5f, 0.5f, // A 0 -0.5f, -0.5f, -0.5f, // B 1 0.5f, -0.5f, -0.5f, // C 2 0.5f, -0.5f, 0.5f, // D 3 -0.5f, 0.5f, 0.5f, // E 4 -0.5f, 0.5f, -0.5f, // F 5 0.5f, 0.5f, -0.5f, // G 6 0.5f, 0.5f, 0.5f // H 7 }; GLuint idx[] = { 0, 1, 2, 3, 0, 4, 7, 3, 2, 6, 7, 6, 5, 4, 5, 1, 0, }; std::vector<GLfloat> container_verts = std::vector<GLfloat>(verts, verts + sizeof verts / sizeof verts[0]); std::vector<GLint> container_idx = std::vector<GLint>(idx, idx + sizeof idx / sizeof idx[0]); /////// Sphere vertices, normals and indices generation ////////////////////////////////////////// std::vector<GLfloat> sphere_verts; std::vector<GLint> sphere_idx; generateSphere( &sphere_verts, &sphere_idx, stacks, slices, radius); ///////////////// DECLARATIONS //////////////////////// GLuint sphere_VBO, sphere_VAO, sphere_EBO; ///////////////// GET VAO READY //////////////////////// GLuint aLoc[3] = {0, 1, 2}; GLint size[3] = {3, 3, 2}; GLsizei vStride[3] = {8 * sizeof(GLfloat), 8 * sizeof(GLfloat), 8 * sizeof(GLfloat)}; const void* vOffset[3] = {(GLvoid*)0, (GLvoid*)(3 * sizeof(GLfloat)), (GLvoid*)(6 * sizeof(GLfloat))}; prepareVAO(&sphere_VAO, &sphere_VBO, &sphere_EBO, sphere_verts, sphere_idx, 2, aLoc, size, vStride, vOffset); aLoc[0] = 0; size[0] = 3; vStride[0] = 3 * sizeof(GLfloat); vOffset[0] = (GLvoid*)0; prepareVAO(&container_VAO, &container_VBO, &container_EBO, container_verts, container_idx, 1, aLoc, size, vStride, vOffset); ///////////////// The positions for the spheres in q4 //////////////////////// // where the cubes will appear in the world space glm::vec3 cubePositions[] = { glm::vec3(1.5f, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f) }; ///////////////// Uniform variables for MVP in VS //////////////////////// GLint modelLoc = glGetUniformLocation(sphereShader.Program, "model"); GLint viewLoc = glGetUniformLocation(sphereShader.Program, "view"); GLint projLoc = glGetUniformLocation(sphereShader.Program, "projection"); // uniforms for lighting GLint objectColorLoc = glGetUniformLocation(sphereShader.Program, "objectColor"); GLint lightColorLoc = glGetUniformLocation(sphereShader.Program, "lightColor"); GLint lightPosLoc = glGetUniformLocation(sphereShader.Program, "lightPos"); GLint viewPosLoc = glGetUniformLocation(sphereShader.Program, "viewPos"); ofstream myfile; myfile.open ("velocity.log"); btTransform trans; // Main loop while (!glfwWindowShouldClose(window)) { GLfloat currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; // Check if any events have been activated (key pressed, mouse moved) glfwPollEvents(); do_movement(); // Clear the color buffer glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); drawSphere(&cubeShader, &container_VAO, &sphereShader, &sphere_VAO, (GLint)sphere_idx.size(), 17, &objectColorLoc, &lightColorLoc, &lightPosLoc, &viewPosLoc, 2, cubePositions, &modelLoc, &viewLoc, &projLoc, dynamicsWorld, sphere1, sphere2, cube); sphere1->getMotionState()->getWorldTransform(trans); myfile << trans.getOrigin().getX() << " " << trans.getOrigin().getY() << " " << trans.getOrigin().getZ() << ":"; sphere2->getMotionState()->getWorldTransform(trans); myfile << trans.getOrigin().getX() << " " << trans.getOrigin().getY() << " " << trans.getOrigin().getZ() << ":"; cube->getMotionState()->getWorldTransform(trans); myfile << trans.getOrigin().getX() << " " << trans.getOrigin().getY() << " " << trans.getOrigin().getZ() << "\n"; // Swap the screen buffers glfwSwapBuffers(window); } // Deallocate glDeleteVertexArrays(1, &sphere_VAO); glDeleteBuffers(1, &sphere_VBO); glDeleteBuffers(1, &sphere_EBO); // Terminate GLFW glfwDestroyWindow(window); glfwTerminate(); myfile.close(); for(int i=0; i<6; i++){ dynamicsWorld->removeRigidBody(sides[i]); delete sides[i]->getMotionState(); delete sides[i]; } delete dynamicsWorld; delete solver; delete dispatcher; delete collisionConfiguration; delete broadphase; return EXIT_SUCCESS; }
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 () { assert (restart_gl_log ()); assert (start_gl ()); /* set up framebuffer with texture attachment */ assert (init_fb ()); /* load the picking shaders */ g_pick_sp = create_programme_from_files (PICK_VS, PICK_FS); g_pick_unique_id_loc = glGetUniformLocation (g_pick_sp, "unique_id"); g_pick_P_loc = glGetUniformLocation (g_pick_sp, "P"); g_pick_V_loc = glGetUniformLocation (g_pick_sp, "V"); g_pick_M_loc = glGetUniformLocation (g_pick_sp, "M"); assert (g_pick_P_loc > -1); assert (g_pick_V_loc > -1); assert (g_pick_M_loc > -1); /* load a mesh to draw in the main scene */ load_sphere (); GLuint sphere_sp = create_programme_from_files (SPHERE_VS, SPHERE_FS); GLint sphere_P_loc = glGetUniformLocation (sphere_sp, "P"); GLint sphere_V_loc = glGetUniformLocation (sphere_sp, "V"); GLint sphere_M_loc = glGetUniformLocation (sphere_sp, "M"); assert (sphere_P_loc > -1); assert (sphere_V_loc > -1); assert (sphere_M_loc > -1); /* set up view and projection matrices for sphere shader */ mat4 P = perspective ( 67.0f, (float)g_gl_width / (float)g_gl_height, 0.1f, 100.0f); mat4 V = look_at ( vec3 (0.0f, 0.0f, 5.0f), vec3 (0.0f, 0.0f, 0.0f), vec3 (0.0f, 1.0f, 0.0f)); glUseProgram (sphere_sp); glUniformMatrix4fv (sphere_P_loc, 1, GL_FALSE, P.m); glUniformMatrix4fv (sphere_V_loc, 1, GL_FALSE, V.m); glViewport (0, 0, g_gl_width, g_gl_height); while (!glfwWindowShouldClose (g_window)) { _update_fps_counter (g_window); /* bind the 'render to a texture' framebuffer for main scene */ glBindFramebuffer (GL_FRAMEBUFFER, 0); /* clear the framebuffer's colour and depth buffers */ glClearColor (0.2, 0.2, 0.2, 1.0); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // render an obj or something glUseProgram (sphere_sp); glBindVertexArray (g_sphere_vao); // model matrices for all 3 spheres mat4 Ms[3]; // first sphere Ms[0] = identity_mat4 (); glUniformMatrix4fv (sphere_M_loc, 1, GL_FALSE, Ms[0].m); glDrawArrays (GL_TRIANGLES, 0, g_sphere_point_count); // 2nd sphere Ms[1] = translate (identity_mat4 (), vec3 (1.0, -1.0, -4.0)); glUniformMatrix4fv (sphere_M_loc, 1, GL_FALSE, Ms[1].m); glDrawArrays (GL_TRIANGLES, 0, g_sphere_point_count); // 3rd sphere Ms[2] = translate (identity_mat4 (), vec3 (-0.50, 2.0, -2.0)); glUniformMatrix4fv (sphere_M_loc, 1, GL_FALSE, Ms[2].m); glDrawArrays (GL_TRIANGLES, 0, g_sphere_point_count); /* bind framebuffer for pick */ draw_picker_colours (P, V, Ms); // flip drawn framebuffer onto the display glfwSwapBuffers (g_window); glfwPollEvents (); if (GLFW_PRESS == glfwGetKey (g_window, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (g_window, 1); } debug_colours = glfwGetKey (g_window, GLFW_KEY_SPACE); if (glfwGetMouseButton (g_window, 0)) { glBindFramebuffer (GL_FRAMEBUFFER, g_fb); double xpos, ypos; glfwGetCursorPos (g_window, &xpos, &ypos); int mx = (int)xpos; int my = (int)ypos; unsigned char data[4] = {0, 0, 0, 0}; glReadPixels ( mx, g_gl_height - my, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &data); int id = decode_id ((int)data[0], (int)data[1], (int)data[2]); int mid = -1; if (id == 255) { mid = 0; } if (id == 65280) { mid = 1; } if (id == 16711680) { mid = 2; } printf ("%i,%i,%i means -> id was %i, and monkey number is %i\n", data[0], data[1], data[2], id, mid); glBindFramebuffer (GL_FRAMEBUFFER, 0); } } 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 ()); /* set up framebuffer with texture attachment */ assert (init_fb ()); init_ss_quad (); /* load the post-processing effect shaders */ GLuint post_sp = create_programme_from_files (POST_VS, POST_FS); /* load a mesh to draw in the main scene */ load_sphere (); GLuint sphere_sp = create_programme_from_files (SPHERE_VS, SPHERE_FS); GLint sphere_P_loc = glGetUniformLocation (sphere_sp, "P"); GLint sphere_V_loc = glGetUniformLocation (sphere_sp, "V"); assert (sphere_P_loc > -1); assert (sphere_V_loc > -1); /* set up view and projection matrices for sphere shader */ mat4 P = perspective ( 67.0f, (float)g_gl_width / (float)g_gl_height, 0.1f, 100.0f); mat4 V = look_at ( vec3 (0.0f, 0.0f, 5.0f), vec3 (0.0f, 0.0f, 0.0f), vec3 (0.0f, 1.0f, 0.0f)); glUseProgram (sphere_sp); glUniformMatrix4fv (sphere_P_loc, 1, GL_FALSE, P.m); glUniformMatrix4fv (sphere_V_loc, 1, GL_FALSE, V.m); glViewport (0, 0, g_gl_width, g_gl_height); while (!glfwWindowShouldClose (g_window)) { _update_fps_counter (g_window); /* bind the 'render to a texture' framebuffer for main scene */ glFlush (); glFinish (); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, 0); glBindFramebuffer (GL_FRAMEBUFFER, g_fb); /* clear the framebuffer's colour and depth buffers */ glClearColor (0.2, 0.2, 0.2, 1.0); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // render an obj or something glUseProgram (sphere_sp); glBindVertexArray (g_sphere_vao); glDrawArrays (GL_TRIANGLES, 0, g_sphere_point_count); /* bind default framebuffer for post-processing effects. sample texture from previous pass */ glFlush (); glFinish (); glBindFramebuffer (GL_FRAMEBUFFER, 0); // clear the framebuffer's colour and depth buffers // glClearColor (0.0, 0.0, 0.0, 1.0); // glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // use our post-processing shader for the screen-space quad glUseProgram (post_sp); // bind the quad's VAO glBindVertexArray (g_ss_quad_vao); // activate the first texture slot and put texture from previous pass in it glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, g_fb_tex); // draw the quad that covers the screen area glDrawArrays (GL_TRIANGLES, 0, 6); // flip drawn framebuffer onto the display glfwSwapBuffers (g_window); glfwPollEvents (); if (GLFW_PRESS == glfwGetKey (g_window, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (g_window, 1); } } return 0; }
// The MAIN function, from here we start the application and run the game loop int main() { // start glfw and glew with default settings assert(start_gl()); // Build and compile our shader program Shader sphereShader("shaders/shader.vs", "shaders/shader.frag"); Shader lampShader("shaders/shader.vs", "shaders/lamp.frag"); /////// Sphere vertices, normals and indices generation ////////////////////////////////////////// std::vector<GLfloat> sphere_verts, q2Verts, cone_verts; std::vector<GLint> sphere_idx; generateCone(&cone_verts, stacks, slices); generateSphere( &sphere_verts, &q2Verts, &sphere_idx, stacks, slices, radius); std::vector<GLint> cone_idx(sphere_idx); ///////////////// DECLARATIONS //////////////////////// GLuint sphere_VBO, sphere_VAO, sphere_EBO, normal_VAO, normal_VBO, cone_VAO, cone_VBO, cone_EBO; ///////////////// GET VAO READY FOR CONE //////////////////////////////////////////////////////// GLuint aLoc[3] = {0}; GLint size[3] = {3}; GLsizei vStride[3] = {3 * sizeof(GLfloat)}; const void* vOffset[3] = {(GLvoid*)0}; prepareVAO(&cone_VAO, &cone_VBO, &cone_EBO, cone_verts, cone_idx, 1, aLoc, size, vStride, vOffset); ///////////////// GET VAO READY FOR SPHERE ////////////////////////////////////////////////////// aLoc[0] = 0; aLoc[1] = 1; aLoc[2] = 2; size[0] = size[1] = 3; size[2] = 2; vStride[0] = vStride[1] = vStride[2] = 8 * sizeof(GLfloat); vOffset[0] = (GLvoid*)0; vOffset[1] = (GLvoid*)(3 * sizeof(GLfloat)); vOffset[2] = (GLvoid*)(6 * sizeof(GLfloat)); prepareVAO(&sphere_VAO, &sphere_VBO, &sphere_EBO, sphere_verts, sphere_idx, 3, aLoc, size, vStride, vOffset); ///////////////// GET VAO READY FOR NORMALS (Q2) //////////////////////////////////////////////// aLoc[0] = 0; size[0] = 3; vStride[0] = 3 * sizeof(GLfloat); vOffset[0] = (GLvoid*)0; prepareVAO(&normal_VAO, &normal_VBO, nullptr, q2Verts, std::vector<GLint>() , 1, aLoc, size, vStride, vOffset); ///////////////// GET Textures ready //////////////////////////////////////////////////////////// GLuint texture1; int width, height, comp; prepareTexture(&texture1, "images/earth.jpg", &width, &height, &comp); ///////////////// The positions for the spheres in q4 //////////////////////////////////////////// // where the cubes will appear in the world space glm::vec3 cubePositions[] = { glm::vec3(1.5f, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f) }; ///////////////// Uniform variables for MVP in VS ///////////////////////////////////////////////// GLint modelLoc = glGetUniformLocation(sphereShader.Program, "model"); GLint viewLoc = glGetUniformLocation(sphereShader.Program, "view"); GLint projLoc = glGetUniformLocation(sphereShader.Program, "projection"); // The question number to switch GLint q = glGetUniformLocation(sphereShader.Program, "q"); // uniforms for lighting GLint objectColorLoc = glGetUniformLocation(sphereShader.Program, "objectColor"); GLint lightColorLoc = glGetUniformLocation(sphereShader.Program, "lightColor"); GLint lightPosLoc = glGetUniformLocation(sphereShader.Program, "lightPos"); GLint viewPosLoc = glGetUniformLocation(sphereShader.Program, "viewPos"); // Main loop while (!glfwWindowShouldClose(window)) { GLfloat currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; // Check if any events have been activated (key pressed, mouse moved) glfwPollEvents(); do_movement(); // Clear the color buffer glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); lightPos.x = sin(glfwGetTime()) * 0.1; lightPos.y = cos(glfwGetTime()) * 0.1; drawSphere(&sphereShader, &sphere_VAO, &sphere_idx, &normal_VAO, &sphere_verts, &cone_VAO, &cone_verts, &cone_idx, &lampShader, &objectColorLoc, &lightColorLoc, &lightPosLoc, &viewPosLoc, &q, &texture1, 2, cubePositions, &modelLoc, &viewLoc, &projLoc); // Swap the screen buffers glfwSwapBuffers(window); } // Deallocate glDeleteVertexArrays(1, &sphere_VAO); glDeleteBuffers(1, &sphere_VBO); glDeleteBuffers(1, &sphere_EBO); glDeleteVertexArrays(1, &normal_VAO); glDeleteVertexArrays(1, &normal_VBO); glDeleteVertexArrays(1, &cone_VAO); glDeleteBuffers(1, &cone_VBO); glDeleteBuffers(1, &cone_EBO); // Terminate GLFW glfwDestroyWindow(window); glfwTerminate(); return EXIT_SUCCESS; }
int main(){ assert(restart_gl_log()); assert(start_gl()); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); 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 vao; char vertex_shader[1024 * 256]; char fragmet_shader[1024 * 256]; GLuint vs, fs, shader_programme; const GLchar* p; int params = -1; GLuint points_vbo; GLuint colours_vbo; glGenBuffers(1, &points_vbo); glBindBuffer(GL_ARRAY_BUFFER, points_vbo); glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), points, GL_STATIC_DRAW); /* create a second VBO, containing the array of colours. note that we could also put them both into a single vertex buffer. in this case we would use the pointer and stride parameters of glVertexAttribPointer() to describe the different data layouts */ glGenBuffers(1, &colours_vbo); glBindBuffer(GL_ARRAY_BUFFER, colours_vbo); glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), colours, GL_STATIC_DRAW); /* create the VAO. we bind each VBO in turn, and call glVertexAttribPointer() to indicate where the memory should be fetched for vertex shader input variables 0, and 1, respectively. we also have to explicitly enable both 'attribute' variables. 'attribute' is the older name for vertex shader 'in' variables. */ 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); // Load shaders from files here assert(parse_file_into_str("test_vs.glsl", vertex_shader, 1024*256)); assert(parse_file_into_str("test_fs.glsl", fragmet_shader, 1024*256)); vs = glCreateShader(GL_VERTEX_SHADER); p = (const GLchar*)vertex_shader; glShaderSource(vs, 1, &p, NULL); glCompileShader(vs); // Check for shader compile errors 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 */ } fs = glCreateShader(GL_FRAGMENT_SHADER); p = (const GLchar*)fragmet_shader; glShaderSource (fs, 1, &p, NULL); glCompileShader (fs); // Check for shader 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 */ } shader_programme = glCreateProgram(); glAttachShader(shader_programme, fs); glAttachShader(shader_programme, vs); glLinkProgram(shader_programme); /* check for shader linking errors - very important! */ 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 1; } 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)){ _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 events like input glfwPollEvents(); 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 () { GLfloat points[] = { 0.0f, 0.5f, 0.0f, 0.5f, -0.5f, 0.0f, -0.5f, -0.5f, 0.0f }; GLuint vbo; GLuint vao; char vertex_shader[1024 * 256]; char fragment_shader[1024 * 256]; GLuint vs, fs, shader_programme; const GLchar* p; int params = -1; GLint colour_loc; assert (restart_gl_log ()); assert (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" */ glGenBuffers (1, &vbo); glBindBuffer (GL_ARRAY_BUFFER, vbo); glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (GLfloat), points, GL_STATIC_DRAW); glGenVertexArrays (1, &vao); glBindVertexArray (vao); glEnableVertexAttribArray (0); glBindBuffer (GL_ARRAY_BUFFER, vbo); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); /* load shaders from files here */ assert (parse_file_into_str ("test_vs.glsl", vertex_shader, 1024 * 256)); assert (parse_file_into_str ("test_fs.glsl", fragment_shader, 1024 * 256)); vs = glCreateShader (GL_VERTEX_SHADER); p = (const GLchar*)vertex_shader; glShaderSource (vs, 1, &p, NULL); glCompileShader (vs); /* check for shader compile errors - very important! */ 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 */ } 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 */ } shader_programme = glCreateProgram (); glAttachShader (shader_programme, fs); glAttachShader (shader_programme, vs); glLinkProgram (shader_programme); /* check for shader linking errors - very important! */ 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 1; } print_all (shader_programme); assert (is_valid (shader_programme)); colour_loc = glGetUniformLocation (shader_programme, "inputColour"); assert (colour_loc > -1); glUseProgram (shader_programme); glUniform4f (colour_loc, 1.0f, 0.0f, 0.0f, 1.0f); while (!glfwWindowShouldClose (g_window)) { _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 (); 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 () { /* initialise GL context and window */ assert (restart_gl_log ()); assert (start_gl ()); /* initialise framebuffer and G-buffer */ assert (init_fb ()); /* load pre-pass shaders that write to the g-buffer */ g_first_pass_sp = create_programme_from_files ( FIRST_PASS_VS, FIRST_PASS_FS); g_first_pass_P_loc = glGetUniformLocation (g_first_pass_sp, "P"); g_first_pass_V_loc = glGetUniformLocation (g_first_pass_sp, "V"); g_first_pass_M_loc = glGetUniformLocation (g_first_pass_sp, "M"); /* load screen-space pass shaders that read from the g-buffer */ g_second_pass_sp = create_programme_from_files ( SECOND_PASS_VS, SECOND_PASS_FS); g_second_pass_P_loc = glGetUniformLocation (g_second_pass_sp, "P"); g_second_pass_V_loc = glGetUniformLocation (g_second_pass_sp, "V"); g_second_pass_M_loc = glGetUniformLocation (g_second_pass_sp, "M"); g_second_pass_L_p_loc = glGetUniformLocation (g_second_pass_sp, "lp"); g_second_pass_L_d_loc = glGetUniformLocation (g_second_pass_sp, "ld"); g_second_pass_L_s_loc = glGetUniformLocation (g_second_pass_sp, "ls"); g_second_pass_p_tex_loc = glGetUniformLocation (g_second_pass_sp, "p_tex"); g_second_pass_n_tex_loc = glGetUniformLocation (g_second_pass_sp, "n_tex"); glUseProgram (g_second_pass_sp); glUniform1i (g_second_pass_p_tex_loc, 0); glUniform1i (g_second_pass_n_tex_loc, 1); /* object positions and matrices */ assert (load_plane ()); g_plane_M = scale (identity_mat4 (), vec3 (200.0f, 1.0f, 200.0f)); g_plane_M = translate (g_plane_M, vec3 (0.0f, -2.0f, 0.0f)); /* load sphere mesh */ assert (load_sphere ()); /* light positions and matrices */ for (int i = 0; i < NUM_LIGHTS; i++) { float x = -sinf ((float)i * 0.5f) * 25.0f; // between +- 10 x float y = 2.0f; float z = (float)-i * 2.0f + 10.0; // 1 light every 2 meters away on z g_L_p[i] = vec3 (x, y, z); } float light_radius = 10.0f; int redi = 0; int bluei = 1; int greeni = 2; for (int i = 0; i < NUM_LIGHTS; i++) { g_L_M[i] = scale (identity_mat4 (), vec3 (light_radius, light_radius, light_radius)); g_L_M[i] = translate (g_L_M[i], g_L_p[i]); /* cycle different colours for each of the lights */ g_L_d[i] = vec3 ( (float)((redi + 1) / 3), (float)((greeni + 1) / 3), (float)((bluei + 1) / 3) ); g_L_s[i] = vec3 (1.0, 1.0, 1.0); redi = (redi + 1) % 3; bluei = (bluei + 1) % 3; greeni = (greeni + 1) % 3; } /* set up virtual camera */ float aspect = (float)g_gl_width / (float)g_gl_height; float near = 0.1f; float far = 1000.0f; float fovy = 67.0f; g_P = perspective (fovy, aspect, near, far); vec3 up (0.0f, 1.0f, 0.0f); vec3 targ_pos (0.0f, 0.0f, 0.0f); vec3 cam_pos (0.0f, 30.0f, 30.0f); g_V = look_at (cam_pos, targ_pos, up); glViewport (0, 0, g_gl_width, g_gl_height); 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)) { _update_fps_counter (g_window); draw_first_pass (); draw_second_pass (); glfwSwapBuffers (g_window); glfwPollEvents (); if (GLFW_PRESS == glfwGetKey (g_window, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (g_window, 1); } } /* close GL context and any other GLFW resources */ glfwTerminate(); return 0; }
int main () { assert (restart_gl_log ()); assert (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" glClearColor (0.2, 0.2, 0.2, 1.0); 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); char vertex_shader[1024 * 256]; char geometry_shader[1024 * 256]; char fragment_shader[1024 * 256]; assert (parse_file_into_str ("test_vs.glsl", vertex_shader, 1024 * 256)); assert (parse_file_into_str ("test_gs.glsl", geometry_shader, 1024 * 256)); assert (parse_file_into_str ("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 } // create geometry shader GLuint gs = glCreateShader (GL_GEOMETRY_SHADER); p = (const GLchar*)geometry_shader; glShaderSource (gs, 1, &p, NULL); glCompileShader (gs); // check for compile errors glGetShaderiv (gs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { fprintf (stderr, "ERROR: GL shader index %i did not compile\n", gs); print_shader_info_log (gs); 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); // attach geometry shader too glAttachShader (shader_programme, gs); 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; } assert (is_programme_valid (shader_programme)); 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)) { _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); // points drawing mode glDrawArrays (GL_POINTS, 0, 3); // update other events like input handling glfwPollEvents (); 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 () { 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; }
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 (); 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 () { 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 () { 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 () { restart_gl_log (); // all the GLFW and GLEW start-up code is moved to here in gl_utils.cpp 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.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); char vertex_shader[1024 * 256]; char fragment_shader[1024 * 256]; parse_file_into_str ("test_vs.glsl", vertex_shader, 1024 * 256); parse_file_into_str ("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; } GLfloat matrix[] = { 1.0f, 0.0f, 0.0f, 0.0f, // first column 0.0f, 1.0f, 0.0f, 0.0f, // second column 0.0f, 0.0f, 1.0f, 0.0f, // third column 0.5f, 0.0f, 0.0f, 1.0f // fourth column }; int matrix_location = glGetUniformLocation (shader_programme, "matrix"); glUseProgram (shader_programme); glUniformMatrix4fv (matrix_location, 1, GL_FALSE, matrix); glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CW); // GL_CCW for counter clock-wise float speed = 1.0f; // move at 1 unit per second float last_position = 0.0f; while (!glfwWindowShouldClose (g_window)) { // add a timer for doing animation 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); // // Note: this call is not necessary, but I like to do it anyway before any // time that I call glDrawArrays() so I never use the wrong shader programme glUseProgram (shader_programme); // update the matrix // - you could simplify this by just using sin(current_seconds) matrix[12] = elapsed_seconds * speed + last_position; last_position = matrix[12]; if (fabs (last_position) > 1.0) { speed = -speed; } // // Note: this call is related to the most recently 'used' shader programme glUniformMatrix4fv (matrix_location, 1, GL_FALSE, matrix); // // Note: this call is not necessary, but I like to do it anyway before any // time that I call glDrawArrays() so I never use the wrong vertex data 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 (); 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; }