Как включить вертикальную синхронизацию в OpenGL? - PullRequest
35 голосов
/ 26 февраля 2009

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

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

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

Ответы [ 3 ]

43 голосов
/ 26 февраля 2009

В 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.

wglSwapIntervalEXT от WGL_EXT_swap_control расширения. Это позволяет указать минимальное количество кадры перед каждой заменой буфера. Обычно это используется для вертикальной синхронизация (если вы установили своп интервал до 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(_wglGetExtensionsStringEXT(), 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) wglGetProcAddress("wglSwapIntervalEXT");

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

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

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

4 голосов
/ 12 августа 2016
Случай

WGL описан в ответе eugensk00 .

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

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

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

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

  2. GLX_MESA_swap_control

    • Установить интервал обмена для контекста: glXSwapIntervalMESA(interval)

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

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

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

  3. GLX_SGI_swap_control

    • Установить интервал обмена: glXSwapIntervalSGI(interval).

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

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

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

Об адаптивной Vsync см. OpenGL wiki .

0 голосов
/ 23 марта 2019
((BOOL(WINAPI*)(int))wglGetProcAddress("wglSwapIntervalEXT"))(1);

google: wglSwapIntervalEXT
https://www.khronos.org/opengl/wiki/Swap_Interval

"wglSwapIntervalEXT (1) используется для включения vsync; wglSwapIntervalEXT (0) для отключения vsync."

"Интервал обмена 1 указывает графическому процессору, что нужно подождать один v-пробел перед заменой переднего и заднего буферов. Интервал обмена 0 указывает, что GPU никогда не должен ждать v-пробелов"

...