![]() |
|
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]()
|
|
| MironenkoDima |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 12 Регистрация: 12.6.2013 Репутация: нет Всего: нет |
Здравствуйте.
Подскажите, пожалуйста, как реализовать плавное обновление экрана в программе. Вся графика выводится с использованием библиотеки GDI+. Программа позволяет перемещаться по рабочей области с помощью зажатия курсора мыши и т.п. манипуляции, при таком подходе экран мерцает при перерисовки. Как это можно преодолеть? |
|||
|
||||
| Dem_max |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1780 Регистрация: 12.4.2007 Репутация: 16 Всего: 39 |
Двойное буфферизирование ?????
-------------------- Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte") |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 33 Всего: 183 |
Т.е. буферизация.
Другими словами - рисуем в памяти, дураку полработы не показываем, а показываем все сразу, плюхнув эту память на экран, что, как правило, быстро. Ну и убираем лишние очистки экрана, которые тоже вызывают мерцания. (В виндовсе они по-умолчанию на каждом шагу.) -------------------- ... |
|||
|
||||
| MironenkoDima |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 12 Регистрация: 12.6.2013 Репутация: нет Всего: нет |
Earnest, спасибо за развёрнутый ответ!
Буду копать дальше ) |
|||
|
||||
| MironenkoDima |
|
||||
![]() Новичок Профиль Группа: Участник Сообщений: 12 Регистрация: 12.6.2013 Репутация: нет Всего: нет |
Под руки попалась книжка "Компьютерная графика" Виктора Порева. В ней нашёл кое-что про двойную буферизацию.
Рассмотрено такое применение:
Попробовал я сделать подобное в своём проекте:
К сожалению не помогло.. Не подскажите, что можно изменить? |
||||
|
|||||
| Dem_max |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1780 Регистрация: 12.4.2007 Репутация: 16 Всего: 39 |
-------------------- Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte") |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 33 Всего: 183 |
Не помогло в каком смысле? Не рисуется? По прежнему мерцает?
-------------------- ... |
|||
|
||||
| MironenkoDima |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 12 Регистрация: 12.6.2013 Репутация: нет Всего: нет |
Рисует, но по-прежнему мерцает. Dem_max, не совсем понял, в какое место Init и UnInit вставлять? Рабочая область у меня меняется, т.е. пользователь может увеличить/уменьшить размеры. Неужели в WM_SIZE постоянно обрабатывать? И правильно ли я понял, что перед всеми InvalidateRect'ов нужно вызывать функцию DrawStudyExampleToMemory(из вашего примера)? А в WM_PAINT'е оставить только функцию переноса BitBlt ? ----------------------------------- Так-с, попробовал ваш пример. В принципе, мерцаний стало гораздо меньше, только теперь пропала плавность. Изменения происходят с дёрганием Это сообщение отредактировал(а) MironenkoDima - 20.6.2013, 18:59 |
|||
|
||||
| Dem_max |
|
||||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1780 Регистрация: 12.4.2007 Репутация: 16 Всего: 39 |
в начале и конце программы.
Да. И постоянно вызывать UnInit() а потом Init().
WM_PAINT не трогай, что я нарисовал то и вставляй.
нет, не обязательно. InvalidateRect 'bh всего лишь одна из функций которая заставляет вызвать WM_PAINT DrawStudyExampleToMemory() вызывается в любой момент времени после Init() и пока не наступит UnInit() Это сообщение отредактировал(а) Dem_max - 20.6.2013, 20:20 -------------------- Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte") |
||||||||
|
|||||||||
| MironenkoDima |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 12 Регистрация: 12.6.2013 Репутация: нет Всего: нет |
Вставил вызов Init в WM_CREATE, вызов UnInit в WM_DESTROY, пару UnInit+Init в WM_SIZE. Обработку WM_PAINT скопировал из вашего примера.
Все прошлые вызовы InvalidateRect заменил на вызов функции, в которой рисуется вся графика, а в конец этой функции поставил InvalidateRect. Как сказал выше, теперь пропала плавность перерисовки.. |
|||
|
||||
| Dem_max |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1780 Регистрация: 12.4.2007 Репутация: 16 Всего: 39 |
Как может пропасть "плавность" перерисовки если в WM_PAINT только 1 функция и то самая быстрая для переноса графики ????
-------------------- Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte") |
|||
|
||||
| MironenkoDima |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 12 Регистрация: 12.6.2013 Репутация: нет Всего: нет |
Попробовал. Сделал rect - глобальной. И поместил GetClientRect в Init. Не помогло..
Может у меня нарушена "общая" логика обновления, но тут я даже не знаю, как можно по-другому. Всякий раз, когда мне нужно обновить экран, вызываю свою функцию рисования. В ней создаётся класс Graphics(gdi+) по дескриптору на контекст граф.устройства, который создаём в памяти(g_hdcMem из примера). Используются различные методы класса Graphics(не мало методов). В конце этой функции находится InvalidateRect.. |
|||
|
||||
| Dem_max |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1780 Регистрация: 12.4.2007 Репутация: 16 Всего: 39 |
Кидай сюда сокращенный код(проект) я посмотрю где накосячил.
P.S. ну и расскажи что я должен увидеть и как ты определил что все не плавно. Это сообщение отредактировал(а) Dem_max - 21.6.2013, 06:26 -------------------- Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte") |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 33 Всего: 183 |
MironenkoDima, за мерцание может отвечать стирание фона. По-умолчанию оно почти всегда есть. Бороться 2 способами: при регистрации класса окна задать нулевую кисть, либо перехватить WM_ERASEBKGND и ничего не делать (и вернуть TRUE... или FALSE... не помню, в MSDN смотри, там написано, чтобы система не лезла).
Что касается принципа двойной буферизации, то он таков: на WM_PAINT ты практически всегда ТОЛЬКО копируешь на экран внеэкранный буфер. Рисовать во внеэкранный буфер можно в любой момент (и даже в отдельном потоке). Хотя можно и на PAINT, но совсем не каждый раз, а только при необходимости перерисовать внутренний буфер. Например, если твое окно временно перекрылось другим, при восстановлении буфер перестраивать не нужно. Бывают случаи, когда рисование происходит как бы двумя частями: на относительно постоянном фоне рисуют какие-то детали. Например, у тебя сложный чертеж, а ты добавляешь линию. Или нужно показать какой-то объект выделенным. Очевидно, что в этом случае неэффективно рисовать все целиком, чтобы добавить (или стереть) фрагмент линии. Тогда либо переменную часть рисуют прямо на экран, либо держат 2 буфера. Как-то так. Надеюсь, принцип понятен. -------------------- ... |
|||
|
||||
| Dem_max |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1780 Регистрация: 12.4.2007 Репутация: 16 Всего: 39 |
Сделай так
-------------------- Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte") |
|||
|
||||
![]()
|
| Правила форума "C/C++: Системное программирование и WinAPI" | |
|
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |