Pertanyaan cara mengaktifkan sinkronisasi vertikal di OpenGL?


Bagaimana Anda mengaktifkan sinkronisasi vertikal?

Apakah itu sesuatu yang sederhana seperti glEnable(GL_VSYNC)? (meskipun tidak ada yang namanya GL_VSYNC atau yang seperti itu dalam opsi yang glEnable terima).

atau tidak ada cara standar untuk melakukan ini di OpenGL?


32
2018-02-26 04:07


asal


Jawaban:


Di Windows ada metode ekstensi OpenGL wglSwapIntervalEXT. Dari pos oleh b2b3 http://www.gamedev.net/community/forums/topic.asp?topic_id=360862:

Jika Anda bekerja pada Windows, Anda harus menggunakan ekstensi untuk digunakan    wglSwapIntervalExt fungsi. ini   didefinisikan dalam wglext.h. Anda juga akan ingin   unduh file glext.h.   Dalam file wglext semua titik masuk untuk ekstensi khusus Windows   dideklarasikan. Semua fungsi tersebut dimulai   dengan awalan wgl.   Untuk mendapatkan info lebih lanjut tentang semua ekstensi yang dipublikasikan, Anda dapat melihatnya   Registry Ekstensi OpenGL.

wglSwapIntervalEXT adalah dari WGL_EXT_swap_control perpanjangan. Saya t   memungkinkan Anda menentukan jumlah minimum   frame sebelum setiap buffer swap.   Biasanya digunakan untuk vertikal   sinkronisasi (jika Anda mengatur swap   interval ke 1). Info selengkapnya tentang keseluruhan   ekstensi dapat ditemukan di sini.   Sebelum menggunakan fungsi ini, Anda perlu query apakah kartu Anda memiliki   mendukung WGL_EXT_swap_control dan   lalu dapatkan penunjuk ke fungsi   menggunakan wglGetProcAddress fungsi.

Untuk menguji dukungan dari ekstensi yang diberikan Anda dapat menggunakan fungsi seperti ini:

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

Untuk menginisialisasi pointer fungsi Anda, Anda perlu:

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

Kemudian Anda dapat menggunakan pointer ini sebagai penunjuk lainnya berfungsi. Untuk mengaktifkan vync Anda bisa menelepon wglSwapIntervalEXT(1), untuk menonaktifkannya Anda panggil wglSwapIntervalEXT(0).

Untuk mendapatkan interval swap saat ini, Anda perlu menelepon wglGetSwapIntervalEXT().


43
2018-02-26 05:33



WGL kasus dijelaskan dalam dijawab oleh eugensk00.

Untuk CGL (MacOSX) lihat jawaban ini ke pertanyaan SO lainnya.

Untuk EGL ada eglSwapInterval () berfungsi, tapi rupanya (lihat ini dan ini) itu tidak menjamin hasil bebas sobekan - hanya menunggu waktu yang diberikan (mungkin itu hanya karena driver yang rusak).

Untuk GLX (Linux dengan X11 dll.) Setidaknya ada 3 ekstensi serupa untuk ini, dengan berbagai tingkat fungsionalitas. OpenGL wiki saat ini hanya daftar satu, yang tidak didukung oleh Mesa <= 10.5.9 (dan mungkin lebih tinggi). Berikut adalah daftar dari sebagian besar ekstensi fitur lengkap (terdaftar dalam wiki OpenGL) ke yang paling sedikit:

  1. GLX_EXT_swap_control

    • Set interval swap per-drawable per-display: glXSwapIntervalEXT(dpy, drawable, interval)

    • Dapatkan interval swap saat ini: glXQueryDrawable(dpy, drawable, GLX_SWAP_INTERVAL_EXT, &interval)

    • Dapatkan interval swap maksimum: glXQueryDrawable(dpy, drawable, GLX_MAX_SWAP_INTERVAL_EXT, &maxInterval)

    • Nonaktifkan Vsync: atur interval ke 0

  2. GLX_MESA_swap_control

    • Set interval swap per-konteks: glXSwapIntervalMESA(interval)

    • Dapatkan interval swap saat ini: glXGetSwapIntervalMESA()

    • Dapatkan interval swap maksimum: tidak didukung

    • Nonaktifkan Vsync: atur interval ke 0

  3. GLX_SGI_swap_control

    • Set interval swap: glXSwapIntervalSGI(interval).

    • Dapatkan interval swap saat ini: tidak didukung

    • Dapatkan interval swap maksimum: tidak didukung

    • Nonaktifkan Vsync: tidak didukung (interval==0 adalah kesalahan)

Untuk melihat Vsync adaptif OpenGL wiki.


3
2017-08-12 09:43