通过代码创建obj格式的三维模型

  • 前言:有一天逛qq群的时候,某大佬说记事本可以打开obj文件,于是便刺激了我的好奇心。捣鼓了一个早上以后终于捣鼓出了如何以在记事本中写入模型信息的方式创建三维模型的方法。话不多说,上干货。

三维模型的基本元素

点、线、面、体是三维模型的基本元素.其中,点是最基本的单位。然后点与点构成线,线与线构成面,面与面构成体。
在这里插入图片描述
三维模型的点元素
在这里插入图片描述
三维模型的线元素,由点与点连接而成
在这里插入图片描述
面与面组合成体

obj文件实现三维模型的方式

要观察obj文件是如何实现一个三维模型的,需要用鼠标右键对obj右击,选择记事本的方式打开。
在这里插入图片描述
打开之后,文本文档显示的内容是这样的:
在这里插入图片描述

# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
# 创建的文件:19.08.2019 15:09:54

mtllib Object.mtl

#
# object Box001
#

v  -24.7281 -32.5248 0.0000
v  -24.7281 14.7423 0.0000
v  24.0942 14.7423 0.0000
v  24.0942 -32.5248 0.0000
v  -24.7281 -32.5248 25.9455
v  24.0942 -32.5248 25.9455
v  24.0942 14.7423 25.9455
v  -24.7281 14.7423 25.9455
# 8 vertices

vn -0.5774 -0.5774 -0.5774
vn -0.5774 0.5774 -0.5774
vn 0.5774 0.5774 -0.5774
vn 0.5774 -0.5774 -0.5774
vn -0.5774 -0.5774 0.5774
vn 0.5774 -0.5774 0.5774
vn 0.5774 0.5774 0.5774
vn -0.5774 0.5774 0.5774
# 8 vertex normals

vt 48.8223 0.0000 0.0000
vt 48.8223 47.2671 0.0000
vt 0.0000 47.2671 0.0000
vt 0.0000 0.0000 0.0000
vt 48.8223 25.9455 0.0000
vt 0.0000 25.9455 0.0000
vt 47.2671 0.0000 0.0000
vt 47.2671 25.9455 0.0000
# 8 texture coords

o Box001
g Box001
usemtl wire_088144225
s 2
f 1/1/1 2/2/2 3/3/3 4/4/4 
s 4
f 5/4/5 6/1/6 7/2/7 8/3/8 
s 8
f 1/4/1 4/1/4 6/5/6 5/6/5 
s 16
f 4/4/4 3/7/3 7/8/7 6/6/6 
s 32
f 3/4/3 2/1/2 8/5/8 7/6/7 
s 64
f 2/4/2 1/7/1 5/8/5 8/6/8 
# 6 polygons

其中,#是注释符号,后面的内容在导入三维模型时都不会被三维软件读取。

另外,我使用3ds max2019导出obj格式模型的时候,会导出两个文件:在这里插入图片描述
一个是模型的网格,另外一个是该模型使用的材质。

1、顶点:
一个模型的顶点信息有两个基本的属性:顶点数量和每个顶点的坐标
在obj文件中,字母v开头的代码表示的是当前三维模型中的顶点信息
有几行v就有几个顶点
v后的三个数字表示当前顶点的三维坐标中的位置。在这里插入图片描述
2、法线:
obj文件中的法线信息记录了模型中各个朝向的法线
obj文件中vn开头的表示该行代码是模型上法线的法线终点信息
在这里插入图片描述
其中,以上通过坐标实现法线朝向的原理如下
在这里插入图片描述

3、UV信息:
obj文件中记录了模型uv坐标系中的顶点信息
obj文件以uv为开头的代码即是记录了模形uv坐标系中uv块顶点信息

在这里插入图片描述
4、模型的名称:
obj文件中,o关键字即是三维软件导入模型时模型显示的名字
g关键字作用暂时未知,请各位试出来的小伙伴告诉我一下,谢谢
在这里插入图片描述
5、模型材质
obj文件中,mtllib表示该脚本引用了哪个mtl文件
在这里插入图片描述
Object.mtl中包含一个名为wire_088144225的材质
在这里插入图片描述
而obj文件中,usemtl表示使用以引用的mtl文件中具有某一名称的材质:
在这里插入图片描述
6、平滑组以及模型面元素:
在obj文件中,表达面的关键字是f,f后面有一组由三个斜杠构成的字符:x/x/x,表示为一个顶点
每一串字符表示构成该面的一个点元素,如图中每个f后面都有四组:x/x/x,说明每个面由四个点组成。
而x/x/x中第一个x代表的是当前顶点所使用的定点位置是当前obj文件中第几个v关键字后的坐标信息,第二个x代表的是当前顶点在uv坐标系中使用的是当前obj文件中第几个vt关键字后的坐标信息,第三个x代表的是当前顶点所使用的法线是当前obj文件中第几个vn关键字后的坐标信息

而在obj文件中,s关键字表示平滑组,s后面放置的一组面属于同一组平滑组。
如下图S 0后面的两个f属于同一平滑组。而s 1后面的四个f属于同一平滑组
在这里插入图片描述

7、记事本的后缀名改为obj方可导入导max、maya、blender等三维模型软件中。

要在QT中使用OpenGL渲染一个OBJ模型,可以按照以下步骤进行: 1. 创建一个QT项目,选择OpenGL窗口模板。 2. 在OpenGL窗口中初始化OpenGL和QT的集成,可以使用以下代码: ```c++ void GLWidget::initializeGL() { initializeOpenGLFunctions(); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_COLOR_MATERIAL); } void GLWidget::resizeGL(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, (double)w / (double)h, 0.01, 100.0); glMatrixMode(GL_MODELVIEW); } void GLWidget::paintGL() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(0.0f, 0.0f, -5.0f); glRotatef(rotationX, 1.0, 0.0, 0.0); glRotatef(rotationY, 0.0, 1.0, 0.0); drawModel(); } ``` 3. 加载OBJ模型,并将其渲染到OpenGL窗口中,可以使用以下代码: ```c++ void GLWidget::loadModel(QString filename) { model = glmReadOBJ(filename.toStdString().c_str()); glmUnitize(model); glmFacetNormals(model); glmVertexNormals(model, 90); } void GLWidget::drawModel() { if (model != NULL) { glmDraw(model, GLM_SMOOTH); } } ``` 4. 在QT的主窗口中添加一个QPushButton,点击按钮后调用loadModel()函数加载OBJ模型。 ```c++ void MainWindow::on_btnLoad_clicked() { QString filename = QFileDialog::getOpenFileName(this, tr("Open File"), ".", tr("OBJ Files (*.obj)")); if (!filename.isEmpty()) { ui->glWidget->loadModel(filename); } } ``` 5. 运行程序,点击按钮加载OBJ模型并在OpenGL窗口中显示。 以上就是在QT中使用OpenGL渲染OBJ模型的基本步骤,需要注意的是,这里使用了OpenGL Utility Toolkit(GLUT)和OpenGL Mathematics(GLM)库来帮助加载OBJ模型和进行矩阵变换等操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值