Свалился тут на меня один громоздкий проект с большим колличеством графики, но ,из-за отсутствия должного опыта в работе с графикой, я увяз в нём как в болоте :-(
Люди добрые, кто в этой области шарит , поведайте пожалуйста как правильно перерисовывать графические объекты (Rect,Rgn,Text и т.д.) при использование зума, скрола, драг-н-дропа ну и прочих передвижений, так, что бы они не мигали...
Я отдаю себе отчёт, что такого рода информация может оказаться очень объёмной,
но я был бы рад любому намёку, подсказке или , может быть, линку на какой-нибудь материал по этой теме.
Здравствуйте 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. Перерисовывать только необходимую область, а не все окно.
Большое спасибо за столь быстрый ответ !
Дело в том , что, вроде, я так и делаю...
Но при перетаскивание, например прямоугольника, мигает его внутренняя область
(я , в свою очередь, перерисовываю только сам прямоугольник...)
Да, забыл сказать, что заливка фона — чёрная
Здравствуйте 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 её нет.
Здравствуйте Аноним, Вы писали:
А>Здравствуйте KaSA, Вы писали:
KSA>>ИМХО, тут два основных момента:
KSA>>1. Рисовать не на экране, а в совместимом контексте, который в оперативной памяти. KSA>>2. Перерисовывать только необходимую область, а не все окно.
А> Большое спасибо за столь быстрый ответ ! А>Дело в том , что, вроде, я так и делаю...
А>Но при перетаскивание, например прямоугольника, мигает его внутренняя область А>(я , в свою очередь, перерисовываю только сам прямоугольник...) А>Да, забыл сказать, что заливка фона — чёрная
Кисть окна обнулить надо и самому бекграунд отрисовывать.
Здравствуйте Аноним, Вы писали:
А>Но при перетаскивание, например прямоугольника, мигает его внутренняя область А>(я , в свою очередь, перерисовываю только сам прямоугольник...) А>Да, забыл сказать, что заливка фона — чёрная
А перетаскивать только рамку нельзя? Рамку можно рисовать XOR-ом.
Делай что должно, и будь что будет
Re[2]: Проблема перерисовок .....
От:
Аноним
Дата:
04.08.02 11:11
Оценка:
Здравствуйте SergH
Огромное спасибо за информацию...
Пойду попробую, хотя, я делаю почти то же самое, что вы подсказали, но кистью для фона окна я ещё не игрался..
Да, и ещё одна странность: Если многократно симулировать перерисовку какого-то одного прямоугольника, через какое-то время он теряет и заливку и содержание (просто становится белым прямоугольником)
Здравствуйте SergH, Вы писали:
SH>Здравствуйте Аноним, Вы писали:
А>>Но при перетаскивание, например прямоугольника, мигает его внутренняя область А>>(я , в свою очередь, перерисовываю только сам прямоугольник...) А>>Да, забыл сказать, что заливка фона — чёрная
SH>А перетаскивать только рамку нельзя? Рамку можно рисовать XOR-ом.
XOR — это, я так понимаю, что-то из GDI+ ? (короче я не сталкивался)
А я рисую контур фигур линиями , но для перерисовки нужной области знаю только InvalidateRgn (ну или InvalidateRct)
Здравствуйте 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, которая позволяет рисовать что угодно в любом месте программы.
Здравствуйте Аноним, Вы писали:
А> Да, и ещё одна странность: Если многократно симулировать перерисовку какого-то одного прямоугольника, через какое-то время он теряет и заливку и содержание (просто становится белым прямоугольником)
Действительно, странно.. Но идея есть. Если я правильно догадался, то у тебя есть родительское окно, на нём дочерние и вот в дочернем этот самый прямоугольник. И, ко всему, у родительского окна белый фон и отсутствует стиль WS_CLIPCHILDREN. Тогда (наверное), возможна ситуация, когда родительское окно перересует этот прямоугольник (просто зальёт своим фоном), а дочернее ещё нет.
Если я угадал правильно, то:
1. Поставь WS_CLIPCHILDREN
2. Если дочернее окно занимает всю клиентскую область родительского, поставь родительскому пустую кисть. Это должно положительно сказаться на производительности.
Здравствуйте Garvold, Вы писали:
G>Спасибо огроменное !!!! Вроде всё заработало как надо...
G>Последний вопрос: G> Когда я увеличиваю изображение, текст, в процессе увеличения, жутко искажается (буквы становятся какими-то кривыми и некрасивыми)
Увеличиваю это StretchBlt? Тогда ничего не поделаешь, красиво будет (теоретически, я не пробовал) только при увиличении в целое количество раз.
Есть два альтернативных варианта:
1. Увиличивать размер шрифта и отрисовывать заново. Если шрифт TrueType, наверное получится неплохо.
2. Использовать метофайлы. Я с ними работал совсем чить-чуть, поэтому незнаю, насколько хорошо будет увиличиваться текст. Зато знаю, что метафайл с битмапами плохо поддаётся масштабированию (знаю — сильно сказано. В моём единсвенном эксперементе под XP система отказалась изменять размер метафайла с битмапом. Причём не просто отказалась, а ругнулась как-то.). Но попробовать стоит.
Метафайлы, конечно, рисуются медленнее чем BitBlt. Но, если тебе нужно часто изменять размер можно совместить эти два подхода. Т.е. из метафайла в memory DC, из него BitBlt на экран.
В MSDN искать по CreateEnhMetaFile. Есть ли MFC-реализация не знаю, но с API MFC уживается без проблем. Использовать обычные (не Enhanced) метафайлы не имеет смысла, т.к. они хуже.
Я, наверное, уже всех задолбал со своими вопросами, но....
Когда я меняю размеры своего главного окна (а в нём у меня плавает три вьюера) ,
дергается рамка вместе с менюшками и тулбарами. ON_SIZE для вьюеров я обработал, а вот для главного фрэйма — чего-то не ладится
Здравствуйте Garvold, Вы писали:
G>Я, наверное, уже всех задолбал со своими вопросами, но....
G>Когда я меняю размеры своего главного окна (а в нём у меня плавает три вьюера) , G>дергается рамка вместе с менюшками и тулбарами. ON_SIZE для вьюеров я обработал, а вот для главного фрэйма — чего-то не ладится
В смысле не ладится? WM_SIZE не обрабатывается или что?
Но вообще-то это нормальное явление. Я сейчас попробовал — и у IE и у MSDN и у VC дергается (я, конечно, не знаю насколько сильно дёргается у тебя, но у этих вполне заметно). Наверное в обработчике WM_SIZE происходит что-то не очень быстрое. Вряд ли это связано с рисованием, скорее с пересчётом координат и перемещением дочерних окон.
Не уверен, что имеет смысл оптимизировать этот процесс (если это вообще возможно) т.к. вряд ли пользователь будет постоянно изменять размер окна.
Здравствуйте Аноним, Вы писали:
А>Здравствуйте SergH
А>Огромное спасибо за информацию... А>Пойду попробую, хотя, я делаю почти то же самое, что вы подсказали, но кистью для фона окна я ещё не игрался..
А> Да, и ещё одна странность: Если многократно симулировать перерисовку какого-то одного прямоугольника, через какое-то время он теряет и заливку и содержание (просто становится белым прямоугольником)
Ты уверен, что после перерисовки ты все перья и кисточки восстанавливаешь?