Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вопрос ламера про рисование
Форум разработчиков электроники ELECTRONIX.ru > Цифровая обработка сигналов - ЦОС (DSP) > Алгоритмы ЦОС (DSP)
M_A
Я пока тока учусь, так что сильно не пинайте за глупые вопросы, просто много уже перерыл, а ответ не нашел.
Учусь рисовать в окне. Нарисовал примитивы типа круга, прямоугольника.
Завел цикл, где рисую круг со смещающимися координатами. Результат - куча выстроившихся друг за другом кругов. Вопрос: как после того, как нарисован круг, очистить окно, чтобы потом нарисовать второй со смещенными координатами и т.д. чтоб получить эффект "движущегося" круга?
З.Ы. просто у меня в идеале должна получиться железяка, передающая информацию из внешнего мира в комп, вот появилась идея отображать все графически, чтоб веселее было....
subver
Смотреть в сторону функций BitBlt, CreateDIBSection и далее по MSDN smile.gif
получается очень аккуратно и быстро.
Kurt
На чем пишите?
Для того чтобы очистить экран перед отрисовкой следующей фигуры можно использовать функции GDI:

CRect rc;
GetClientRect(rc);

// clear background
dc.SetBkColor(::GetSysColor(COLOR_BTNFACE));
dc.ExtTextOut(0, 0, ETO_OPAQUE, rc, NULL, 0, NULL);

Еще стоит поискать в инете на тему flicker free drawing так как наверняка такая проблема возникнет.
M_A
subver, Kurt Спасибо что откликнулись!

Я уже и сам кой-чего нашел!
Я был уверен, что есть какие то стандартные и простые решения для этого, вот одно из них и нашел (для MFC):

Invalidate(TRUE);
makc
Цитата(M_A @ Jul 20 2005, 10:35)
Invalidate(TRUE);
*


Это приводит к мерцанию, очень заметному на медленных машинах. Правильнее всего делать BitBlt для сохранения и восстановления изображения между выводом кругов.
M_A
Цитата(makc @ Jul 20 2005, 10:28)
Цитата(M_A @ Jul 20 2005, 10:35)
Invalidate(TRUE);
*


Это приводит к мерцанию, очень заметному на медленных машинах. Правильнее всего делать BitBlt для сохранения и восстановления изображения между выводом кругов.
*



Про BitBlt почитал, вкратце он делает следующее:

Copies a bitmap from a specified device context.

Пните меня в нужном направлении, как это может мне помочь очищать окно?
subver
Цитата
Пните меня в нужном направлении, как это может мне помочь очищать окно?


Очищать нужно не окно, а внеэкранный буфер.
BitBlt копирует с одного HDC на другой, один из них - DC вашего окна, другой - DC битмапа, который можно создать с помошью функции CreateDIBSection, вот пример:

Код
COLORREF *ScreenBuffer;
       ScreenBuffer = (COLORREF *)malloc(SCREEN_H*SCREEN_W*4);
       hdcDest=GetDC(Handle);
       bmi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
       bmi.bmiHeader.biWidth=SCREEN_W;
       bmi.bmiHeader.biHeight=SCREEN_H;
       bmi.bmiHeader.biPlanes=1;
       bmi.bmiHeader.biBitCount=32;
       bmi.bmiHeader.biCompression=BI_RGB;
       bmi.bmiHeader.biSizeImage=0;
       bmi.bmiHeader.biClrUsed=0;
       bmi.bmiHeader.biClrImportant=0;
       hdcSrc=CreateCompatibleDC(NULL);
       BitMap=CreateDIBSection(hdcSrc,&bmi,DIB_RGB_COLORS,&(void *)ScreenBuffer,NULL,0);
       SelectObject(hdcSrc,BitMap);
     
       /*здесь рисуем в ScreenBuffer
        .................................*/


      //А теперь копируем буфер на окно
       BitBlt(hdcDest,0,0,SCREEN_W,SCREEN_H,hdcSrc,0,0,SRCCOPY);


ScreenBuffer - выделенный блок памяти размером SCREEN_W*SCREEN_H*biBitCount/8 байт.

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

если biBitCount == 32, то формат цвета соответствует стандартному COLORREF.

Чтобы поставить точку с координатами 10,10 делаем так:
Код
ScreenBuffer[10+10*SCREEN_W]=color;


Соответственно, по окончании необходимо удалить все, что насоздавали:

Код
       DeleteObject(BitMap);
       DeleteDC(hdcSrc);
       free(ScreenBuffer);


Да, и еще - создавать и удалять буферы и битмапы надо при старте и закрытии приложения соответственно, а алгоритм отрисовки одного кадра такой:

1. Заполняем ScreenBuffer цветом фона
2. Рисуем все что нужно
3. Делаем BitBlt

Если возникает мерцание, то перед 3. надо дождаться обратного хода луча монитора, как это сделать сейчас не скажу, ибо не помню smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.