улучшить прорисовку

uniqueman
Уже с Приветом
Posts: 2013
Joined: 16 Mar 2002 10:01
Location: New York City

улучшить прорисовку

Post by uniqueman »

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

По совету из форума выбрал компонент ChartDirector. компонент неплохой, но один недостаток. Если надо мне прорисовать заново какую то часть графика, то приходится удалять весь график и строить заново. Из за этого график довольно сильно мерцает. Связался с разработчиками. Они подтвердили что так и надо. И что типа если надо обновлять что то быстро, то надо смотреть на компоненты которые работают с DirectX или подобными интерфейсами. В принципе они правы...

Я пытался схимичить что то наподобие двойного буфера с текущим графиком.

Текущий компонент использует какой нибудь подходящий контрол (говорим про MFC) для вывода графика... Допустим я использую CStatic с присвоенным свойством SS_BITMAP.

То есть я создаю график в памяти, перевожу его в битмап и просто натягиваю битмап на CStatic...

chart = sStaic->SetBitmap(chart)
if (0 != chart)
DeleteObject(chart);

и затем sStatic.ShowWindow (TRUE);

Попробовав улучшить и сделал следующее. Вместо одного статик контрола, положил на диалог два и один сделал инвизибл.

CStatic static1;
CStatic static2;

на ран тайме смотрю какой статик контрол невидим (то бишь готов принять новый график), создаю и натягиваю на него график, делаю его видимым, а первый (который был видим) делаю невидимым.

--------------------------
void Class :: BuildChart ()
{
if (static1.IsWindowVisible())
{
CreateChart (static2);
static2.ShowWindow(TRUE);
static1.ShowWindow (FALSE);
}
else
{
CreateChart (static1);
static1.ShowWindow(TRUE);
static2.ShowWindow (FALSE);
}
}

Таким образом производительность немного улучшилась, но все равно недостаточно. Если диалоговое окно не двигать с самого начала, то вроде работает неплохо. Если же его передвинуть куда то, то опять начинает мерцаение сильное.. не пойму из за чего.

Подскажите идеи как еще можно улучшить прорисовку?
Спасибо
lozzy
Уже с Приветом
Posts: 2435
Joined: 12 Jun 2001 09:01

Re: улучшить прорисовку

Post by lozzy »

uniqueman wrote:Подскажите идеи как еще можно улучшить прорисовку?
Спасибо


Нет, так не пойдет. Двойная буферизация делается несколько не так. И, в принципе, никакой ДиректИкс тут не нужен. К сожалению, я не могу привести пример кода, поскольку он был писан в Дельфяях несколько лет назад. А делается это так:

Есть окно с известным дескриптором, в которое надо рисовать. Создается битмап, в который рисуется актуальный график, а потом, по требованию системы (ну, скажем, на WM_PAINT или WM_ERASEBGR), этот битмап просто копируется функцией BitBlt или StretchBlt (или подобным StretchDIBits, если работаете с device independent bitmaps). Скорость работы этих функций достаточно высока, что бы пользователь не заметил перерисовки. Вот это и есть двойная буферизация.
Steel helmet protects your teeth from the morning to the evening.
uniqueman
Уже с Приветом
Posts: 2013
Joined: 16 Mar 2002 10:01
Location: New York City

Re: улучшить прорисовку

Post by uniqueman »

lozzy wrote:
uniqueman wrote:Подскажите идеи как еще можно улучшить прорисовку?
Спасибо


Нет, так не пойдет. Двойная буферизация делается несколько не так. И, в принципе, никакой ДиректИкс тут не нужен. К сожалению, я не могу привести пример кода, поскольку он был писан в Дельфяях несколько лет назад. А делается это так:

Есть окно с известным дескриптором, в которое надо рисовать. Создается битмап, в который рисуется актуальный график, а потом, по требованию системы (ну, скажем, на WM_PAINT или WM_ERASEBGR), этот битмап просто копируется функцией BitBlt или StretchBlt (или подобным StretchDIBits, если работаете с device independent bitmaps). Скорость работы этих функций достаточно высока, что бы пользователь не заметил перерисовки. Вот это и есть двойная буферизация.


насколько я понял из МСДН все равно перед прорисовкой битмапа, окно делается SW_HIDE а затем SW_SHOW. Я думаю что проблема в этом. Данный компонент тратит на создание чарта свего порядка 100 наносекунд процесорного времени. Мне кажется моргание именно из за частых вызовов ShowWindow..
User avatar
roadman
Уже с Приветом
Posts: 707
Joined: 12 Mar 2003 22:29
Location: Moscow->Bay Area, CA

Post by roadman »

lozzy прав.
Если работаете с MFC, то
1. переопределяете функцию OnPaint
2. вызываете регулярно (на таймере) функцию Invalidate, а она в свою очередь вызовет OnPaint.
3. Создаете device-context in memory (CreateCompatibleDC) и рисуете там свой график. Обновляете, когда надо и вызываете функцию Invalidate
4. И самое главное! В функции OnPaint просто копируете один device-context в другой, используя функцию BitBlt.
User avatar
DR_35_USA
Уже с Приветом
Posts: 1194
Joined: 07 Jul 2001 09:01
Location: Tomsk->Mountain View->Milpitas

Post by DR_35_USA »

Ещё может быть на перерисовку background надо посмотреть... В некоторых случаях моргание из за того, что элемент (окно) при перерисовке перерисовывает задний план, а потом проложение - график поверх него... Было там что-то чтобы это отлючить... может самому WM_ERASE_BACKGROUND (или как оно там) обрабатывать
Оно вроде и ни что-либо как, а приведись такое дело так вот тебе и пожалуйста.

Return to “Вопросы и новости IT”