Подтвердить что ты не робот

В каком порядке следует отправлять мои вершины в OpenGL для Culling

Я изучаю место 3d opengl, и все идет хорошо, у меня есть хорошая камера, движущаяся и некоторые простые объекты куба, на данный момент. В настоящее время используется вершинные массивы, но я быстро переключаюсь на VBOs. Я просто пытаюсь включить отбраковывание, однако я не уверен, какой порядок, в котором я должен указывать свои вершины, прямо сейчас это то, что я делаю:

void cube::update_verts(){
GLushort cur=0;

///back face
verts[cur++]=x; verts[cur++]=y; verts[cur++]=z;
verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z;
verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z;
verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z;

///right face
verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z;
verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z;
verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z+sz;
verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z+sz;

///top face
verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z;
verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z;
verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z+sz;
verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z+sz;

///front face
verts[cur++]=x; verts[cur++]=y; verts[cur++]=z+sz;
verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z+sz;
verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z+sz;
verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z+sz;

///bottom face
verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z;
verts[cur++]=x; verts[cur++]=y; verts[cur++]=z;
verts[cur++]=x; verts[cur++]=y; verts[cur++]=z+sz;
verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z+sz;

///left face
verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z;
verts[cur++]=x; verts[cur++]=y; verts[cur++]=z;
verts[cur++]=x; verts[cur++]=y; verts[cur++]=z+sz;
verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z+sz;


}

///Drawing Code:

glVertexPointer(3,GL_FLOAT,0,object.verts);
glColorPointer(3,GL_UNSIGNED_BYTE,0,object.colors);
glDrawArrays(GL_QUADS,0,6*4);

Однако это определенно неверно, потому что, когда я glEnable(GL_CULL_FACE);, мои кубы не отображают правильные грани (как показано ниже).

Normal Regular View From Top

Проблема Ребенок View From Side

С обоими этими изображениями отбраковка включена.

В каком порядке я должен указывать вершины?


(EDIT) Обновленная рабочая функция:

void cube::update_verts(){
GLushort cur=0;

///top face
verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z;
verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z+sz;
verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z+sz;
verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z;


///bottom face
verts[cur++]=x; verts[cur++]=y; verts[cur++]=z;
verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z;
verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z+sz;
verts[cur++]=x; verts[cur++]=y; verts[cur++]=z+sz;

///left face
verts[cur++]=x; verts[cur++]=y; verts[cur++]=z;
verts[cur++]=x; verts[cur++]=y; verts[cur++]=z+sz;
verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z+sz;
verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z;

///right face
verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z;
verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z;
verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z+sz;
verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z+sz;

///front face
verts[cur++]=x; verts[cur++]=y; verts[cur++]=z+sz;
verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z+sz;
verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z+sz;
verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z+sz;


///back face
verts[cur++]=x; verts[cur++]=y; verts[cur++]=z;
verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z;
verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z;
verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z;

}
4b9b3361

Ответ 1

По умолчанию? В порядке против часовой стрелки.

Рассмотрим треугольник, обращенный к камере:

A
|\
| \
|  \
B---C

A- > B- > C будет фронтальной стороной (против часовой стрелки), A- > C- > B будет обращен назад (по часовой стрелке).

Вы можете изменить, каким образом OpenGL рассматривает "переднюю сторону" через glFrontFace():

Предполагается, что проекция координат многоугольника в окно имеет по часовой стрелке, если воображаемый объект, следуя пути от его первой вершины, ее второй вершины и т.д. до ее последней вершины и наконец, вернется к своей первой вершине, движется по часовой стрелке внутренность многоугольника. Говорят, что полигональная обмотка против часовой стрелки, если мнимый объект, следующий за тем же путем, перемещается в направлении против часовой стрелки вокруг внутренней части многоугольника. glFrontFace указывает, будут ли полигоны с намоткой по часовой стрелке в оконные координаты или намотка влево в координатах окна, считаются передними. Передача GL_CCW в mode выбирает полигоны против часовой стрелки спереди; GL_CW выбирает по часовой стрелке полигоны спереди.

По умолчанию полигоны против часовой стрелки берутся перед собой.

Для упорядочения ваших вершин рассмотрим идеальный куб:

  6---7
 /|  /|
2---3 |
| 4-|-5
|/  |/ 
0---1

Для каждого лица мысленно поверните его лицом к камере (ваш глаз ума):

Sides:
2---3  3---7  7---6  6---2
|   |  |   |  |   |  |   |
|   |  |   |  |   |  |   |
0---1  1---5  5---4  4---0

Bottom/Top
0---1  6---7
|   |  |   |
|   |  |   |
4---5  2---3

Затем вы можете просто визуально считывать квадранты или пары треугольников в правом порядке против часовой стрелки:

2---3                3         2---3 
|   |  becomes      /|   and   |  / 
|   |             /  |         |/ 
0---1            0---1         0 

Triangles 0-1-3 and 0-3-2
Quad 0-1-3-2

Ответ 2

Я узнал другое эмпирическое правило (буквально) для определения порядка вершин, известного как "правило правой руки".
Представьте свою открытую руку (справа) внутри куба, указав большой палец на центр куба. Если вы затем скрутите свою руку в кулак, ваши пальцы передадут вершины в правильном порядке. Поскольку вы используете свою правую руку для этого, это называется правилом правой руки.

И наоборот, если вы начнете с левой руки и укажете свой палец от центра куба, ваши пальцы снова проведут верхушки в правильном порядке. Это известно как "правило левой руки" (сюрприз).

Оба метода работают, чтобы дать вам возможность против часовой стрелки. Для заказа по часовой стрелке просто используйте противоположную руку.