2011-11-15 28 views
26

Tôi đang học tại chỗ của 3d opengl, và nó đang diễn ra khá tốt, tôi có một chiếc máy ảnh đẹp đang di chuyển và một số vật thể lập phương đơn giản. Hiện đang sử dụng mảng đỉnh, nhưng tôi đang đổi sang VBO khá nhanh ở đây. Tôi chỉ cố gắng để cho phép tiêu huỷ, tuy nhiên tôi không chắc chắn những gì thứ tự mà tôi phải để xác định đỉnh của tôi, ngay bây giờ đây là những gì tôi đang làm:Trong thứ tự nào tôi có thể gửi các đỉnh của mình tới OpenGL cho Culling

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

Tuy nhiên nó chắc chắn là hoàn toàn sai lầm, bởi vì khi tôi glEnable(GL_CULL_FACE); hình khối của tôi không hiển thị khuôn mặt chính xác (như được thấy bên dưới).

Bình thường Regular View From Top

Vấn đề trẻ em View From Side

Với cả hai hình ảnh tiêu huỷ được kích hoạt.

Tôi nên chỉ định các đỉnh nào?


(EDIT) Cập nhật Chức năng làm việc:

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; 

} 

Trả lời

95

Theo mặc định? Theo thứ tự ngược chiều kim đồng hồ.

Xem xét một tam giác đối diện với máy ảnh:

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

A-> B-> C sẽ phải đối mặt trước (ngược chiều kim đồng hồ theo thứ tự), A-> C-> B sẽ là phía sau (chiều kim đồng hồ gọi món).

Bạn có thể thay đổi cách mà OpenGL coi "trước phải đối mặt với" qua glFrontFace():

Các chiếu của một đa giác để cửa sổ tọa độ được cho là có chiều kim đồng hồ quanh co nếu một đối tượng tưởng tượng đi theo con đường từ nó đầu tiên đỉnh, đỉnh thứ hai, v.v., đến đỉnh cuối cùng của nó, và cuối cùng quay lại đỉnh đầu tiên của nó, di chuyển theo chiều kim đồng hồ khoảng phần bên trong của đa giác. Cuộn dây của đa giác được cho là ngược chiều kim đồng hồ nếu đối tượng tưởng tượng theo cùng một đường di chuyển theo hướng ngược chiều kim đồng hồ bên trong đa giác. glFrontFace chỉ định các đa giác có quanh co theo chiều kim đồng hồ trong các tọa độ cửa sổ hoặc xoay chiều kim đồng hồ trong các tọa độ cửa sổ, được chụp ở mặt trước. Vượt qua GL_CCW để mode chọn đa giác ngược chiều như mặt trước; GL_CW chọn theo chiều kim đồng hồ đa giác như mặt trước.

Theo mặc định, đa giác ngược chiều kim đồng hồ được chụp ở mặt trước.

Đối với đặt hàng đỉnh của bạn, hãy xem xét một khối lý tưởng:

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

Đối với mỗi đối mặt với tinh thần xoay nó phải đối mặt với máy ảnh (mắt của tâm trí của bạn):

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 

Sau đó, bạn có thể chỉ đọc trực quan các cặp tứ giác hoặc tam giác theo thứ tự ngược chiều kim đồng hồ phải:

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

Có phải bắt đầu bằng một đỉnh cụ thể không? – ultifinitus

+1

@ultifinitus: Số –

+2

Tuyệt vời, cảm ơn bạn. – ultifinitus

5

Tôi đã học một nguyên tắc khác (theo nghĩa đen) để xác định thứ tự đỉnh được gọi là "quy tắc tay phải".
Hãy tưởng tượng bàn tay mở của bạn (bên phải) bên trong khối lập phương với ngón cái trỏ về phía trung tâm của khối lập phương. Nếu sau đó bạn cuộn tay thành nắm đấm, ngón tay của bạn sẽ vượt qua các đỉnh theo đúng thứ tự. Vì bạn đang sử dụng tay phải của bạn cho điều này nó được gọi là "quy tắc tay phải".

Ngược lại, nếu bạn bắt đầu bằng tay trái và chỉ ngón tay cái ra khỏi tâm của khối lập phương, các ngón tay của bạn sẽ quét các đỉnh theo thứ tự đúng. Điều này được gọi là "quy tắc tay trái" (ngạc nhiên).

Cả hai phương pháp đều hoạt động để cung cấp cho bạn thứ tự ngược chiều kim đồng hồ. Để đặt hàng theo chiều kim đồng hồ, chỉ cần sử dụng tay đối diện.

+0

Mặc dù bạn đúng là ngược chiều kim đồng hồ là thứ tự quanh co mặc định (được gọi là) cho OpenGL, có thể hữu ích khi đề cập đến thứ tự quanh co thực sự được cấu hình bằng [glFrontFace] (http://www.opengl.org/sdk) /docs/man/xhtml/glFrontFace.xml). – sigpwned

+2

Đây là một câu trả lời cũ, nhưng gọi đây là quy tắc tay phải có khả năng gây ra rất nhiều rắc rối. Khi xử lý hình học euclide 3D, quy tắc tay phải hầu như luôn đề cập đến việc sử dụng ngón cái, ngón trỏ và ngón giữa của bạn để nhớ cấu hình của các trục trong hệ tọa độ RH, chẳng hạn như điển hình trong toán học và OpenGL. – bcrist

Các vấn đề liên quan