wayland(xdg_wm_base) + egl + opengles 使用 Assimp 加载3D model 最简实例(十三)

文章目录

  • 前言
  • 一、3D model 文件介绍
    • 1. 3d model 介绍
      • 1.1 如何获取3d model 文件
      • 1.2 3d model 的文件格式
      • 1.3 obj模型数据格式
    • 2. 3d 立方体 model 实例——cube.obj
  • 二、Assimp 介绍
    • 1. Assimp 简介
    • 2.ubuntu 上安装libassimp
    • 3. 使用Assimp 解析 cube.obj 文件
      • 3.1 assimp_load_cube.cpp 文件内容如下
      • 3.2 编译
      • 3.3 运行
  • 三、opengles 使用 Assimp 加载 3D 立方体 model 实例
    • 1. egl_wayland_assimp_cube.c
    • 2. xdg-shell-client-protocol.h 和 xdg-shell-protocol.c
    • 3. 编译
    • 4. 运行
  • 总结
  • 参考资料


前言

`本文主要介绍opengles 如何使用 第三方库Assimp(基于C++) 加载一个最简当的3d 立方体model
软硬件环境:
硬件:PC
软件:ubuntu22.04 egl1.4 weston9.0 opengles3.0 libassimp.so.5.2.0


一、3D model 文件介绍

1. 3d model 介绍

1.1 如何获取3d model 文件

模型通常都是通过Blender、3DS Max或者Maya这样的3D建模工具(3D Modeling Tool)精心制作出来的

1.2 3d model 的文件格式

模型的文件格式有很多种,每一种都会以它们自己的方式来导出模型数据。像是Wavefront的.obj这样的模型格式,只包含了模型数据以及材质信息,像是模型颜色和漫反射/镜面光贴图。而以XML为基础的Collada文件格式则非常的丰富,包含模型、光照、多种材质、动画数据、摄像机、完整的场景信息等等。Wavefront的.obj格式通常被认为是一个易于解析的模型格式

1.3 obj模型数据格式

  • 以#开始的行为注释行
  • usemtl 和 mtllib表示的材质相关数据
  • o 引入一个新的object
  • v 表示顶点坐标
  • vt 表示顶点纹理坐标
  • vn 表示顶点法线
  • f 表示一个面,面使用1/2/8这样格式,表示顶点坐标/纹理坐标/法线的索引,这里索引的是前面用v,vt,vn定义的数据

2. 3d 立方体 model 实例——cube.obj

最简单的3d 立方体model 文件 cube.obj 内容如下
cube.obj

# Number of vertices: 8
v -0.5 0.5 0.5
v -0.5 -0.5 0.5
v 0.5 -0.5 0.5
v 0.5 0.5 0.5
v 0.5 0.5 -0.5
v 0.5 -0.5 -0.5
v -0.5 -0.5 -0.5
v -0.5 0.5 -0.5# Number of Polygons: 12
f 1 2 3
f 1 3 4
f 4 3 6
f 4 6 5
f 5 6 7
f 5 7 8
f 8 7 2
f 8 2 1
f 2 7 6
f 2 6 3
f 8 1 4
f 8 4 5

在PC 上使用3D 查看器打开cube.obj 文件,如下图所示
在这里插入图片描述

二、Assimp 介绍

1. Assimp 简介

一个非常流行的模型导入库是Assimp,它是Open Asset Import Library(开放的资产导入库)的缩写。Assimp能够导入很多种不同的模型文件格式(并也能够导出部分的格式),它会将所有的模型数据加载至Assimp的通用数据结构中。当Assimp加载完模型之后,我们就能够从Assimp的数据结构中提取我们所需的所有数据了。由于Assimp的数据结构保持不变,不论导入的是什么种类的文件格式,它都能够将我们从这些不同的文件格式中抽象出来,用同一种方式访问我们需要的数据。
当使用Assimp导入一个模型的时候,它通常会将整个模型加载进一个场景(Scene)对象,它会包含导入的模型/场景中的所有数据。Assimp会将场景载入为一系列的节点(Node),每个节点包含了场景对象中所储存数据的索引,每个节点都可以有任意数量的子节点。Assimp数据结构的(简化)模型如下:
在这里插入图片描述

  • 一个Mesh对象本身包含了渲染所需要的所有相关数据,像是顶点位置、法向量、纹理坐标、面(Face)和物体的材质;
  • 一个网格包含了多个面。Face代表的是物体的渲染图元(Primitive)(三角形、方形、点)。一个面包含了组成图元的顶点的索引。由于顶点和索引是分开的,使用一个索引缓冲来渲染是非常简单的;
  • 一个网格也包含了一个Material对象,它包含了一些函数能让我们获取物体的材质属性,比如说颜色和纹理贴图(比如漫反射和镜面光贴图);
  • 当使用建模工具对物体建模的时候,艺术家通常不会用单个形状创建出整个模型。通常每个模型都由几个子模型/形状组合而成。组合模型的每个单独的形状就叫做一个网格(Mesh)。比如说有一个人形的角色:艺术家通常会将头部、四肢、衣服、武器建模为分开的组件,并将这些网格组合而成的结果表现为最终的模型。一个网格是我们在OpenGL中绘制物体所需的最小单位(顶点数据、索引和材质属性)。一个模型(通常)会包括多个网格;

所以,我们需要做的第一件事是将一个物体加载到Scene对象中,遍历节点,获取对应的Mesh对象(我们需要递归搜索每个节点的子节点),并处理每个Mesh对象来获取顶点数据、索引以及它的材质属性。最终的结果是一系列的网格数据,我们会将它们包含在一个Model对象中

2.ubuntu 上安装libassimp

使用如下命令可以在ubuntu 上安装 libassimp
sudo apt install libassimp-dev
安装完成后,在/usr/lib/x86_64-linux-gnu/目录下就能看到libassimp相关的库文件,如下图所示
在这里插入图片描述

3. 使用Assimp 解析 cube.obj 文件

3.1 assimp_load_cube.cpp 文件内容如下

#include <iostream>
#include <stdio.h>
#include <GLES3/gl3.h>// 使用 Assimp 加载模型文件
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>int main()
{Assimp::Importer importer;const aiScene* scene = importer.ReadFile("./cube.obj", aiProcess_Triangulate | aiProcess_FlipUVs);if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {// 加载模型失败printf("cube.obj load failed\n");return -1;}aiMesh* mesh = scene->mMeshes[0];printf("mesh->mNumVertices = %d\n", mesh->mNumVertices);printf("mesh->mNumFaces = %d\n", mesh->mNumFaces);// 获取顶点坐标数据printf("cube vVertices : \n");GLfloat* vVertices = new GLfloat[mesh->mNumVertices * 3];for (unsigned int i = 0; i < mesh->mNumVertices; i++) {vVertices[i * 3] = mesh->mVertices[i].x;vVertices[i * 3 + 1] = mesh->mVertices[i].y;vVertices[i * 3 + 2] = mesh->mVertices[i].z;printf("%.1f, %.1f, %.1f,\n", vVertices[i * 3], vVertices[i * 3 + 1], vVertices[i * 3 + 2]);}// 获取面索引数据printf("cube indices : \n");GLushort* indices = new GLushort[mesh->mNumFaces * 3];for (unsigned int i = 0; i < mesh->mNumFaces; i++) {for (unsigned int j = 0; j < 3; j++) {indices[i * 3 + j] = mesh->mFaces[i].mIndices[j];}printf("%d, %d, %d,\n", indices[i * 3], indices[i * 3 + 1], indices[i * 3 + 2]);}return 0;
}

3.2 编译

使用如下命令对 assimp_load_cube.cpp 文件进行编译
g++ assimp_load_cube.cpp -o assimp_load_cube -lassimp
编译成功会在当前目录下得到可执行文件 assimp_load_cube

3.3 运行

将cube.obj 和 可执行文件 assimp_load_cube 放到同一个目录下,执行 ./assimp_load_cube 命令,打印解析出来的顶点坐标和顶点索引信息如下:

lkh@ubuntu:~/lkh2024/opengles_test$ ./assimp_load_cube 
mesh->mNumVertices = 36
mesh->mNumFaces = 12
cube vVertices : 
-0.5, 0.5, 0.5,
-0.5, -0.5, 0.5,
0.5, -0.5, 0.5,
-0.5, 0.5, 0.5,
0.5, -0.5, 0.5,
0.5, 0.5, 0.5,
0.5, 0.5, 0.5,
0.5, -0.5, 0.5,
0.5, -0.5, -0.5,
0.5, 0.5, 0.5,
0.5, -0.5, -0.5,
0.5, 0.5, -0.5,
0.5, 0.5, -0.5,
0.5, -0.5, -0.5,
-0.5, -0.5, -0.5,
0.5, 0.5, -0.5,
-0.5, -0.5, -0.5,
-0.5, 0.5, -0.5,
-0.5, 0.5

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2814279.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

【ArcGIS】统计格网中不同土地利用类型占比

基于ArcGIS统计格网中不同土地利用类型占比 数据准备ArcGIS操作步骤1、创建渔网&#xff08;Create Fishnet&#xff09;2、建立唯一标识3、选择格网4、提取不同类别土地利用类型5、各类用地面积计算 参考另&#xff1a;可能出现的问题总结Q1&#xff1a;ArcGIS获取唯一值&…

备战蓝桥杯————如何判断回文链表

如何判断回文链表 题目描述 给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为回文链表。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,2,1] 输出&#xff1a;true示例 2&#xff1a;…

AI学习(5):PyTorch-核心模块(Autograd):自动求导

1.介绍 在深度学习中&#xff0c;自动求导是一项核心技术&#xff0c;它使得我们能够方便地计算梯度并优化模型参数。PyTorch 提供了一个强大的自动求导模块(Autograd)&#xff0c;它可以自动计算张量的导数得出梯度信息&#xff0c;同时也支持高阶导数计算。 1.1 概念词 在学…

无人机飞行控制系统技术,四旋翼无人机控制系统建模技术详解

物理建模是四旋翼无人机控制系统建模的基础&#xff0c;主要涉及到无人机的物理特性和运动学特性。物理建模的目的是将无人机的运动与输入信号&#xff08;如控制电压&#xff09;之间的关系进行数学描述。 四旋翼无人直升机是具有四个输入力和六个坐标输出的欠驱动动力学旋翼…

Linux系统——Nginx服务——响应四级模型

stream和http模块是同级 [rootnode2 html]#yum install epel-release.noarch -y [rootnode2 html]#yum install redis -y [rootnode2 html]#systemctl start redis[rootnode3 html]#yum install epel-release.noarch -y [rootnode3 html]#yum install redis -y [rootnode3 html…

基于java+IDEA+Mysql开发的SSM+旅游后台管理系统

基于javaIDEAMysql开发的SSM旅游后台管理系统 项目介绍&#x1f481;&#x1f3fb; 旅游后台管理系统是一款应用于旅游后台管理的业务系统&#xff0c;实现旅游工作内容可视化、旅游管理专业化、业务评估数字化&#xff0c;从而提高旅游后台数据管理的高效性。 随着互联网时代的…

自动驾驶消息传输机制-LCM

需要用到LCM消息通讯&#xff0c;遂研究下。 这里写目录标题 1 LCM简介2. LCM源码分析3 LCM C教程与实例3.1 安装配置及介绍3.2 创建类型定义3.3 初始化LCM3.4 发布publish一个消息3.5 订阅和接收一个消息3.6 LCM进程间通讯3.7 注意事项&#xff1f;3.7.1 当数据结构定义的是数…

【ArcGIS】重采样栅格像元匹配问题:不同空间分辨率栅格数据统一

重采样栅格像元匹配问题&#xff1a;不同空间分辨率栅格数据统一 原始数据数据1&#xff1a;GDP分布数据2.1&#xff1a;人口密度数据2.2&#xff1a;人口总数数据3&#xff1a;土地利用类型 数据处理操作1&#xff1a;将人口密度数据投影至GDP数据&#xff08;栅格数据的投影变…

阿里云定价_ECS产品价格_云服务器收费标准 - 阿里云官方活动

2024年最新阿里云服务器租用费用优惠价格表&#xff0c;轻量2核2G3M带宽轻量服务器一年61元&#xff0c;折合5元1个月&#xff0c;新老用户同享99元一年服务器&#xff0c;2核4G5M服务器ECS优惠价199元一年&#xff0c;2核4G4M轻量服务器165元一年&#xff0c;2核4G服务器30元3…

Docker 常用操作命令备忘

Docker 一旦设置好了环境&#xff0c;日常就只要使用简单命令就可以运行和停止。 于是&#xff0c;我每次用的时候&#xff0c;都想不起来一些关键性的命令到底怎么用&#xff0c;特此记录。 一、镜像管理 从公有仓库拉取镜像 &#xff08;对于使用苹果电脑 M1/M2/M3 芯片的 …

Java玩转《啊哈算法》之模拟链表

人应该支配习惯&#xff0c;而绝不是让习惯支配人。一个人要是不能改掉坏习惯&#xff0c;那么他就一文不值。 目录 缘代码地址模拟链表创建遍历打印插入插入优化 完整代码 缘 各位小伙伴们好呀&#xff01;本人最近看了下《啊哈算法》&#xff0c;写的确实不错。 但稍显遗憾…

在Golang中简化日志记录:提升性能和调试效率

最大化效率和有效故障排除&#xff1a;在Golang中简化日志记录 日志记录是软件开发的一个基本方面&#xff0c;有助于调试、监控和理解应用程序的流程。在Golang中&#xff0c;有效的日志记录实践可以显著提高性能并简化调试过程。本文探讨了优化Golang日志记录的技术&#xf…

Android WebView实现网页滚动截图

WebView 网页滚动截屏&#xff0c;可对整个网页进行截屏而不是仅当前屏幕哦&#xff01; 注意若Web页面存在position:fixed; 的话得在调用前设置为 position:absolute; 哦&#xff0c;否则会出现很多次的&#xff0c;请看下面的具体解说吧&#xff01;&#xff01; private s…

一周学会Django5 Python Web开发-Django5列表视图ListView

锋哥原创的Python Web开发 Django5视频教程&#xff1a; 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计27条视频&#xff0c;包括&#xff1a;2024版 Django5 Python we…

[数据集][目标检测]狗狗表情识别VOC+YOLO格式3971张4类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;3971 标注数量(xml文件个数)&#xff1a;3971 标注数量(txt文件个数)&#xff1a;3971 标注…

Spring注解之前后端传值

目录 PathVariable 和 RequestParam RequestBody PathVariable 和 RequestParam PathVariable用于获取路径参数&#xff0c;RequestParam用于获取查询参数。 举个简单的例子&#xff1a; GetMapping("/lazzes/{clazzId}/teachers") public List<Teacher> …

HP笔记本电脑如何恢复出厂设置?这里提供几种方法

要恢复出厂设置Windows 11或10的HP笔记本电脑,你可以使用操作系统的标准方法。如果你运行的是早期版本,你可以使用HP提供的单独程序清除计算机并重新安装操作系统。 恢复出厂设置运行Windows 11的HP笔记本电脑​ 所有Windows 11计算机都有一个名为“重置此电脑”的功能,可…

【Nginx笔记02】通过Nginx服务器转发客户端的WebSocket接口到后端服务

这篇文章&#xff0c;主要介绍如何通过Nginx服务器转发客户端的WebSocket接口到后端服务【知识星球】。 目录 一、Nginx配置WebSocket 1.1、Nginx配置内容 1.2、客户端请求地址 1.3、创建WebSocket测试工程 1.4、启动测试 1.5、WebSocket超时问题 1.5.1、设置超时时间 …

数据结构与算法(数组,栈,队列,链表,哈希表,搜索算法,排序算法,查找算法,策略算法,递归算法,二叉搜索树BST,动态规划算法)

文章目录 1 课程介绍1.1 前置知识1.2 为什么要学习算法1.3 大厂面试常见数据结构题目(基础)1.4 数据结构和算法的关系 2 数据结构2.1 数据结构概述2.1.1 数据结构是什么2.1.2 数据结构分类2.1.2.1 线性结构2.1.2.2 非线性结构2.1.2.3 小总结 2.1.3 数据结构范围 2.2 数组Array2…

关于电脑一天24小时多少度电电脑的一天用电量计算

随着这几年物价的上涨&#xff0c;一些地区的电价越来越高&#xff0c;而我们经常需要使用电脑&#xff0c;那么一台电脑一天24小时用多少度电呢&#xff1f; 如何计算电脑一天的用电量&#xff1f; 让我们跟随小编来了解更多吧。 1、功耗、主机箱功耗 现在的计算机中&#xf…