c++ - Assimp 不导入纹理

标签 c++ opengl assimp

我正在使用 assimp 在我的游戏引擎中导入 3d 模型。出于某种原因,无论我使用什么模型或模型格式,assimp 都不会报告任何纹理。这是为什么?

以下是使用 assimp 的非常简单的设置:

const aiScene* scene = importer.ReadFile(asset, aiProcessPreset_TargetRealtime_Quality);

if (scene->HasMaterials())
        {
            for (unsigned int i = 0; i < scene->mNumMaterials; i++)
            {
                const aiMaterial* material = scene->mMaterials[i];
                aiString texturePath;

                unsigned int numTextures= material->GetTextureCount(aiTextureType_DIFFUSE);   // always 0

                if (material->GetTextureCount(aiTextureType_DIFFUSE) > 0 && material->GetTexture(aiTextureType_DIFFUSE, 0, &texturePath) == AI_SUCCESS) 
                {
                   // never happens..
                   // scene->mNumTextures is always 0 aswell.
                }
            }
        }

我正在使用我确信具有纹理的各种模型,例如教程中的模型,这些模型是为使用 assimp 加载纹理模型的特定原因而设计的。 (例如,http://www.lighthouse3d.com/cg-topics/code-samples/importing-3d-models-with-assimp)

这可能是什么原因?

最佳答案

我知道这已经很老了,但过去几天我遇到了这个确切的问题并设法解决了,所以这里有一个解决方案供正在寻找的人使用。

纹理未加载的可能原因有两个:

  1. 纹理是嵌入的。

  1. 您的模型 Material 文件有问题。

如果是第 1 种情况,则它无法正常工作,因为 GetTexture 和 GetTextureCount 不适用于嵌入 Material 。嵌入 Material 通常只是简单的颜色。如果您想知道如何导入嵌入 Material ,请查看 ASSIMP 示例代码或 AssimpView 的源代码。

您的问题很可能是第 2 种情况:您的 Material 文件有问题。例如,.OBJ 模型文件带有相应的 .MTL 文件(如果它们带有纹理)。如果缺少 .MTL 文件,则不会加载纹理。如果 .MTL 文件有问题,纹理也不会加载。

因此,请确保您所有的 .mtl 文件和任何其他 Material 文件(包括纹理本身的图像)都在那里。如果它们在那里,那么您接下来要做的就是使用 AssimpView 工具打开模型。确保模型正确加载所有纹理。如果没有,要么 Material 文件有问题(下面的解决方案),要么模型文件有问题,Assimp 根本无法加载它(或者 Assimp 有根本性的问题)。如果加载正确,您应该会在 AssimpView 的右侧看到漫反射纹理的名称。

因此,如果所有这些都检查出来并且程序中的 Assimp 导入器仍然无法识别模型中的纹理(即使 AssimpView 可以识别),那么您接下来要做的就是使用某些东西打开 .MTL 文件像记事本。你会看到这样的东西:

# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
# File Created: 06.10.2013 19:40:35

newmtl 01___Default
Ns 10.0000
illum 2
Ka 0.0000 0.0000 0.0000
Kd 0.5882 0.5882 0.5882
Ks 0.0000 0.0000 0.0000
Ni 1
d 0
map_Kd MoonMap2_2500x1250.jpg

这些文件可能有很多错误。请注意,map_Kd 定义了用于漫反射纹理的图像文件。有时,您不会看到正确的路径或只有文件名,而是会看到相对于创建模型的计算机的整个目录路径(即它会说类似 C:/Users/blah blah blah/MoonMap2 ...)。您可以通过删除目录路径并仅保留图像文件名(并将图像保存在与模型相同的文件夹中)轻松解决此问题,或者您可以放置​​自己的自定义路径并将纹理放在那里。

您可能会看到的另一种问题是在 .MTL 文件中列出的变量实际上没有被赋予值。

例如:

# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
# File Created: 06.10.2013 19:40:35

newmtl 01___Default
Ns 10.0000
illum 2
Ka 0.0000 0.0000 0.0000
Kd 0.5882 0.5882 0.5882
Ks 0.0000 0.0000 0.0000
Ni 1
d 0
map_Kd MoonMap2_2500x1250.jpg
map_Ka 

注意最后的“map_Ka”。它旁边没有任何东西。这不仅会阻止纹理被正确识别,实际上还会阻止 AssimpView 加载模型。当它们旁边没有值时,只需删除您看到的任何此类属性。

最后,如果这些都不起作用,那么您可能只需要尝试 .MTL 文件 - 其中可能列出了一个属性/变量,由于某种原因导致了问题,所以请尝试删除您绝对确定的行确定你不需要(请注意,Kd 代表漫反射纹理,Ka 代表环境纹理,Ks 镜面反射等)。我在这里用作示例的 .MTL 文件包含我认为是 MTL 文件应该具有的最低限度的行,以便能够加载漫反射纹理。

希望这对您有所帮助。如果这些都不起作用,我会怀疑您的 ASSIMP 库存在根本性的错误。如果您的模型文件没有 Material 文件,那是您的问题。

关于c++ - Assimp 不导入纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16134605/

相关文章:

java - LWJGL Assimp : Loading Textures

C++ 模板化映射包含自身

java - LWJGL + 光滑纹理未加载

c++ - "Protobuf compiler version doesn' t 匹配库版本 3.6.1"不使用系统 Protobuf 库时

java - 尽管宽度和高度发生变化,Lwjgl/openGL 窗口大小始终保持不变

c++ - 纹理splat opengl的最有效方法?

c++ - gpu 蒙皮的矩阵计算

c++ - 使用 assimp 在 OpenGL 中使用法线作为颜色

c++ - 使用 ifstream 检查 C++ 中的数据类型

c++ - 如果我在整个类上使用 std::swap,是否会使用专门的 shared_ptr::swap() 函数?