OpenGL вычисляет нормаль пользовательской формы

у меня есть форма со следующими вершинами и гранями:

static Vec3f cubeVerts[24] = {
{ -0.5,  0.5, -0.5 },   /* backside */
{ -0.5, -0.5, -0.5 },   
{ -0.3,  4.0, -0.5 },
{ -0.3,  3.0, -0.5 },
{ -0.1,  5.5, -0.5 },
{ -0.1,  4.5, -0.5 },
{  0.1,  5.5, -0.5 },
{  0.1,  4.5, -0.5 },
{  0.3,  4.0, -0.5 },           
{  0.3,  3.0, -0.5 },
{  0.5,  0.5, -0.5 },   
{  0.5, -0.5, -0.5 },   

{ -0.5,  0.5,  0.5 },   /* frontside */
{ -0.5, -0.5,  0.5 },   
{ -0.3,  4.0,  0.5 },
{ -0.3,  3.0,  0.5 },
{ -0.1,  5.5,  0.5 },
{ -0.1,  4.5,  0.5 },
{  0.1,  5.5,  0.5 },
{  0.1,  4.5,  0.5 },
{  0.3,  4.0,  0.5 },           
{  0.3,  3.0,  0.5 },
{  0.5,  0.5,  0.5 },   
{  0.5, -0.5,  0.5 }
};

static GLuint cubeFaces[] = {
0, 1, 3, 2,     /*backfaces*/
2, 3, 5, 4,
4, 5, 7, 6, 
6, 7, 9, 8, 
8, 9, 11, 10,

12, 13, 15, 14, /*frontfaces*/
14, 15, 17, 16,
16, 17, 19, 18,
18, 19, 21, 20,
20, 21, 23, 22,

0, 2, 14, 12,   /*topfaces*/
2, 4, 16, 14,
4, 6, 18, 16, 
6, 8, 20, 18,
8, 10, 22, 20,

1, 3, 15, 13,   /*bottomfaces*/
3, 5, 17, 15,
5, 7, 19, 17,
7, 9, 21, 19,
9, 11, 23, 21,

0, 1, 13, 12,   /*sidefaces*/
10, 11, 23, 22
};

и я хочу, чтобы это было нормально, как это:

static Vec3f cubeNorms[] = {
{ 0, 1, 0 },
{ 0, 1, 0 },
{ 0, 1, 0 },
{ 0, 1, 0 }
};

Может кто-нибудь сказать мне, как рассчитать его нормаль и поместить его в массив, чтобы я мог использовать все это вместе, вот так, я знаю, что что-то не так с моей нормалью, потому что освещение на моей форме неправильное, и я также не уверен, что это правильный способ настройки нормали, достаточно одного примера, я прочитал кучу нормальных вычислений и до сих пор не могу понять, как это сделать.

static void drawCube()
{
//vertexes
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, cubeVerts);
//norms
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 0, cubeNorms);
//faces
glDrawElements(GL_QUADS, 22 * 4, GL_UNSIGNED_INT, cubeFaces);
}

person Mindless    schedule 05.11.2013    source источник
comment
При индексированном рисовании вам понадобится нормаль для каждой вершины — какое поведение вы хотите, когда грани имеют общую вершину?   -  person Brett Hale    schedule 05.11.2013
comment
@Бретт Хейл, спасибо, фигура представляет собой кривую с соединенными гранями, я понимаю, что мне нужно вычислить нормаль для каждой вершины, но я не знаю, как ее вычислить в моем случае, можете ли вы показать мне один пример нормы вершины из мой код?   -  person Mindless    schedule 05.11.2013


Ответы (1)


Я предполагаю, что ваши лица повернуты против часовой стрелки вперед. - Не знаю, так ли это - а четверки, конечно, выпуклые и плоские.

В качестве грани возьмем вершины {0, 1, 2}. Я не знаю спецификации Vec3f (а также если это класс или структура C), но мы можем найти нормаль для всех вершин в квадрате с помощью:

Vec3f va = v0 - v1; // quad vertex 1 -> 0
Vec3f vb = v2 - v1; // quad vertex 1 -> 2
Vec3f norm = cross(vb, va); // cross product.

float norm_len = sqrt(dot(norm, norm));
norm /= norm_len; // divide each component of norm by norm_len.

Это дает вам нормаль для этого лица. Если вершины являются общими, и вы хотите придать модели восприятие кривизны с помощью освещения, вам придется решить, какое значение нормали следует «согласовать». Возможно, наилучшей отправной точкой будет просто взять среднее значение нормалей граней в этой вершине и масштабировать результат до единицы длины по мере необходимости.

person Brett Hale    schedule 05.11.2013
comment
Я думаю, что вы неправильно поняли порядок, с лицами против часовой стрелки ваш код будет давать нормальное направление назад. В противном случае правильный ответ, конечно. - person Christian Rau; 05.11.2013
comment
@BrettHale Спасибо, Бретт и Кристиан. - person Mindless; 06.11.2013