Проблема перерисовок .....
От: Garvold Израиль  
Дата: 04.08.02 10:08
Оценка:
Свалился тут на меня один громоздкий проект с большим колличеством графики, но ,из-за отсутствия должного опыта в работе с графикой, я увяз в нём как в болоте :-(

Люди добрые, кто в этой области шарит , поведайте пожалуйста как правильно перерисовывать графические объекты (Rect,Rgn,Text и т.д.) при использование зума, скрола, драг-н-дропа ну и прочих передвижений, так, что бы они не мигали...

Я отдаю себе отчёт, что такого рода информация может оказаться очень объёмной,
но я был бы рад любому намёку, подсказке или , может быть, линку на какой-нибудь материал по этой теме.

Заранее благодарен.
Re: Проблема перерисовок .....
От: KaSA  
Дата: 04.08.02 10:16
Оценка:
Здравствуйте Garvold, Вы писали:

G> Свалился тут на меня один громоздкий проект с большим колличеством графики, но ,из-за отсутствия должного опыта в работе с графикой, я увяз в нём как в болоте

G>
G> Люди добрые, кто в этой области шарит , поведайте пожалуйста как правильно перерисовывать графические объекты (Rect,Rgn,Text и т.д.) при использование зума, скрола, драг-н-дропа ну и прочих передвижений, так, что бы они не мигали...

G> Я отдаю себе отчёт, что такого рода информация может оказаться очень объёмной,

G>но я был бы рад любому намёку, подсказке или , может быть, линку на какой-нибудь материал по этой теме.

G> Заранее благодарен.


ИМХО, тут два основных момента:

1. Рисовать не на экране, а в совместимом контексте, который в оперативной памяти.
2. Перерисовывать только необходимую область, а не все окно.
Re[2]: Проблема перерисовок .....
От: Аноним  
Дата: 04.08.02 10:32
Оценка:
Здравствуйте KaSA, Вы писали:


KSA>ИМХО, тут два основных момента:


KSA>1. Рисовать не на экране, а в совместимом контексте, который в оперативной памяти.

KSA>2. Перерисовывать только необходимую область, а не все окно.


Большое спасибо за столь быстрый ответ !
Дело в том , что, вроде, я так и делаю...

Но при перетаскивание, например прямоугольника, мигает его внутренняя область
(я , в свою очередь, перерисовываю только сам прямоугольник...)
Да, забыл сказать, что заливка фона — чёрная
Re: Проблема перерисовок .....
От: SergH Россия  
Дата: 04.08.02 10:32
Оценка: 3 (1)
Здравствуйте Garvold, Вы писали:

G> Свалился тут на меня один громоздкий проект с большим колличеством графики, но ,из-за отсутствия должного опыта в работе с графикой, я увяз в нём как в болоте :-(

G>
G> Люди добрые, кто в этой области шарит , поведайте пожалуйста как правильно перерисовывать графические объекты (Rect,Rgn,Text и т.д.) при использование зума, скрола, драг-н-дропа ну и прочих передвижений, так, что бы они не мигали...

G> Я отдаю себе отчёт, что такого рода информация может оказаться очень объёмной,

G>но я был бы рад любому намёку, подсказке или , может быть, линку на какой-нибудь материал по этой теме.

G> Заранее благодарен.


Я могу только несколько общих советов дать.

1. Сначала рисовать всё в память (CreateCompatibleDC & Co), а потом выводить результат на экран.
2. Можно перехватывать сообщение WM_ERASEBKGND и не делать в обработчике ничего, а главное — не вызывать стандартный обработчик. Можно вместо этого поставить фону окна прозрачную кисть (GetStockObject(NULL_BRUSH) или HOLLOW_BRUSH). Но учти, что при этом фон окна не будет восстанавливаться автоматически.
3. При прокрутке использовать ScrollDC или ScrollWindow
4. При рисовании в OnPaint рисовать только то, что нужно. Т.е. использовать информацию из поля m_ps CPaintDC.

P.S. В Программисте #2001_8 ,была статья на эту тему. Но она ... как бы это по мягче сказать.. Короче, если не ошибаюсь, я уже посоветовал больше чем там. Но, возможно, я что-то не упомянул. Статья очень маленькая, можно прочитать даже у прилавка магазина. В online на www.programme.ru её нет.
Делай что должно, и будь что будет
Re[3]: Проблема перерисовок .....
От: KaSA  
Дата: 04.08.02 10:36
Оценка:
Здравствуйте Аноним, Вы писали:

А>Здравствуйте KaSA, Вы писали:



KSA>>ИМХО, тут два основных момента:


KSA>>1. Рисовать не на экране, а в совместимом контексте, который в оперативной памяти.

KSA>>2. Перерисовывать только необходимую область, а не все окно.


А> Большое спасибо за столь быстрый ответ !

А>Дело в том , что, вроде, я так и делаю...

А>Но при перетаскивание, например прямоугольника, мигает его внутренняя область

А>(я , в свою очередь, перерисовываю только сам прямоугольник...)
А>Да, забыл сказать, что заливка фона — чёрная

Кисть окна обнулить надо и самому бекграунд отрисовывать.

::SetClassLong(this->GetSafeHwnd(), GCL_HBRBACKGROUND, GetStockObject(NULL_BRUSH));
Re[3]: Проблема перерисовок .....
От: SergH Россия  
Дата: 04.08.02 10:38
Оценка:
Здравствуйте Аноним, Вы писали:

А>Но при перетаскивание, например прямоугольника, мигает его внутренняя область

А>(я , в свою очередь, перерисовываю только сам прямоугольник...)
А>Да, забыл сказать, что заливка фона — чёрная

А перетаскивать только рамку нельзя? Рамку можно рисовать XOR-ом.
Делай что должно, и будь что будет
Re[2]: Проблема перерисовок .....
От: Аноним  
Дата: 04.08.02 11:11
Оценка:
Здравствуйте SergH

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

Да, и ещё одна странность: Если многократно симулировать перерисовку какого-то одного прямоугольника, через какое-то время он теряет и заливку и содержание (просто становится белым прямоугольником)
Re[4]: Проблема перерисовок .....
От: Garvold Израиль  
Дата: 04.08.02 11:24
Оценка:
Здравствуйте SergH, Вы писали:

SH>Здравствуйте Аноним, Вы писали:


А>>Но при перетаскивание, например прямоугольника, мигает его внутренняя область

А>>(я , в свою очередь, перерисовываю только сам прямоугольник...)
А>>Да, забыл сказать, что заливка фона — чёрная

SH>А перетаскивать только рамку нельзя? Рамку можно рисовать XOR-ом.


XOR — это, я так понимаю, что-то из GDI+ ? (короче я не сталкивался)

А я рисую контур фигур линиями , но для перерисовки нужной области знаю только InvalidateRgn (ну или InvalidateRct)

Как я могу перерисовать только контур ?
Re[5]: Проблема перерисовок .....
От: SergH Россия  
Дата: 04.08.02 11:49
Оценка: 3 (1)
Здравствуйте Garvold, Вы писали:

SH>>А перетаскивать только рамку нельзя? Рамку можно рисовать XOR-ом.


G> XOR — это, я так понимаю, что-то из GDI+ ? (короче я не сталкивался)


Нет. Это такое условное название для одного из режимов рисования линий (в том числе) на DC. Пиксели цвета текущего pen'а просто копируются. А в этом режиме проводится операция XOR (в С обозначается ^) между пикселем pen'а и пикселем DC. Основной смысл в том, что:

1. Что бы не было нарисовано на DC, белая линия скорее всего будет видима (исключение — серый цвет 128, 128, 128).
2. Для стирания линии достаточно ещё раз нарисовать такую же линию в том же месте и в том же режиме. Это верно т.к. (A XOR B) XOR B == A

Режимы задаются функцей SetROP2, то что я говорил — параметр R2_XORPEN

G> А я рисую контур фигур линиями , но для перерисовки нужной области знаю только InvalidateRgn (ну или InvalidateRct)


G> Как я могу перерисовать только контур ?


Не обязательно перерисовывать всё в OnPaint. Есть функция GetDC, которая позволяет рисовать что угодно в любом месте программы.
Делай что должно, и будь что будет
Re[6]: Проблема перерисовок .....
От: SergH Россия  
Дата: 04.08.02 11:52
Оценка:
Здравствуйте SergH, Вы писали:

Имелось ввиду
Обычно пиксели цвета текущего pen'а просто копируются...
Делай что должно, и будь что будет
Re[3]: Проблема перерисовок .....
От: SergH Россия  
Дата: 04.08.02 12:10
Оценка: 3 (1)
Здравствуйте Аноним, Вы писали:

А> Да, и ещё одна странность: Если многократно симулировать перерисовку какого-то одного прямоугольника, через какое-то время он теряет и заливку и содержание (просто становится белым прямоугольником)


Действительно, странно.. Но идея есть. Если я правильно догадался, то у тебя есть родительское окно, на нём дочерние и вот в дочернем этот самый прямоугольник. И, ко всему, у родительского окна белый фон и отсутствует стиль WS_CLIPCHILDREN. Тогда (наверное), возможна ситуация, когда родительское окно перересует этот прямоугольник (просто зальёт своим фоном), а дочернее ещё нет.

Если я угадал правильно, то:

1. Поставь WS_CLIPCHILDREN
2. Если дочернее окно занимает всю клиентскую область родительского, поставь родительскому пустую кисть. Это должно положительно сказаться на производительности.
Делай что должно, и будь что будет
Re[7]: Проблема перерисовок .....
От: Garvold Израиль  
Дата: 04.08.02 12:21
Оценка:
Здравствуйте SergH



Спасибо огроменное !!!! Вроде всё заработало как надо...

Последний вопрос:
Когда я увеличиваю изображение, текст, в процессе увеличения, жутко искажается (буквы становятся какими-то кривыми и некрасивыми)
Re[8]: Проблема перерисовок .....
От: SergH Россия  
Дата: 04.08.02 12:56
Оценка: 3 (1)
Здравствуйте Garvold, Вы писали:

G>Спасибо огроменное !!!! Вроде всё заработало как надо...




G>Последний вопрос:

G> Когда я увеличиваю изображение, текст, в процессе увеличения, жутко искажается (буквы становятся какими-то кривыми и некрасивыми)

Увеличиваю это StretchBlt? Тогда ничего не поделаешь, красиво будет (теоретически, я не пробовал) только при увиличении в целое количество раз.

Есть два альтернативных варианта:

1. Увиличивать размер шрифта и отрисовывать заново. Если шрифт TrueType, наверное получится неплохо.

2. Использовать метофайлы. Я с ними работал совсем чить-чуть, поэтому незнаю, насколько хорошо будет увиличиваться текст. Зато знаю, что метафайл с битмапами плохо поддаётся масштабированию (знаю — сильно сказано. В моём единсвенном эксперементе под XP система отказалась изменять размер метафайла с битмапом. Причём не просто отказалась, а ругнулась как-то.). Но попробовать стоит.

Метафайлы, конечно, рисуются медленнее чем BitBlt. Но, если тебе нужно часто изменять размер можно совместить эти два подхода. Т.е. из метафайла в memory DC, из него BitBlt на экран.

В MSDN искать по CreateEnhMetaFile. Есть ли MFC-реализация не знаю, но с API MFC уживается без проблем. Использовать обычные (не Enhanced) метафайлы не имеет смысла, т.к. они хуже.
Делай что должно, и будь что будет
Re[9]: Проблема перерисовок .....
От: Garvold Израиль  
Дата: 04.08.02 13:19
Оценка:
Здравствуйте SergH

Я, наверное, уже всех задолбал со своими вопросами, но....

Когда я меняю размеры своего главного окна (а в нём у меня плавает три вьюера) ,
дергается рамка вместе с менюшками и тулбарами. ON_SIZE для вьюеров я обработал, а вот для главного фрэйма — чего-то не ладится
Re[10]: Проблема перерисовок .....
От: SergH Россия  
Дата: 04.08.02 13:39
Оценка: 3 (1)
Здравствуйте Garvold, Вы писали:

G>Я, наверное, уже всех задолбал со своими вопросами, но....


G>Когда я меняю размеры своего главного окна (а в нём у меня плавает три вьюера) ,

G>дергается рамка вместе с менюшками и тулбарами. ON_SIZE для вьюеров я обработал, а вот для главного фрэйма — чего-то не ладится

В смысле не ладится? WM_SIZE не обрабатывается или что?

Но вообще-то это нормальное явление. Я сейчас попробовал — и у IE и у MSDN и у VC дергается (я, конечно, не знаю насколько сильно дёргается у тебя, но у этих вполне заметно). Наверное в обработчике WM_SIZE происходит что-то не очень быстрое. Вряд ли это связано с рисованием, скорее с пересчётом координат и перемещением дочерних окон.

Не уверен, что имеет смысл оптимизировать этот процесс (если это вообще возможно) т.к. вряд ли пользователь будет постоянно изменять размер окна.
Делай что должно, и будь что будет
Re[11]: Проблема перерисовок .....
От: Garvold Израиль  
Дата: 04.08.02 14:18
Оценка:
Здравствуйте SergH


Большое спасибо!

Приятно получать исчерпывающие ответы
Re[9]: Проблема перерисовок .....
От: PSP Беларусь  
Дата: 05.08.02 06:49
Оценка:
Здравствуйте SergH, Вы писали:


SH>В MSDN искать по CreateEnhMetaFile. Есть ли MFC-реализация не знаю,


CMetaFileDC.

очень удобна.Рекомендую.
Всегда Ваш, PSP.
Re[3]: Проблема перерисовок .....
От: Grog13M Россия http://kyra.spb.ru/maxim/
Дата: 06.08.02 06:13
Оценка:
Здравствуйте Аноним, Вы писали:

А>Здравствуйте SergH


А>Огромное спасибо за информацию...

А>Пойду попробую, хотя, я делаю почти то же самое, что вы подсказали, но кистью для фона окна я ещё не игрался..

А> Да, и ещё одна странность: Если многократно симулировать перерисовку какого-то одного прямоугольника, через какое-то время он теряет и заливку и содержание (просто становится белым прямоугольником)


Ты уверен, что после перерисовки ты все перья и кисточки восстанавливаешь?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.