2013-01-04 110 views
3

我想將obj模型導入到我的opengl程序中。我有我使用傳遞屬性數據爲着色器類/數據格式:解析wavefront obj文件格式

class CustomVertex : public IVtxFmt 
{ 
public: 
    float m_Position[3];  // x, y, z  offset 0, size = 3*sizeof(float)  
    float m_Normal[3];  // nx, ny, nz; offset 3 
    float m_TexCoords[2];  // u, v   offset 6 
    float m_Colour[4];  // r, g, b, a offset 8 
    float m_Tangent[3];  // r, g, b  offset 12 
    float m_Bitangent[3];  // r, g, b  offset 15 
}; 

所以我有一個小木屋我從互聯網上下載的模式工作。

小木屋有幾個頂點,法線和紋理座標定義,後面跟着一個面部定義列表。

所以,我的第一反應是解析OBJ文件,並與

vector<vertex> 
vector<Normal> 
vector<TexCoord> 

這不是直白地翻譯成我CUSTOMVERTEX格式,因爲可能有210個頂點,100個TEX COORDS和定義80個法線結束文件。

〜390面孔在此格式的信息列表後:

f 83/42/1 67/46/1 210/42/1 

我遇到文件中的以下內容:

# 
# object tile00 
# 

隨後更頂點定義。因此,我推斷出一個模型可能由若干個子對象組成,每個子對象都由多個面定義;每個面由3個頂點/正常/ texcoord索引值定義。

因此爲了與CUSTOMVERTEX的矢量到達時,我在想,我需要做到以下幾點:

創建並填充:

vector <vertex> 
vector <normal> 
vector <texcoord> 

vector <indices> 

我需要爲每一個CUSTOMVERTEX面部定義中唯一的v/vn/vt三元組。

因此,我認爲有關創建地圖:

std::vector<CustomVertex> and 
std::map< nHashId, CustomVertex_index > 

所以我的想法是,每個V/VN/VT我遇到,我創建這個字符串的哈希例如nHashId =散列(「80/50/1」)*並在地圖上搜索散列。如果不存在,我創建一個CustomVertex並將其添加到矢量,然後將新創建的散列和CustomVertex_index添加到地圖中。

*:通過創建v/vn/vt字符串的散列,我創建了一個與該字符串對應的唯一數字值,我希望在地圖中搜索/比較的速度快於等效文本。

如果我遇到一個匹配的哈希,我認爲CUSTOMVERTEX已經存在,而不是創建一個新的CUSTOMVERTEX,我只需添加CustomVertex_index項指數向量,繼續前進。

因爲這看起來像是一個計算成本很高的練習,所以我想我會將CustomVertex數組(和相應的索引數組)存儲到磁盤供以後檢索,而不是每次都解析obj文件。

在問我的問題之前,我可以指出,由於時間限制,不想重新設計我的Vbo類(一個不平凡的任務),我堅持使用CustomVertex格式 - 我知道它是可能的在單獨的數組中提供屬性給我的着色器,但是我已經讀過,像我用CustomVertex交織數據可以提高性能。

所以對我的問題: 1.我的方法看起來好聽還是瘋狂?如果瘋了,請指出我要出錯的地方。

  1. 你能發現任何潛在的問題嗎?

  2. 有沒有人以前做過這個,可以推薦一個更簡單的方法來實現我想要的?

+2

如果你可以散列一些東西,爲什麼不使用'unordered_map'呢?否則你的方法看起來很好,不會過於複雜。 – pmr

+0

通過創建v/vn/vt字符串的散列,我創建了一個與該字符串相對應的唯一數字值,我希望在地圖中搜索/比較的速度要快於等效文本。 – fishfood

+0

@lapin:這就是所謂的「過早優化」。只需比較指數(如*數字*,而不是文字)。如果你的配置文件顯示它很慢,那麼解決它。 –

回答

0

你能找出潛在的問題是什麼?

你的意思是除了哈希碰撞?因爲我沒有看到你的算法處理那部分。

有沒有人做過此事,並可以推薦一個更簡單的方法來實現我想要的?

有一種更簡單的方法:只比較索引而不使用散列。

0

而不是創建「v/vn/vt」的字符串哈希,這個想法是隻將v作爲整數散列。之後,您將得到一個包含共享相同v索引的所有「v/vn/vt」組合的存儲桶。

如果發生散列衝突(遇到相同的v),您可以將衝突的組合與存儲桶中的組合進行比較,以確定它是否真的重複。如果不是,請記住將相沖突的組合添加到存儲桶中。