热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

QT_OPENGL5.model

在qt中实现openglobj模型导入:main.cpp#include#include#include#inclu

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

main.cpp

#include
#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;
}

mish.h

#include
GLuint CreateBufferObject(GLenum bufferType, GLsizeiptr size, GLenum usage,
void*data = nullptr);
char *LoadFileContent(const char*path);

mish.cpp

#include "misc.h"
#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;
}

model.h

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

model.cpp

#include "model.h"
#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
positions;
std::vector
texcoords;
std::vector
normals;
std::vector
int> objIndexes;// -> opengl indexes
std::vector vertices;// -> opengl vertexes

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;ii)
{
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;
}

model.pro

TEMPLATE = app
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

最后的效果:



推荐阅读
author-avatar
chenshu华
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有