首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Assimp不导入纹理

Assimp不导入纹理
EN

Stack Overflow用户
提问于 2013-04-22 02:19:54
回答 3查看 15.3K关注 0票数 4

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

下面是使用assimp进行的非常简单的设置:

代码语言:javascript
运行
复制
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)

这可能是什么原因呢?

EN

回答 3

Stack Overflow用户

发布于 2014-04-19 06:25:28

我知道这很古老,但我在过去的几天里遇到了这个问题,并设法解决了它,所以对于正在寻找的人来说,这里有一个解决方案。

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

  1. 纹理已嵌入。

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

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

你的问题很可能出现在第二种情况:你的材料文件有问题。例如,如果.OBJ模型文件带有纹理,则会附带相应的.MTL文件。如果缺少.MTL文件,则不会加载纹理。如果.MTL文件有问题,纹理也不会加载。

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

因此,如果所有这些都得到了验证,并且程序中的Assimp导入器仍然无法识别模型中的纹理(即使AssimpView可以),那么您要做的下一件事实际上是使用记事本之类的东西打开.MTL文件。您将看到类似如下的内容:

代码语言:javascript
运行
复制
# 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文件中列出,但实际上并没有给出值。

例如:

代码语言:javascript
运行
复制
# 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库存在根本性问题。如果您的模型文件没有材质文件...这就是你的问题所在。

票数 12
EN

Stack Overflow用户

发布于 2016-03-21 18:53:08

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

在obj文件中,存在对材料文件的引用以及该文件中的材料名称。如果已重命名该文件,则这些文件将不匹配,系统将找不到该材料。

在obj文件中,您将发现如下所示的行

代码语言:javascript
运行
复制
mtllib deer-obj.mtl

这是材质文件的名称。如果已重命名材质,则必须在此处对其进行重命名。

在同一文件中,您可以找到在材质文件中定义的材质名称的引用,如下所示:

代码语言:javascript
运行
复制
usemtl deer

这必须与材料文件中材料的名称相匹配。在mtl文件中,我定义了以下内容:

代码语言:javascript
运行
复制
newmtl deer

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

票数 1
EN

Stack Overflow用户

发布于 2018-02-28 23:36:29

对assimp源的探索表明,在OBJ进口商中根本没有mNumTextures++。因此,导入OBJ文件将永远不会是积极的。

加载纹理的正确方法是将以下代码(D语言)添加到apply_material()的末尾(您可以在github上的assimp存储库中获得示例源代码):

代码语言:javascript
运行
复制
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()中添加下一行:

代码语言:javascript
运行
复制
glTexCoord2f(mesh.mTextureCoords[0][index].x, 1.0-mesh.mTextureCoords[0][index].y);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16134605

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档