2013-04-21 83 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);