Страница 1 из 1

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

Добавлено: Чт ноя 13, 2003 2:56 pm
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);
}
}

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

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

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

Добавлено: Пт ноя 14, 2003 3:36 am
lozzy
uniqueman писал(а):Подскажите идеи как еще можно улучшить прорисовку?
Спасибо


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

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

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

Добавлено: Пт ноя 14, 2003 2:40 pm
uniqueman
lozzy писал(а):
uniqueman писал(а):Подскажите идеи как еще можно улучшить прорисовку?
Спасибо


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

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


насколько я понял из МСДН все равно перед прорисовкой битмапа, окно делается SW_HIDE а затем SW_SHOW. Я думаю что проблема в этом. Данный компонент тратит на создание чарта свего порядка 100 наносекунд процесорного времени. Мне кажется моргание именно из за частых вызовов ShowWindow..

Добавлено: Пт ноя 14, 2003 7:33 pm
roadman
lozzy прав.
Если работаете с MFC, то
1. переопределяете функцию OnPaint
2. вызываете регулярно (на таймере) функцию Invalidate, а она в свою очередь вызовет OnPaint.
3. Создаете device-context in memory (CreateCompatibleDC) и рисуете там свой график. Обновляете, когда надо и вызываете функцию Invalidate
4. И самое главное! В функции OnPaint просто копируете один device-context в другой, используя функцию BitBlt.

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