Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Задний буффер 
V
    Опции темы
TGrey
Дата 23.2.2010, 20:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: 1
Всего: 1



Здравствуйте, пишу приложение с графическим интерфейсом и на данный момент происходит слишком много бликов. С этим я пока ничего не делал, но возникла другая проблема. По сути соединяются 2 объекта линией. И получается что если создать:
1 объект
Линия
2 Объект
то при перемещении концы линии рисуются у объекта создавая эффект положения на месте. Но если создать в таком порядке, то линия рисуется раньше чем второй объект и перед тем, как конец линии будет дорисован возле объекта видно, что линия тоже двигается. Так я вот что подумал, это же видно только если рисовать прямо на канву формы, но если построить изображение в буффере, а потом вывести его полностью, то этого не будет. Сделал значит я буфер и получил значит все тоже самое, только мигает сильнее smile 
Код

            HDC dc = BeginPaint(hwnd, &ps), memdc;
            memdc = CreateCompatibleDC(dc);
            HBITMAP oldbm, bm = CreateCompatibleBitmap(dc, 800, 600);
            oldbm = (HBITMAP)SelectObject(memdc, bm);
            RECT r;
            r.left=0;
            r.top=0;
            r.right=800;
            r.bottom = 600;
            FillRect(memdc, &r, (HBRUSH)GetStockObject(LTGRAY_BRUSH));
            int old = SetGraphicsMode(dc, GM_ADVANCED);
            if( !d.elements.empty() )
                for(int i=0; i < d.elements.size(); i++)
                {
                    d.elements[i]->Draw(&memdc);
                }
                BitBlt(dc,0,0,800,600,memdc,0,0, SRCCOPY);
                SelectObject(memdc, (HBITMAP)oldbm);
                DeleteObject(bm);
                DeleteDC(memdc);

Не пойму почему оно движение линии продолжает рисовать если по идее рисунок уже должен быть цельным?!
Что посоветуете?
PM MAIL   Вверх
GremlinProg
Дата 23.2.2010, 22:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



TGrey, что такое "движение линии"?


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
TGrey
Дата 24.2.2010, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: 1
Всего: 1



Ну графический интерфейс. Линия это объект, выделили ее одним кликом и потащили мышкой в другое место. Если имеются другие объекты к которым подключена линия(прямоугольник к примеру), то при его отрисовке  конец, которым подключена линия рисуется возле прямоугольника. И выходит, что если линия в векторе объектов находится раньше второго прямоугольника, а значит рисуется раньше, видно что она пытается двигаться, хоть сразу при отрисовке второго прямоугольника линию перерисовывает в нужно место, но этот эффект не очень желателен.
Как я сказал, если в теории выдавать все на задний буфер, а потом полностью уже на форму, то по идее оно не должно так дергать линии, ведь рисунок уже будет полный.

На рисунке, что прикрепил линия соединяет 2 прямоугольника и я ее пытаюсь перетянуть и как видно 2 конец, где-то в стороне.

Присоединённый файл ( Кол-во скачиваний: 7 )
Присоединённый файл  error.JPG 26,28 Kb
PM MAIL   Вверх
GremlinProg
Дата 24.2.2010, 13:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(TGrey @  24.2.2010,  15:19 Найти цитируемый пост)
если в теории выдавать все на задний буфер, а потом полностью уже на форму, то по идее оно не должно так дергать линии, ведь рисунок уже будет полный

верно, так и будет, если вышеприведенный код вызывается только в ответ на сообщение WM_PAINT,
если это не так, то заводить задний буфер смысла нет, т.к. для него не выполнено главное условие: единовременный вывод буфера на передний план


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
TGrey
Дата 24.2.2010, 17:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: 1
Всего: 1



Да тот код вызывается в WM_PAINT, почему же я и говорю, что никакой разницы, только моргает в 2 раза больше и заметнее.

Это сообщение отредактировал(а) TGrey - 24.2.2010, 17:54
PM MAIL   Вверх
GremlinProg
Дата 24.2.2010, 22:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



здесь ключевое слово не "WM_PAINT", а "только WM_PAINT"

если стало моргать сильнее, значит увеличилось число перерисовок (число смен цвета на пиксел),
поэтому я и предлагаю проверить этот момент,

хотя конечно, если WM_ERASEBKGND не контролируется, двойной буфер от морганий так же не спасет,
только вот сила моргания от этого не зависит


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
TGrey
Дата 25.2.2010, 17:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: 1
Всего: 1



Что значит только WM_PAINT? У меня отрисовка всех элементов в этом сообщении только записана. Остальные действия вызывают Invalidate тем самым вызывая перерисовку. Что мне еще проверять?
PM MAIL   Вверх
GremlinProg
Дата 25.2.2010, 22:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(TGrey @  25.2.2010,  19:48 Найти цитируемый пост)
Что мне еще проверять?

например отсутствие UpdateWindow после Invalidate в любом виде, хоть через RedrawWindow или явные вызовы методов прорисовки при движении мыши и т.п., т.к. видимость вот этого движения линии от присоединенного к ней объекта говорит о том, что изменение координат и линии и этих объектов производится с некоторым отставанием друг от друга с разбавлением этого процесса перерисовкой

если конечно я правильно понял проблему

неплохо бы было посмотреть именно этот момент,
я так понимаю - WM_MOUSEMOVE, а лучше всю связку: HITTEST-DOWN-MOVE-UP

Добавлено через 1 минуту и 42 секунды
а еще лучше - прикрепить к этому собранный бинарник для наглядности


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
TGrey
Дата 26.2.2010, 01:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: 1
Всего: 1



Во всех сообщениях мыши вызываются виртуальные функции которые рассчитывают клик, перемещение и другие функции над объектами. И в конце каждого сообщения
InvalidateRect(hwnd, NULL, true);

Для теста сперва создать Проводник, а потом два любых объекта и соединить их проводником. Выделение снимать Еск.

Это сообщение отредактировал(а) TGrey - 26.2.2010, 01:35

Присоединённый файл ( Кол-во скачиваний: 5 )
Присоединённый файл  TOE.rar 106,42 Kb
PM MAIL   Вверх
GremlinProg
Дата 26.2.2010, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



посмотрел,
тут дело не в прорисовке,
неправильно производится перемещение объектов, т.е. привязка смещения для мыши должна быть постоянной, а у тебя ее скорее всего нет, надо делать примерно так:
при старте перемещения:
Код

const_dx = mouse.x - obj.x
const_dy = mouse.y - obj.y
при самом перемещении:
Код

obj.x = mouse.x + const_dx
obj.y = mouse.y + const_dy

это первое, второе - это то, что привязанный проводник пытается самостоятельно двигаться,
т.е. каша у тебя в перемещениях и видимо в структуре самих объектов,
выдели проводники как отдельный объект и работай с ними отдельно,
это же не точечный объект, и двигать-то его не надо,
либо, если уж и двигать, то совсем по-другому: с перемещением связных объектов,
т.е. в любом случае, первым делом надо отделить отрезки от точек


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
TGrey
Дата 26.2.2010, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: 1
Всего: 1



Насчет того, что оно перекидывает объект на центр курсора это я знаю думал потом профиксить.
Не понял, что нужно сделать для проводника?
Что значит пытается двигаться самостоятельно? Он же и так вроде один и должен перемещаться если его тянуть? А если конец  прикреплен к чему либо, то я рассчитывал, что оно в общей картинке отрисует конец в месте соединенияи проблем не должно было быть.

Не понял, что имелось ввиду под !"это же не точечный объект, и двигать-то его не надо" и "первым делом надо отделить отрезки от точек ".
Буду благодарен за пояснения.
PM MAIL   Вверх
GremlinProg
Дата 26.2.2010, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(TGrey @  26.2.2010,  15:47 Найти цитируемый пост)
Насчет того, что оно перекидывает объект на центр курсора это я знаю думал потом профиксить.

нет, это как раз работает нормально (при залипании мыши на таких мелких точках, центрирование курсора - нормально)
Цитата(TGrey @  26.2.2010,  15:47 Найти цитируемый пост)
Что значит пытается двигаться самостоятельно?

ну соедини проводник с 2-мя объектами и попробуй его переместить, видно, что производится попытка его двигать,
а присоединенные объекты ему этого сделать не дают, проводник бьется в конвульсиях - это ненормально
Цитата(TGrey @  26.2.2010,  15:47 Найти цитируемый пост)
это же не точечный объект, и двигать-то его не надо

соединяющая линия обычно не живет своей жизнью, т.к. ее смысл как раз в объединении нескольких объектов, какой смысл ее двигать, пусть она опирается на координаты соответствующих присоединенных объектов, тогда ее и двигать не придется: сама будет двигаться за объектами при их перемещении
Цитата(TGrey @  26.2.2010,  15:47 Найти цитируемый пост)
первым делом надо отделить отрезки от точек

значит делаем не 1 массив объектов, а 2
в первом будут отрезки, во втором - объекты
вместо концов отрезков можно указать номера объектов, тогда привязка будет корректной всегда, не придется постоянно синхронизировать координаты


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
TGrey
Дата 26.2.2010, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: 1
Всего: 1



Но проводник идет с расчетом на то, что его можно отсоединить, переключить, сторону переместить... В таком случае я могу дописать проверку, что если сторона подключена, то пропускать вызов функции перемещения конца.
Ну так а с миганием, что делать то?)
PM MAIL   Вверх
GremlinProg
Дата 26.2.2010, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



с миганием уже сказал: контролировать, или просто перекрыть WM_ERASEBKGND:
Код

case WM_ERASEBKGND:
  return TRUE;



--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
TGrey
Дата 26.2.2010, 18:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: 1
Всего: 1



Здается мне, что я уже пробовал и эффект был плохим. А так же посылал в Инвалидат последний параметр ФОЛС. Попробую сейчас еще.

Добавлено через 8 минут и 56 секунд
О спасибо все получилось. Дело в том, что когда я пробовал, то я запрещая удаление бекграуна сразу рисовал, но форме. Потому там получалась каша из всего, что есть. А сейчас заливая битмап цветом фона после чего рисуя на нем все элементы и выводя готовое в окно все мерцание пропало smile 

Оно хоть никак не влияет на систему, что оно постоянно рисует поверх? Это так на всякий случай.
PM MAIL   Вверх
GremlinProg
Дата 1.3.2010, 20:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(TGrey @  26.2.2010,  20:53 Найти цитируемый пост)
Оно хоть никак не влияет на систему, что оно постоянно рисует поверх?

в принципе - нет,
будет влиять только тогда, когда оно будет постоянно рисовать впустую,
т.е. рисовать те места серого буфера, которые не будут выводиться на передний план

вот когда накопится достаточный объем таких "пустых" операций, появятся тормоза,
но я бы за саму закраску (FillRect) заднего плана не переживал,
т.к. эта операция достаточно быстрая, по сравнению с окружностями, линиями и п.р. загагулинами


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0559 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.