2012-10-24 13 views
7

Câu hỏi gốc

Tôi muốn sử dụng 'gluPerspective', 'glViewport' và 'gluLookAt' để thao tác máy ảnh và màn hình của tôi.gluPerspective, glViewport, gluLookAt và GL_PROJECTION và GL_MODELVIEW Matricies

Tôi có thể áp dụng các chức năng nào cho chế độ ma trận nào? Và tôi nên sử dụng thứ tự nào?

Ví dụ, tôi đang cố gắng để thiết lập màn hình và máy ảnh của tôi như thế này: (Nhưng nó không làm việc!)

glMatrixMode(GL_PROJECTION) // Apply following to projection matrix - is this correct? 
glLoadIdentity(); // Reset first 
glPerspective(45.0, (double)w/(double)h, 1.0, 200.0); // Set perspective 
glViewport(0, 0, w, h); // Set viewport 

glMatrixMode(GL_MODELVIEW); // Apply following to modelview - should glViewport come under here? 
glLoadIdentity(); // Reset first 
gluLookAt(px, py, pz, cx, cy, cz, ux, uy, uz); // Set position, centre and then up vectors 
// This surely comes after calling GL_MODELVIEW? 

Tôi đã nhìn xung quanh cho tài liệu trực tuyến, và tôi hiểu chức năng, chỉ không phải nơi họ nên đi và theo thứ tự nào!

Một thời gian sau ...

Đó là vài tháng sau đó ngay bây giờ và tôi thêm một chỉnh sửa nhanh chóng để hiển thị các hệ thống tôi sử dụng để làm việc với OpenGL. Điều này là để giúp những người khác nhìn thấy câu hỏi này trong tương lai.

Tôi chủ yếu sử dụng hai phương pháp.

Phương pháp 1:

này nhóm phương pháp tất cả mọi thứ lại với nhau.

// Firstly, the window may have been resized so re-create the viewing area 
glViewport(0, 0, width_of_window_rendering_area, height_of_window_rendering area); 

Thao tác này sẽ tạo lại chế độ xem để hiển thị trên toàn bộ khu vực bên trong cửa sổ. Với SFML, bạn sẽ làm cái gì đó như window.width() hoặc window.height(), hoặc một cái gì đó tương tự như tùy thuộc vào windowing toolkit bạn sử dụng (dư thừa, glfw, SDL vv) ...

// The second step is to add a projection matrix. There are three main ones I like to use 
// Uncomment the one you want 
glMatrixMode(GL_PROJECTION); // Tell OpenGL to manipulate the correct matrix stack 
glLoadIdentity(); // Reset the projection matrix, or bad things happen after multiple calls to below functions! 
// glOrtho(...) // Uncomment to use 2D rendering 
// gluPerspective(...) // Uncomment to use (easy) 3D rendering 
glFrustrum(...) // Uncomment to use (harder/less intuitive?) 3D rendering 
glMatrixMode(GL_MODELVIEW); // I always prefer to leave OpenGL in the modelview manipulation mode. 
    // I consider it the "default" and safest mode to leave OpenGL in, as any rogue 
    // calls to functions changing its contents is likely to mess up your geometry 
    // which should be visible as a problem on the screen, which tells you you need 
    // to fix something! Manipulating the other matrix stacks may not show obvious 
    // problems. 

Bạn sẽ cần chọn một trong ba từ 'glOrtho', 'gluPerspective' và 'glFrustrum'. Ngoài ra còn có 'gluOrtho2D', nhưng sử dụng cẩn thận! (Tôi thích để xác định máy bay gần và xa bản thân mình với 'glOrtho'.) Bạn cần phải thay thế '...' với các đối số của bạn để chức năng cũng có.

// The third step is to clear the screen and set your camera/geometry position 
glClear(GL_COLOR_BUFFER_BIT); // use bitwise OR ('||') with 'GL_DEPTH_BUFFER_BIT' and 'GL_STENCIL_BUFFER_BIT' if required 
gluLookAt(...); 
// I like to use gluLookAt, or at least I _italic_used to! Now I implement my own camera... 
// That is another fun thing you should try if you are comfortable with 3D geometry and hard math! 

// The fourth step is to draw your scene. You may want to put lighting stuff first or in with the drawing 
glutWireTeapot(...); 

Cách 2:

Phương pháp thứ hai là tương tự như trên, nhưng để di chuyển bước đầu tiên vào một chức năng riêng biệt. Sau đó, bạn phải phát hiện các sự kiện thay đổi kích thước cửa sổ và gọi hàm này. Với glut, bạn có thể chỉ định một cuộc gọi lại. Với SFML, bạn có thể phát hiện sự kiện khi cửa sổ được thay đổi kích thước. Tôi quên cách SDL hoạt động, nhưng nó tương tự. Tôi chưa học được cách glfw hoạt động.

Hy vọng điều đó sẽ giúp ích cho bạn.

Một số người mới sử dụng OpenGL (có thể là bản thân tôi cùng một lúc) cố gắng chỉ định bản dịch máy ảnh trên ma trận PROJECTION. Đừng làm điều này - Tôi làm cho nó lộn xộn lên ánh sáng và có thể là những thứ khác.

+0

Những gì bạn có ở đó có vẻ phù hợp với tôi. Có lẽ lỗi của bạn là ở nơi khác. – Tim

+0

Đảm bảo cảnh của bạn nằm giữa các mặt phẳng gần và xa bạn đã chỉ định trong glPerspective. – Max

+0

Nếu bạn hiểu các chức năng, bạn sẽ hiểu chúng đi đâu. Ví dụ, bạn dường như tin rằng 'glViewport' tạo ra một ma trận. Nó không. –

Trả lời

3

Tôi xác định chức năng gọi lại định dạng lại của tôi là:

Gọi glViewport(...) một lần ngay từ đầu.

Sau đó tải lại ma trận chiếu với một ma trận sắc:

glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 

Sau đó:

glPerspective(...) 
glMatrixMode(GL_MODELVIEW); 

gluLookAt(...) có thể được gọi bất cứ lúc nào sau này nếu bạn cần thay đổi vị trí máy ảnh của bạn.

Làm việc cho mục đích đơn giản của tôi.

+0

Cảm ơn, đây là câu trả lời tôi đang tìm kiếm. Nếu tôi gọi gluLookAt hai lần, nó sẽ di chuyển máy ảnh một lần nữa? Trong cùng một cách, gọi glRotatef hai lần S rotate xoay máy ảnh/cảnh hai lần, sẽ gluLookAt làm như vậy? – user3728501

+0

Xin lỗi, một câu hỏi khác: Liệu glViewPort có chỉnh sửa ma trận không? Tôi có nên gọi glMatrixMode (GL_PROJECTION) trước khi có cuộc gọi đến glViewPort không? – user3728501

+0

Có, nó sẽ xoay toàn bộ cảnh hai lần. Nhưng nếu bạn đặt nó trong chức năng gọi lại hiển thị của bạn, sau đó nhớ chức năng hiển thị được gọi nhiều lần, bạn phải tải ma trận xem mô hình với ma trận nhận dạng trong phần đầu của hàm gọi lại hiển thị của bạn. – Max