【问题标题】:Assimp does not import texturesAssimp 不导入纹理
【发布时间】:2013-04-14 14:48:13
【问题描述】:

我正在使用 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

这可能是什么原因?

【问题讨论】:

  • 老实说,我从那里找到源代码下载 (modelimport.zip) 一些我很长时间以来遇到的最糟糕的“C”类。
  • 呵呵。我刚刚修复了它,所以它可以在 GCC 4.7 3 files changed, 1174 insertions(+), 1172 deletions(-) 上编译。 (我建议你也许能找到更好的样本来学习?)https://gist.github.com/sehe/0f8f711f44d48b9ecbbf
  • 我没有使用教程,仅使用它提供的模型
  • 哦,太好了。那是缓刑! :)
  • 所以那个长凳模型不包含任何纹理。

标签: c++ opengl assimp


【解决方案1】:

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

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

  1. 纹理被嵌入。

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

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

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

因此,请确保您的所有 .mtl 文件以及任何其他材质文件(包括纹理本身的图像)都在那里。如果它们在那里,那么您接下来要做的就是使用 AssimpView 工具打开模型。确保模型的所有纹理都正确加载。如果没有,要么是材料文件有问题(下面的解决方案),要么是模型文件有问题,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 库存在根本问题。如果您的模型文件没有很好的材料文件...那是您的问题。

【讨论】:

    【解决方案2】:

    继续 Matt 所说的材料文件有效,我发现了另一个可能的问题,即材料无法加载以及解决方案。

    在 obj 文件中有对材料文件的引用和该文件中的材料名称。如果你重命名了文件,这些将不匹配,它不会找到材料。

    在 obj 文件中,你会找到如下所示的一行

    mtllib deer-obj.mtl
    

    这是材料文件的名称。如果你已经重命名了材质,你也必须在这里重命名它。

    在同一个文件中,您会发现对材料文件中定义的材料名称的引用,如下所示:

    usemtl deer
    

    这必须与材质文件中的材质名称相匹配。在 mtl 文件中,我定义了这个:

    newmtl deer
    

    “usemtl”名称和“newmtl”名称必须匹配才能找到材料。

    【讨论】:

      【解决方案3】:

      对assimp来源的探索表明OBJ导入器中根本没有mNumTextures++。 因此,导入 OBJ 文件永远不会积极。

      加载纹理的正确方法是在apply_material()的末尾添加下一个代码(D语言):

      aiString path;
      if(aiReturn_SUCCESS == aiGetMaterialTexture(mtl, aiTextureType_DIFFUSE, 0, &path))
      {
          string p = (cast(const(char)*)(path.data)).to!(string)();
      
          GLuint texture_name;
          glGenTextures(1, &texture_name);// generate GL-textures ID's
          glBindTexture(GL_TEXTURE_2D, texture_name);// Binding of texture name
          //
          //redefine standard texture values
          //
          // We will use linear interpolation for magnification filter
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
          // tiling mode
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, true ? GL_REPEAT : GL_CLAMP);
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, true ? GL_REPEAT : GL_CLAMP);
      
          auto image = IMG_Load(p.toStringz);
          if (!image)
          {
              throw new Exception(format("Error while loading texture: %s", p));
          }
      
          // Texture specification
          glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.w, image.h, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                  image.pixels);
      }
      

      为了显示这个纹理,在 glColor4fv 和 glNormal3fv 之间的 recursive_render() 中添加下一行:

      glTexCoord2f(mesh.mTextureCoords[0][index].x, 1.0-mesh.mTextureCoords[0][index].y);
      

      【讨论】:

        猜你喜欢
        • 2022-12-21
        • 1970-01-01
        • 2018-04-17
        • 1970-01-01
        • 2017-09-27
        • 2012-01-13
        • 2013-05-01
        • 2019-03-25
        • 2013-12-27
        相关资源
        最近更新 更多