2013-04-21 49 views
2

我正在使用assimp在我的游戏引擎中导入3D模型。出于某种原因,无论使用何种型号或型号,assimp都不会报告任何纹理。为什么是这样?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

这是什么原因?

+3

说实话,我觉得从这里下载源程序(modelimport.zip)一些-with类我遇到的最糟糕的“C”的在很长的时间。 – sehe 2013-04-21 18:40:49

+1

呵呵。我只是修复它,所以它编译GCC 4.7,'3文件改变,1174插入(+),1172删除( - )'。 (我建议你可以找到更好的样本来学习?)** [https://gist.github.com/sehe/0f8f711f44d48b9ecbbf](https://gist.github.com/sehe/0f8f711f44d48b9ecbbf)** – sehe 2013-04-21 18:59:07

+0

我不使用教程,只是它提供的模型 – KaiserJohaan 2013-04-21 19:09:33

回答

10

我知道这已经很老了,但过去几天我有这个确切的问题,并设法弄清楚,所以这里有一个解决方案,无论谁在寻找。

有为什么你的纹理不加载两个可能的原因:

  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库存在根本性错误。如果你的模型文件没有很好的材料文件...那就是你的问题。

0

继续从马特所说的关于材料文件的有效性,我发现了材料未加载的另一个可能的问题和解决方案。

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

在OBJ文件,你会发现一条线,看起来像这样

mtllib deer-obj.mtl 

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

上,你会发现在材料文件中定义的,像这样的材料的名称引用同一个文件:

usemtl deer 

这有可能在材料文件材料的名称相匹配。在MTL文件中我有这样的定义:

newmtl deer 

的“usemtl”名称和“newmtl”名称必须匹配,以便能够找到的材料。

0

探索assimp源代码显示根本没有OBJ导入器中的mNumTextures ++。 因此,它永远不会对导入OBJ文件产生积极影响。

加载纹理正确的方法是增加)apply_material(结束(你可以得到例如在GitHub上assimp库源)下一个代码(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);