热门标签 | 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

最后的效果:



推荐阅读
  • PBO(PixelBufferObject),将像素数据存储在显存中。优点:1、快速的像素数据传递,它采用了一种叫DMA(DirectM ... [详细]
  • vue引入echarts地图的四种方式
    一、vue中引入echart1、安装echarts:npminstallecharts--save2、在main.js文件中引入echarts实例:  Vue.prototype.$echartsecharts3、在需要用到echart图形的vue文件中引入:   importechartsfrom&amp;quot;echarts&amp;quot;;4、如果用到map(地图),还 ... [详细]
  • 兆芯X86 CPU架构的演进与现状(国产CPU系列)
    本文详细介绍了兆芯X86 CPU架构的发展历程,从公司成立背景到关键技术授权,再到具体芯片架构的演进,全面解析了兆芯在国产CPU领域的贡献与挑战。 ... [详细]
  • IOS Run loop详解
    为什么80%的码农都做不了架构师?转自http:blog.csdn.netztp800201articledetails9240913感谢作者分享Objecti ... [详细]
  • [转]doc,ppt,xls文件格式转PDF格式http:blog.csdn.netlee353086articledetails7920355确实好用。需要注意的是#import ... [详细]
  • 字节流(InputStream和OutputStream),字节流读写文件,字节流的缓冲区,字节缓冲流
    字节流抽象类InputStream和OutputStream是字节流的顶级父类所有的字节输入流都继承自InputStream,所有的输出流都继承子OutputStreamInput ... [详细]
  • PTArchiver工作原理详解与应用分析
    PTArchiver工作原理及其应用分析本文详细解析了PTArchiver的工作机制,探讨了其在数据归档和管理中的应用。PTArchiver通过高效的压缩算法和灵活的存储策略,实现了对大规模数据的高效管理和长期保存。文章还介绍了其在企业级数据备份、历史数据迁移等场景中的实际应用案例,为用户提供了实用的操作建议和技术支持。 ... [详细]
  • 深入剖析Java中SimpleDateFormat在多线程环境下的潜在风险与解决方案
    深入剖析Java中SimpleDateFormat在多线程环境下的潜在风险与解决方案 ... [详细]
  • 在Android平台中,播放音频的采样率通常固定为44.1kHz,而录音的采样率则固定为8kHz。为了确保音频设备的正常工作,底层驱动必须预先设定这些固定的采样率。当上层应用提供的采样率与这些预设值不匹配时,需要通过重采样(resample)技术来调整采样率,以保证音频数据的正确处理和传输。本文将详细探讨FFMpeg在音频处理中的基础理论及重采样技术的应用。 ... [详细]
  • 在处理 XML 数据时,如果需要解析 `` 标签的内容,可以采用 Pull 解析方法。Pull 解析是一种高效的 XML 解析方式,适用于流式数据处理。具体实现中,可以通过 Java 的 `XmlPullParser` 或其他类似的库来逐步读取和解析 XML 文档中的 `` 元素。这样不仅能够提高解析效率,还能减少内存占用。本文将详细介绍如何使用 Pull 解析方法来提取 `` 标签的内容,并提供一个示例代码,帮助开发者快速解决问题。 ... [详细]
  • 本文讨论了在 Oracle 10gR2 和 Solaris 10 64-bit 环境下,从 XMLType 列中提取数据并插入到 VARCHAR2 列时遇到的性能问题,并提供了优化建议。 ... [详细]
  • Leetcode学习成长记:天池leetcode基础训练营Task01数组
    前言这是本人第一次参加由Datawhale举办的组队学习活动,这个活动每月一次,之前也一直关注,但未亲身参与过,这次看到活动 ... [详细]
  • 本文详细介绍了 Spark 中的弹性分布式数据集(RDD)及其常见的操作方法,包括 union、intersection、cartesian、subtract、join、cogroup 等转换操作,以及 count、collect、reduce、take、foreach、first、saveAsTextFile 等行动操作。 ... [详细]
  • 单片微机原理P3:80C51外部拓展系统
      外部拓展其实是个相对来说很好玩的章节,可以真正开始用单片机写程序了,比较重要的是外部存储器拓展,81C55拓展,矩阵键盘,动态显示,DAC和ADC。0.IO接口电路概念与存 ... [详细]
  • Java Socket 关键参数详解与优化建议
    Java Socket 的 API 虽然被广泛使用,但其关键参数的用途却鲜为人知。本文详细解析了 Java Socket 中的重要参数,如 backlog 参数,它用于控制服务器等待连接请求的队列长度。此外,还探讨了其他参数如 SO_TIMEOUT、SO_REUSEADDR 等的配置方法及其对性能的影响,并提供了优化建议,帮助开发者提升网络通信的稳定性和效率。 ... [详细]
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社区 版权所有