Рисование без мерцания

У меня есть приложение win32, которое было разработано на C ++. Приложение рисует что-то в окне, используя базовые формы (прямоугольники). Окна перекрашиваются каждые 20 мс (50 Гц) с помощью InvalidateRect. Все работает хорошо, но рисунок мерцает. Как предотвратить мерцание? В c # я обычно использую компонент с двойной буферизацией (например, pictureBox), как я могу избавиться от этого в c ++ с помощью win32?


person blejzz    schedule 21.09.2011    source источник


Ответы (4)


Вы также можете легко реализовать двойную буферизацию в Win32. Предполагая, что вы рисуете прямо в Окне, используя контекст устройства, сделайте следующее:

Создайте контекст устройства «памяти» и сделайте все свои рисунки в контексте этого устройства, затем скопируйте недействительные части окна в фактический контекст устройства, когда это необходимо, используя _ 1_ function

Здесь есть довольно хороший (хотя и высокого уровня) обзор .

person Chad    schedule 21.09.2011
comment
выберите этот ответ, так как он единственный с примером - person blejzz; 21.09.2011

Вы можете создать контекст устройства в памяти, нарисовать на нем эти формы (точно так же, как если бы вы делали это в контексте устройства окна), а затем перенести из него в контекст устройства окна, когда окно становится недействительным.

Вам также необходимо отключить очистку фона (обработайте WM_ERASEBKGND window соответственно) до того, как произойдет розыгрыш.

Изменить: я наткнулся на довольно исчерпывающий учебник по рисованию без мерцания в GDI, в котором объясняются все аспекты рисования. в Windows и поставляется с примерами.

person macbirdie    schedule 21.09.2011
comment
+1 Совет WM_ERASEBKGND важен. Я забыл об этом, когда ошибся в своем ответе. - person Adrian McCarthy; 23.09.2011

Вы также можете удвоить буфер в C ++.

Когда вы получаете DC для рисования, вы создаете закадровое растровое изображение (CreateCompatibleBitmap) и DC памяти (CreateCompatibleDC). Сделайте всю свою картину для этого DC. В конце сделайте BitBlt из DC памяти в фактический DC.

Для повышения производительности вы можете захотеть кэшировать закадровое растровое изображение и DC, но не забудьте воссоздать их при изменении размера окна.

person Adrian McCarthy    schedule 21.09.2011

Вот лучший учебник, который я когда-либо нашел:

https://msdn.microsoft.com/en-us/library/ms969905.aspx

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

person Kirill Starostin    schedule 09.05.2018