int main () { GLFWwindow* window = NULL; const GLubyte* renderer; const GLubyte* version; GLuint shader_programme; GLuint vao; // // Start OpenGL using helper libraries // -------------------------------------------------------------------------- if (!glfwInit ()) { fprintf (stderr, "ERROR: could not start GLFW3\n"); return 1; } /* change to 3.2 if on Apple OS X glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 0); glfwWindowHint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); */ window = glfwCreateWindow (gl_width, gl_height, "Spinning Cube", NULL, NULL); if (!window) { fprintf (stderr, "ERROR: opening OS window\n"); return 1; } glfwMakeContextCurrent (window); glewExperimental = GL_TRUE; glewInit (); /* get version info */ renderer = glGetString (GL_RENDERER); /* get renderer string */ version = glGetString (GL_VERSION); /* version as a string */ printf ("Renderer: %s\n", renderer); printf ("OpenGL version supported %s\n", version); int point_count = 0; // // Set up vertex buffers and vertex array object // -------------------------------------------------------------------------- { GLfloat* vp = NULL; // array of vertex points GLfloat* vn = NULL; // array of vertex normals (we haven't used these yet) GLfloat* vt = NULL; // array of texture coordinates (or these) assert (load_obj_file ("cube.obj", vp, vt, vn, point_count)); GLuint points_vbo, texcoord_vbo; glGenBuffers (1, &points_vbo); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); // copy our points from the header file into our VBO on graphics hardware glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 3 * point_count, vp, GL_STATIC_DRAW); // and grab the normals glGenBuffers (1, &texcoord_vbo); glBindBuffer (GL_ARRAY_BUFFER, texcoord_vbo); glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 2 * point_count, vt, GL_STATIC_DRAW); glGenVertexArrays (1, &vao); glBindVertexArray (vao); glEnableVertexAttribArray (0); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (1); glBindBuffer (GL_ARRAY_BUFFER, texcoord_vbo); glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 0, NULL); free (vp); free (vn); free (vt); } // // Load shaders from files // -------------------------------------------------------------------------- { char* vertex_shader_str; char* fragment_shader_str; // allocate some memory to store shader strings vertex_shader_str = (char*)malloc (81920); fragment_shader_str = (char*)malloc (81920); // load shader strings from text files assert (parse_file_into_str ("teapot.vert", vertex_shader_str, 81920)); assert (parse_file_into_str ("teapot.frag", fragment_shader_str, 81920)); GLuint vs, fs; vs = glCreateShader (GL_VERTEX_SHADER); fs = glCreateShader (GL_FRAGMENT_SHADER); glShaderSource (vs, 1, (const char**)&vertex_shader_str, NULL); glShaderSource (fs, 1, (const char**)&fragment_shader_str, NULL); // free memory free (vertex_shader_str); free (fragment_shader_str); glCompileShader (vs); glCompileShader (fs); shader_programme = glCreateProgram (); glAttachShader (shader_programme, fs); glAttachShader (shader_programme, vs); glLinkProgram (shader_programme); /* TODO NOTE: you should check for errors and print logs after compiling and also linking shaders */ } // // Create some matrices // -------------------------------------------------------------------------- mat4 M, V, P; M = identity_mat4 ();//scale (identity_mat4 (), vec3 (0.05, 0.05, 0.05)); vec3 cam_pos (0.0, 0.0, 5.0); vec3 targ_pos (0.0, 0.0, 0.0); vec3 up (0.0, 1.0, 0.0); V = look_at (cam_pos, targ_pos, up); P = perspective (67.0f, (float)gl_width / (float)gl_height, 0.1, 1000.0); int M_loc = glGetUniformLocation (shader_programme, "M"); int V_loc = glGetUniformLocation (shader_programme, "V"); int P_loc = glGetUniformLocation (shader_programme, "P"); // send matrix values to shader immediately glUseProgram (shader_programme); glUniformMatrix4fv (M_loc, 1, GL_FALSE, M.m); glUniformMatrix4fv (V_loc, 1, GL_FALSE, V.m); glUniformMatrix4fv (P_loc, 1, GL_FALSE, P.m); int dt_pixel_c = 16 * 16; char* dt_data = (char*)malloc (4 * dt_pixel_c); if (!dt_data) { fprintf (stderr, "ERROR: out of memory. malloc default texture\n"); return 1; } for (int i = 0; i < dt_pixel_c * 4; i += 4) { int sq_ac = i / 16; if ((sq_ac / 2) * 2 == sq_ac) { dt_data[i] = 0; dt_data[i + 1] = 0; dt_data[i + 2] = 0; dt_data[i + 3] = (char)255; } else { dt_data[i] = (char)255; dt_data[i + 1] = 0; dt_data[i + 2] = (char)255; dt_data[i + 3] = (char)255; } int sq_dn = i / (16 * 16); if ((sq_dn / 2) * 2 == sq_dn) { dt_data[i] = (char)255 - dt_data[i]; dt_data[i + 2] = (char)255 - dt_data[i + 2]; } } GLuint tex; glGenTextures (1, &tex); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, tex); int x,y,n; unsigned char *data = stbi_load ("move_me.png", &x, &y, &n, 4); if (!data) { fprintf (stderr, "ERROR: could not load image 'move_me.png'. using default texture\n"); glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, dt_data ); } else { glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data ); stbi_image_free(data); data = NULL; printf ("loaded image with [%i,%i] res and %i chans\n", x, y, n); } glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); free (dt_data); dt_data = NULL; // */ // // Start rendering // -------------------------------------------------------------------------- // tell GL to only draw onto a pixel if the fragment is closer to the viewer glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" glClearColor (0.01, 0.01, 0.25, 1.0); float a = 0.0f; double prev = glfwGetTime (); while (!glfwWindowShouldClose (window)) { glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // just the default viewport, covering the whole render area glViewport (0, 0, gl_width, gl_height); double curr = glfwGetTime (); double elapsed = curr - prev; prev = curr; glUseProgram (shader_programme); glBindVertexArray (vao); a += sinf (elapsed * 50.0f); M = rotate_y_deg (identity_mat4 (), a); glUniformMatrix4fv (M_loc, 1, GL_FALSE, M.m); glDrawArrays (GL_TRIANGLES, 0, point_count); /* this just updates window events and keyboard input events (not used yet) */ glfwPollEvents (); glfwSwapBuffers (window); } return 0; }
int main () { GLFWwindow* window = NULL; const GLubyte* renderer; const GLubyte* version; GLuint shader_programme; GLuint vao; // // Start OpenGL using helper libraries // -------------------------------------------------------------------------- if (!glfwInit ()) { fprintf (stderr, "ERROR: could not start GLFW3\n"); return 1; } // change to 3.2 if on Apple OS X glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint (GLFW_SAMPLES, msaa); window = glfwCreateWindow (gl_width, gl_height, "Textured Mesh", NULL, NULL); if (!window) { fprintf (stderr, "ERROR: opening OS window\n"); return 1; } glfwMakeContextCurrent (window); glewExperimental = GL_TRUE; glewInit (); /* get version info */ renderer = glGetString (GL_RENDERER); /* get renderer string */ version = glGetString (GL_VERSION); /* version as a string */ printf ("Renderer: %s\n", renderer); printf ("OpenGL version supported %s\n", version); int point_count = 0; // // Set up vertex buffers and vertex array object // -------------------------------------------------------------------------- { GLfloat* vp = NULL; // array of vertex points GLfloat* vn = NULL; // array of vertex normals (we haven't used these yet) GLfloat* vt = NULL; // array of texture coordinates (or these) //assert (load_obj_file ("cube.obj", vp, vt, vn, point_count)); assert (load_obj_file ("monkey.obj", vp, vt, vn, point_count)); GLuint points_vbo, texcoord_vbo, normal_vbo; glGenBuffers (1, &points_vbo); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 3 * point_count, vp, GL_STATIC_DRAW); glGenBuffers (1, &texcoord_vbo); glBindBuffer (GL_ARRAY_BUFFER, texcoord_vbo); glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 2 * point_count, vt, GL_STATIC_DRAW); glGenBuffers (1, &normal_vbo); glBindBuffer (GL_ARRAY_BUFFER, normal_vbo); glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 3 * point_count, vn, GL_STATIC_DRAW); glGenVertexArrays (1, &vao); glBindVertexArray (vao); glEnableVertexAttribArray (0); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (1); glBindBuffer (GL_ARRAY_BUFFER, texcoord_vbo); glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (2); glBindBuffer (GL_ARRAY_BUFFER, normal_vbo); glVertexAttribPointer (2, 3, GL_FLOAT, GL_FALSE, 0, NULL); free (vp); free (vn); free (vt); } // // Load shaders from files // -------------------------------------------------------------------------- { char* vertex_shader_str; char* fragment_shader_str; // allocate some memory to store shader strings vertex_shader_str = (char*)malloc (81920); fragment_shader_str = (char*)malloc (81920); // load shader strings from text files assert (parse_file_into_str ("teapot.vert", vertex_shader_str, 81920)); assert (parse_file_into_str ("teapot.frag", fragment_shader_str, 81920)); GLuint vs, fs; vs = glCreateShader (GL_VERTEX_SHADER); fs = glCreateShader (GL_FRAGMENT_SHADER); glShaderSource (vs, 1, (const char**)&vertex_shader_str, NULL); glShaderSource (fs, 1, (const char**)&fragment_shader_str, NULL); // free memory free (vertex_shader_str); free (fragment_shader_str); int params = -1; glCompileShader (vs); glGetShaderiv (vs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { printf ("ERROR: GL shader index %i (teapot.vert) did not compile\n", vs); int max_length = 2048; int actual_length = 0; char log[2048]; glGetShaderInfoLog (vs, max_length, &actual_length, log); printf ("shader info log for GL index %u\n%s\n", vs, log); } glCompileShader (fs); glGetShaderiv (fs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { printf ("ERROR: GL shader index %i (teapot.frag) did not compile\n", fs); int max_length = 2048; int actual_length = 0; char log[2048]; glGetShaderInfoLog (fs, max_length, &actual_length, log); printf ("shader info log for GL index %u\n%s\n", vs, log); } shader_programme = glCreateProgram (); glAttachShader (shader_programme, fs); glAttachShader (shader_programme, vs); glBindAttribLocation (shader_programme, 0, "vp"); glBindAttribLocation (shader_programme, 1, "vt"); glBindAttribLocation (shader_programme, 2, "vn"); glLinkProgram (shader_programme); glGetProgramiv (shader_programme, GL_LINK_STATUS, ¶ms); if (GL_TRUE != params) { printf ("ERROR: could not link shader programme GL index %u\n", shader_programme); int max_length = 2048; int actual_length = 0; char log[2048]; glGetProgramInfoLog (shader_programme, max_length, &actual_length, log); printf ("program info log for GL index %u\n%s\n", shader_programme, log); } /* TODO NOTE: you should check for errors and print logs after compiling and also linking shaders */ } // // Create some matrices // -------------------------------------------------------------------------- mat4 M, V, P; M = identity_mat4 ();//scale (identity_mat4 (), vec3 (0.05, 0.05, 0.05)); vec3 cam_pos (0.0, 5.0, 5.0); vec3 targ_pos (0.0, 0.0, 0.0); vec3 up = normalise (vec3 (0.0, 1.0, -1.0)); V = look_at (cam_pos, targ_pos, up); P = perspective (67.0f, (float)gl_width / (float)gl_height, 0.1, 10.0); int M_loc = glGetUniformLocation (shader_programme, "M"); int V_loc = glGetUniformLocation (shader_programme, "V"); int P_loc = glGetUniformLocation (shader_programme, "P"); int ol_loc = glGetUniformLocation (shader_programme, "ol_mode"); int sm_loc = glGetUniformLocation (shader_programme, "sm_shaded"); // send matrix values to shader immediately glUseProgram (shader_programme); glUniformMatrix4fv (M_loc, 1, GL_FALSE, M.m); glUniformMatrix4fv (V_loc, 1, GL_FALSE, V.m); glUniformMatrix4fv (P_loc, 1, GL_FALSE, P.m); glUniform1f (ol_loc, 0.0f); glUniform1f (sm_loc, 0.0f); // // Start rendering // -------------------------------------------------------------------------- // tell GL to only draw onto a pixel if the fragment is closer to the viewer glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" glDepthFunc (GL_LESS); // depth-testing is to use a "less than" function glEnable (GL_CULL_FACE); // enable culling of faces glCullFace (GL_BACK); glFrontFace (GL_CCW); glClearColor (0.04, 0.04, 0.75, 1.0); bool multi_pass = true; GLuint fb, c_tex, d_tex;; { // fb glGenFramebuffers (1, &fb); glBindFramebuffer (GL_FRAMEBUFFER, fb); glGenTextures (1, &c_tex); glGenTextures (1, &d_tex); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, c_tex); glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, gl_width, gl_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, c_tex, 0); glBindTexture (GL_TEXTURE_2D, d_tex); glTexImage2D (GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, gl_width, gl_height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, d_tex, 0); glBindFramebuffer (GL_FRAMEBUFFER, 0); } GLuint quad_vao; { float quad_pts[] = {-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0}; GLuint quad_vbo; glGenBuffers (1, &quad_vbo); glGenVertexArrays (1, &quad_vao); glBindVertexArray (quad_vao); glEnableVertexAttribArray (0); glBindBuffer (GL_ARRAY_BUFFER, quad_vbo); glBufferData (GL_ARRAY_BUFFER, 8 * sizeof (float), quad_pts, GL_STATIC_DRAW); glVertexAttribPointer (0, 2, GL_FLOAT, GL_FALSE, 0, NULL); } GLuint post_sp; { char* vertex_shader_str; char* fragment_shader_str; // allocate some memory to store shader strings vertex_shader_str = (char*)malloc (81920); fragment_shader_str = (char*)malloc (81920); // load shader strings from text files assert (parse_file_into_str ("post.vert", vertex_shader_str, 81920)); assert (parse_file_into_str ("post.frag", fragment_shader_str, 81920)); GLuint vs, fs; vs = glCreateShader (GL_VERTEX_SHADER); fs = glCreateShader (GL_FRAGMENT_SHADER); glShaderSource (vs, 1, (const char**)&vertex_shader_str, NULL); glShaderSource (fs, 1, (const char**)&fragment_shader_str, NULL); // free memory free (vertex_shader_str); free (fragment_shader_str); int params = -1; glCompileShader (vs); glGetShaderiv (vs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { printf ("ERROR: GL shader index %i (post.vert) did not compile\n", vs); int max_length = 2048; int actual_length = 0; char log[2048]; glGetShaderInfoLog (vs, max_length, &actual_length, log); printf ("shader info log for GL index %u\n%s\n", vs, log); } glCompileShader (fs); glGetShaderiv (fs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { printf ("ERROR: GL shader index %i (post.frag) did not compile\n", fs); int max_length = 2048; int actual_length = 0; char log[2048]; glGetShaderInfoLog (fs, max_length, &actual_length, log); printf ("shader info log for GL index %u\n%s\n", vs, log); } post_sp = glCreateProgram (); glAttachShader (post_sp, fs); glAttachShader (post_sp, vs); glBindAttribLocation (post_sp, 0, "vp"); glLinkProgram (post_sp); glGetProgramiv (post_sp, GL_LINK_STATUS, ¶ms); if (GL_TRUE != params) { printf ("ERROR: could not link shader programme GL index %u\n", post_sp); int max_length = 2048; int actual_length = 0; char log[2048]; glGetProgramInfoLog (post_sp, max_length, &actual_length, log); printf ("program info log for GL index %u\n%s\n", post_sp, log); } } double a = 0.0f; double prev = glfwGetTime (); while (!glfwWindowShouldClose (window)) { if (multi_pass) { glBindFramebuffer (GL_FRAMEBUFFER, fb); } glViewport (0, 0, gl_width, gl_height); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, 0); double curr = glfwGetTime (); double elapsed = curr - prev; prev = curr; glUseProgram (shader_programme); glBindVertexArray (vao); a += elapsed * 50.0f; //float ang = (float)sin (a); M = rotate_y_deg (identity_mat4 (), a); glUniformMatrix4fv (M_loc, 1, GL_FALSE, M.m); glUniform1f (sm_loc, 1.0f); // smooth shaded or not (exception is flat-shaded, they might not be great // if non-cube anyway due to scaling) if (!multi_pass) { glFrontFace (GL_CW); glUniform1f (ol_loc, 1.0f); glDrawArrays (GL_TRIANGLES, 0, point_count); } glFrontFace (GL_CCW); glUniform1f (ol_loc, 0.0f); glDrawArrays (GL_TRIANGLES, 0, point_count); /* this just updates window events and keyboard input events (not used yet) */ if (multi_pass) { glFlush (); glFinish (); glBindFramebuffer (GL_FRAMEBUFFER, 0); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport (0, 0, gl_width, gl_height); glUseProgram (post_sp); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, d_tex); glBindVertexArray (quad_vao); glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); } glfwPollEvents (); glfwSwapBuffers (window); } return 0; }
int main () { GLFWwindow* window = NULL; const GLubyte* renderer; const GLubyte* version; GLuint cube_sp, knot_sp; GLuint vao; // // Start OpenGL using helper libraries // -------------------------------------------------------------------------- if (!glfwInit ()) { fprintf (stderr, "ERROR: could not start GLFW3\n"); return 1; } /* change to 3.2 if on Apple OS X glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 0); glfwWindowHint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); */ glfwWindowHint (GLFW_SAMPLES, msaa); window = glfwCreateWindow (gl_width, gl_height, "{quadratic bezier}", NULL, NULL); if (!window) { fprintf (stderr, "ERROR: opening OS window\n"); return 1; } glfwMakeContextCurrent (window); glewExperimental = GL_TRUE; glewInit (); /* get version info */ renderer = glGetString (GL_RENDERER); /* get renderer string */ version = glGetString (GL_VERSION); /* version as a string */ printf ("Renderer: %s\n", renderer); printf ("OpenGL version supported %s\n", version); int point_count = 0; // // Set up vertex buffers and vertex array object // -------------------------------------------------------------------------- { GLfloat* vp = NULL; // array of vertex points GLfloat* vn = NULL; // array of vertex normals (we haven't used these yet) GLfloat* vt = NULL; // array of texture coordinates (or these) assert (load_obj_file ("smcube.obj", vp, vt, vn, point_count)); GLuint points_vbo, texcoord_vbo, normal_vbo; glGenBuffers (1, &points_vbo); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 3 * point_count, vp, GL_STATIC_DRAW); glGenBuffers (1, &texcoord_vbo); glBindBuffer (GL_ARRAY_BUFFER, texcoord_vbo); glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 2 * point_count, vt, GL_STATIC_DRAW); glGenBuffers (1, &normal_vbo); glBindBuffer (GL_ARRAY_BUFFER, normal_vbo); glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 3 * point_count, vn, GL_STATIC_DRAW); glGenVertexArrays (1, &vao); glBindVertexArray (vao); glEnableVertexAttribArray (0); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (1); glBindBuffer (GL_ARRAY_BUFFER, texcoord_vbo); glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (2); glBindBuffer (GL_ARRAY_BUFFER, normal_vbo); glVertexAttribPointer (2, 3, GL_FLOAT, GL_FALSE, 0, NULL); free (vp); free (vn); free (vt); } // // Load shaders from files // -------------------------------------------------------------------------- { char* vertex_shader_str; char* fragment_shader_str; // allocate some memory to store shader strings vertex_shader_str = (char*)malloc (81920); fragment_shader_str = (char*)malloc (81920); // load shader strings from text files assert (parse_file_into_str ("cube.vert", vertex_shader_str, 81920)); assert (parse_file_into_str ("cube.frag", fragment_shader_str, 81920)); GLuint vs, fs; vs = glCreateShader (GL_VERTEX_SHADER); fs = glCreateShader (GL_FRAGMENT_SHADER); glShaderSource (vs, 1, (const char**)&vertex_shader_str, NULL); glShaderSource (fs, 1, (const char**)&fragment_shader_str, NULL); // free memory free (vertex_shader_str); free (fragment_shader_str); glCompileShader (vs); glCompileShader (fs); cube_sp = glCreateProgram (); glAttachShader (cube_sp, fs); glAttachShader (cube_sp, vs); glBindAttribLocation (cube_sp, 0, "vp"); glBindAttribLocation (cube_sp, 1, "vt"); glBindAttribLocation (cube_sp, 2, "vn"); glLinkProgram (cube_sp); } { char* vertex_shader_str; char* fragment_shader_str; // allocate some memory to store shader strings vertex_shader_str = (char*)malloc (81920); fragment_shader_str = (char*)malloc (81920); // load shader strings from text files assert (parse_file_into_str ("knot.vert", vertex_shader_str, 81920)); assert (parse_file_into_str ("knot.frag", fragment_shader_str, 81920)); GLuint vs, fs; vs = glCreateShader (GL_VERTEX_SHADER); fs = glCreateShader (GL_FRAGMENT_SHADER); glShaderSource (vs, 1, (const char**)&vertex_shader_str, NULL); glShaderSource (fs, 1, (const char**)&fragment_shader_str, NULL); // free memory free (vertex_shader_str); free (fragment_shader_str); glCompileShader (vs); glCompileShader (fs); knot_sp = glCreateProgram (); glAttachShader (knot_sp, fs); glAttachShader (knot_sp, vs); glLinkProgram (knot_sp); } // // Create some matrices // -------------------------------------------------------------------------- mat4 M, V, P; M = identity_mat4 ();//scale (identity_mat4 (), vec3 (0.05, 0.05, 0.05)); vec3 cam_pos (0.0, 0.0, 15.0); vec3 targ_pos (0.0, 0.0, 0.0); vec3 up = normalise (vec3 (0.0, 1.0, 0.0)); V = look_at (cam_pos, targ_pos, up); P = perspective (67.0f, (float)gl_width / (float)gl_height, 0.1, 1000.0); int M_loc = glGetUniformLocation (cube_sp, "M"); int V_loc = glGetUniformLocation (cube_sp, "V"); int P_loc = glGetUniformLocation (cube_sp, "P"); int A_loc = glGetUniformLocation (cube_sp, "A"); int B_loc = glGetUniformLocation (cube_sp, "B"); int C_loc = glGetUniformLocation (cube_sp, "C"); int t_loc = glGetUniformLocation (cube_sp, "t"); // send matrix values to shader immediately glUseProgram (cube_sp); glUniformMatrix4fv (M_loc, 1, GL_FALSE, M.m); glUniformMatrix4fv (V_loc, 1, GL_FALSE, V.m); glUniformMatrix4fv (P_loc, 1, GL_FALSE, P.m); // // specific knots for bezier here A, C are start, end, B is control point // vec3 A = vec3 (-7.0f, -5.0f, 0.0f); vec3 B = vec3 (0.0f, 8.0f, 0.0f); vec3 C = vec3 (7.0f, -5.0f, 0.0f); glUniform3fv (A_loc, 1, A.v); glUniform3fv (B_loc, 1, B.v); glUniform3fv (C_loc, 1, C.v); int knot_loc = glGetUniformLocation (knot_sp, "pos"); int knotP_loc = glGetUniformLocation (knot_sp, "P"); int knotV_loc = glGetUniformLocation (knot_sp, "V"); glUseProgram (knot_sp); glUniformMatrix4fv (knotV_loc, 1, GL_FALSE, V.m); glUniformMatrix4fv (knotP_loc, 1, GL_FALSE, P.m); // // Start rendering // -------------------------------------------------------------------------- // tell GL to only draw onto a pixel if the fragment is closer to the viewer glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" glDepthFunc (GL_LESS); // depth-testing is to use a "less than" function glEnable (GL_CULL_FACE); // enable culling of faces glCullFace (GL_BACK); glFrontFace (GL_CCW); glClearColor (0.04, 0.04, 0.75, 1.0); /* Render Points, allow resize in vertex shader */ glEnable (GL_PROGRAM_POINT_SIZE); glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); float t = 0.0f; float speed = 0.5f; double prev = glfwGetTime (); while (!glfwWindowShouldClose (window)) { glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // just the default viewport, covering the whole render area glViewport (0, 0, gl_width, gl_height); double curr = glfwGetTime (); double elapsed = curr - prev; prev = curr; // // move along spline if (GLFW_PRESS == glfwGetKey (window, GLFW_KEY_LEFT)) { t -= elapsed * speed; if (t < 0.0f) { t = 0.0f; } } if (GLFW_PRESS == glfwGetKey (window, GLFW_KEY_RIGHT)) { t += elapsed * speed; if (t > 1.0f) { t = 1.0f; } } // // render 3 knots glEnable (GL_PROGRAM_POINT_SIZE); glUseProgram (knot_sp); glUniform3fv (knot_loc, 1, A.v); glDrawArrays (GL_POINTS, 0, 1); glUseProgram (knot_sp); glUniform3fv (knot_loc, 1, B.v); glDrawArrays (GL_POINTS, 0, 1); glUseProgram (knot_sp); glUniform3fv (knot_loc, 1, C.v); glDrawArrays (GL_POINTS, 0, 1); glDisable (GL_PROGRAM_POINT_SIZE); glUseProgram (cube_sp); glBindVertexArray (vao); M = identity_mat4 ();//rotate_y_deg (identity_mat4 (), a); glUniformMatrix4fv (M_loc, 1, GL_FALSE, M.m); glUniform1f (t_loc, t); glDrawArrays (GL_TRIANGLES, 0, point_count); /* this just updates window events and keyboard input events (not used yet) */ glfwPollEvents (); glfwSwapBuffers (window); } return 0; }
int main () { /* 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; }