我正在根据 Apple 的示例代码在 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;
}
}