Я делаю несколько довольно простых фигур в OpenGL-ES на основе примера кода от Apple. Они использовали массив точек, с массивом индексов в первом массиве, и каждый набор из трех индексов создает многоугольник. Это все замечательно, я могу делать формы, которые я хочу. Чтобы правильно затенить фигуры, я считаю, что мне нужно вычислить нормали для каждой вершины каждого многоугольника. Сначала формы были кубовидными, поэтому это было очень легко, но теперь я делаю (немного) более сложные формы, я хочу автоматически создавать эти нормали. Это кажется достаточно простым, если я получу векторы для двух ребер многоугольника (здесь все многоугольники являются треугольниками) и использую их перекрестное произведение для каждой вершины этого многоугольника. После этого я использую код, как показано ниже, чтобы нарисовать форму.
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;
}
}