void setup_vertex_normal_buffer_object(bool smoothed) { std::vector<glm::vec3> vertices = trig.Vertices(); std::vector<glm::vec3> normals; if (smoothed) { // initialize map of normals to zero // note that we store readily hashable vector<double> types instead of // vec3s and convert between the two as required // ...avoids some of the pain using <map> without much C++ knowledge std::map< std::vector<double>, std::vector<double> > normal_map; for (int i = 0; i < vertices.size(); i++) { std::vector<double> zeros; zeros.push_back(0.0); zeros.push_back(0.0); zeros.push_back(0.0); normal_map[to_vector(vertices[i])] = zeros; } for (int i = 0; i < vertices.size(); i += 3) { // get vertices of the current triangle glm::vec3 v1 = vertices[i]; glm::vec3 v2 = vertices[i + 1]; glm::vec3 v3 = vertices[i + 2]; std::vector<double> v1_key = to_vector(v1); std::vector<double> v2_key = to_vector(v2); std::vector<double> v3_key = to_vector(v3); // compute face normal glm::vec3 face_normal = glm::cross(v3 - v2, v1 - v2); // get the old vertex normal glm::vec3 v1_old = to_vec3(normal_map[v1_key]); glm::vec3 v2_old = to_vec3(normal_map[v2_key]); glm::vec3 v3_old = to_vec3(normal_map[v3_key]); // replace the old value with the new value normal_map.erase(v1_key); normal_map.erase(v2_key); normal_map.erase(v3_key); normal_map[v1_key] = to_vector(glm::normalize(v1_old + face_normal)); normal_map[v2_key] = to_vector(glm::normalize(v2_old + face_normal)); normal_map[v3_key] = to_vector(glm::normalize(v3_old + face_normal)); } // convert the map of normals to a vector of normals for (int i = 0; i < vertices.size(); i++) { normals.push_back(to_vec3(normal_map[to_vector(vertices[i])])); } } else { for (int i = 0; i < vertices.size(); i += 3) { // get vertices of this triangle glm::vec3 v1 = vertices[i]; glm::vec3 v2 = vertices[i + 1]; glm::vec3 v3 = vertices[i + 2]; // compute face normal glm::vec3 face_normal = glm::cross(v3 - v2, v1 - v2); normals.push_back(glm::normalize(face_normal)); normals.push_back(glm::normalize(face_normal)); normals.push_back(glm::normalize(face_normal)); } } glGenBuffers(1, &vertex_normal_buffer); glBindBuffer(GL_ARRAY_BUFFER, vertex_normal_buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * normals.size(), &normals[0], GL_STATIC_DRAW); }
//Program entry point. //argc is a count of the number of arguments (including the filename of the program). //argv is a pointer to each c-style string. int main(int argc, char **argv) { atexit(cleanup); cout << "Computer Graphics Assignment 1 Demo Program" << endl; if (argc > 1) { geom.LoadFile(argv[1]); } else { cerr << "Usage:" << endl; cerr << argv[0] << " <filename> " << endl; exit(1); } geom.CalculateNormals(); //initialise OpenGL GLFWwindow* window = initialiseGL(); //create framebuffers glGenFramebuffers(1, &frameBuffer); glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer); renderTarget = setupTextureGL(NULL, 800, 600, GL_RGBA); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderTarget, 0); //depth/stencil buffer glGenTextures(1, &depthStencil); glBindTexture(GL_TEXTURE_2D, depthStencil); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 800, 600, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 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_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthStencil, 0); GLenum err = GL_NO_ERROR; while ((err = glGetError()) != GL_NO_ERROR) { printf("%d\n", err); } //load and compile the shaders GLuint objectVertexShader = loadVertexShaderGL("vertex.glsl"); GLuint objectFragmentShader = loadFragmentShaderGL("fragment.glsl"); objectShaderProgram = makeShaderProgramGL(objectVertexShader, objectFragmentShader); GLuint screenVertexShader = loadVertexShaderGL("postvertex.glsl"); GLuint screenFragmentShader = loadFragmentShaderGL("postfragment.glsl"); screenShaderProgram = makeShaderProgramGL(screenVertexShader, screenFragmentShader); //transfer the geometry to the GPU glGenVertexArrays(1, &objectVertexArray); glBindVertexArray(objectVertexArray); //create buffers we will use glGenBuffers(1, &objectVertexBuffer); glGenBuffers(1, &objectElementBuffer); glGenBuffers(1, &objectNormBuffer); //get geometry vertices, normals and edge lists vector <glm::vec3> vert = geom.Vertices(); vector <glm::vec3> norm = geom.Norms(); //vector <glm::vec2> uv=geom.UVs(); vector <Triangle> tri = geom.Triangles(); //transfer to GPU //data for each vertex glBindBuffer(GL_ARRAY_BUFFER, objectVertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * vert.size(), &vert[0], GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, objectNormBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * norm.size(), &norm[0], GL_STATIC_DRAW); //element array (triangles) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, objectElementBuffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, tri.size() * 3 * sizeof(unsigned int), &tri[0], GL_STATIC_DRAW); //setup for postprocessing glGenVertexArrays(1, &screenVertexArray); glBindVertexArray(screenVertexArray); //create buffers we will use glGenBuffers(1, &screenVertexBuffer); glGenBuffers(1, &screenElementBuffer); //data for each vertex glBindBuffer(GL_ARRAY_BUFFER, screenVertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 2 * 4, &screenVertex[0], GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, screenElementBuffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, 2 * 3 * sizeof(GLuint), &screenTri[0], GL_STATIC_DRAW); //load the texture readTexture(); texture = setupTextureGL(tex, 256, 256, GL_RGB); //main loop while (!glfwWindowShouldClose(window)) { DemoDisplay(); glfwSwapBuffers(window); glfwPollEvents(); } glfwTerminate(); }
void setup_vertex_position_buffer_object(void) { glGenBuffers(1, &vertex_position_buffer); glBindBuffer(GL_ARRAY_BUFFER, vertex_position_buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * trig.VertexCount(), &trig.Vertices()[0], GL_STATIC_DRAW); }