2009-02-26 70 views
31

Làm cách nào để bật đồng bộ hóa dọc?cách bật đồng bộ hóa dọc trong opengl?

Có điều gì đó đơn giản như glEnable(GL_VSYNC) không? (mặc dù không có những thứ như GL_VSYNC hoặc bất cứ thứ gì giống như nó trong các tùy chọn mà glEnable chấp nhận).

hoặc không có cách nào tiêu chuẩn để làm điều này trong opengl?

Trả lời

41

Trên Windows có phương pháp mở rộng OpenGL wglSwapIntervalEXT.
Từ bài của b2b3 http://www.gamedev.net/community/forums/topic.asp?topic_id=360862:

---- quote bắt đầu -----

Nếu bạn đang làm việc trên Windows bạn phải sử dụng phần mở rộng để sử dụng wglSwapIntervalExt chức năng. Nó là được định nghĩa trong wglext.h. Bạn cũng sẽ muốn tải xuống tệp glext.h. Trong tệp wglext, tất cả các điểm nhập cho các tiện ích mở rộng cụ thể của Windows là được khai báo. Tất cả các chức năng như vậy bắt đầu với tiền tố wgl. Để biết thêm thông tin về tất cả các tiện ích mở rộng đã xuất bản, bạn có thể xem Đăng ký tiện ích OpenGL.

wglSwapIntervalEXT là từ WGL_EXT_swap_control mở rộng. Nó cho phép bạn chỉ định số lượng tối thiểu là khung trước mỗi lần hoán đổi bộ đệm. Thông thường nó được sử dụng để đồng bộ hóa dọc (nếu bạn đặt hoán đổi khoảng thời gian thành 1). Bạn có thể tìm thêm thông tin về toàn bộ tiện ích mở rộng tại đây. Trước khi sử dụng chức năng này, bạn cần truy vấn xem thẻ của bạn có hỗ trợ cho WGL_EXT_swap_control và sau đó lấy con trỏ đến hàm bằng hàm wglGetProcAddress.

Để kiểm tra sự hỗ trợ của phần mở rộng cho bạn có thể sử dụng chức năng như thế này:

#include <windows.h> 
#include "wglext.h" 

bool WGLExtensionSupported(const char *extension_name) 
{ 
    // this is pointer to function which returns pointer to string with list of all wgl extensions 
    PFNWGLGETEXTENSIONSSTRINGEXTPROC _wglGetExtensionsStringEXT = NULL; 

    // determine pointer to wglGetExtensionsStringEXT function 
    _wglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC) wglGetProcAddress("wglGetExtensionsStringEXT"); 

    if (strstr(_wglGetExtensionsString(), extension_name) == NULL) 
    { 
     // string was not found 
     return false; 
    } 

    // extension is supported 
    return true; 
} 

Để khởi tạo con trỏ hàm của bạn, bạn cần phải:

PFNWGLSWAPINTERVALEXTPROC  wglSwapIntervalEXT = NULL; 
PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT = NULL; 

if (WGLExtensionSupported("WGL_EXT_swap_control")) 
{ 
    // Extension is supported, init pointers. 
    wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) LogGetProcAddress("wglSwapIntervalEXT"); 

    // this is another function from WGL_EXT_swap_control extension 
    wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC) LogGetProcAddress("wglGetSwapIntervalEXT"); 
} 

Sau đó, bạn có thể sử dụng các con trỏ này như bất kỳ con trỏ nào khác để hoạt động. Để kích hoạt vync, bạn có thể gọi wglSwapIntervalEXT (1), để tắt nó, bạn gọi wglSwapIntervalEXT (0).

Để nhận khoảng thời gian hoán đổi hiện tại, bạn cần gọi wglGetSwapIntervalEXT().

---- quote kết thúc -----

+2

Trong đoạn mã đầu tiên của bạn nếu (strstr (_wglGetExtensionsString(), extension_name) == NULL) nên đọc nếu (strstr (_wglGetExtensionsStringEXT(), extension_name) == NULL) - Nhưng cảm ơn, điều này đã giúp tôi !!! – HoboBen

+3

Ngoài ra tôi đã sử dụng wglGetProcAddress thay vì LogGetProcAddress – HoboBen

+3

Đó không phải là phần mở rộng của OpenGL, mà là WGL (API hệ thống cửa sổ Microsoft Windows cho OpenGL). Buffer hoán đổi là do bản chất của nó một hệ thống cửa sổ hoạt động cụ thể. Theo như GL là có liên quan nó chỉ rút ra một bộ đệm phía trước/bên trái/phải hoặc một số FBO tùy ý. Hệ thống cửa sổ là điều duy nhất có đủ kiến ​​thức về hệ thống máy chủ cơ bản để đồng bộ hóa việc trình bày các bộ đệm được vẽ tới một số sự kiện (trong trường hợp này là truy vấn dọc của màn hình). –

10

Nó tóm tắt trên wiki OpenGL, ở đây: http://www.opengl.org/wiki/Swap_Interval

+1

Lưu ý rằng trang này rất không đầy đủ: phần mở rộng GLX Vsync duy nhất được liệt kê ở đó không được hỗ trợ trên Mesa, đây là triển khai OpenGL mặc định trên hầu hết các bản phân phối Linux cho tất cả phần cứng. Xem [câu trả lời của tôi] (http://stackoverflow.com/a/38914829/673852) để có danh sách đầy đủ hơn về các phần mở rộng GLX Vsync. – Ruslan

0

WGL trường hợp được mô tả trong answer by eugensk00.

Đối với CGL (MacOSX) xem this answer cho một câu hỏi SO khác.

Đối EGLeglSwapInterval() chức năng, nhưng dường như (xem thisthis) nó không đảm bảo kết quả rách miễn phí - chỉ chờ đợi thời gian nhất định (có thể nó chỉ là do bị phá vỡ trình điều khiển).

Đối với GLX (Linux với X11 vv) có ít nhất 3 phần mở rộng tương tự cho điều này, với mức độ chức năng khác nhau. OpenGL wiki hiện chỉ liệt kê một trang, không được hỗ trợ bởi Mesa < = 10.5.9 (và có thể cao hơn). Dưới đây là một danh sách từ hầu hết các phần mở rộng tính năng đầy đủ (được liệt kê trong OpenGL wiki) vào tối thiểu:

  1. GLX_EXT_swap_control

    • Set khoảng hoán đổi mỗi drawable mỗi display: glXSwapIntervalEXT(dpy, drawable, interval)

    • Nhận khoảng thời gian hoán đổi hiện tại: glXQueryDrawable(dpy, drawable, GLX_SWAP_INTERVAL_EXT, &interval)

    • Nhận khoảng thời gian hoán đổi tối đa: glXQueryDrawable(dpy, drawable, GLX_MAX_SWAP_INTERVAL_EXT, &maxInterval)

    • Disable Vsync: set interval để 0

  2. GLX_MESA_swap_control

    • Set khoảng hoán đổi mỗi bối cảnh: glXSwapIntervalMESA(interval)

    • Nhận khoảng swap hiện tại: glXGetSwapIntervalMESA()

    • Nhận khoảng hoán đổi tối đa: không được hỗ trợ

    • Disable Vsync: set interval để 0

  3. GLX_SGI_swap_control

    • Set khoảng swap: glXSwapIntervalSGI(interval).

    • Nhận khoảng swap hiện tại: không được hỗ trợ

    • Nhận khoảng tối đa swap: không được hỗ trợ

    • Disable Vsync: không được hỗ trợ (interval==0 là một lỗi)

Đối với Vsync thích ứng, hãy xem OpenGL wiki.

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