// glfwTest.cpp : 定义控制台应用程序的入口点。 // #include "glew.h" #include <glfw3.h> #include "common/loadShader.h" #include "common/controls.h" #include "common/objloader.h" #include "common/vboindexer.h" #include "glm.hpp" #include "ext.hpp" GLFWwindow* window; int main(void) { //GLFWwindow* window; /* Initialize the library */ if (!glfwInit()) return -1; /* Create a windowed mode window and its OpenGL context */ window = glfwCreateWindow(480, 320, "Hello World", NULL, NULL); if (!window) { glfwTerminate(); return -1; } /* Make the window's context current */ glfwMakeContextCurrent(window); // Needed in core profile if( glewInit() != GLEW_OK) { glfwTerminate(); return -1; } glClearColor(0.0f, 0.0f, 0.4f, 0.0f); // Enable depth test glEnable(GL_DEPTH_TEST); // Accept fragment if it closer to the camera than the former one glDepthFunc(GL_LESS); glEnable(GL_CULL_FACE); GLuint VertexArrayID; glGenVertexArrays(1, &VertexArrayID); glBindVertexArray(VertexArrayID); // Our vertices. Tree consecutive floats give a 3D vertex; Three consecutive vertices give a triangle. // A cube has 6 faces with 2 triangles each, so this makes 6*2=12 triangles, and 12*3 vertices std::vector<glm::vec3> vertices; std::vector<glm::vec2> uvs; std::vector<glm::vec3> normals; // Won't be used at the moment. bool res = loadOBJ("./resource/suzanne.obj", vertices, uvs, normals); std::vector<unsigned short>indices; std::vector<glm::vec3> indexed_vertices; std::vector<glm::vec2> indexed_uvs; std::vector<glm::vec3> indexed_normals; indexVBO(vertices,uvs,normals,indices,indexed_vertices,indexed_uvs,indexed_normals); //This will identify our vertex buffer GLuint vertexbuffer; //Generate 1 buffer,put the resulting identifier in vertexbuffer glGenBuffers(1,&vertexbuffer); //The following commands will talk about our 'vertexbuffer' buffer glBindBuffer(GL_ARRAY_BUFFER,vertexbuffer); //Give our vertices to OpenGL. glBufferData(GL_ARRAY_BUFFER, indexed_vertices.size() * sizeof(glm::vec3), &indexed_vertices[0], GL_STATIC_DRAW); GLuint uvbuffer; glGenBuffers(1, &uvbuffer); glBindBuffer(GL_ARRAY_BUFFER, uvbuffer); glBufferData(GL_ARRAY_BUFFER, indexed_uvs.size() * sizeof(glm::vec2), &indexed_uvs[0], GL_STATIC_DRAW); GLuint normalbuffer; glGenBuffers(1, &normalbuffer); glBindBuffer(GL_ARRAY_BUFFER, normalbuffer); glBufferData(GL_ARRAY_BUFFER, indexed_normals.size() * sizeof(glm::vec3), &indexed_normals[0], GL_STATIC_DRAW); GLuint Texture = loadDDS("./resource/uvmap.DDS");//loadBMP_custom("./resource/uvtemplate.bmp"); // One color for each vertex. They were generated randomly. GLuint elementbuffer; glGenBuffers(1,&elementbuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,elementbuffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER,indices.size() * sizeof(unsigned short),&indices[0],GL_STATIC_DRAW); GLuint programID = LoadShaders("./shader/vertex.shader","./shader/fragment.shader"); glClearColor(0.0f, 0.0f, 0.4f, 0.0f); /* Loop until the user closes the window */ // Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit 100 units //glm::mat4 Projection = glm::ortho(-4.0f/3.0f, 4.0f/3.0f, -1.0f, 1.0f, 0.1f, 100.0f); // Get a handle for our "MVP" uniform. // Only at initialisation time. GLuint MatrixID = glGetUniformLocation(programID,"MVP"); GLuint ViewMatrixID = glGetUniformLocation(programID, "V"); GLuint ModelMatrixID = glGetUniformLocation(programID, "M"); GLuint LightID = glGetUniformLocation(programID, "LightPosition_worldspace"); // Send our transformation to the currently bound shader, // in the "MVP" uniform // For each model you render, since the MVP will be different (at least the M part) GLuint TextureID = glGetUniformLocation(programID,"myTextureSampler"); int width,height; glfwGetWindowSize(window,&width,&height); float centerX = width; float centerY = height; centerX /= 2; centerY /= 2; //initMatrices(); double lastTime = glfwGetTime(); int nbFrames = 0; while (glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS && !glfwWindowShouldClose(window)) { double currentTime = glfwGetTime(); nbFrames++; if (currentTime - lastTime >= 1.0) { // printf and reset //printf("%f ms/frame\n", 1000.0/double(nbFrames)); printf("fps %d ", nbFrames); nbFrames = 0; lastTime += 1.0; } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(programID); computeMatricesFromInputs(); glm::mat4 ProjectionMatrix = getProjectionMatrix(); glm::mat4 ViewMatrix = getViewMatrix(); glm::mat4 ModelMatrix = glm::mat4(1.0); glm::mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix; // Send our transformation to the currently bound shader, // in the "MVP" uniform glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]); glUniformMatrix4fv(ModelMatrixID, 1, GL_FALSE, &ModelMatrix[0][0]); glUniformMatrix4fv(ViewMatrixID, 1, GL_FALSE, &ViewMatrix[0][0]); glm::vec3 lightPos = glm::vec3(4,4,4); glUniform3f(LightID, lightPos.x, lightPos.y, lightPos.z); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,Texture); glUniform1i(TextureID, 0); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER,vertexbuffer); glVertexAttribPointer( 0, // attribute 0. No particular reason for 0, but must match the layout in the shader. 3, // size GL_FLOAT, // type GL_FALSE, // normalized? 0, // stride (void*)0 // array buffer offset ); glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER,uvbuffer); glVertexAttribPointer( 1, // attribute 0. No particular reason for 0, but must match the layout in the shader. 2, // size GL_FLOAT, // type GL_FALSE, // normalized? 0, // stride (void*)0 // array buffer offset ); glEnableVertexAttribArray(2); glBindBuffer(GL_ARRAY_BUFFER, normalbuffer); glVertexAttribPointer( 2, // attribute 3, // size GL_FLOAT, // type GL_FALSE, // normalized? 0, // stride (void*)0 // array buffer offset ); //glDrawArrays(GL_TRIANGLES, 0, vertices.size() ); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,elementbuffer); glDrawElements(GL_TRIANGLES,indices.size(),GL_UNSIGNED_SHORT,(void*)0); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glDisableVertexAttribArray(2); /* Swap front and back buffers */ glfwSwapBuffers(window); /* Poll for and process events */ glfwPollEvents(); } glfwTerminate(); return 0; }
#include "stdio.h" #include "vboindexer.h" #include <map> struct PackedVertex{ glm::vec3 position; glm::vec2 uv; glm::vec3 normal; bool operator<(const PackedVertex that) const{ return memcmp((void*)this, (void*)&that, sizeof(PackedVertex))>0; }; }; bool getSimilarVertexIndex_fast( PackedVertex & packed, std::map<PackedVertex,unsigned short> &VertexToOutIndex, unsigned short & result ) { std::map<PackedVertex,unsigned short>::iterator it = VertexToOutIndex.find(packed); if ( it == VertexToOutIndex.end() ){ return false; }else{ result = it->second; return true; } } void indexVBO( std::vector<glm::vec3> & in_vertices, std::vector<glm::vec2> & in_uvs, std::vector<glm::vec3> & in_normals, std::vector<unsigned short> & out_indices, std::vector<glm::vec3> & out_vertices, std::vector<glm::vec2> & out_uvs, std::vector<glm::vec3> & out_normals ) { std::map<PackedVertex,unsigned short> VertexToOutIndex; for (unsigned int i = 0; i< in_vertices.size();i++) { PackedVertex packed = {in_vertices[i],in_uvs[i],in_normals[i]}; unsigned short index; bool found = getSimilarVertexIndex_fast(packed,VertexToOutIndex,index); if (found) { out_indices.push_back(index); } else { out_vertices.push_back(in_vertices[i]); out_uvs .push_back(in_uvs[i]); out_normals .push_back(in_normals[i]); unsigned short newindex = (unsigned short)out_vertices.size() - 1; out_indices.push_back(newindex); VertexToOutIndex[packed] = newindex; } } }