2011-06-28 81 views
7

我目前正在編寫OpenGL中的.obj加載器。我將頂點數據存儲在VBO中,然後使用Vertex Attribs將其綁定。法線同樣。事情是,正常的數據和頂點數據不以相同的順序存儲。在glDrawElements(OpenGL/VBOs)中爲頂點和法線使用不同的陣列

我使用glDrawElements渲染網格的指數,我想通過OpenGL獲取頂點VBO中的頂點並獲取法線VBO中的法線。

除了使用glBegin/glVertex/glNormal/glEnd來告訴glDrawElements使用頂點索引和其他正常的索引之外,還有一種opengl方式嗎? 謝謝

回答

2

你必須使用位置/法線/紋理座標等相同的指數等。這意味着,加載.obj時,你必須插入獨特的頂點,並指向你的面孔。

7

雖然你可以用模擬,但它並沒有直接的方法來做到這一點,只需在着色器內建立緩衝區紋理(OpenGL3.1特性)即可。

儘管如此,通常不建議做這樣的事情。 OBJ格式允許一個法線一次被幾個(原則上任意數量的)頂點引用,所以通常要做的是構造一個「完整」頂點,包括每個頂點的座標和法線和texcoords(複製相應的數據)。

這確保
一個)平滑陰影表面呈現正確
b)中硬邊緣正確渲染

(兩者之間的不同之處僅幾個頂點共享相同的,相同的正常)

+2

請注意,當我說「不可取」時,我的確是這個意思。這不僅比構造適當的頂點流並上傳它更復雜,而且它意味着隨機而不是順序數據訪問,也就是說,每個頂點都有或多或少的保證緩存未命中。 – Damon

2

的OpenGL將頂點看作單個長向量

(position, normal, texcoord[0]…texcoord[n], attrib[0]…attrib[n]) 

並且這些長向量被索引。您的問題屬於同一類別,例如如何使用具有多個法線的共享頂點。規範的答案是,那些頂點事實上並不共享,因爲從長遠來看,它們並不相同。

所以你需要做的是遍歷面的索引數組,並構造「長」頂點將這些添加到具有uniquenes約束的(新)列表中;來自頂點→索引的(散列)圖服務於此作業。像這樣的東西

next_uniq_index = 0 
for f in faces: 
    for i in f.indices: 
     vpos = vertices[i.vertex] 
     norm = normals[i.normal] 
     texc = texcoords[i.texcoord] 
     vert = tuple(vpos, norm, texc) 
     key 
     if uniq_vertices.has_key(key): 
      uniq_faces_indices.append(uniq_vertices[key].index) 
     else: 
      uniq_vertices[key] = {vertex = key, index = next_uniq_index} 
      next_uniq_index = next_uniq_index + 1 
相關問題