// returns a view matrix using the opengl lookAt style. COLUMN ORDER. void GLCamera::look_at(const vector3& pos, vector3 targ_pos, const vector3& up_v) { this->cam_pos = pos; // inverse translation matriz4x4 p = identity_mat4(); p = p.translate(vector3(-pos.v[0], -pos.v[1], -pos.v[2])); // distance vector vector3 d = targ_pos - pos; // forward vector vector3 f = d.normalise(); // right vector vector3 r = cross(f, up_v).normalise(); // real up vector vector3 u = cross(r, f).normalise(); matriz4x4 ori = identity_mat4(); ori.m[0] = r.v[0]; ori.m[4] = r.v[1]; ori.m[8] = r.v[2]; ori.m[1] = u.v[0]; ori.m[5] = u.v[1]; ori.m[9] = u.v[2]; ori.m[2] = -f.v[0]; ori.m[6] = -f.v[1]; ori.m[10] = -f.v[2]; R = ori; T = p; view_mat = R * T; // recalc axes to suit new orientation mat4_to_quat(quaternion, R.m); fwd = R * vector4(0.0, 0.0, -1.0, 0.0); rgt = R * vector4(1.0, 0.0, 0.0, 0.0); up = R * vector4(0.0, 1.0, 0.0, 0.0); }
void createShaders(GLuint shader_programme) { #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 }; mat4 T = translate (identity_mat4 (), vec3 (-cam_pos[0], -cam_pos[1], -cam_pos[2])); mat4 R = rotate_z_deg (identity_mat4 (), -cam_zaw); mat4 view_mat = T * R; view_mat_location = glGetUniformLocation (shader_programme, "view"); glUseProgram (shader_programme); glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, view_mat.m); proj_mat_location = glGetUniformLocation (shader_programme, "proj"); glUseProgram (shader_programme); glUniformMatrix4fv (proj_mat_location, 1, GL_FALSE, proj_mat); }
// Maintain translations and rotations. inline void updateView() { mat4 T = translate (identity_mat4 (), vec3 (-cam_pos[0], -cam_pos[1], -cam_pos[2])); // cam translation mat4 R = rotate_z_deg(identity_mat4(), -cam_zaw) * rotate_y_deg(identity_mat4(), -cam_yaw) * rotate_x_deg(identity_mat4(), -cam_xaw); mat4 view_mat = T * R; glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, view_mat.m); }
Camera::Camera(int view_mat_location, int proj_mat_location) { this->view_mat_location = view_mat_location; this->proj_mat_location = proj_mat_location; cam_pos = vec3 (0.0f, 0.0f, 5.0f); near = 0.1f; // clipping plane far = 100.0f; // clipping plane fovy = 67.0f; // 67 degrees // aspect ratio aspect = (float)g_gl_width / (float)g_gl_height; proj_mat = perspective (fovy, aspect, near, far); cam_speed = 5.0f; // 1 unit per second cam_heading_speed = 100.0f; // 30 degrees per second cam_heading = 0.0f; // y-rotation in degrees T = translate ( identity_mat4 (), vec3 (-cam_pos.v[0], -cam_pos.v[1], -cam_pos.v[2]) ); create_versor (quaternion, -cam_heading, 0.0f, 1.0f, 0.0f); // convert the quaternion to a rotation matrix (just an array of 16 floats) quat_to_mat4 (R.m, quaternion); // combine the inverse rotation and transformation to make a view matrix view_mat = R * T; fwd = FORWARD; rgt = RIGHT; up = UP; set_view(); set_proj(); reset_control(); }
Mesh::Mesh(const std::string filename, std::shared_ptr<Texture> tex) : vp(NULL), vn(NULL), vt(NULL), point_count(0), model(identity_mat4()), model_uniform(), vao(0), loaded(true), texture(tex) { load_obj_file(filename.c_str(), vp, vt, vn, point_count); build(); }
GLCamera::GLCamera(float aspect) { near = 0.1f; far = 100.0f; fovy = 67.0f; //aspect = (float)g_gl_width / (float)g_gl_height; this->aspect = aspect; proj_mat = perspective(fovy, this->aspect, near, far); cam_speed = 5.0f; cam_heading_speed = 100.0f; cam_heading = 0.0f; cam_pos = vector3(0.0f, 0.0f, 5.0f); T = identity_mat4().translate( vector3(-cam_pos.v[0], -cam_pos.v[1], -cam_pos.v[2]) ); create_versor(quaternion, -cam_heading, 0.0f, 1.0f, 0.0f); quat_to_mat4(R.m, quaternion); // combine the inverse rotation and transformation to make a view matrix view_mat = R * T; // keep track of some useful vectors that can be used for keyboard movement fwd = vector4(0.0f, 0.0f, -1.0f, 0.0f); rgt = vector4(1.0f, 0.0f, 0.0f, 0.0f); up = vector4(0.0f, 1.0f, 0.0f, 0.0f); cam_yaw = 0.0f; // y-rotation in degrees cam_pitch = 0.0f; cam_roll = 0.0; }
void Camera::CreateViewMat() { translation=translate(identity_mat4(), vec3(-position.v[0], -position.v[1], -position.v[2])); CreateVersor(quaternion, -pitch, 0.0f, 1.0f, 0.0f); QuatToMat4(rotation.m, quaternion); viewMat=rotation*translation; }
void GLCamera::setPosition(vector3 pos) { this->cam_pos = pos; T = identity_mat4().translate(vector3(-cam_pos.v[0], -cam_pos.v[1], -cam_pos.v[2])); T = identity_mat4().translate( vector3(-cam_pos.v[0], -cam_pos.v[1], -cam_pos.v[2]) ); create_versor(quaternion, -cam_heading, 0.0f, 1.0f, 0.0f); quat_to_mat4(R.m, quaternion); // combine the inverse rotation and transformation to make a view matrix view_mat = R * T; // keep track of some useful vectors that can be used for keyboard movement fwd = vector4(0.0f, 0.0f, -1.0f, 0.0f); rgt = vector4(1.0f, 0.0f, 0.0f, 0.0f); up = vector4(0.0f, 1.0f, 0.0f, 0.0f); cam_yaw = 0.0f; // y-rotation in degrees cam_pitch = 0.0f; cam_roll = 0.0; }
void meshInit(Mesh* mesh, GLfloat* proj_mat){ /** load memory etc. */ assert(meshLoadMeshFile(MESH_FILE, &mesh->vao, &mesh->vertexCount)); meshLoadTexture(mesh); meshLoadShaderProgram(mesh); glUseProgram(mesh->shader); meshGetUniforms(mesh); //set initial shader conditions glUniform4f(mesh->location_clip_plane, 0.0f, -1.0f, 0.0f, 1.0f); glUniformMatrix4fv(mesh->location_projection_mat , 1, GL_FALSE, proj_mat); mat4 s = scale(identity_mat4(), vec3(10,10,10)); mesh->modelMatrix = s; glUniformMatrix4fv(mesh->location_model_mat , 1, GL_FALSE, mesh->modelMatrix.m); }
void Camera::update() { // update view matrix if (cam_moved) { quat_to_mat4 (R.m, quaternion); // checking for fp errors // printf ("dot fwd . up %f\n", dot (fwd, up)); // printf ("dot rgt . up %f\n", dot (rgt, up)); // printf ("dot fwd . rgt\n %f", dot (fwd, rgt)); cam_pos += vec3 (fwd) * -move.v[2]; cam_pos += vec3 (up) * move.v[1]; cam_pos += vec3 (rgt) * move.v[0]; T = translate (identity_mat4 (), vec3 (cam_pos)); view_mat = inverse (R) * inverse (T); set_view(); } }
void GLCamera::updatePosition(vector3 move) { quat_to_mat4(R.m, quaternion); // checking for fp errors // printf ("dot fwd . up %f\n", dot (fwd, up)); // printf ("dot rgt . up %f\n", dot (rgt, up)); // printf ("dot fwd . rgt\n %f", dot (fwd, rgt)); cam_pos = cam_pos + vector3(fwd) * -move.v[2]; cam_pos = cam_pos + vector3(up) * move.v[1]; cam_pos = cam_pos + vector3(rgt) * move.v[0]; matriz4x4 T = identity_mat4().translate(vector3(cam_pos)); view_mat = R.inverse() * T.inverse(); cam_yaw = 0.0f; cam_pitch = 0.0f; cam_roll = 0.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; }
Mesh::Mesh(GLfloat* vpoints, GLfloat* vnormals, GLfloat* vtexture, int pt_count, std::shared_ptr<Texture> tex) : vp(vpoints), vn(vnormals), vt(vtexture), point_count(pt_count), model(identity_mat4()), model_uniform(), vao(0), loaded(false), texture(tex) { build(); }
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 () { // start GL context with helper libraries assert (glfwInit ()); /* We must specify 3.2 core if on Apple OS X -- other O/S can specify anything here. I defined 'APPLE' in the makefile for OS X */ #ifdef APPLE glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); #endif GLFWwindow* window = glfwCreateWindow ( g_viewport_width, g_viewport_height, "GUI Panels", NULL, NULL); glfwSetWindowSizeCallback (window, glfw_window_size_callback); glfwMakeContextCurrent (window); glewExperimental = GL_TRUE; glewInit (); const GLubyte* renderer = glGetString (GL_RENDERER); // get renderer string const GLubyte* version = glGetString (GL_VERSION); // version as a string printf ("Renderer: %s\n", renderer); printf ("OpenGL version supported %s\n", version); // create a 2d panel. from 2 triangles = 6 xy coords. float points[] = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f }; // for ground plane we can just re-use panel points but y is now z GLuint vp_vbo, vao; glGenBuffers (1, &vp_vbo); glBindBuffer (GL_ARRAY_BUFFER, vp_vbo); glBufferData (GL_ARRAY_BUFFER, sizeof (points), points, GL_STATIC_DRAW); glGenVertexArrays (1, &vao); glBindVertexArray (vao); // note: vertex buffer is already bound glVertexAttribPointer (0, 2, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (0); // create a 3d camera to move in 3d so that we can tell that the panel is 2d // 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); vec3 cam_pos (0.0f, 1.0f, 5.0f); mat4 T_inv = translate (identity_mat4 (), cam_pos); // point slightly downwards to see the plane versor quaternion = quat_from_axis_deg (0.0f, 1.0f, 0.0f, 0.0f); mat4 R_inv = quat_to_mat4 (quaternion); // combine the inverse rotation and transformation to make a view matrix V = inverse (R_inv) * inverse (T_inv); // projection matrix P = perspective ( 67.0f, (float)g_viewport_width / (float)g_viewport_height, 0.1f, 100.0f); const float cam_speed = 3.0f; // 1 unit per second const float cam_heading_speed = 50.0f; // 30 degrees per second create_ground_plane_shaders (); create_gui_shaders (); // textures for ground plane and gui GLuint gp_tex, gui_tex; assert (load_texture ("tile2-diamonds256x256.png", &gp_tex)); assert (load_texture ("skulluvmap.png", &gui_tex)); // rendering defaults glDepthFunc (GL_LESS); // set depth function but don't enable yet glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CCW); // GL_CCW for counter clock-wise // absolute panel dimensions in pixels const float panel_width = 256.0f; const float panel_height = 256.0f; glViewport (0, 0, g_viewport_width, g_viewport_height); // start main rendering loop while (!glfwWindowShouldClose (window)) { // update timers static double previous_seconds = glfwGetTime (); double current_seconds = glfwGetTime (); double elapsed_seconds = current_seconds - previous_seconds; previous_seconds = current_seconds; bool cam_moved = false; vec3 move (0.0, 0.0, 0.0); // wipe the drawing surface clear glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // draw ground plane. note: depth test is enabled here glEnable (GL_DEPTH_TEST); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, gp_tex); glUseProgram (gp_sp); glBindVertexArray (vao); glDrawArrays (GL_TRIANGLES, 0, 6); // draw GUI panel. note: depth test is disabled here and drawn AFTER scene glDisable (GL_DEPTH_TEST); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, gui_tex); glUseProgram (gui_sp); // resize panel to size in pixels float x_scale = panel_width / g_viewport_width; float y_scale = panel_height / g_viewport_height; glUniform2f (gui_scale_loc, x_scale, y_scale); glBindVertexArray (vao); glDrawArrays (GL_TRIANGLES, 0, 6); // update other events like input handling glfwPollEvents (); if (GLFW_PRESS == glfwGetKey (window, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (window, 1); } float cam_yaw = 0.0f; // y-rotation in degrees float cam_pitch = 0.0f; float cam_roll = 0.0; if (glfwGetKey (window, GLFW_KEY_A)) { move.v[0] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_D)) { move.v[0] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_Q)) { move.v[1] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_E)) { move.v[1] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_W)) { move.v[2] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_S)) { move.v[2] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_LEFT)) { cam_yaw += cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_yaw = quat_from_axis_deg (cam_yaw, up.v[0], up.v[1], up.v[2]); quaternion = q_yaw * quaternion; } if (glfwGetKey (window, GLFW_KEY_RIGHT)) { cam_yaw -= cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_yaw = quat_from_axis_deg (cam_yaw, up.v[0], up.v[1], up.v[2]); quaternion = q_yaw * quaternion; } if (glfwGetKey (window, GLFW_KEY_UP)) { cam_pitch += cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_pitch = quat_from_axis_deg ( cam_pitch, rgt.v[0], rgt.v[1], rgt.v[2]); quaternion = q_pitch * quaternion; } if (glfwGetKey (window, GLFW_KEY_DOWN)) { cam_pitch -= cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_pitch = quat_from_axis_deg ( cam_pitch, rgt.v[0], rgt.v[1], rgt.v[2]); quaternion = q_pitch * quaternion; } if (glfwGetKey (window, GLFW_KEY_Z)) { cam_roll -= cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_roll = quat_from_axis_deg ( cam_roll, fwd.v[0], fwd.v[1], fwd.v[2]); quaternion = q_roll * quaternion; } if (glfwGetKey (window, GLFW_KEY_C)) { cam_roll += cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_roll = quat_from_axis_deg ( cam_roll, fwd.v[0], fwd.v[1], fwd.v[2]); quaternion = q_roll * quaternion; } // update view matrix if (cam_moved) { // re-calculate local axes so can move fwd in dir cam is pointing R_inv = quat_to_mat4 (quaternion); fwd = R_inv * vec4 (0.0, 0.0, -1.0, 0.0); rgt = R_inv * vec4 (1.0, 0.0, 0.0, 0.0); up = R_inv * 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]; T_inv = translate (identity_mat4 (), cam_pos); V = inverse (R_inv) * inverse (T_inv); glUseProgram (gp_sp); glUniformMatrix4fv (gp_V_loc, 1, GL_FALSE, V.m); } // put the stuff we've been drawing onto the display glfwSwapBuffers (window); } // done glfwTerminate(); return 0; }
| Working in clip space in 2d, you can very quickly build lots of widgety | | graphics elements. It's also very easy to work out if the mouse is hovering | | over one of your 2d panels | \******************************************************************************/ #include "maths_funcs.h" #include "stb_image.h" // Sean Barrett's image loader #include <GL/glew.h> // include GLEW and new version of GL on Windows #include <GLFW/glfw3.h> // GLFW helper library #include <stdio.h> #include <assert.h> int g_viewport_width = 640; int g_viewport_height = 480; // virtual camera view matrix mat4 V = identity_mat4 (); // virtual camera projection matrix mat4 P = identity_mat4 (); GLuint gp_sp; // ground plane shader programme GLint gp_V_loc; // view matrix location in gp_sp GLint gp_P_loc; // projection matrix location in gp_sp GLuint gui_sp; // 2d GUI panel shader programme GLint gui_scale_loc; // scale factors for gui shader void create_ground_plane_shaders () { /* here i used negative y from the buffer as the z value so that it was on the floor but also that the 'front' was on the top side. also note how i work out the texture coordinates, st, from the vertex point position */ const char* gp_vs_str = "#version 410\n"
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 () { 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 () { 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 () { // start GL context and O/S window using the GLFW helper library if (!glfwInit ()) { fprintf (stderr, "ERROR: could not start GLFW3\n"); return 1; } // uncomment these lines if on Apple OS X glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); GLFWwindow* window = glfwCreateWindow (640, 480, "Cube to Sphere", NULL, NULL); if (!window) { fprintf (stderr, "ERROR: could not open window with GLFW3\n"); glfwTerminate(); return 1; } GLFWwindow* window2 = glfwCreateWindow (640, 480, "Just checking", NULL, NULL); if (!window2) { fprintf (stderr, "ERROR: could not open window with GLFW3\n"); glfwTerminate(); return 1; } glfwMakeContextCurrent (window); //start GLEW extension handler glewExperimental = GL_TRUE; glewInit (); // get version info const GLubyte* renderer = glGetString (GL_RENDERER); // get renderer string const GLubyte* version = glGetString (GL_VERSION); // version as a string printf ("Renderer: %s\n", renderer); printf ("OpenGL version supported %s\n", version); //CLGLUtils::init(); boost::compute::context context; try { context = boost::compute::opengl_create_shared_context(); } catch (std::exception e) { std::cerr<<"Failed to initialize a CLGL context"<<e.what()<<std::endl; exit(0); } // tell GL to only draw onto a pixel if the shape is closer to the viewer glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" // OTHER STUFF GOES HERE NEXT float points[] = { -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f }; GLuint vbo; glGenBuffers (1, &vbo); glBindBuffer (GL_ARRAY_BUFFER, vbo); glBufferData (GL_ARRAY_BUFFER, 3 * 36 * sizeof (float), &points, GL_STATIC_DRAW); GLuint vao; glGenVertexArrays (1, &vao); glBindVertexArray (vao); glEnableVertexAttribArray (0); glBindBuffer (GL_ARRAY_BUFFER, vbo); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); //Create Cube map GLuint cube_map_texture; create_cube_map ((resource_dir+"negz.jpg").c_str(), (resource_dir+"posz.jpg").c_str(), (resource_dir+"posy.jpg").c_str(), (resource_dir+"negy.jpg").c_str(), (resource_dir+"negx.jpg").c_str(), (resource_dir+"posx.jpg").c_str(), &cube_map_texture); boost::shared_ptr<boost::compute::opengl_texture> cl_cube_map_texture; try { cl_cube_map_texture = boost::shared_ptr<boost::compute::opengl_texture>(new boost::compute::opengl_texture(context,GL_TEXTURE_2D_ARRAY,0,cube_map_texture,boost::compute::memory_object::mem_flags::read_only)); } catch ( const std::exception& e ) { std::cerr << e.what() << std::endl; } const char* vertex_shader = "#version 400\n" "in vec3 vp;" "uniform mat4 P, V;" // "uniform vec3 vertOut;" "out vec3 texcoords;" "vec3 newP;" "void main () {" " texcoords = vp;" // " vertOut = vp;" " gl_Position = P * V * vec4 (vp, 1.0);" "}"; const char* fragment_shader = loadShader(resource_dir+"fragmentShader.frag").c_str(); /*"#version 400\n" "in vec3 texcoords;" "uniform samplerCube cube_texture;" "out vec4 frag_colour;" "vec4 cubeToLatLon(samplerCube cubemap, vec3 inUV) {" "vec3 cubmapTexCoords;" //"cubmapTexCoords.x = inUV.x*sqrt(1 - ( (inUV.y * inUV.y)/2 ) - ( (inUV.z * inUV.z)/2 ) + ( ( (inUV.y * inUV.y) * (inUV.z * inUV.z))/3));" "cubmapTexCoords.x = inUV.x;" //"cubmapTexCoords.y= inUV.y*sqrt(1 - ( (inUV.z * inUV.z)/2 ) - ( (inUV.x * inUV.x)/2 ) + ( ( (inUV.z * inUV.z) * (inUV.x * inUV.x))/3));" "cubmapTexCoords.y = inUV.y;" "cubmapTexCoords.z = inUV.z*sqrt(1 - ( (inUV.x * inUV.x)/2 ) - ( (inUV.y * inUV.y)/2 ) + ( ( (inUV.x * inUV.x) * (inUV.y * inUV.y))/3));" //"cubmapTexCoords.z = inUV.z;" "return texture(cubemap, cubmapTexCoords);" "}" "void main () {" //" frag_colour = texture (cube_texture, texcoords);" " frag_colour = cubeToLatLon (cube_texture, texcoords);" "}";*/ GLuint vs = glCreateShader (GL_VERTEX_SHADER); glShaderSource (vs, 1, &vertex_shader, NULL); glCompileShader (vs); GLuint fs = glCreateShader (GL_FRAGMENT_SHADER); glShaderSource (fs, 1, &fragment_shader, NULL); glCompileShader (fs); GLuint cube_sp = glCreateProgram (); glAttachShader (cube_sp, fs); glAttachShader (cube_sp, vs); glLinkProgram (cube_sp); //*-----------------------------Compile Shaders for second window - square --------*/ glfwMakeContextCurrent(window2); //start GLEW extension handler glewExperimental = GL_TRUE; glewInit (); glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" float squarePoints[] = { -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f }; GLfloat texcoords[] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; GLuint vbo_square; glGenBuffers (1, &vbo_square); glBindBuffer (GL_ARRAY_BUFFER, vbo_square); glBufferData (GL_ARRAY_BUFFER, 3 * 6 * sizeof (float), &squarePoints, GL_STATIC_DRAW); GLuint texcoords_vbo; glGenBuffers (1, &texcoords_vbo); glBindBuffer (GL_ARRAY_BUFFER, texcoords_vbo); glBufferData (GL_ARRAY_BUFFER, 12 * sizeof (GLfloat), texcoords, GL_STATIC_DRAW); GLuint vao_square; glGenVertexArrays (1, &vao_square); glBindVertexArray (vao_square); glBindBuffer (GL_ARRAY_BUFFER, vbo_square); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glBindBuffer (GL_ARRAY_BUFFER, texcoords_vbo); glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 0, NULL); // normalise! glEnableVertexAttribArray (0); glEnableVertexAttribArray (1); GLuint square_sp = create_programme_from_files((resource_dir+"square.vert").c_str(), (resource_dir+"square.frag").c_str()); GLuint tex; assert (load_texture ((resource_dir+"negz.jpg").c_str(), &tex)); //*----------------------------------------------------------------------------------*/ glfwMakeContextCurrent (window); int cube_V_location = glGetUniformLocation (cube_sp, "V"); int cube_P_location = glGetUniformLocation (cube_sp, "P"); //int cube_vertOut = glGetUniformLocation (cube_sp, "vertOut"); /*-------------------------------CREATE GLOBAL CAMERA--------------------------------*/ #define ONE_DEG_IN_RAD (2.0 * M_PI) / 360.0 // 0.017444444 // input variables float near = 0.1f; // clipping plane float far = 100.0f; // clipping plane float fovy = 80.0f; // 67 degrees float aspect = (float)g_gl_width / (float)g_gl_height; // aspect ratio proj_mat = perspective (fovy, aspect, near, far); float cam_speed = 3.0f; // 1 unit per second float cam_heading_speed = 50.0f; // 30 degrees per second float cam_heading = 0.0f; // y-rotation in degrees mat4 T = translate (identity_mat4 (), vec3 (-cam_pos.v[0], -cam_pos.v[1], -cam_pos.v[2])); mat4 R = rotate_y_deg (identity_mat4 (), -cam_heading); versor q = quat_from_axis_deg (-cam_heading, 0.0f, 1.0f, 0.0f); view_mat = R * T; // keep track of some useful vectors that can be used for keyboard movement vec4 fwd (0.0f, 0.0f, -1.0f, 0.0f); vec4 rgt (1.0f, 0.0f, 0.0f, 0.0f); vec4 up (0.0f, 1.0f, 0.0f, 0.0f); /*---------------------------SET RENDERING DEFAULTS---------------------------*/ glUseProgram (cube_sp); glUniformMatrix4fv (cube_V_location, 1, GL_FALSE, R.m); glUniformMatrix4fv (cube_P_location, 1, GL_FALSE, proj_mat.m); // unique model matrix for each sphere mat4 model_mat = identity_mat4 (); glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CCW); // set counter-clock-wise vertex order to mean the front glClearColor (0.2, 0.2, 0.2, 1.0); // grey background to help spot mistakes glViewport (0, 0, g_gl_width, g_gl_height); while (!glfwWindowShouldClose (window) && !glfwWindowShouldClose (window2)) { // update timers static double previous_seconds = glfwGetTime (); double current_seconds = glfwGetTime (); double elapsed_seconds = current_seconds - previous_seconds; previous_seconds = current_seconds; //_update_fps_counter (window); // wipe the drawing surface clear glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // render a sky-box using the cube-map texture glDepthMask (GL_FALSE); glUseProgram (cube_sp); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_CUBE_MAP, cube_map_texture); glBindVertexArray (vao); glDrawArrays (GL_TRIANGLES, 0, 36); glDepthMask (GL_TRUE); //*---------------------------------Display for second window-------------------*/ glfwMakeContextCurrent (window2); glUseProgram (square_sp); int cubemap_vert = glGetUniformLocation (square_sp, "cubeMap_texcoords"); glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CCW); // set counter-clock-wise vertex order to mean the front glClearColor (0.3, 0.2, 0.3, 1.0); // grey background to help spot mistakes glViewport (0, 0, g_gl_width, g_gl_height); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDepthMask (GL_FALSE); glUseProgram (square_sp); glBindVertexArray (vao_square); glDrawArrays (GL_TRIANGLES, 0, 6); glDepthMask (GL_TRUE); //*------------------------------GO back to cubemap window--------------------*/ glfwMakeContextCurrent (window); // update other events like input handling glfwPollEvents (); // control keys bool cam_moved = false; vec3 move (0.0, 0.0, 0.0); float cam_yaw = 0.0f; // y-rotation in degrees float cam_pitch = 0.0f; float cam_roll = 0.0; if (glfwGetKey (window, GLFW_KEY_A)) { move.v[0] -= cam_speed * elapsed_seconds; cam_moved = true; print(move); } if (glfwGetKey (window, GLFW_KEY_D)) { move.v[0] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_Q)) { move.v[1] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_E)) { move.v[1] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_W)) { move.v[2] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_S)) { move.v[2] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_LEFT)) { cam_yaw += cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_yaw = quat_from_axis_deg ( cam_yaw, up.v[0], up.v[1], up.v[2] ); q = q_yaw * q; } if (glfwGetKey (window, GLFW_KEY_RIGHT)) { cam_yaw -= cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_yaw = quat_from_axis_deg ( cam_yaw, up.v[0], up.v[1], up.v[2] ); q = q_yaw * q; } if (glfwGetKey (window, GLFW_KEY_UP)) { cam_pitch += cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_pitch = quat_from_axis_deg ( cam_pitch, rgt.v[0], rgt.v[1], rgt.v[2] ); q = q_pitch * q; } if (glfwGetKey (window, GLFW_KEY_DOWN)) { cam_pitch -= cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_pitch = quat_from_axis_deg ( cam_pitch, rgt.v[0], rgt.v[1], rgt.v[2] ); q = q_pitch * q; } if (glfwGetKey (window, GLFW_KEY_Z)) { cam_roll -= cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_roll = quat_from_axis_deg ( cam_roll, fwd.v[0], fwd.v[1], fwd.v[2] ); q = q_roll * q; } if (glfwGetKey (window, GLFW_KEY_C)) { cam_roll += cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_roll = quat_from_axis_deg ( cam_roll, fwd.v[0], fwd.v[1], fwd.v[2] ); q = q_roll * q; } // update view matrix if (cam_moved) { cam_heading += cam_yaw; // re-calculate local axes so can move fwd in dir cam is pointing R = quat_to_mat4 (q); fwd = R * vec4 (0.0, 0.0, -1.0, 0.0); rgt = R * vec4 (1.0, 0.0, 0.0, 0.0); up = R * vec4 (0.0, 1.0, 0.0, 0.0); cam_pos = cam_pos + vec3 (fwd) * -move.v[2]; cam_pos = cam_pos + vec3 (up) * move.v[1]; cam_pos = cam_pos + vec3 (rgt) * move.v[0]; mat4 T = translate (identity_mat4 (), vec3 (cam_pos)); view_mat = inverse (R) * inverse (T); //std::cout<<inverse(R).m<<std::endl; // cube-map view matrix has rotation, but not translation glUseProgram (cube_sp); glUniformMatrix4fv (cube_V_location, 1, GL_FALSE, inverse (R).m); } if (GLFW_PRESS == glfwGetKey (window, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (window, 1); } if (GLFW_PRESS == glfwGetKey (window2, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (window2, 1); } // put the stuff we've been drawing onto the display glfwSwapBuffers (window); glfwMakeContextCurrent (window2); glfwSwapBuffers (window2); glfwMakeContextCurrent (window); } // close GL context and any other GLFW resources glfwTerminate(); return 0; }
void display(){ computeMatricesFromInputs(); glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" glClearColor (0.5f, 0.5f, 0.5f, 1.0f); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram (shaderProgramID); //glBindTexture(GL_TEXTURE_2D, texs[1]); glActiveTexture(GL_TEXTURE0); glBindVertexArray(vaos[1]); // int matrix_location2 = glGetUniformLocation (shaderProgramID, "model"); int view_mat_location2 = glGetUniformLocation (shaderProgramID, "view"); int proj_mat_location2 = glGetUniformLocation (shaderProgramID, "proj"); int tex_loc2 = glGetUniformLocation (shaderProgramID,"basic_texture"); mat4 viewMatrix2 = getViewMatrix(); mat4 persp_proj2 = getProjectionMatrix(); mat4 model3 = identity_mat4 (); model3 = rotate_x_deg(model3,90); model3 = scale(model3, vec3(20,20,20)); glUniformMatrix4fv (proj_mat_location2, 1, GL_FALSE, persp_proj2.m); glUniformMatrix4fv (view_mat_location2, 1, GL_FALSE, viewMatrix2.m); glUniformMatrix4fv (matrix_location2, 1, GL_FALSE, model3.m); // glBindTexture(GL_TEXTURE_2D, texs[1]); glDrawArrays(GL_TRIANGLES,0,g_point_count2); glBindVertexArray(vaos[2]); int matrix_location3 = glGetUniformLocation (shaderProgramID, "model"); int view_mat_location3 = glGetUniformLocation (shaderProgramID, "view"); int proj_mat_location3 = glGetUniformLocation (shaderProgramID, "proj"); zombie = identity_mat4(); move(zombie, getPosition()); // zombie = translate(zombie, getE_Position()); //zombie = translate(zombie, vec3(0.0,-20.0, 0)); glUniformMatrix4fv (proj_mat_location3, 1, GL_FALSE, persp_proj2.m); glUniformMatrix4fv (view_mat_location3, 1, GL_FALSE, viewMatrix2.m); glUniformMatrix4fv(matrix_location3,1,GL_FALSE, zombie.m); glDrawArrays(GL_TRIANGLES, 0, g_point_count3); // ---------------------------SKYBOX---------------------------------------------------------------- glDepthMask (GL_FALSE); glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_CUBE_MAP, texs[0]); glBindVertexArray(vaos[0]); int matrix_location = glGetUniformLocation (shaderProgramID, "model"); int view_mat_location = glGetUniformLocation (shaderProgramID, "view"); int proj_mat_location = glGetUniformLocation (shaderProgramID, "proj"); int tex_loc = glGetUniformLocation (shaderProgramID,"basic_texture"); mat4 viewMatrix = getViewMatrix(); mat4 persp_proj = getProjectionMatrix(); model = identity_mat4(); model = rotate_x_deg(model, 90); model = translate(model, getPosition()); // mat4 global = model3 * model; glUniformMatrix4fv (proj_mat_location, 1, GL_FALSE, persp_proj.m); glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, viewMatrix.m); glUniformMatrix4fv (matrix_location, 1, GL_FALSE, model.m); glDrawArrays(GL_TRIANGLES,0,36); // tell GL to only draw onto a pixel if the shape is closer to the viewer glDepthMask (GL_TRUE); //glUseProgram (shaderProgramID); /* glBindVertexArray(vaos[1]); //Declare your uniform variables that will be used in your shader int matrix_location2 = glGetUniformLocation (shaderProgramID, "model"); // int tex_loc = glGetUniformLocation (shaderProgramID,"basic_texture"); glUniform1i(tex_loc,0); mat4 model2 = identity_mat4(); model2 = scale(model2, vec3(100,100,100)); model2 = rotate_x_deg(model2, 90); mat4 global2 = global2 * model2; glUniformMatrix4fv(matrix_location2, 1, GL_FALSE, model2.m); glDrawArrays(GL_TRIANGLES,0, g_point_count2); */ /* // BOTTOM-LEFT mat4 viewMatrix2 = getViewMatrix(); mat4 persp_proj2 = getProjectionMatrix(); mat4 model2 = identity_mat4 (); model2 = rotate_z_deg (model, 180) * rotate_y_deg(model, 180); model2 = scale (model2, vec3(.1,.1,.1)); mat4 global1 = model2; // view = translate (view, vec3 (-cam_pos[0], -cam_pos[1], -cam_pos[2])); // glViewport (200, 150, width / 2, height / 2); glUniformMatrix4fv (proj_mat_location2, 1, GL_FALSE, persp_proj2.m); glUniformMatrix4fv (view_mat_location2, 1, GL_FALSE, viewMatrix2.m); glUniformMatrix4fv (matrix_location2, 1, GL_FALSE, model2.m); glDrawArrays (GL_TRIANGLES, 36, g_point_count3); */ // int matrix_location2 = glGetUniformLocation(shaderProgramID, "model"); // glDrawElements(GL_TRIANGLES, g_point_count2, GL_UNSIGNED_SHORT, &vaos[0]); /* glBindVertexArray(vaos[1]); int matrix_location2 = glGetUniformLocation (shaderProgramID, "model"); int view_mat_location2 = glGetUniformLocation (shaderProgramID, "view"); int proj_mat_location2 = glGetUniformLocation (shaderProgramID, "proj"); mat4 model2 = identity_mat4 (); model2 = rotate_x_deg (model, 180) * rotate_y_deg(model, 180); // model2 = scale (model, vec3(5,5,5)); // view = translate (view, vec3 (-cam_pos[0], -cam_pos[1], -cam_pos[2])); // glViewport (200, 150, width / 2, height / 2); glUniformMatrix4fv (matrix_location2, 1, GL_FALSE, model2.m); // mat4 spiral = identity_mat4(); // mat4 global = model * spiral; // glUniformMatrix4fv(matrix_location,1,GL_FALSE, global.m); glDrawArrays(GL_TRIANGLES,g_point_count2 + 1,g_point_count3); // glDrawElements(GL_TRIANGLES, g_point_count3, GL_UNSIGNED_SHORT, &vaos[1]); */ glutSwapBuffers(); }
/** * calculate a new View Matrix */ static void calculateViewMatrices(Camera *camera, Cursor *cursor){ camera->T = translate (identity_mat4 (), vec3 (-camera->pos[0], -camera->pos[1], -camera->pos[2])); camera->viewMatrix = camera->Rpitch * camera->Ryaw * camera->T; cursor->T = translate (identity_mat4 (), vec3 (-cursor->X, +cursor->Y, -cursor->Z)); cursor->viewMatrix = camera->viewMatrix * cursor->T * cursor->Rpitch * cursor->Ryaw * cursor->Rroll ; }
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; }
void skeleton_animate ( Skeleton_Node* node, double anim_time, mat4 parent_mat, mat4* bone_offset_mats, mat4* bone_animation_mats ) { assert (node); /* the animation of a node after inheriting its parent's animation */ mat4 our_mat = parent_mat; /* the animation for a particular bone at this time */ mat4 local_anim = identity_mat4 (); mat4 node_T = identity_mat4 (); if (node->num_pos_keys > 0) { int prev_key = 0; int next_key = 0; for (int i = 0; i < node->num_pos_keys - 1; i++) { prev_key = i; next_key = i + 1; if (node->pos_key_times[next_key] >= anim_time) { break; } } float total_t = node->pos_key_times[next_key] - node->pos_key_times[prev_key]; float t = (anim_time - node->pos_key_times[prev_key]) / total_t; vec3 vi = node->pos_keys[prev_key]; vec3 vf = node->pos_keys[next_key]; vec3 lerped = vi * (1.0f - t) + vf * t; node_T = translate (identity_mat4 (), lerped); } mat4 node_R = identity_mat4 (); if (node->num_rot_keys > 0) { // find next and previous keys int prev_key = 0; int next_key = 0; for (int i = 0; i < node->num_rot_keys - 1; i++) { prev_key = i; next_key = i + 1; if (node->rot_key_times[next_key] >= anim_time) { break; } } float total_t = node->rot_key_times[next_key] - node->rot_key_times[prev_key]; float t = (anim_time - node->rot_key_times[prev_key]) / total_t; versor qi = node->rot_keys[prev_key]; versor qf = node->rot_keys[next_key]; versor slerped = slerp (qi, qf, t); node_R = quat_to_mat4 (slerped); } local_anim = node_T * node_R; // if node has a weighted bone... int bone_i = node->bone_index; if (bone_i > -1) { // ... then get offset matrices mat4 bone_offset = bone_offset_mats[bone_i]; our_mat = parent_mat * local_anim; bone_animation_mats[bone_i] = parent_mat * local_anim * bone_offset; } for (int i = 0; i < node->num_children; i++) { skeleton_animate ( node->children[i], anim_time, our_mat, bone_offset_mats, bone_animation_mats ); } }
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; }
/** * Called everytime we press a key on the keyboard * in window - the focused window * in key - which key? * in scancode * in action - One of GFLW_PRESS, GLFW_REPEAT or GLFW_RELEASE */ static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { switch (key) { case GLFW_KEY_W: input.wPressed = action == GLFW_PRESS ? true: ((action == GLFW_RELEASE) ? false: input.wPressed); camera.move_angle = action == GLFW_PRESS ? 0:camera.move_angle; break; case GLFW_KEY_S: input.sPressed = action == GLFW_PRESS ? true: ((action == GLFW_RELEASE) ? false: input.sPressed); camera.move_angle = action == GLFW_PRESS ? 180:camera.move_angle; break; case GLFW_KEY_A: input.aPressed = action == GLFW_PRESS ? true: ((action == GLFW_RELEASE) ? false: input.aPressed); camera.move_angle = action == GLFW_PRESS ? -90:camera.move_angle; break; case GLFW_KEY_D: input.dPressed = action == GLFW_PRESS ? true: ((action == GLFW_RELEASE) ? false: input.dPressed); camera.move_angle = action == GLFW_PRESS ? 90:camera.move_angle; break; case GLFW_KEY_PAGE_UP: if (action == GLFW_PRESS) { switch (state) { case STATE_POSITION: cursor.Y = grid.heightValue += 1.0f;updateGridHeight(&grid, &cursor); break; case STATE_SCALE:break; case STATE_ORIENTATION: cursor.roll += 45.0f; calculateCursorRotations(&cursor);break; } } break; case GLFW_KEY_PAGE_DOWN: if (action == GLFW_PRESS) { switch (state) { case STATE_POSITION: cursor.Y = grid.heightValue -= 1.0f; updateGridHeight(&grid, &cursor); break; case STATE_SCALE:break; case STATE_ORIENTATION: cursor.roll -= 45.0f; calculateCursorRotations(&cursor); break; } } break; case GLFW_KEY_UP: if(action == GLFW_PRESS || action == GLFW_REPEAT) { switch (state) { case STATE_POSITION: cursor.Z += 1.0f; break; case STATE_SCALE: cursor.Xs += 0.2f; updateScales(&cursor); break; case STATE_ORIENTATION: cursor.pitch += 45.0f; calculateCursorRotations(&cursor); break; } } break; case GLFW_KEY_DOWN: if(action == GLFW_PRESS || action == GLFW_REPEAT) { switch (state) { case STATE_POSITION: cursor.Z -= 1.0f; break; case STATE_SCALE: cursor.Xs -= 0.2f; updateScales(&cursor); break; case STATE_ORIENTATION: cursor.pitch -= 45.0f; calculateCursorRotations(&cursor); break; } } break; case GLFW_KEY_LEFT: if(action == GLFW_PRESS || action == GLFW_REPEAT) { switch (state) { case STATE_POSITION: cursor.X += 1.0f; break; case STATE_SCALE: cursor.Zs += 0.2f; updateScales(&cursor); break; case STATE_ORIENTATION: cursor.yaw += 45.0f; calculateCursorRotations(&cursor); break; } } break; case GLFW_KEY_RIGHT: if(action == GLFW_PRESS || action == GLFW_REPEAT) { switch (state) { case STATE_POSITION: cursor.X -= 1.0f; break; case STATE_SCALE: cursor.Zs -= 0.2f; updateScales(&cursor); break; case STATE_ORIENTATION: cursor.yaw -= 45.0f; calculateCursorRotations(&cursor); break; } } break; case GLFW_KEY_ENTER: { //create a new wall and place it into walls vector. Wall wall = {}; wall.position = vec3(cursor.X, cursor.Y, cursor.Z); wall.orientation = vec3(cursor.pitch, cursor.yaw, cursor.roll); wall.scale = vec3(cursor.Xs, cursor.Ys, cursor.Zs); wall.T = translate(identity_mat4(), vec3(-wall.position.v[0], wall.position.v[1], -wall.position.v[2])); walls.push_back(wall); } break; case GLFW_KEY_1:state = STATE_POSITION; break; case GLFW_KEY_2:state = STATE_ORIENTATION;break; case GLFW_KEY_3:state = STATE_SCALE; break; } }
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 ()); /* 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 () { 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 (); // 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; }