当前位置: 首页 > article >正文

计算机图形学:实验四 带纹理的OBJ文件读取和显示

一、程序功能设计

在程序中读取带纹理的obj文件,载入相应的纹理图片文件,将带纹理的模型显示在程序窗口中。实现带纹理的OBJ文件读取与显示功能,具体设计如下:

OBJ文件解析与数据存储

通过实现TriMesh类中的readObj函数,解析OBJ文件中的顶点、法线、UV纹理坐标等信息,将其存储在指定的数据结构中:

  1. vertex_positions:存储顶点几何坐标。
  2. vertex_normals:存储顶点法线,用于光照计算。
  3. vertex_textures:存储UV纹理坐标,用于纹理映射。
  4. faces:存储面片顶点的索引信息,用于定义几何形状。
  5. normal_index和texture_index:分别存储面片顶点对应的法线索引和纹理坐标索引。
    此外,由于OBJ文件不包含顶点颜色数据,本实验利用顶点法线的数值作为颜色数据进行渲染。

数据组织与存储逻辑完善
通过补全storeFacesPoints函数,进一步完善面片顶点的索引解析与数据存储过程:

  1. 遍历面片数据,按顶点、法线、UV坐标的索引组织顶点信息。
  2. 确保所有几何数据、法线数据和UV数据一一对应,以便后续渲染时正确应用纹理。

纹理加载与显示

在main.cpp文件中修改init函数,通过以下步骤实现带纹理模型的加载与显示:

  1. 加载纹理图片文件并绑定到模型的UV坐标上。
  2. 根据模型的顶点、法线、纹理坐标等数据渲染模型。
  3. 显示玩偶和桌子模型,通过调整它们的位置与比例,生成合理的场景布局。

 实现效果

实现了多模型、多纹理的加载和显示功能。程序窗口中,带有纹理的玩偶模型和桌子模型正确显示,纹理映射效果清晰且无失真。

二、程序代码实现

补全TriMesh.cpp中的storeFacesPoints函数

通过补全storeFacesPoints函数,根据读取的模型数据,将三角面片的顶点属性(包括顶点位置、法线、颜色、纹理等)整理成适合传递给GPU的数据格式,为后续的渲染做准备。

顶点数据解析与存储(根据三角面片的索引将属性数据组织到GPU需要的格式):遍历每个三角面片的数据,根据顶点的索引将顶点属性依次存入对应的容器(points、colors、normals、textures)。每个三角面片的顶点属性都要按照顶点索引依次写入。要注意的是:

  1. faces:存储三角形面片的顶点索引。
  2. color_index:存储面片顶点的颜色索引。
  3. normal_index:存储面片顶点法线的索引。
  4. texture_index:存储面片顶点纹理坐标的索引。

补全TriMesh.cpp中的generateDisk函数和generateCone函数

generateDisk 函数生成圆盘,生成一个圆盘的网格,包括底面和相应的三角面片。generateCone 函数生成圆锥,生成一个圆锥体的网格,包括底面和圆锥侧面。两个函数分别用来生成圆盘和圆锥体(同实验4.1),依赖于三角形扇形的方式来连接底面和顶部(尖端)的顶点,生成相应的三角面片。

  • generateDisk 函数
  1. 生成顶点:使用循环计算每个切片的边界点(顶点坐标 x, y, z),其中 z 始终为 0(在 xy 平面上),并根据该顶点的法向量(法向量始终为 (0, 0, 1))添加颜色(这里简化为与法向量相同的颜色)。在循环结束后,添加一个圆盘的中心点(顶点坐标为 (0, 0, 0))。
  2. 生成三角面片:使用三角形扇形的方式将每个切片连接起来,形成三角面片,通过 faces.push_back() 存储每个三角形的三个顶点索引。为每个顶点生成相应的纹理坐标,并存储索引。
  3. 法向量和颜色设置:通过 normal_index 和 color_index 将每个三角面片的顶点与法向量和颜色的索引关联起来。

  • generateCone 函数:
  1. 生成底部顶点:使用循环计算圆锥底部的每个顶点坐标(x, y, z),其中 z 始终为 0。根据每个顶点位置生成法向量(平面上每个顶点的法向量为 (x, y, 0) 的归一化向量),并生成颜色(与法向量相同)。
  2. 添加圆锥的顶点:圆锥顶端添加一个顶点,坐标为 (0, 0, height),法向量为 (0, 0, 1)。
  3. 生成圆锥侧面三角面片:每两个相邻的底面顶点和圆锥顶点连接,形成一个三角形。通过 faces.push_back() 将每个侧面三角形的三个顶点索引存储起来。对每个三角面片的三个顶点生成纹理坐标并存储。
  4. 法向量和颜色设置:通过 normal_index 和 color_index 将三角面片与法向量、颜色的索引关联起来。

最终,所有的顶点、法向量、颜色、纹理坐标和面片索引通过 storeFacesPoints() 存储起来,以便后续使用。

补全TriMesh.cpp中的readObj函数

readObj函数实现了从 .obj 文件中读取三维模型的顶点数据、法向量数据、纹理坐标数据和面片数据,并将这些数据存储在类的成员变量中,供后续的渲染或计算使用。需要补充的代码逻辑如下:

  • 解析每一行的数据:
  1. 顶点数据 ("v"):读取顶点坐标(x, y, z),将其存入 vertex_positions 向量中。
  2. 法向量数据 ("vn"):读取法向量坐标(x, y, z),将其存入 vertex_normals 向量中。
  3. 纹理坐标数据 ("vt"):读取纹理坐标(x, y),将其存入 vertex_textures 向量中。
  4. 面数据 ("f"):读取面数据,包含三个顶点的索引(顶点、纹理和法向量索引),这些索引会被转换为从0开始的索引,并存储在 faces、texture_index、normal_index 中。
  • 处理面数据:

每一行的面数据包含三个顶点,使用索引(如 a0, b0, c0)来表示这些顶点在对应的数组中的位置。索引是从1开始的,因此需要将其减去1来转换为从0开始的索引。

  • 顶点颜色和法向量同步:

在 vertex_colors 中存储的是法向量(即 vertex_normals),因为通常情况下法向量用作顶点的颜色。

补全main.cpp中的init函数

在init() 函数加载桌子和娃娃的三维模型,并根据指定的平移、旋转和缩放变换进行调整。将这些模型添加到绘制管线(painter)中,供渲染使用。

  • 加载并设置桌子模型
  1. 创建一个新的 TriMesh 对象 table,并读取桌子模型文件 table.obj。
  2. 通过 setNormalize(true) 方法确保模型数据被归一化。
  3. 使用 readObj("./assets/table.obj") 函数加载桌子的几何数据。
  4. 设置桌子的平移(setTranslation)、旋转(setRotation)、缩放(setScale)变换。

平移:glm::vec3(-0.7, 0.0, 0.0) 将桌子稍微平移。

旋转:glm::vec3(-90.0, 0.0, 0.0) 将桌子旋转 -90 度。

缩放:glm::vec3(2.0, 2.0, 2.0) 放大桌子的大小。

将桌子模型添加到 painter 中,通过 painter->addMesh 方法加载模型并指定纹理和着色器。

加载并设置娃娃模型

  1. 创建一个新的 TriMesh 对象 wawa,并读取娃娃模型文件 wawa.obj。
  2. 同样通过 setNormalize(true) 方法归一化模型数据,并使用 readObj("./assets/wawa.obj") 函数加载娃娃的几何数据。
  3. 设置娃娃的平移、旋转和缩放变换:

平移:glm::vec3(0.7, 0.0, 0.0) 将娃娃平移。

旋转:glm::vec3(-90.0, 0.0, 0.0) 旋转 -90 度。

缩放:glm::vec3(2.0, 2.0, 2.0) 放大娃娃的大小。

将娃娃模型添加到 painter 中,指定纹理和着色器。

三、程序运行结果

运行程序初始界面

进行水平方向左右旋转

进行竖直方向旋转


http://www.kler.cn/a/518587.html

相关文章:

  • 深入MapReduce——引入
  • MySQL数据库基础
  • 【云安全】云原生-Docker(五)容器逃逸之漏洞利用
  • debian12.9编译freeswitch1.10.12【默认安装】
  • 沃尔玛 礼品卡绑定 分析
  • 基于SpringBoot的httpclient实现(高级版)
  • vue3自定义表格生成动态列
  • linux系统中的 scp的使用方法
  • 【面试题】 Java 三年工作经验(2025)
  • 2025美赛数学建模C题 奥运奖牌模型保姆级教程讲解|模型讲解
  • 为AI聊天工具添加一个知识系统 之68 详细设计 之9 三种中台和时间度量 之1
  • SpringBoot打包为JAR包或WAR 包,这两种打包方式在运行时端口将如何采用?又有什么不同?这篇文章将给你解惑
  • ESP8266 NodeMCU与WS2812灯带:实现多种花样变换
  • 家政预约小程序09服务管理
  • 使用Redis缓解数据库压力+三种常见问题
  • 【C++图论 最短路】2642. 设计可以求最短路径的图类|1810
  • 蓝桥杯3519 填充 | 分类讨论
  • 大型齿轮箱健康监测与智能维护系列套件:测试台+故障诊断算法工具箱+齿轮箱智能维护系统平台+案例分析
  • 数字MIC PDM接口
  • 【探索前端技术之 React Three.js—— 简单的人脸动捕与 3D 模型表情同步应用】
  • 【Web开发】一步一步详细分析使用Bolt.new生成的简单的VUE项目
  • LeetCode 力扣热题100 二叉树的直径
  • 使用 Python 和 Tesseract 实现验证码识别
  • ASP.NET Blazor托管模型有哪些?
  • Python数据分析-准备工作(一)
  • Electron 项目运行问题:Electron failed to install correctly