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

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

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

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

Ответов (3)

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

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

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

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

  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 .

((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, указывает, что графический процессор никогда не должен ждать v-пробелов»

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