W aplikacji systemu Windows mam wiele otwartych okien OpenGL w tym samym czasie. Idealnie byłoby, gdyby każdy z nich rysował z prędkością 60 fps, zsynchronizowany z odświeżaniem ekranu.Synchronizacja wielu okien OpenGL z funkcją vsync
Dla każdego kontekstu renderowania, wywołuję wglSwapIntervalEXT(1)
, aby włączyć vsync. Każde okno ma własny wątek wyświetlania, który rysuje ramkę, a następnie wywołuje SwapBuffers
, aby zaktualizować.
Okazuje się, że okna "walczą" ze sobą nawzajem: wygląda na to, że połączenia SwapBuffers
są zsynchronizowane i czekają na siebie nawzajem, nawet jeśli są w osobnych wątkach. Zmierzam czas od klatka po klatce do każdego okna, a przy dwóch oknach spada do 30 klatek na sekundę, z trzema do 20 klatek na sekundę itp.
Jeśli wyłączysz funkcję pomijania przy pomocy wglSwapIntervalEXT(0)
, odświeżą się w 60 fps, bez względu na to, ile okien otworzę. Ale przy otwartym oknie nie jest to prawie tak gładkie, jak przy włączonej funkcji vsync.
Czy istnieje sposób, aby osiągnąć to, co chcę z OpenGL?
Jeśli pomyślisz o problemie, zdasz sobie sprawę, że muszą one zsynchronizować się ze sobą, jeśli synchronizujesz je wszystkie ze współczynnikiem odświeżania. Dla każdego wyświetlanego okna nie ma unikalnego zdarzenia odświeżania. Jedyne rozwiązanie, jakie mogę wymyślić (to prawie na pewno nierozpoczynający proces uruchamiania) to użycie jednego okna i utworzenie w nim własnego menedżera okien za pomocą rzutni. – Robinson
Jeśli SwapBuffers po prostu zasygnalizuje, że bufory muszą zostać zamienione, może natychmiast powrócić (dopóki nie zostanie zapisany nowy bufor zwrotny, który musiałby zostać zablokowany). Oddzielny wątek posiadany przez sterownik ekranu może następnie czekać na wersję vsync i zamienić wszystkie bufory oznaczone jako wymagające wymiany w odpowiednim momencie. Jednak najwyraźniej to nie działa ... –