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



    前言

    `本文主要介绍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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    在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 
    #include 
    #include 
    
    // 使用 Assimp 加载模型文件
    #include 
    #include 
    #include 
    
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    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
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
  • 相关阅读:
    GBase 8s ALTER FRAGMENT 语句 MODIFY子句(三)
    openGauss数据库源码解析系列文章—— 密态等值查询技术详解(下)
    分开的两个程序使用共同的mysql,一端更新了表,另一端怎么及时更新缓存,使用mybatis
    nginx(七十九)nginx与tls/ssl续
    Unity 通过jar包形式接入讯飞星火SDK
    1.6 IntelliJ IDEA开发工具
    本地MQTT协议消息服务远程连接教程介绍
    Visual Studio 2022 设置 PySide6 扩展工具
    uni-app入门:WXML列表渲染与条件渲染
    微服务-grpc-consul-protoBuf-micro
  • 原文地址:https://blog.csdn.net/lh0616/article/details/136221168