OpenGL Assimp加载各类型模型(.obj、.fbx、.glb、.3ds)

2024-01-16 02:04

本文主要是介绍OpenGL Assimp加载各类型模型(.obj、.fbx、.glb、.3ds),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.简介

本博客以.glb格式为例,加载glb格式的3d模型,网上找了一圈,基本上都是根据OpenGL官方示例,加载.obj格式的3d模型。

下面以.obj和.glb格式的3D模型简单介绍一下。

常见的.obj格式的3D模型如下所示:纹理都已经被剥离出来了。所以在使用Assimp库加载的时候,加载了指定的路径即可。

但是.glb格式的3D模型如下所示,就只有一个glb文件,纹理嵌入到模型当中,假如我们使用Assimp库去加载的时候,能够加载出模型,但是加载出来的效果全是黑的,加载不了纹理。

加载的效果如下图所示,黑的一片。

原因分析:找不到纹理路径。

2.解决方法

将纹理分离,保存到本地文件,加载本地纹理文件。

首先通过ReadFile,读取本地文件,返回aiScene。

获取纹理数量:scene->mNumTextures。

获取当前的纹理:aiTexture* texture = scene->mTextures[i]。

然后看一下aiTexture官网文档介绍。

    /** Width of the texture, in pixels** If mHeight is zero the texture is compressed in a format* like JPEG. In this case mWidth specifies the size of the* memory area pcData is pointing to, in bytes.*/unsigned int mWidth;/** Height of the texture, in pixels** If this value is zero, pcData points to an compressed texture* in any format (e.g. JPEG).*/unsigned int mHeight;/** Data of the texture.** Points to an array of mWidth * mHeight aiTexel's.* The format of the texture data is always ARGB8888 to* make the implementation for user of the library as easy* as possible. If mHeight = 0 this is a pointer to a memory* buffer of size mWidth containing the compressed texture* data. Good luck, have fun!*/C_STRUCT aiTexel* pcData;char achFormatHint[ HINTMAXTEXTURELEN ]

mWidth:纹理的像素宽,如果高度为0,mWidth指定pcData指向的内存区域,以字节为单位。

mHeigth:纹理的像素高,像jpeg类型,该值为0。

pcData:纹理数据,数据的rgba值保存到这个数据里面。

achFormatHint:图片的格式,png或者jpg或者别的。

再进去看一下aiTexel结构,结构如下:包含r、g、b、a值,代表每一个像素的r、g、b、a值。

struct aiTexel {unsigned char b,g,r,a;#ifdef __cplusplus//! Comparison operatorbool operator== (const aiTexel& other) const{return b == other.b && r == other.r &&g == other.g && a == other.a;}//! Inverse comparison operatorbool operator!= (const aiTexel& other) const{return b != other.b || r != other.r ||g != other.g || a != other.a;}//! Conversion to a floating-point 4d coloroperator aiColor4D() const{return aiColor4D(r/255.f,g/255.f,b/255.f,a/255.f);}
#endif // __cplusplus} PACK_STRUCT;

 根据上面的条件,将图片保存到本地。

   const aiScene *scene = import.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs);if(!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {qDebug() << "ERROR::ASSIMP::" << import.GetErrorString();return;}directory = path.substr(0, path.find_last_of('/'));for (int i = 0; i < scene->mNumTextures; i++){aiTexture* texture = scene->mTextures[i];char fileName[100];sprintf(fileName, "%s/%s.%s", modelDirectory.c_str(), texture->mFilename.C_Str(), texture->achFormatHint);QFile file(fileName);if (file.exists()){m_mapPath.insert(i, QString(fileName));continue;}if (!file.open(QIODevice::WriteOnly))break;unsigned char* buffer = new unsigned char[texture->mWidth * 4];memset(buffer, 0, texture->mWidth * 4);for (int x = 0; x < texture->mWidth; ++x){//拷贝RGBA数据到缓冲区int index = x * 4;buffer[index] = texture->pcData[x].b; // Bluebuffer[index + 1] = texture->pcData[x].g; // Greenbuffer[index + 2] = texture->pcData[x].r;         // Redbuffer[index + 3] = texture->pcData[x].a; // Alpha}file.write((char*)buffer, texture->mWidth * 4);file.close();m_mapPath.insert(i, QString(fileName));delete[]buffer;}

如下图所示,将glb格式的纹理图片剥离出来保存到了本地。 

最后加载对应的纹理即可。

3.加载效果图

4.完整源码

https://download.csdn.net/download/wzz953200463/88746271

这篇关于OpenGL Assimp加载各类型模型(.obj、.fbx、.glb、.3ds)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/610966

相关文章

Golang的CSP模型简介(最新推荐)

《Golang的CSP模型简介(最新推荐)》Golang采用了CSP(CommunicatingSequentialProcesses,通信顺序进程)并发模型,通过goroutine和channe... 目录前言一、介绍1. 什么是 CSP 模型2. Goroutine3. Channel4. Channe

IDEA如何将String类型转json格式

《IDEA如何将String类型转json格式》在Java中,字符串字面量中的转义字符会被自动转换,但通过网络获取的字符串可能不会自动转换,为了解决IDEA无法识别JSON字符串的问题,可以在本地对字... 目录问题描述问题原因解决方案总结问题描述最近做项目需要使用Ai生成json,可生成String类型

SpringBoot项目启动后自动加载系统配置的多种实现方式

《SpringBoot项目启动后自动加载系统配置的多种实现方式》:本文主要介绍SpringBoot项目启动后自动加载系统配置的多种实现方式,并通过代码示例讲解的非常详细,对大家的学习或工作有一定的... 目录1. 使用 CommandLineRunner实现方式:2. 使用 ApplicationRunne

SpringBoot项目删除Bean或者不加载Bean的问题解决

《SpringBoot项目删除Bean或者不加载Bean的问题解决》文章介绍了在SpringBoot项目中如何使用@ComponentScan注解和自定义过滤器实现不加载某些Bean的方法,本文通过实... 使用@ComponentScan注解中的@ComponentScan.Filter标记不加载。@C

springboot 加载本地jar到maven的实现方法

《springboot加载本地jar到maven的实现方法》如何在SpringBoot项目中加载本地jar到Maven本地仓库,使用Maven的install-file目标来实现,本文结合实例代码给... 在Spring Boothttp://www.chinasem.cn项目中,如果你想要加载一个本地的ja

Mysql 中的多表连接和连接类型详解

《Mysql中的多表连接和连接类型详解》这篇文章详细介绍了MySQL中的多表连接及其各种类型,包括内连接、左连接、右连接、全外连接、自连接和交叉连接,通过这些连接方式,可以将分散在不同表中的相关数据... 目录什么是多表连接?1. 内连接(INNER JOIN)2. 左连接(LEFT JOIN 或 LEFT

最好用的WPF加载动画功能

《最好用的WPF加载动画功能》当开发应用程序时,提供良好的用户体验(UX)是至关重要的,加载动画作为一种有效的沟通工具,它不仅能告知用户系统正在工作,还能够通过视觉上的吸引力来增强整体用户体验,本文给... 目录前言需求分析高级用法综合案例总结最后前言当开发应用程序时,提供良好的用户体验(UX)是至关重要

Redis的Hash类型及相关命令小结

《Redis的Hash类型及相关命令小结》edisHash是一种数据结构,用于存储字段和值的映射关系,本文就来介绍一下Redis的Hash类型及相关命令小结,具有一定的参考价值,感兴趣的可以了解一下... 目录HSETHGETHEXISTSHDELHKEYSHVALSHGETALLHMGETHLENHSET

Python基于火山引擎豆包大模型搭建QQ机器人详细教程(2024年最新)

《Python基于火山引擎豆包大模型搭建QQ机器人详细教程(2024年最新)》:本文主要介绍Python基于火山引擎豆包大模型搭建QQ机器人详细的相关资料,包括开通模型、配置APIKEY鉴权和SD... 目录豆包大模型概述开通模型付费安装 SDK 环境配置 API KEY 鉴权Ark 模型接口Prompt

Python中异常类型ValueError使用方法与场景

《Python中异常类型ValueError使用方法与场景》:本文主要介绍Python中的ValueError异常类型,它在处理不合适的值时抛出,并提供如何有效使用ValueError的建议,文中... 目录前言什么是 ValueError?什么时候会用到 ValueError?场景 1: 转换数据类型场景