void load_sphere () { float* points = NULL; float* tex_coords = NULL; float* normals = NULL; g_sphere_point_count = 0; assert (load_obj_file ( MESH_FILE, points, tex_coords, normals, g_sphere_point_count )); glGenVertexArrays (1, &g_sphere_vao); glBindVertexArray (g_sphere_vao); GLuint vbo; glGenBuffers (1, &vbo); glBindBuffer (GL_ARRAY_BUFFER, vbo); glBufferData ( GL_ARRAY_BUFFER, sizeof (float) * 3 * g_sphere_point_count, points, GL_STATIC_DRAW ); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (0); }
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(); }
/* load spherical mesh used for coverage area of each light */ bool load_sphere () { float* sphere_points = NULL; float* sphere_tex_coords = NULL; float* sphere_normals = NULL; if (!load_obj_file ( SPHERE_FILE, sphere_points, sphere_tex_coords, sphere_normals, g_sphere_point_count )) { fprintf (stderr, "ERROR loading sphere mesh %s\n", SPHERE_FILE); return false; } // create vao glGenVertexArrays (1, &g_sphere_vao); glBindVertexArray (g_sphere_vao); GLuint points_vbo; glGenBuffers (1, &points_vbo); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glBufferData ( GL_ARRAY_BUFFER, g_sphere_point_count * 3 * sizeof (GLfloat), sphere_points, GL_STATIC_DRAW ); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (0); return true; }
void DepthOfField::setupBuffers() { // VAO + VBO for debug. glGenVertexArrays(1, &vao); glBindVertexArray(vao); glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); float* vertices; num_vertices = load_obj_file("sphere.obj", &vertices, true); glBufferData(GL_ARRAY_BUFFER, num_vertices * 6 * sizeof(float), vertices, GL_STATIC_DRAW); delete[] vertices; GLint pos = glGetAttribLocation(scene_prog, "a_pos"); GLint norm = glGetAttribLocation(scene_prog, "a_norm"); glEnableVertexAttribArray(pos); glEnableVertexAttribArray(norm); glVertexAttribPointer(pos, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, (GLvoid*)0); glVertexAttribPointer(norm, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, (GLvoid*)12); // VAO + VBO for image debug drawer glGenVertexArrays(1, &image_vao); glBindVertexArray(image_vao); glGenBuffers(1, &image_vbo); glBindBuffer(GL_ARRAY_BUFFER, image_vbo); float s = 1.0f; float img_verts[] = { -s, -s, 0.0f, 0.0f, s, -s, 1.0f, 0.0f, s, s, 1.0f, 1.0f, -s, -s, 0.0f, 0.0f, s, s, 1.0f, 1.0f, -s, s, 0.0f, 1.0f }; glBufferData(GL_ARRAY_BUFFER, sizeof(img_verts), img_verts, GL_STATIC_DRAW); pos = glGetAttribLocation(image_prog, "a_pos"); GLint tex = glGetAttribLocation(image_prog, "a_tex"); glEnableVertexAttribArray(pos); glEnableVertexAttribArray(tex); glVertexAttribPointer(pos, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 4, (GLvoid*)0); glVertexAttribPointer(tex, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, (GLvoid*)8); }
void create_vao_from_obj (const char* fn, uint* vao, int* pc) { float* v[3]; assert (load_obj_file (fn, &v[0], &v[1], &v[2], pc)); uint vbos[3]; glGenVertexArrays (1, vao); glBindVertexArray (*vao); glGenBuffers (3, vbos); glEnableVertexAttribArray (0); glBindBuffer (GL_ARRAY_BUFFER, vbos[0]); glBufferData (GL_ARRAY_BUFFER, 4 * 3 * *pc, v[0], GL_STATIC_DRAW); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (1); glBindBuffer (GL_ARRAY_BUFFER, vbos[1]); glBufferData (GL_ARRAY_BUFFER, 4 * 2 * *pc, v[1], GL_STATIC_DRAW); glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (2); glBindBuffer (GL_ARRAY_BUFFER, vbos[2]); glBufferData (GL_ARRAY_BUFFER, 4 * 3 * *pc, v[2], GL_STATIC_DRAW); glVertexAttribPointer (2, 3, GL_FLOAT, GL_FALSE, 0, NULL); }
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 _tmain(int argc, _TCHAR* argv[]) { cout << "Zhou's obj -> objx Converter, Mar.2016." << endl << endl; if(argc < 2) { cout << "Usage:" << endl << endl << "objcvt.exe [-a] [-c] [-p] \"input file path name\"" << endl<< endl << "-a: amalgamate groups as much as possible. Groups using different materials, or belonging to different objects, cannot be merged together." << endl << "-c: move geometry centre to the origin. Use it only when the source file contains one mesh" << endl << "-p: remove path from texture file name." << endl << endl; system("pause"); return E_INVALIDARG; } TCHAR infile[MAX_PATH], outfile[MAX_PATH]; bool amalgamation = false, centralization = false, removepath = false; for(int i = 1; i < argc; i++) { if(0 == StrCmpI(_T("-a"), argv[i])) amalgamation = true; else if(0 == StrCmpI(_T("-c"), argv[i])) centralization = true; else if(0 == StrCmpI(_T("-p"), argv[i])) removepath = true; else _tcscpy_s(infile, MAX_PATH, argv[i]); } _tcscpy_s(outfile, MAX_PATH, infile); PathRenameExtension(outfile, _T(".objx")); obj_mesh_data data; objects objs; mtllib mtlib; scene scn; if(!load_obj_file(infile, data, objs, mtlib, scn, amalgamation, removepath, disp_propress)) { int err = GetLastError(); printf("Failed to open input file, error code: %X.\n\n", err); system("pause"); return err; } if(centralization) centralize(data.vertices); disp_statistics(data, objs, mtlib); scene_desc sd; sd.camera_pos = scn.cameraPosition; sd.camera_ypr = scn.cameraYPR; for(int i = 0; i < MAXLIGHTS; i++) { sd.light_pos[i] = scn.lightPositions[i]; sd.light_dir[i] = scn.lightDirections[i]; } HOBJXIO hobjxio = create_objx(outfile, sd); if(!hobjxio) { int err = GetLastError(); printf("Failed to open input file, error code: %X.\n\n", err); system("pause"); return err; } mesh_info mesh; for(int o = 0; o < (int)objs.size(); o++) { groups& grps = objs[o]; for(groups::iterator g = grps.begin(); g != grps.end(); g++) { group& grp = g->second; for(group::iterator it = grp.begin(); it != grp.end(); it++) { material mtl; mtllib::iterator it_mtl = mtlib.find(it->first); if(mtlib.end() == it_mtl) mtl = DEF_MATERIAL; else mtl = it_mtl->second; faces& fs = it->second; if(!write_face(hobjxio, g->first, fs, data, mtl)) { int err = GetLastError(); printf("Failed to write output file, error code: %X.\n\n", err); break; } } } } close_objx(hobjxio); cout << endl << endl << "Succeeded." << endl << "Output file: \"" << CT2CA(outfile) << "\"" << endl << endl; system("pause"); return 0; }
int main () { GLFWwindow* window = NULL; const GLubyte* renderer; const GLubyte* version; GLuint cube_sp, knot_sp; GLuint vao; // // Start OpenGL using helper libraries // -------------------------------------------------------------------------- if (!glfwInit ()) { fprintf (stderr, "ERROR: could not start GLFW3\n"); return 1; } /* change to 3.2 if on Apple OS X glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 0); glfwWindowHint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); */ glfwWindowHint (GLFW_SAMPLES, msaa); window = glfwCreateWindow (gl_width, gl_height, "{quadratic bezier}", NULL, NULL); if (!window) { fprintf (stderr, "ERROR: opening OS window\n"); return 1; } glfwMakeContextCurrent (window); glewExperimental = GL_TRUE; glewInit (); /* get version info */ renderer = glGetString (GL_RENDERER); /* get renderer string */ version = glGetString (GL_VERSION); /* version as a string */ printf ("Renderer: %s\n", renderer); printf ("OpenGL version supported %s\n", version); int point_count = 0; // // Set up vertex buffers and vertex array object // -------------------------------------------------------------------------- { GLfloat* vp = NULL; // array of vertex points GLfloat* vn = NULL; // array of vertex normals (we haven't used these yet) GLfloat* vt = NULL; // array of texture coordinates (or these) assert (load_obj_file ("smcube.obj", vp, vt, vn, point_count)); GLuint points_vbo, texcoord_vbo, normal_vbo; glGenBuffers (1, &points_vbo); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 3 * point_count, vp, GL_STATIC_DRAW); glGenBuffers (1, &texcoord_vbo); glBindBuffer (GL_ARRAY_BUFFER, texcoord_vbo); glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 2 * point_count, vt, GL_STATIC_DRAW); glGenBuffers (1, &normal_vbo); glBindBuffer (GL_ARRAY_BUFFER, normal_vbo); glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 3 * point_count, vn, GL_STATIC_DRAW); glGenVertexArrays (1, &vao); glBindVertexArray (vao); glEnableVertexAttribArray (0); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (1); glBindBuffer (GL_ARRAY_BUFFER, texcoord_vbo); glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (2); glBindBuffer (GL_ARRAY_BUFFER, normal_vbo); glVertexAttribPointer (2, 3, GL_FLOAT, GL_FALSE, 0, NULL); free (vp); free (vn); free (vt); } // // Load shaders from files // -------------------------------------------------------------------------- { char* vertex_shader_str; char* fragment_shader_str; // allocate some memory to store shader strings vertex_shader_str = (char*)malloc (81920); fragment_shader_str = (char*)malloc (81920); // load shader strings from text files assert (parse_file_into_str ("cube.vert", vertex_shader_str, 81920)); assert (parse_file_into_str ("cube.frag", fragment_shader_str, 81920)); GLuint vs, fs; vs = glCreateShader (GL_VERTEX_SHADER); fs = glCreateShader (GL_FRAGMENT_SHADER); glShaderSource (vs, 1, (const char**)&vertex_shader_str, NULL); glShaderSource (fs, 1, (const char**)&fragment_shader_str, NULL); // free memory free (vertex_shader_str); free (fragment_shader_str); glCompileShader (vs); glCompileShader (fs); cube_sp = glCreateProgram (); glAttachShader (cube_sp, fs); glAttachShader (cube_sp, vs); glBindAttribLocation (cube_sp, 0, "vp"); glBindAttribLocation (cube_sp, 1, "vt"); glBindAttribLocation (cube_sp, 2, "vn"); glLinkProgram (cube_sp); } { char* vertex_shader_str; char* fragment_shader_str; // allocate some memory to store shader strings vertex_shader_str = (char*)malloc (81920); fragment_shader_str = (char*)malloc (81920); // load shader strings from text files assert (parse_file_into_str ("knot.vert", vertex_shader_str, 81920)); assert (parse_file_into_str ("knot.frag", fragment_shader_str, 81920)); GLuint vs, fs; vs = glCreateShader (GL_VERTEX_SHADER); fs = glCreateShader (GL_FRAGMENT_SHADER); glShaderSource (vs, 1, (const char**)&vertex_shader_str, NULL); glShaderSource (fs, 1, (const char**)&fragment_shader_str, NULL); // free memory free (vertex_shader_str); free (fragment_shader_str); glCompileShader (vs); glCompileShader (fs); knot_sp = glCreateProgram (); glAttachShader (knot_sp, fs); glAttachShader (knot_sp, vs); glLinkProgram (knot_sp); } // // Create some matrices // -------------------------------------------------------------------------- mat4 M, V, P; M = identity_mat4 ();//scale (identity_mat4 (), vec3 (0.05, 0.05, 0.05)); vec3 cam_pos (0.0, 0.0, 15.0); vec3 targ_pos (0.0, 0.0, 0.0); vec3 up = normalise (vec3 (0.0, 1.0, 0.0)); V = look_at (cam_pos, targ_pos, up); P = perspective (67.0f, (float)gl_width / (float)gl_height, 0.1, 1000.0); int M_loc = glGetUniformLocation (cube_sp, "M"); int V_loc = glGetUniformLocation (cube_sp, "V"); int P_loc = glGetUniformLocation (cube_sp, "P"); int A_loc = glGetUniformLocation (cube_sp, "A"); int B_loc = glGetUniformLocation (cube_sp, "B"); int C_loc = glGetUniformLocation (cube_sp, "C"); int t_loc = glGetUniformLocation (cube_sp, "t"); // send matrix values to shader immediately glUseProgram (cube_sp); glUniformMatrix4fv (M_loc, 1, GL_FALSE, M.m); glUniformMatrix4fv (V_loc, 1, GL_FALSE, V.m); glUniformMatrix4fv (P_loc, 1, GL_FALSE, P.m); // // specific knots for bezier here A, C are start, end, B is control point // vec3 A = vec3 (-7.0f, -5.0f, 0.0f); vec3 B = vec3 (0.0f, 8.0f, 0.0f); vec3 C = vec3 (7.0f, -5.0f, 0.0f); glUniform3fv (A_loc, 1, A.v); glUniform3fv (B_loc, 1, B.v); glUniform3fv (C_loc, 1, C.v); int knot_loc = glGetUniformLocation (knot_sp, "pos"); int knotP_loc = glGetUniformLocation (knot_sp, "P"); int knotV_loc = glGetUniformLocation (knot_sp, "V"); glUseProgram (knot_sp); glUniformMatrix4fv (knotV_loc, 1, GL_FALSE, V.m); glUniformMatrix4fv (knotP_loc, 1, GL_FALSE, P.m); // // Start rendering // -------------------------------------------------------------------------- // tell GL to only draw onto a pixel if the fragment is closer to the viewer glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" glDepthFunc (GL_LESS); // depth-testing is to use a "less than" function glEnable (GL_CULL_FACE); // enable culling of faces glCullFace (GL_BACK); glFrontFace (GL_CCW); glClearColor (0.04, 0.04, 0.75, 1.0); /* Render Points, allow resize in vertex shader */ glEnable (GL_PROGRAM_POINT_SIZE); glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); float t = 0.0f; float speed = 0.5f; double prev = glfwGetTime (); while (!glfwWindowShouldClose (window)) { glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // just the default viewport, covering the whole render area glViewport (0, 0, gl_width, gl_height); double curr = glfwGetTime (); double elapsed = curr - prev; prev = curr; // // move along spline if (GLFW_PRESS == glfwGetKey (window, GLFW_KEY_LEFT)) { t -= elapsed * speed; if (t < 0.0f) { t = 0.0f; } } if (GLFW_PRESS == glfwGetKey (window, GLFW_KEY_RIGHT)) { t += elapsed * speed; if (t > 1.0f) { t = 1.0f; } } // // render 3 knots glEnable (GL_PROGRAM_POINT_SIZE); glUseProgram (knot_sp); glUniform3fv (knot_loc, 1, A.v); glDrawArrays (GL_POINTS, 0, 1); glUseProgram (knot_sp); glUniform3fv (knot_loc, 1, B.v); glDrawArrays (GL_POINTS, 0, 1); glUseProgram (knot_sp); glUniform3fv (knot_loc, 1, C.v); glDrawArrays (GL_POINTS, 0, 1); glDisable (GL_PROGRAM_POINT_SIZE); glUseProgram (cube_sp); glBindVertexArray (vao); M = identity_mat4 ();//rotate_y_deg (identity_mat4 (), a); glUniformMatrix4fv (M_loc, 1, GL_FALSE, M.m); glUniform1f (t_loc, t); glDrawArrays (GL_TRIANGLES, 0, point_count); /* this just updates window events and keyboard input events (not used yet) */ glfwPollEvents (); glfwSwapBuffers (window); } return 0; }
/** * Set OpenGL initial state */ void tree_renderer::init() { /* Set clear color */ glClearColor(0.0, 0.0, 0.0, 1.0); /* Set 2D orthogonal projection */ //gluOrtho2D(0.0,800,600, 0.0); std::ifstream ifs; std::string line = "", text = ""; /* Initialize the vertex shader (generate, load, compile and check errors) */ ifs.open("tree_vertex.glsl", std::ios::in); while (ifs.good()) { getline(ifs, line); text += line + "\n"; } vertexSource = text.c_str(); vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexSource, NULL); glCompileShader(vertexShader); GLint status = 0; glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status); if (status != GL_TRUE) { char buffer[512]; glGetShaderInfoLog(vertexShader, 512, NULL, buffer); std::cout << "Error while compiling the vertex shader: " << std::endl << buffer << std::endl; } /* Initialize the fragment shader (generate, load, compile and check errors) */ ifs.open("tree_fragment.glsl", std::ios::in); line = "", text = ""; while (ifs.good()) { getline(ifs, line); text += line + "\n"; } fragmentSource = text.c_str(); fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentSource, NULL); glCompileShader(fragmentShader); status = 0; glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &status); if (status != GL_TRUE) { char buffer[512]; glGetShaderInfoLog(fragmentShader, 512, NULL, buffer); std::cout << "Error while compiling the fragment shader: " << std::endl << buffer << std::endl; } /* Load the information of the cylinder */ load_obj_file("cylinder.obj", cylinderVertices, cylinderCoords, cylinderNormals, cylinderVertexCount); /* Load the information of the 3D cone */ load_obj_file("cone.obj", coneVertices, coneCoords, coneNormals, coneVertexCount); /* Initialize the Vertex Buffer Object for the vertices */ glGenBuffers(1, &cylinderVerticesVbo); glBindBuffer(GL_ARRAY_BUFFER, cylinderVerticesVbo); glBufferData(GL_ARRAY_BUFFER, 3 * cylinderVertexCount * sizeof(GLfloat), cylinderVertices, GL_STATIC_DRAW); glGenBuffers(1, &coneVerticesVbo); glBindBuffer(GL_ARRAY_BUFFER, coneVerticesVbo); glBufferData(GL_ARRAY_BUFFER, 3 * coneVertexCount * sizeof(GLfloat), coneVertices, GL_STATIC_DRAW); glGenBuffers(1, &lineVerticesVbo); glBindBuffer(GL_ARRAY_BUFFER, lineVerticesVbo); glBufferData(GL_ARRAY_BUFFER, 3 * lineVerticesCount * sizeof(GLfloat), lineVertices, GL_STATIC_DRAW); glGenBuffers(1, &colorVbo); glBindBuffer(GL_ARRAY_BUFFER, colorVbo); glBufferData(GL_ARRAY_BUFFER, 3 * lineVerticesCount * sizeof(GLfloat), colors, GL_STATIC_DRAW); /* Define the Vertex Array Object of the 3D model */ /* glGenVertexArrays(1, &lineVao); glBindVertexArray(lineVao); glBindBuffer(GL_ARRAY_BUFFER, lineVerticesVbo); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glBindBuffer(GL_ARRAY_BUFFER, colorVbo); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); */ glGenVertexArrays(1, &cylinderVao); glBindVertexArray(cylinderVao); glBindBuffer(GL_ARRAY_BUFFER, cylinderVerticesVbo); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); //glBindBuffer(GL_ARRAY_BUFFER, colorVbo); //glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray(0); //glEnableVertexAttribArray(1); /* Initialize the shader program */ shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glBindAttribLocation(shaderProgram, 0, "inPoint"); glBindAttribLocation(shaderProgram, 1, "inColor"); glLinkProgram(shaderProgram); /* Get the location of the uniform variables */ modelMatrixLocation = glGetUniformLocation(shaderProgram, "modelMatrix"); viewMatrixLocation = glGetUniformLocation(shaderProgram, "viewMatrix"); projMatrixLocation = glGetUniformLocation(shaderProgram, "projMatrix"); colorLocation = glGetUniformLocation(shaderProgram, "inColor"); /* Set the shader program in the pipeline */ glUseProgram(shaderProgram); }
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 OPENGL--------------------------------*/ assert (restart_gl_log ()); // start GL context and O/S window using the GLFW helper library assert (start_gl ()); // set a function to be called when the mouse is clicked glfwSetMouseButtonCallback (g_window, glfw_mouse_click_callback); /*------------------------------CREATE GEOMETRY-------------------------------*/ GLfloat* vp = NULL; // array of vertex points GLfloat* vn = NULL; // array of vertex normals GLfloat* vt = NULL; // array of texture coordinates int g_point_count = 0; assert (load_obj_file (MESH_FILE, vp, vt, vn, g_point_count)); GLuint vao; glGenVertexArrays (1, &vao); glBindVertexArray (vao); GLuint points_vbo; if (NULL != vp) { glGenBuffers (1, &points_vbo); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glBufferData ( GL_ARRAY_BUFFER, 3 * g_point_count * sizeof (GLfloat), vp, GL_STATIC_DRAW ); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (0); } /*-------------------------------CREATE SHADERS-------------------------------*/ GLuint shader_programme = create_programme_from_files ( VERTEX_SHADER_FILE, FRAGMENT_SHADER_FILE ); int model_mat_location = glGetUniformLocation (shader_programme, "model"); int view_mat_location = glGetUniformLocation (shader_programme, "view"); int proj_mat_location = glGetUniformLocation (shader_programme, "proj"); int blue_location = glGetUniformLocation (shader_programme, "blue"); /*-------------------------------CREATE CAMERA--------------------------------*/ #define ONE_DEG_IN_RAD (2.0 * M_PI) / 360.0 // 0.017444444 // input variables float near = 0.1f; // clipping plane float far = 100.0f; // clipping plane float fovy = 67.0f; // 67 degrees float aspect = (float)g_gl_width / (float)g_gl_height; // aspect ratio proj_mat = perspective (fovy, aspect, near, far); float cam_speed = 3.0f; // 1 unit per second float cam_heading_speed = 50.0f; // 30 degrees per second float cam_heading = 0.0f; // y-rotation in degrees mat4 T = translate ( identity_mat4 (), vec3 (-cam_pos.v[0], -cam_pos.v[1], -cam_pos.v[2]) ); mat4 R = rotate_y_deg (identity_mat4 (), -cam_heading); versor q = quat_from_axis_deg (-cam_heading, 0.0f, 1.0f, 0.0f); view_mat = R * T; // keep track of some useful vectors that can be used for keyboard movement vec4 fwd (0.0f, 0.0f, -1.0f, 0.0f); vec4 rgt (1.0f, 0.0f, 0.0f, 0.0f); vec4 up (0.0f, 1.0f, 0.0f, 0.0f); /*---------------------------SET RENDERING DEFAULTS---------------------------*/ glUseProgram (shader_programme); glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, view_mat.m); glUniformMatrix4fv (proj_mat_location, 1, GL_FALSE, proj_mat.m); // unique model matrix for each sphere mat4 model_mats[NUM_SPHERES]; for (int i = 0; i < NUM_SPHERES; i++) { model_mats[i] = translate (identity_mat4 (), sphere_pos_wor[i]); } glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CCW); // set counter-clock-wise vertex order to mean the front glClearColor (0.2, 0.2, 0.2, 1.0); // grey background to help spot mistakes glViewport (0, 0, g_gl_width, g_gl_height); /*-------------------------------RENDERING LOOP-------------------------------*/ while (!glfwWindowShouldClose (g_window)) { // update timers static double previous_seconds = glfwGetTime (); double current_seconds = glfwGetTime (); double elapsed_seconds = current_seconds - previous_seconds; previous_seconds = current_seconds; _update_fps_counter (g_window); // wipe the drawing surface clear glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram (shader_programme); glBindVertexArray (vao); for (int i = 0; i < NUM_SPHERES; i++) { if (g_selected_sphere == i) { glUniform1f (blue_location, 1.0f); } else { glUniform1f (blue_location, 0.0f); } glUniformMatrix4fv (model_mat_location, 1, GL_FALSE, model_mats[i].m); glDrawArrays (GL_TRIANGLES, 0, g_point_count); } // update other events like input handling glfwPollEvents (); // control keys bool cam_moved = false; vec3 move (0.0, 0.0, 0.0); float cam_yaw = 0.0f; // y-rotation in degrees float cam_pitch = 0.0f; float cam_roll = 0.0; if (glfwGetKey (g_window, GLFW_KEY_A)) { move.v[0] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_D)) { move.v[0] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_Q)) { move.v[1] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_E)) { move.v[1] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_W)) { move.v[2] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_S)) { move.v[2] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_LEFT)) { cam_yaw += cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_yaw = quat_from_axis_deg ( cam_yaw, up.v[0], up.v[1], up.v[2] ); q = q_yaw * q; } if (glfwGetKey (g_window, GLFW_KEY_RIGHT)) { cam_yaw -= cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_yaw = quat_from_axis_deg ( cam_yaw, up.v[0], up.v[1], up.v[2] ); q = q_yaw * q; } if (glfwGetKey (g_window, GLFW_KEY_UP)) { cam_pitch += cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_pitch = quat_from_axis_deg ( cam_pitch, rgt.v[0], rgt.v[1], rgt.v[2] ); q = q_pitch * q; } if (glfwGetKey (g_window, GLFW_KEY_DOWN)) { cam_pitch -= cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_pitch = quat_from_axis_deg ( cam_pitch, rgt.v[0], rgt.v[1], rgt.v[2] ); q = q_pitch * q; } if (glfwGetKey (g_window, GLFW_KEY_Z)) { cam_roll -= cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_roll = quat_from_axis_deg ( cam_roll, fwd.v[0], fwd.v[1], fwd.v[2] ); q = q_roll * q; } if (glfwGetKey (g_window, GLFW_KEY_C)) { cam_roll += cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_roll = quat_from_axis_deg ( cam_roll, fwd.v[0], fwd.v[1], fwd.v[2] ); q = q_roll * q; } // update view matrix if (cam_moved) { // re-calculate local axes so can move fwd in dir cam is pointing R = quat_to_mat4 (q); fwd = R * vec4 (0.0, 0.0, -1.0, 0.0); rgt = R * vec4 (1.0, 0.0, 0.0, 0.0); up = R * vec4 (0.0, 1.0, 0.0, 0.0); cam_pos = cam_pos + vec3 (fwd) * -move.v[2]; cam_pos = cam_pos + vec3 (up) * move.v[1]; cam_pos = cam_pos + vec3 (rgt) * move.v[0]; mat4 T = translate (identity_mat4 (), vec3 (cam_pos)); view_mat = inverse (R) * inverse (T); glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, view_mat.m); } if (GLFW_PRESS == glfwGetKey (g_window, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (g_window, 1); } // put the stuff we've been drawing onto the display glfwSwapBuffers (g_window); } // close GL context and any other GLFW resources glfwTerminate(); return 0; }
int main () { /*--------------------------------START OPENGL---------------------------*/ assert (restart_gl_log ()); // start GL context and O/S window using the GLFW helper library assert (start_gl ()); glEnable (GL_DEPTH_TEST); // enable depth-testing // depth-testing interprets a smaller value as "closer" glDepthFunc (GL_LESS); glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face // set counter-clock-wise vertex order to mean the front glFrontFace (GL_CCW); glClearColor (0.2, 0.2, 0.2, 1.0); // grey background to help spot mistakes glViewport (0, 0, g_gl_width, g_gl_height); /*------------------------------CREATE GEOMETRY------------------------------*/ GLfloat* vp = NULL; // array of vertex points GLfloat* vn = NULL; // array of vertex normals GLfloat* vt = NULL; // array of texture coordinates int g_point_count = 0; assert (load_obj_file (MESH_FILE, vp, vt, vn, g_point_count)); GLuint vao; glGenVertexArrays (1, &vao); glBindVertexArray (vao); GLuint points_vbo; if (NULL != vp) { glGenBuffers (1, &points_vbo); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glBufferData (GL_ARRAY_BUFFER, 3 * g_point_count * sizeof (GLfloat), vp, GL_STATIC_DRAW); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (0); } GLuint normals_vbo; if (NULL != vn) { glGenBuffers (1, &normals_vbo); glBindBuffer (GL_ARRAY_BUFFER, normals_vbo); glBufferData (GL_ARRAY_BUFFER, 3 * g_point_count * sizeof (GLfloat), vn, GL_STATIC_DRAW); glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (1); } GLuint texcoords_vbo; if (NULL != vp) { glGenBuffers (1, &texcoords_vbo); glBindBuffer (GL_ARRAY_BUFFER, texcoords_vbo); glBufferData (GL_ARRAY_BUFFER, 2 * g_point_count * sizeof (GLfloat), vp, GL_STATIC_DRAW); glVertexAttribPointer (2, 2, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (2); } /*-------------------------------CREATE SHADERS------------------------------*/ GLuint shader_programme = create_programme_from_files (VERTEX_SHADER_FILE, FRAGMENT_SHADER_FILE); int view_mat_location = glGetUniformLocation (shader_programme, "view"); int proj_mat_location = glGetUniformLocation (shader_programme, "proj"); /* 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 = 10.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; glUseProgram (shader_programme); glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, view_mat.m); 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 (vao); // draw points 0-3 from the currently bound VAO with current 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; }