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 () { 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; }
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; }