Как избежать разрыва с Pygame на Linux/X11
Я играл с Pygame (на Debian/Lenny). Кажется, это работает хорошо, за исключением раздражающего разрывания блиттов (полноэкранный или оконный режим).
Я использую драйвер SDL X11 по умолчанию. Googling предполагает, что это известная проблема с SDL, что X11 не предоставляет средства vsync (даже с дисплеем, созданным с FULLSCREEN|DOUBLEBUF|HWSURFACE
flags), и вместо этого я должен использовать драйвер "dga".
Тем не менее, работает
SDL_VIDEODRIVER=dga ./mygame.py
добавляет инициализацию Pygame с помощью
pygame.error: No available video device
(несмотря на xdpyinfo
показывая расширение XFree86-DGA).
Итак: в чем прикол, чтобы получить vsynced сальто без слез? Или заставить эту вещь работать с DGA или какой-то другой механизм?
3 ответа
Что ж, моим возможным решением было переключиться на Pyglet, который, кажется, поддерживает OpenGL намного лучше, чем Pygame, и не имеет никаких проблем с мерцанием.
Лучший способ свести разрыв к минимуму - поддерживать частоту кадров как можно ближе к частоте экрана. Библиотека SDL не имеет vsync, если вы не запускаете OpenGL через нее, поэтому единственный способ - приблизить частоту кадров самостоятельно. Аппаратный двойной буфер SDL не гарантируется, хотя хорошо, когда он работает. Я редко видел это в действии.
По моему опыту с SDL вы должны использовать OpenGL, чтобы полностью устранить разрыв. Это немного корректирует, но рисование простых 2D текстур не так уж сложно, и вы получаете несколько других дополнительных бонусов, которые вы можете реализовать, например, вращение, масштабирование, смешивание и так далее.
Однако, если вы все еще хотите использовать программный рендеринг, я бы порекомендовал использовать грязное обновление прямоугольника. К этому также немного сложно привыкнуть, но это экономит массу обработки, что может облегчить поддержание обновлений в нужном темпе и позволяет избежать показа всего экрана (если вы не прокручиваете всю игровую область или что-то в этом роде). Кроме того, время, необходимое для рисования в буфер, минимально, что может предотвратить перехват, происходящий во время обновления экрана, что является причиной разрыва.
Использовать
SCALED
флаг и
vsync=True
при звонкеset_mode
и вы должны быть готовы (по крайней мере, на любых системах, которые действительно поддерживают это; в некоторых сценариях SDL все еще не может предоставить вам поверхность с поддержкой VSync, но они становятся все более редкими).