opengl模型加载
opengl模型加载,将模型中的顶点和纹理坐标写到buffer中。将buffer数据传过opengl.
#include "glew.h"
#include <glfw3.h>
#include "common/loadShader.h"
#include "common/controls.h"
#include "common/objloader.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;
}
// 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("cube.obj", vertices, uvs, 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, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);
GLuint uvbuffer;
glGenBuffers(1, &uvbuffer);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(glm::vec2), &uvs[0], GL_STATIC_DRAW);
GLuint Texture = loadBMP_custom("./resource/uvtemplate.bmp");
// One color for each vertex. They were generated randomly.
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");
// 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;
glfwSetCursorPos(window,centerX,centerY);
while (glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS && !glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(programID);
computeMatricesFromInputs();
glm::mat4 Projection = getProjectionMatrix();
glm::mat4 View = getViewMatrix();
//Model matrix : an identity matrix (model will be at the origin)
glm::mat4 Model = glm::mat4(1.0f);
// Our ModelViewProjection : multiplication of our 3 matrices
glm::mat4 MVP = Projection * View * Model;// Remember, matrix multiplication is the other way around
glUniformMatrix4fv(MatrixID,1,GL_FALSE,&MVP[0][0]);
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
);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glDrawArrays(GL_TRIANGLES,0,12*3);// Starting from vertex 0; 3 vertices total -> 1 triangle
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
loadobj
#include "stdio.h"
#include "objloader.h"
bool loadOBJ(
const char* path,
std::vector<glm::vec3> & out_vertices,
std::vector<glm::vec2> & out_uvs,
std::vector<glm::vec3> & out_normals
)
{
std::vector<unsigned int> vertexIndices,uvIndices,normalIndices;
std::vector<glm::vec3> temp_vertices;
std::vector<glm::vec2> temp_uvs;
std::vector<glm::vec3> temp_normals;
FILE * file = fopen(path,"r");
if (file == NULL)
{
printf("IMpossible to open the file !\n");
return false;
}
while(1){
char lineHeader[128];
int res = fscanf(file,"%s",lineHeader);
if (res == EOF)
{
break;
}
if (strcmp(lineHeader,"v") == 0)
{
glm::vec3 vertex;
fscanf(file,"%f %f %f\n",&vertex.x,&vertex.y,&vertex.z);
temp_vertices.push_back(vertex);
}else if (strcmp(lineHeader,"vt") == 0)
{
glm::vec2 uv;
fscanf(file,"%f %f\n",&uv.x,&uv.y);
uv.y = -uv.y;
temp_uvs.push_back(uv);
}
else if (strcmp(lineHeader,"vn")== 0)
{
glm::vec3 normal;
fscanf(file,"%f %f %f\n",&normal.x,&normal.y,&normal.z);
temp_normals.push_back(normal);
}
else if(strcmp(lineHeader,"f") == 0)
{
std::string vertex1,vertex2,vertex3;
unsigned int vertexIndex[3],uvIndex[3],normalIndex[3];
int matches = fscanf(file,"%d/%d/%d %d/%d/%d %d/%d/%d\n",&vertexIndex[0], &uvIndex[0], &normalIndex[0], &vertexIndex[1], &uvIndex[1], &normalIndex[1], &vertexIndex[2], &uvIndex[2], &normalIndex[2] );
if (matches != 9)
{
printf("File can't be read by our simple parser :-( Try exporting with other options\n");
return false;
}
vertexIndices.push_back(vertexIndex[0]);
vertexIndices.push_back(vertexIndex[1]);
vertexIndices.push_back(vertexIndex[2]);
uvIndices .push_back(uvIndex[0]);
uvIndices .push_back(uvIndex[1]);
uvIndices .push_back(uvIndex[2]);
normalIndices.push_back(normalIndex[0]);
normalIndices.push_back(normalIndex[1]);
normalIndices.push_back(normalIndex[2]);
}
else
{
// Probably a comment, eat up the rest of the line
char stupidBuffer[1000];
fgets(stupidBuffer, 1000, file);
}
}
for( unsigned int i=0; i<vertexIndices.size(); i++ ){
// Get the indices of its attributes
unsigned int vertexIndex = vertexIndices[i];
unsigned int uvIndex = uvIndices[i];
unsigned int normalIndex = normalIndices[i];
// Get the attributes thanks to the index
glm::vec3 vertex = temp_vertices[ vertexIndex-1 ];
glm::vec2 uv = temp_uvs[ uvIndex-1 ];
glm::vec3 normal = temp_normals[ normalIndex-1 ];
// Put the attributes in buffers
out_vertices.push_back(vertex);
out_uvs .push_back(uv);
out_normals .push_back(normal);
}
return true;
}