我在基於Apple示例代碼的OpenGL-ES中製作了一些相當基本的形狀。他們使用了一系列點,第一個數組中有一系列索引,每個三個索引都創建一個多邊形。這非常棒,我可以製作我想要的形狀。要正確遮蔽形狀,我相信我需要爲每個多邊形上的每個頂點計算法線。起初這些形狀是立方形的,所以非常容易,但是現在我正在製作(稍微)更高級的形狀,我想自動創建這些法線。如果我得到一個多邊形的兩個邊(這裏所有的多邊形都是三角形)的矢量並且將它們的叉積用於該多邊形上的每個頂點似乎很容易。之後,我使用下面的代碼來繪製形狀。自動計算GLKit/OpenGL-ES中的法線數
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, triangleVertices);
glEnableVertexAttribArray(GLKVertexAttribColor);
glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, 0, triangleColours);
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 0, triangleNormals);
glDrawArrays(GL_TRIANGLES, 0, 48);
glDisableVertexAttribArray(GLKVertexAttribPosition);
glDisableVertexAttribArray(GLKVertexAttribColor);
glDisableVertexAttribArray(GLKVertexAttribNormal);
我無法理解的是爲什麼我必須手動執行此操作。我敢肯定,有些情況下,除了垂直於表面的矢量以外,還需要其他東西,但我也確定這是迄今爲止最流行的用例,所以不應該有更簡單的方法嗎?我錯過了明顯的東西嗎? glCalculateNormals()會很好。
//這裏是一個答案 傳入一個GLKVector3 [],你希望用你的法線填充,另一個用頂點(每三個分組成多邊形),然後是頂點的數量。
- (void) calculateSurfaceNormals: (GLKVector3 *) normals forVertices: (GLKVector3 *)incomingVertices count:(int) numOfVertices
{
for(int i = 0; i < numOfVertices; i+=3)
{
GLKVector3 vector1 = GLKVector3Subtract(incomingVertices[i+1],incomingVertices[i]);
GLKVector3 vector2 = GLKVector3Subtract(incomingVertices[i+2],incomingVertices[i]);
GLKVector3 normal = GLKVector3Normalize(GLKVector3CrossProduct(vector1, vector2));
normals[i] = normal;
normals[i+1] = normal;
normals[i+2] = normal;
}
}
我原以爲我的案子是多數案件,但如果不是通常的做法,那麼我可以理解它是一項手工工作。我主要想要塊,所以我可能會堅持我的系統。用平均的平均頂點法線方法描述瞭如何告訴OpenGL,雖然我有12個多邊形和36個頂點,但我只計算了8個法線?我是否需要一個包含36個法線的數組來匹配頂點,並將法線放置在相同的順序中?這意味着當有兩個多邊形共享一個頂點時,有些會重複,或者有一種方法可以鏈接法線和頂點? – Craig
@Craig每個頂點總是有一個法線。如果計算法線,則必須爲每個面的每個頂點重複每個面的法向(每個面)。如果計算每個頂點法線,則每個頂點法線將重複用於頂點所屬的每個面,就像頂點實際一樣。從概念上講,頂點是其所有屬性的全部,而不僅僅是位置,在OpenGL中,這不幸也稱爲頂點。 –
@Craig但是每個頂點法線(關於存儲效率)的優點是,您可以使用索引數組(和'glDrawElements')並完全減少重複,因爲每個唯一頂點具有相同的法線。對於每面法線,指數不會爲您購買任何東西,因爲您無論如何都需要複製頂點,因爲每個具有唯一位置的頂點可能有多個不同的法線。 –