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

Как включить вертикальную синхронизацию в opengl?

Как включить вертикальную синхронизацию?

Это что-то простое, как glEnable(GL_VSYNC)? (хотя нет такой вещи, как GL_VSYNC или что-нибудь подобное в параметрах, которые glEnable принимает).

или нет стандартного способа сделать это в opengl?

4b9b3361

Ответ 1

В Windows есть метод расширения OpenGL wglSwapIntervalEXT.
Из сообщения b2b3 http://www.gamedev.net/community/forums/topic.asp?topic_id=360862:

---- цитата начинается -----

Если вы работаете в Windows, вам нужно использовать расширения для использования Функция wglSwapIntervalExt. это определенный в wglext.h. Вы также захотите Загрузите файл glext.h. В wglext файле все точки входа для Windows-расширений объявлен. Все такие функции начинаются с префиксом wgl. Чтобы получить дополнительную информацию обо всех опубликованных расширениях, вы можете изучить OpenGL Extension Registry.

wglSwapIntervalEXT имеет расширение WGL_EXT_swap_control. Это позволяет указать минимальное количество кадры перед каждой заменой буфера. Обычно он используется для вертикального синхронизация (если вы установите swap интервал до 1). Больше информации о целом расширение можно найти здесь. Перед использованием этой функции вам необходимо запросить, имеет ли ваша карта поддержка WGL_EXT_swap_control и затем получить указатель на функцию используя функцию wglGetProcAddress.

Чтобы проверить поддержку данного расширения, вы можете использовать такую ​​функцию:

#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;
}

Чтобы инициализировать указатели на функции, вам необходимо:

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

Затем вы можете использовать эти указатели как любой другой указатель на функцию. Чтобы включить vync, вы можете вызвать wglSwapIntervalEXT (1), чтобы отключить его, вы вызываете wglSwapIntervalEXT (0).

Чтобы получить текущий интервал подкачки, вам нужно вызвать wglGetSwapIntervalEXT().

---- цитаты заканчиваются -----

Ответ 3

WGL случай описан в ответе eugensk00.

Для CGL (MacOSX) см. этот ответ в другой вопрос SO.

Для EGL существует eglSwapInterval(), но, по-видимому (см. this и this), он не гарантирует результат без разрывов - только ждет данный период (возможно, это просто из-за сломанные драйверы).

Для GLX (Linux с X11 и т.д.) для этого существует, по крайней мере, 3 одинаковых расширения, с разной степенью функциональности. В вики OpenGL в настоящее время отображается только одна, которая не поддерживается Mesa <= 10.5.9 (и, возможно, выше). Вот список из большинства полнофункциональных расширений (перечисленных в OpenGL wiki):

  • GLX_EXT_swap_control

    • Установите интервал подкачки для каждого вывода: glXSwapIntervalEXT(dpy, drawable, interval)

    • Получить текущий интервал подкачки: glXQueryDrawable(dpy, drawable, GLX_SWAP_INTERVAL_EXT, &interval)

    • Получить максимальный интервал подкачки: glXQueryDrawable(dpy, drawable, GLX_MAX_SWAP_INTERVAL_EXT, &maxInterval)

    • Отключить Vsync: установить interval в 0

  • GLX_MESA_swap_control

    • Установить интервал подкачки для каждого контекста: glXSwapIntervalMESA(interval)

    • Получить текущий интервал подкачки: glXGetSwapIntervalMESA()

    • Получить максимальный интервал подкачки: неподдерживаемый

    • Отключить Vsync: установить interval в 0

  • GLX_SGI_swap_control

    • Установите интервал подкачки: glXSwapIntervalSGI(interval).

    • Получить текущий интервал подкачки: неподдерживаемый

    • Получить максимальный интервал подкачки: неподдерживаемый

    • Отключить Vsync: неподдерживаемый (interval==0 - ошибка)

Для адаптивного Vsync см. OpenGL wiki.