简体   繁体   English

Assimp不会导入纹理

[英]Assimp does not import textures

I am using assimp to import 3d models in my game engine. 我正在使用assimp在我的游戏引擎中导入3d模型。 For some reason, no matter what model or model format I use, assimp does not report any textures whatsoever. 出于某种原因,无论我使用何种型号或型号格式,assimp都不会报告任何纹理。 Why is this? 为什么是这样?

The following is the very simple setup with 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.
                }
            }
        }

I'm using various models that I am positive has textures, for example models from tutorials that are designed for the very specific reason of loading textured models using assimp. 我正在使用各种模型,我肯定有纹理,例如教程中的模型是为使用assimp加载纹理模型的非常具体的原因而设计的。 (for example, http://www.lighthouse3d.com/cg-topics/code-samples/importing-3d-models-with-assimp ) (例如, http://www.lighthouse3d.com/cg-topics/code-samples/importing-3d-models-with-assimp

What could be the reason for this? 这可能是什么原因?

I know this is quite old, but I was having this exact problem the past couple days and managed to figure it out, so here's a solution for whoever is looking. 我知道这已经很老了,但过去几天我遇到了这个确切的问题,并设法弄明白了,所以这里有一个解决方案,无论是谁在寻找。

There are two possible reasons for why your textures are not loading: 纹理未加载的原因有两个:

  1. The textures are embedded. 纹理是嵌入的。

or 要么

  1. Something is wrong with your materials file for the model. 您的模型的材料文件有问题。

If it is case #1, then it is not working simply because GetTexture and GetTextureCount do not apply to embedded materials. 如果它是#1的情况,那么它就不起作用,因为GetTexture和GetTextureCount不适用于嵌入式材料。 Embedded materials are usually just simple colours. 嵌入式材料通常只是简单的颜色。 If you would like to know how to import embedded materials, take a look at the ASSIMP sample codes, or the source code for AssimpView. 如果您想知道如何导入嵌入材料,请查看ASSIMP示例代码或AssimpView的源代码。

Chances are your issue is in case #2: something is wrong with your materials file. 机密是你的问题#2:你的材料文件有问题。 .OBJ model files, for example, come with a corresponding .MTL file, if they are textured. 例如,.OBJ模型文件带有相应的.MTL文件,如果它们是纹理的。 If the .MTL file is missing, the textures will not load. 如果缺少.MTL文件,则不会加载纹理。 If there is something wrong with the .MTL file, the textures also will not load. 如果.MTL文件有问题,纹理也不会加载。

So, make sure all of your .mtl files are there and any other material files (including the images for the textures themselves). 因此,请确保所有.mtl文件都在那里以及任何其他材质文件(包括纹理本身的图像)。 If they are there, then the next thing you will want to do is open the model using the AssimpView tool. 如果它们在那里,那么接下来你要做的就是使用AssimpView工具打开模型。 Make sure that the model loads in properly with all of its textures. 确保模型正确加载其所有纹理。 If it doesn't, either something is wrong with the materials file (solution below), or something is wrong with the model file and Assimp simply can't load it (or something is fundamentally wrong with Assimp). 如果没有,那么材料文件(下面的解决方案)出现问题,或者模型文件出现问题,而Assimp根本无法加载它(或者Assimp的根本错误)。 If it loads properly, You should see the names of the diffuse textures on the right side of AssimpView. 如果正确加载,您应该在AssimpView的右侧看到漫反射纹理的名称。

So, if all of this checks out and the Assimp importer in your program is still not recognizing textures from your model (even though AssimpView does), then the next thing you want to do is actually open the .MTL file using something like notepad. 因此,如果所有这些都检出并且程序中的Assimp导入器仍然无法识别模型中的纹理(即使AssimpView确实如此),那么您要做的下一件事实际上是使用记事本之类的东西打开.MTL文件。 You will see something like this: 你会看到这样的事情:

# 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

There are various things that can be wrong with these files. 这些文件有各种各样的错误。 Notice that map_Kd defines the image file to be used for the diffuse texture. 请注意,map_Kd定义了用于漫反射贴图的图像文件。 Sometimes, instead of having the correct path or just the filename there, you will instead see an entire directory path relative to the computer that the model was made on (ie it'll say something like C:/Users/blah blah blah/MoonMap2...). 有时候,你不会在那里找到正确的路径或文件名,而是看到相对于制作模型的计算机的整个目录路径(即它会说像C:/ Users / blah blah blah / MoonMap2 ...)。 You can easily fix this by removing the directory path and only keeping the image file name (and keeping the image in the same folder as the model), or you can put your own custom path and put the textures there. 您可以通过删除目录路径并仅保留图像文件名(并将图像保持在与模型相同的文件夹中)来轻松解决此问题,或者您可以放置​​自己的自定义路径并将纹理放在那里。

Another kind of issue that you may see is variables being listed in the .MTL file without actually being given values. 您可能会看到的另一类问题是.MTL文件中列出的变量实际上没有给定值。

For example: 例如:

# 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 

Notice the "map_Ka" at the end there. 注意那里的“map_Ka”。 It has nothing next to it. 它旁边没有任何东西。 Not only does this prevent textures from being recognized properly, it actually prevents AssimpView from being able to load models at all. 这不仅可以防止纹理被正确识别,而且实际上阻止了AssimpView能够加载模型。 Simply remove any properties like this that you see when they have no values next to them. 只需删除它们旁边没有值时所见的任何属性。

Finally, if none of this works, then you may just have to experiment with the .MTL file - there might be a property/variable listed in it that's causing trouble for some reason, so try removing lines that you're absolutely sure you don't need (Note that Kd represents the diffuse texture, Ka would represent the ambient texture, Ks the specular, etc.). 最后,如果这些都不起作用,那么你可能只需要试验.MTL文件 - 可能有一个属性/变量列在其中由于某种原因导致麻烦,所以尝试删除你绝对确定不要的行不需要(注意Kd代表漫反射纹理,Ka代表环境纹理,Ks代表镜面反射等)。 The .MTL file that I have been using as an example here contains what I believe is the bare minimum lines that an MTL file should have in order to be able to load in a diffuse texture. 我在这里作为示例使用的.MTL文件包含我认为MTL文件应该具有的最小行,以便能够加载漫反射纹理。

Hope this helps. 希望这可以帮助。 If none of this works, I would suspect that something is fundamentally wrong with your ASSIMP library. 如果这些都不起作用,我会怀疑你的ASSIMP库存在根本性的错误。 If your model file has no materials file well... there's your problem. 如果您的模型文件没有很好的材料文件......那就是您的问题。

Exploring of assimp sources shows that there is no mNumTextures++ in OBJ importer at all. 探索assimp源表明OBJ导入器中根本没有mNumTextures ++。 So it will never positive with importing OBJ-files. 因此,导入OBJ文件永远不会是积极的。

The right method to load textures is add to the end of apply_material() (you can get example sources in assimp repository on github) the next code (D Language): 加载纹理的正确方法是添加到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);
}

And to display this textures add to recursive_render() between glColor4fv and glNormal3fv the next line: 并显示此纹理添加到glColor4fv和glNormal3fv之间的recursive_render()下一行:

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

Continuing from what Matt said about the material file being valid, I found out another possible problem with the materials not loading and a solution for it. 继续Matt所说的关于材料文件的有效性,我发现了另一个可能的问题,即材料没有加载并且是一个解决方案。

In the obj file there are references to the material file and the material name in that file. 在obj文件中,引用了该文件中的材料文件和材料名称。 If you have renamed the file, these will not match and it will not find the material. 如果您已重命名该文件,则这些文件将不匹配,并且找不到该材料。

In the obj file you will find a line that looks like this 在obj文件中,您将找到一个如下所示的行

mtllib deer-obj.mtl

This is the name of the material file. 这是材料文件的名称。 If you have renamed the material, you have to rename it here too. 如果您已重命名该材料,则必须在此处重命名。

On the same file you will find references to the names of the materials defined in the material file like so: 在同一文件中,您将找到对材料文件中定义的材料名称的引用,如下所示:

usemtl deer

This has to match the names of the materials in the material file. 这必须匹配材料文件中材料的名称。 In the mtl file I have this defined: 在mtl文件中我定义了这个:

newmtl deer

The "usemtl" name and "newmtl" names have to match to be able to find the material. “usemtl”名称和“newmtl”名称必须匹配才能找到材料。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM