OpenGL读取obj模型 源码 以及文件解析

在最开始先贴出源码的下载路径

最初版本:http://download.csdn.net/detail/mahabharata_/9614958  

! 最新版本: 主体代码 http://download.csdn.net/detail/mahabharata_/9821347

                        漏掉的一段reference.h :http://download.csdn.net/detail/mahabharata_/9847993

                       (对于最新版本,这两个链接都要下载,因为我在reference.h中实现了一些接口)

                    本来是免费资源,但是CSDN换新版后给我调了。
                    因为CSDN无法调整积分,如果没有积分的可以邮箱联系我直接发(liuzh96@outlook.com)

【下载前请读】

1. 这两份资源,是我在大一时做的代码。若需要了解进一步优化,请邮箱联系我。

2. 解释为什么分成了两部分上传?因为CSDN的原因,我至今无法删除已上传过的资源,所以干脆单独上传了之前漏掉的头文件。如果没有积分的朋友,可以邮箱联系我,我有时间给您单独发~~~

3. 更新Update:

但是!竟然有人因为下载需要积分而举报我????我滴个天鸭,分享资源还要被骂的,况且这下载积分还不是我自己设置的,搞不明白!!!!!  生气!!希望各路大仙们,有问题好好交流。说实话,我本没有分享代码的义务的,但是因为我自己在初学计算机图形学时遇到太多困难,所以分享出这些入门级代码也写了一些小教程来帮助初学者。我也知道喷子是少数,但是国内为啥分享的氛围不好,我觉得很大程度上拖了这些自私者的福。基于这一个原因,我暂时先撤回了在CSDN上上传的所有代码并不再使用CSDN,如果有需要请邮件联系我。

但是我很乐意帮助任何初学者去入门这个领域,和讨论编程问题。我也开发了很多免费的建模辅助性工具。希望各位能通过我的代码从而对Computer Graphics感兴趣。

程序执行结果如下:

         

       这个程序是博主大二暑假写的,现在的这一段话是发表这边博文后的一年才加上的,回看那个时候的程序,我滴妈,我竟然不会使用顶点数组啊,也没有速度优化啊,而且只能支持单纹理文件,读取方法也非常局限。因此,现在在原来的基础上重新上传了一个最新版本。

说明:

      两个版本的代码是Qt下,使用C++/OpenGL编写的。

      - 最初的版本:

             1. 仅仅支持单个纹理、对mtl文件的诸多材质不能很好的处理。

             2. 采用最原始的方法glvertex..()显示顶点,计算效率非常低。

             3. 这个版本是完整的工程文件,使用qt加载之后,可以直接运行。

      - 最新的版本:

             1. 能够支持多个纹理文件,能够解析包含多种材质的mtl文件。

             2. 使用vertex array改进绘制方式,渲染速度有了很大的提高~。

             3. 这里上传的是.h和.cpp文件,在.h文件中仅仅包含几个函数。可以采用下面的代码来读取和显示模型。

// 加载模型
ObjLoader loader;
loader.loadFromFile("D:/ali.obj","D:/ali.mtl");

// 渲染模型
loader.renderObj();

使用我的代码的一个要注意的地方:

          需要将objLoader.cpp的72行,修改为你的电脑中纹理所在的文件夹路径。如下图所示:

三维模型比较常见的是obj模型和3ds模型,处理方法大同小异,下面先介绍一下obj文件的简单处理方法:

OBJ文件的基本结构
    OBJ文件由一行行文本组成,可以用记事本打开。注释行以符号“#”为开头,空格和空行可以随意加到文件中以增加文件的可读性。有字的行都由一两个标记字母也就是关键字(Keyword)开头,关键字可以说明这一行是什么样的数据。多行可以逻辑地连接在一起表示一行,方法是在每一行最后添加一个连接符(\)。 注意连接符(\)后面不能出现空格或Tab格,否则将导致文件出错。
下列常用的关键字可以在OBJ文件使用。
顶点数据(Vertex data):
          v 几何体顶点(Geometric vertices)
           vt 贴图坐标点(Texture vertices)
           vn 顶点法线(Vertex normals)
           vp 参数空格顶点 (Parameter space vertices)

元素(Elements):
        p  点(Point)
             l  线(Line)
             f  面(Face)

成组(Grouping):
              g  组名称(Group name)
              o 对象名称(Object name)

显示(Display)/渲染属性(render attributes):
           usemtl 材质名称(Material name)
           mtllib 材质库(Material library)

obj文件的一个实例

# The units used in this file are centimeters.  
g default  
v -0.500000 -0.500000 0.500000  
v 0.500000 -0.500000 0.500000  
v -0.500000 0.500000 0.500000  
v 0.500000 0.500000 0.500000  
v -0.500000 0.500000 -0.500000  
v 0.500000 0.500000 -0.500000  
v -0.500000 -0.500000 -0.500000  
v 0.500000 -0.500000 -0.500000  
vt 0.000000 0.000000  
vt 1.000000 0.000000  
vt 0.000000 1.000000  
vt 1.000000 1.000000  
vt 0.000000 2.000000  
vt 1.000000 2.000000  
vt 0.000000 3.000000  
vt 1.000000 3.000000  
vt 0.000000 4.000000  
vt 1.000000 4.000000  
vt 2.000000 0.000000  
vt 2.000000 1.000000  
vt -1.000000 0.000000  
vt -1.000000 1.000000  
vn 0.000000 0.000000 1.000000  
vn 0.000000 0.000000 1.000000  
vn 0.000000 0.000000 1.000000  
vn 0.000000 0.000000 1.000000  
vn 0.000000 1.000000 0.000000  
vn 0.000000 1.000000 0.000000  
vn 0.000000 1.000000 0.000000  
vn 0.000000 1.000000 0.000000  
vn 0.000000 0.000000 -1.000000  
vn 0.000000 0.000000 -1.000000  
vn 0.000000 0.000000 -1.000000  
vn 0.000000 0.000000 -1.000000  
vn 0.000000 -1.000000 0.000000  
vn 0.000000 -1.000000 0.000000  
vn 0.000000 -1.000000 0.000000  
vn 0.000000 -1.000000 0.000000  
vn 1.000000 0.000000 0.000000  
vn 1.000000 0.000000 0.000000  
vn 1.000000 0.000000 0.000000  
vn 1.000000 0.000000 0.000000  
vn -1.000000 0.000000 0.000000  
vn -1.000000 0.000000 0.000000  
vn -1.000000 0.000000 0.000000  
vn -1.000000 0.000000 0.000000  
s off  
g pCube1  
usemtl initialShadingGroup  
f 1/1/1 2/2/2 4/4/3 3/3/4  
f 3/3/5 4/4/6 6/6/7 5/5/8  
f 5/5/9 6/6/10 8/8/11 7/7/12  
f 7/7/13 8/8/14 2/10/15 1/9/16  
f 2/2/17 8/11/18 6/12/19 4/4/20  
f 7/13/21 1/1/22 3/3/23 5/14/24 


这个文件看起来稍复杂一些,可以对照前面的列表查看一下每个keyword的意思:
   "vt 1.000000 0.000000"这句"vt"代表点的纹理贴图坐标。
   "vn 0.000000 0.000000 -1.000000"这句"vn"代表点的法线向量。
   "s off"表示关闭光滑组。
   "usemtl initialShadingGroup"表示使用的材质。
   "f 7/13/21"这时在面的数据中多了顶点点和纹理坐标和法线的索引号。这里f包含三组顶点,意味一个三角面,当然有时候会是n角面。
   格式:"f 顶点索引v/纹理uv点索引vt/法线索引vn"。

   "g pCube1"表示组。

   

   了解了这一些之后,我们便能够设计专门的数据结构来存储obj文件中的数据,并采用索引数组的方式渲染出模型,这里不多赘述,诸位可以参考一下代码。

  • 15
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 28
    评论
要在Qt OpenGL读取OBJ模型文件,可以使用Qt自带的QOpenGLFunctions库。 首先,需要在项目文件中添加以下依赖: ``` QT += opengl ``` 然后,可以使用QOpenGLFunctions类来加载模型文件和绘制模型。 以下是一个简单的示例代码,可以读取和绘制一个OBJ模型文件: ```c++ #include <QOpenGLFunctions> #include <QOpenGLShaderProgram> #include <QOpenGLBuffer> #include <QVector3D> #include <QVector2D> #include <QFile> #include <QStringList> struct VertexData { QVector3D position; QVector2D texCoord; }; class ObjModel : protected QOpenGLFunctions { public: ObjModel(); virtual ~ObjModel(); void init(QString filename); void render(); private: QOpenGLShaderProgram m_program; QOpenGLBuffer m_vbo; int m_vertexCount; }; ObjModel::ObjModel() : m_vertexCount(0) { } ObjModel::~ObjModel() { m_vbo.destroy(); } void ObjModel::init(QString filename) { initializeOpenGLFunctions(); // Load OBJ file QFile file(filename); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return; QVector<QVector3D> positions; QVector<QVector2D> texCoords; while (!file.atEnd()) { QByteArray line = file.readLine().trimmed(); QList<QByteArray> tokens = line.split(' '); if (tokens.isEmpty()) continue; if (tokens[0] == "v") { positions.append(QVector3D(tokens[1].toFloat(), tokens[2].toFloat(), tokens[3].toFloat())); } else if (tokens[0] == "vt") { texCoords.append(QVector2D(tokens[1].toFloat(), tokens[2].toFloat())); } else if (tokens[0] == "f") { for (int i = 1; i < tokens.size(); ++i) { QList<QByteArray> face = tokens[i].split('/'); VertexData data; data.position = positions[face[0].toInt() - 1]; data.texCoord = texCoords[face[1].toInt() - 1]; m_vertices.append(data); } } } m_vertexCount = m_vertices.size(); // Create VBO m_vbo.create(); m_vbo.bind(); m_vbo.allocate(m_vertices.constData(), m_vertexCount * sizeof(VertexData)); // Load shader program m_program.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/obj.vert"); m_program.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/obj.frag"); m_program.link(); } void ObjModel::render() { m_program.bind(); m_vbo.bind(); m_program.enableAttributeArray("position"); m_program.enableAttributeArray("texCoord"); m_program.setAttributeBuffer("position", GL_FLOAT, offsetof(VertexData, position), 3, sizeof(VertexData)); m_program.setAttributeBuffer("texCoord", GL_FLOAT, offsetof(VertexData, texCoord), 2, sizeof(VertexData)); glDrawArrays(GL_TRIANGLES, 0, m_vertexCount); m_vbo.release(); m_program.release(); } ``` 在上面的示例代码中,我们使用QFile类来读取OBJ文件,然后使用QOpenGLBuffer类创建一个VBO,并将OBJ文件中的顶点数据存储到VBO中。最后,使用QOpenGLShaderProgram类加载并绑定着色器程序,并使用glDrawArrays函数绘制模型。 注意,上面的代码仅仅是一个简单的示例,不足以处理所有的OBJ文件。在实际开发中,还需要对OBJ文件中的各种情况进行判断和处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值