在qt中实现opengl obj模型导入:
main.cpp
#include mish.h #include mish.cpp #include "misc.h" model.h struct VertexData model.cpp #include "model.h" model.pro TEMPLATE = app 最后的效果:
#include
#include
#include
#include
#include"misc.h"
#include"model.h"
GLfloat deltaTime = 0.0f;
GLfloat lastFrame = 0.0f;
GLint CreateGPUProgram(const char*vsShaderPath,const char*fsShaderPath)
{
GLuint vsShader=glCreateShader(GL_VERTEX_SHADER);
GLuint fsShader=glCreateShader(GL_FRAGMENT_SHADER);
const char*vsCode=LoadFileContent(vsShaderPath);
const char*fsCode=LoadFileContent(fsShaderPath);
glShaderSource(vsShader,1,&vsCode,nullptr);
glShaderSource(fsShader,1,&fsCode,nullptr);
glCompileShader(vsShader);
glCompileShader(fsShader);
GLuint program=glCreateProgram();
glAttachShader(program,vsShader);
glAttachShader(program,fsShader);
glLinkProgram(program);
glDetachShader(program,vsShader);
glDetachShader(program,fsShader);
glDeleteShader(vsShader);
glDeleteShader(fsShader);
return program;
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
int main(void)
{
GLFWwindow* window;
if (!glfwInit())
return -1;
window = glfwCreateWindow(480, 320, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
// 还需要注册这个函数,告诉GLFW我们希望每当窗口调整大小的时候调用这个函数。
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
glewInit();
GLuint program = CreateGPUProgram("/home/jun/OpenGL/model/sample.vs", "/home/jun/OpenGL/model/sample.fs");
GLint posLocation, texcoordLocation,normalLocation, MLocation, VLocation, PLocation;
posLocation = glGetAttribLocation(program, "pos");
texcoordLocation = glGetAttribLocation(program, "texcoord");
normalLocation = glGetAttribLocation(program, "normal");
MLocation = glGetUniformLocation(program, "M");
VLocation = glGetUniformLocation(program, "V");
PLocation = glGetUniformLocation(program, "P");
unsigned int *indexes = nullptr;
int vertexCount = 0, indexCount = 0;
VertexData*vertexes = LoadObjModel("/home/jun/OpenGL/model/MODEL/niutou.obj", &indexes, vertexCount, indexCount);
if (vertexes==nullptr)
{
printf("load obj model fail\n");
}
//obj model -> vbo & ibo
GLuint vbo = CreateBufferObject(GL_ARRAY_BUFFER, sizeof(VertexData) * vertexCount, GL_STATIC_DRAW, vertexes);
GLuint ibo = CreateBufferObject(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * indexCount, GL_STATIC_DRAW, indexes);
printf("vertex count %d index count %d\n",vertexCount,indexCount);
glClearColor(41.0f / 255.0f, 71.0f / 255.0f, 121.0f / 255.0f, 1.0f);
//ShowWindow(hwnd, SW_SHOW);
//UpdateWindow(hwnd);
float identity[] = {
1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1
};
//创建一个投影矩阵
glm::mat4 model;
model = glm::translate(model, glm::vec3(0.0f, 0.0f, -54.0f));
model = glm::scale(model, glm::vec3(0.2f, 0.2f, 0.2f));
glm::mat4 projection=glm::perspective(45.0f,800.0f/600.0f,0.1f,1000.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
while (!glfwWindowShouldClose(window))
{
GLfloat currentFrame = (GLfloat)glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
glfwPollEvents();
// glClearColor(1.0f, 0.04f, 0.14f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glUseProgram(program);
glUniformMatrix4fv(MLocation, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(VLocation, 1, GL_FALSE, identity);
glUniformMatrix4fv(PLocation, 1, GL_FALSE, glm::value_ptr(projection));
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glEnableVertexAttribArray(posLocation);
glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)0);
glEnableVertexAttribArray(texcoordLocation);
glVertexAttribPointer(texcoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)(sizeof(float) * 3));
glEnableVertexAttribArray(normalLocation);
glVertexAttribPointer(normalLocation, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)(sizeof(float) * 5));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glUseProgram(0);
glfwSwapBuffers(window);
}
glfwTerminate();
return 0;
}
GLuint CreateBufferObject(GLenum bufferType, GLsizeiptr size, GLenum usage, void*data = nullptr);
char *LoadFileContent(const char*path);
#include
GLuint CreateBufferObject(GLenum bufferType, GLsizeiptr size, GLenum usage, void*data /* = nullptr */)
{
GLuint object;
glGenBuffers(1, &object);
glBindBuffer(bufferType, object);
glBufferData(bufferType, size, data, usage);
glBindBuffer(bufferType, 0);
return object;
}
char *LoadFileContent(const char*path)
{
FILE*pFile = fopen(path, "rb");
if (pFile)
{
fseek(pFile, 0, SEEK_END);
int nLen = ftell(pFile);
char*buffer = nullptr;
if (nLen!=0)
{
buffer=new char[nLen + 1];
rewind(pFile);
fread(buffer, nLen, 1, pFile);
buffer[nLen] = '\0';
}
else
{
printf("load file fail %s content len is 0\n", path);
}
fclose(pFile);
return buffer;
}
else
{
printf("open file %s fail\n",path);
}
fclose(pFile);
return nullptr;
}
{
float position[3];
float texcoord[2];
float normal[3];
};
VertexData*LoadObjModel(const char* filePath,unsigned int **indexes,int&vertexCount,int&indexCount);
#include "misc.h"
#include
#include <string.h>
#include
#include
VertexData*LoadObjModel(const char* filePath, unsigned int **indexes, int&vertexCount, int&indexCount)
{
char*fileCOntent= LoadFileContent(filePath);
if (fileContent!=nullptr)
{
//obj model decode
struct VertexInfo
{
float v[3];
};
struct VertexDefine
{
int positionIndex;
int texcoordIndex;
int normalIndex;
};
std::vector
std::vector
std::vector
std::vector
std::vector
std::stringstream ssObjFile(fileContent);
char szOneLine[256];
std::string temp;
while (!ssObjFile.eof())
{
memset(szOneLine, 0, 256);
ssObjFile.getline(szOneLine,256);
if (strlen(szOneLine)>0)
{
std::stringstream ssOneLine(szOneLine);
if (szOneLine[0]=='v')
{
if (szOneLine[1]=='t')
{
//vertex coord
ssOneLine >> temp;
VertexInfo vi;
ssOneLine >> vi.v[0];
ssOneLine >> vi.v[1];
texcoords.push_back(vi);
printf("%s %f,%f\n", temp.c_str(), vi.v[0], vi.v[1]);
}
else if(szOneLine[1]=='n')
{
//normal
ssOneLine >> temp;
VertexInfo vi;
ssOneLine >> vi.v[0];
ssOneLine >> vi.v[1];
ssOneLine >> vi.v[2];
normals.push_back(vi);
printf("%s %f,%f,%f\n", temp.c_str(), vi.v[0], vi.v[1], vi.v[2]);
}
else
{
//position
ssOneLine >> temp;
VertexInfo vi;
ssOneLine >> vi.v[0];
ssOneLine >> vi.v[1];
ssOneLine >> vi.v[2];
positions.push_back(vi);
printf("%s %f,%f,%f\n",temp.c_str(), vi.v[0], vi.v[1], vi.v[2]);
}
}
else if (szOneLine[0] == 'f')
{
//face
ssOneLine >> temp;// 'f'
std::string vertexStr;
for (int i=0;i<3;i++)
{
ssOneLine >> vertexStr;
size_t pos = vertexStr.find_first_of('/');
std::string positiOnIndexStr= vertexStr.substr(0, pos);
size_t pos2 = vertexStr.find_first_of('/', pos + 1);
std::string texcoordIndexStr = vertexStr.substr(pos + 1, pos2 - pos - 1);
std::string normalIndexStr = vertexStr.substr(pos2 + 1, vertexStr.length() - pos2 - 1);
VertexDefine vd;
vd.positionIndex = atoi(positionIndexStr.c_str())-1;
vd.texcoordIndex = atoi(texcoordIndexStr.c_str()) - 1;
vd.normalIndex = atoi(normalIndexStr.c_str()) - 1;
int nCurrentIndex = -1;//indexes
//check if exist
size_t nCurrentVerticeCount = vertices.size();
for (size_t j = 0; j
{
if (vertices[j].positiOnIndex== vd.positionIndex&&
vertices[j].texcoordIndex == vd.texcoordIndex&&
vertices[j].normalIndex == vd.normalIndex)
{
nCurrentIndex = j;
break;
}
}
if (nCurrentIndex==-1)
{
//create new vertice
nCurrentIndex = vertices.size();
vertices.push_back(vd);//vertexes define
}
objIndexes.push_back(nCurrentIndex);
}
}
}
}
printf("face count %u\n",objIndexes.size()/3);
//objIndexes->indexes buffer -> ibo
indexCount = (int)objIndexes.size();
*indexes = new unsigned int[indexCount];
for (int i=0;i
{
(*indexes)[i] = objIndexes[i];
}
//vertices -> vertexes -> vbo
vertexCount = (int)vertices.size();
VertexData*vertexes = new VertexData[vertexCount];
for (int i=0;i
{
memcpy(vertexes[i].position, positions[vertices[i].positionIndex].v, sizeof(float) * 3);
memcpy(vertexes[i].texcoord, texcoords[vertices[i].texcoordIndex].v, sizeof(float) * 2);
memcpy(vertexes[i].normal, normals[vertices[i].normalIndex].v, sizeof(float) * 3);
}
return vertexes;
}
return nullptr;
}
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += main.cpp \
misc.cpp \
model.cpp
LIBS+= -L/usr/lib64 -lGLEW
LIBS +=-L/usr/local/lib -lglfw3 -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -lGL -lpthread -ldl
HEADERS += \
misc.h \
model.h