在qt中实现opengl obj模型导入:

main.cpp

#include<GL/glew.h>
#include <GLFW/glfw3.h>
#include<stdio.h>
#include<glm/glm.hpp>
#include<glm/ext.hpp>
#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,,&vsCode,nullptr);
glShaderSource(fsShader,,&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(, , width, height);
}
int main(void)
{
GLFWwindow* window; if (!glfwInit())
return -; window = glfwCreateWindow(, , "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -;
}
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 = , indexCount = ;
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[] = {
,,,,
,,,,
,,,,
,,,
};
//创建一个投影矩阵
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, , GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(VLocation, , GL_FALSE, identity);
glUniformMatrix4fv(PLocation, , GL_FALSE, glm::value_ptr(projection)); glBindBuffer(GL_ARRAY_BUFFER, vbo);
glEnableVertexAttribArray(posLocation);
glVertexAttribPointer(posLocation, , GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*));
glEnableVertexAttribArray(texcoordLocation);
glVertexAttribPointer(texcoordLocation, , GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)(sizeof(float) * ));
glEnableVertexAttribArray(normalLocation);
glVertexAttribPointer(normalLocation, , GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)(sizeof(float) * )); glBindBuffer(GL_ARRAY_BUFFER, );
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, );
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, );
glUseProgram();
glfwSwapBuffers(window); } glfwTerminate();
return ;
}

mish.h

#include<GL/glew.h>
GLuint CreateBufferObject(GLenum bufferType, GLsizeiptr size, GLenum usage, void*data = nullptr);
char *LoadFileContent(const char*path);

mish.cpp

#include "misc.h"
#include <stdio.h> GLuint CreateBufferObject(GLenum bufferType, GLsizeiptr size, GLenum usage, void*data /* = nullptr */)
{
GLuint object;
glGenBuffers(, &object);
glBindBuffer(bufferType, object);
glBufferData(bufferType, size, data, usage);
glBindBuffer(bufferType, );
return object;
} char *LoadFileContent(const char*path)
{
FILE*pFile = fopen(path, "rb");
if (pFile)
{
fseek(pFile, , SEEK_END);
int nLen = ftell(pFile);
char*buffer = nullptr;
if (nLen!=)
{
buffer=new char[nLen + ];
rewind(pFile);
fread(buffer, nLen, , 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;
}

model.h

struct VertexData
{
float position[];
float texcoord[];
float normal[];
}; VertexData*LoadObjModel(const char* filePath,unsigned int **indexes,int&vertexCount,int&indexCount);

model.cpp

#include "model.h"
#include "misc.h"
#include <stdio.h>
#include <string.h>
#include <sstream>
#include <vector> 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[];
}; struct VertexDefine
{
int positionIndex;
int texcoordIndex;
int normalIndex;
};
std::vector<VertexInfo> positions;
std::vector<VertexInfo> texcoords;
std::vector<VertexInfo> normals; std::vector<unsigned int> objIndexes;// -> opengl indexes
std::vector<VertexDefine> vertices;// -> opengl vertexes std::stringstream ssObjFile(fileContent);
char szOneLine[];
std::string temp;
while (!ssObjFile.eof())
{
memset(szOneLine, , );
ssObjFile.getline(szOneLine,);
if (strlen(szOneLine)>)
{
std::stringstream ssOneLine(szOneLine); if (szOneLine[]=='v')
{
if (szOneLine[]=='t')
{
//vertex coord
ssOneLine >> temp;
VertexInfo vi;
ssOneLine >> vi.v[];
ssOneLine >> vi.v[];
texcoords.push_back(vi);
printf("%s %f,%f\n", temp.c_str(), vi.v[], vi.v[]);
}
else if(szOneLine[]=='n')
{
//normal
ssOneLine >> temp;
VertexInfo vi;
ssOneLine >> vi.v[];
ssOneLine >> vi.v[];
ssOneLine >> vi.v[];
normals.push_back(vi);
printf("%s %f,%f,%f\n", temp.c_str(), vi.v[], vi.v[], vi.v[]);
}
else
{
//position
ssOneLine >> temp;
VertexInfo vi;
ssOneLine >> vi.v[];
ssOneLine >> vi.v[];
ssOneLine >> vi.v[];
positions.push_back(vi);
printf("%s %f,%f,%f\n",temp.c_str(), vi.v[], vi.v[], vi.v[]);
}
}
else if (szOneLine[] == 'f')
{
//face
ssOneLine >> temp;// 'f'
std::string vertexStr;
for (int i=;i<;i++)
{
ssOneLine >> vertexStr;
size_t pos = vertexStr.find_first_of('/');
std::string positionIndexStr = vertexStr.substr(, pos);
size_t pos2 = vertexStr.find_first_of('/', pos + );
std::string texcoordIndexStr = vertexStr.substr(pos + , pos2 - pos - );
std::string normalIndexStr = vertexStr.substr(pos2 + , vertexStr.length() - pos2 - );
VertexDefine vd;
vd.positionIndex = atoi(positionIndexStr.c_str())-;
vd.texcoordIndex = atoi(texcoordIndexStr.c_str()) - ;
vd.normalIndex = atoi(normalIndexStr.c_str()) - ; int nCurrentIndex = -;//indexes
//check if exist
size_t nCurrentVerticeCount = vertices.size();
for (size_t j = ; j < nCurrentVerticeCount; j++)
{
if (vertices[j].positionIndex == vd.positionIndex&&
vertices[j].texcoordIndex == vd.texcoordIndex&&
vertices[j].normalIndex == vd.normalIndex)
{
nCurrentIndex = j;
break;
}
}
if (nCurrentIndex==-)
{
//create new vertice
nCurrentIndex = vertices.size();
vertices.push_back(vd);//vertexes define
}
objIndexes.push_back(nCurrentIndex);
}
}
}
}
printf("face count %u\n",objIndexes.size()/);
//objIndexes->indexes buffer -> ibo
indexCount = (int)objIndexes.size();
*indexes = new unsigned int[indexCount];
for (int i=;i<indexCount;i++)
{
(*indexes)[i] = objIndexes[i];
}
//vertices -> vertexes -> vbo
vertexCount = (int)vertices.size();
VertexData*vertexes = new VertexData[vertexCount];
for (int i=;i<vertexCount;++i)
{
memcpy(vertexes[i].position, positions[vertices[i].positionIndex].v, sizeof(float) * );
memcpy(vertexes[i].texcoord, texcoords[vertices[i].texcoordIndex].v, sizeof(float) * );
memcpy(vertexes[i].normal, normals[vertices[i].normalIndex].v, sizeof(float) * );
}
return vertexes;
}
return nullptr;
}

model.pro

TEMPLATE = app
CONFIG += console c++
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

最后的效果:

最新文章

  1. 分组统计并计算每组数量sql
  2. Ubuntu 12.04 禁用触摸板
  3. 日志分析-Web
  4. 将一个字符串映射为一个Delphi页面控件属性名(通过FindComponent和GetPropInfo找到这个控件指针)
  5. ubuntu下新建VPN连接
  6. expr的简单应用
  7. grid.Column INT 所对应的文本
  8. C# / MSSQL / WinForm / ASP.NET - SQLHelper中返回SqlDataReader数据
  9. 在C#代码中应用Log4Net系列教程
  10. Riemann流形上的梯度,散度与Laplace算子
  11. AX2009 批处理作业中使用多线程---独立任务模式
  12. DevOps 在公司项目中的实践落地
  13. freeswitch报错
  14. linux服务之apache篇(一)
  15. JavaWeb学习篇--Filter过滤器
  16. JDK并发包总结
  17. 词频统计 SPEC 20160911
  18. 谈vs2013单元测试感想
  19. Linux内核中的printf实现【转】
  20. Java-JUC(十一):线程8锁

热门文章

  1. 2018-2-13-win10-uwp-设置启动窗口大小--获取窗口大小
  2. Laravel 日志权限问题
  3. 2016年省赛 G Triple Nim
  4. MySQL系列(六)--索引优化
  5. 非常好理解的KNN算法示例
  6. SpringBoot+Shiro+mybatis整合实战
  7. Mysql千万级访问量架构
  8. 【大数据】Hadoop常用启动命令
  9. python学生管理系统
  10. Leetcode641.Design Circular Deque设计循环双端队列