2011-11-15 8 views
26

Uczę się miejsca na 3D OpenGL, i idzie całkiem nieźle, mam w tej chwili ładną kamerę i kilka prostych obiektów kostki. Obecnie używam tablic werteksów, ale bardzo szybko zamieniam się na VBO. Po prostu próbuję włączyć uboju, jednak nie jestem pewien, co kolejność, w jakiej powinienem podać moje wierzchołki, w tej chwili jest to, co robię:W jakiej kolejności powinienem wysyłać Moje wierzchołki do OpenGL do uśmiercania

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); 

Jednak to zdecydowanie bardzo źle, ponieważ kiedy moje kostki nie pokazują właściwych twarzy (jak widać poniżej).

Normal Regular View From Top

Problem Child View From Side

Z obu tych obrazów uboju jest włączony.

W jakiej kolejności należy określić wierzchołki?


(EDIT) Updated Funkcja pracy:

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; 

} 

Odpowiedz

95

domyślnie? W kolejności przeciwnej do ruchu wskazówek zegara.

Rozważmy trójkąta naprzeciwko kamery:

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

A-> B-> C będzie przednia okładzina (kolejność przeciwnym do ruchu wskazówek zegara), A-> C-> B byłby skierowane do tyłu (zgodnie ze wskazówkami zegara zamówienie).

można zmienić w jaki sposób OpenGL uważa „przednie w obliczu” poprzez glFrontFace():

Projekcja wielokąta do okna współrzędne mówi się, że wskazówek zegara nawijania czy wyimaginowany obiekt podążanie ścieżką od jego pierwszy wierzchołek, drugi wierzchołek i tak dalej, do ostatniego wierzchołka, a ostatecznie z powrotem do pierwszego wierzchołka, porusza się w kierunku zgodnym z ruchem wskazówek zegara o około wnętrze wielokąta. Uzwojenie wielokąta ma być przeciwnie do ruchu wskazówek zegara, jeśli obiekt wyobrażony, który podąża tą samą ścieżką, porusza się w kierunku przeciwnym do ruchu wskazówek zegara wokół wnętrza wielokąta. glFrontFace określa, czy wielokąty z nawojami zgodnymi z ruchem wskazówek zegara w współrzędnych okna , czy też nawijanie w kierunku współrzędnych okna, , są przyjmowane z przodu. Przekazywanie GL_CCW do mode wybiera wielokątów przeciwnych do ruchu wskazówek zegara jak przednie; GL_CW wybiera wielokąty zgodne z ruchem wskazówek zegara jako przednie.

Domyślnie wielokąty przeciwne do ruchu wskazówek zegara są przyjmowane z przodu.

Dla zamawiania wierzchołki rozważyć idealną kostkę:

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

Dla każdego czoła psychicznie obrócić się twarzą do aparatu (myślach):

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 

Następnie można po prostu wizualnie odczytaj quady lub pary trójkątów w prawo w lewo:

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 
+1

Czy zaczyna się od określonego wierzchołka? – ultifinitus

+1

@ultifinitus: No. –

+2

Fantastyczne, dziękuję. – ultifinitus

5

Nauczyłem się innej zasady (dosłownie) do określania porządku wierzchołków zwanego "regułą prawej ręki".
Wyobraź sobie swoją otwartą dłoń (prawą) wewnątrz kostki kciukiem skierowanym w stronę środka sześcianu. Jeśli następnie zwiniesz dłoń w pięść, twoje palce przejdą wierzchołki we właściwej kolejności. Ponieważ używasz swojej prawej ręki, nazywa się to "regułą prawej ręki".

Odwrotnie, jeśli zaczniesz lewą ręką i będziesz kciukiem oddalać się od środka sześcianu, twoje palce znów zmienią wierzchołki we właściwej kolejności. Jest to znane jako "zasada lewej ręki" (niespodzianka).

Obie metody działają w sposób przeciwny do ruchu wskazówek zegara. Aby zamawiać zgodnie z ruchem wskazówek zegara, po prostu użyj przeciwnej ręki.

+0

Chociaż masz rację, że przeciwnie do ruchu wskazówek zegara jest domyślna kolejność nawijania (jak się nazywa) dla OpenGL, warto wspomnieć, że kolejność nawijania jest faktycznie konfigurowalna za pomocą [glFrontFace] (http://www.opengl.org/sdk /docs/man/xhtml/glFrontFace.xml). – sigpwned

+2

To jest stara odpowiedź, ale nazwanie tej zasady prawą ręką może spowodować wiele zamieszania. W przypadku geometrii euklidesowej 3D zasada prawej ręki prawie zawsze odnosi się do użycia prawego kciuka, palca wskazującego i środkowego palca, aby zapamiętać konfigurację osi w układzie współrzędnych RH, tak jak jest to typowe w matematyce i OpenGL. – bcrist