Графика для Windows средствами DirectDraw | страница 59



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

Потеря поверхностей происходит из-за того, что DirectDraw выделяет занятую видеопамять для других целей. Потерянную поверхность можно легко восстановить, но лишь после того, как приложение станет активным, поэтому перед тем, как восстанавливать поверхности, функция PreDrawScene() ждет установки флага window_active (состояние флага window_active зависит от сообщений WM_ACTIVATEAPP, обрабатываемых функцией DirectDrawWin::OnActivateApp). После восстановления первичной поверхности и вторичного буфера вызывается функция RestoreSurfaces(). Она является чисто виртуальной функцией, которая должна быть реализована в производных классах. Сейчас мы рассмотрим ее возможную реализацию.

Так как функция OnIdle() вызывает DrawScene() лишь после проверки результата PreDrawScene(), DrawScene() будет вызвана лишь в том случае, если приложение активно, а первичная и вторичная поверхности не были потеряны.

Функция DrawScene()

Классы, производные от DirectDrawWin, реализуют функцию DrawScene(), в которой происходит обновление экрана. Версия DrawScene() из класса BounceWin выглядит так:

>void BounceWin::DrawScene() {

> CRect limitrect=GetDisplayRect();

> x+=xinc;

> y+=yinc;

> if (x<-160 || x>limitrect.right-160) {

>  xinc=-xinc;

>  x+=xinc;

> }

> if (y<-100 || y>limitrect.bottom-120) {

>  yinc=-yinc;

>  y+=yinc;

> }

> ClearSurface(backsurf, 0);

> BltSurface(backsurf, surf1, x, y);

> primsurf->Flip(0, DDFLIP_WAIT);

>}

Сначала функция GetDisplayRect() получает объект CRect, хранящий ширину и высоту текущего видеорежима. Эти размеры будут использоваться для ограничения перемещений растрового изображения в соответствии с видеорежимом. Далее вычисляются значения переменных x и y класса BounceWin, определяющих местонахождение растра на экране.

Затем мы вызываем функцию ClearSurface() и передаем ей два аргумента: указатель backsurf и 0. Это приводит к тому, что вторичный буфер заполняется черным цветом. Хотя я упоминал о том, что использование ClearSurface() иногда осложняется различными форматами пикселей, заполнение поверхностей черным работает надежно. Для палитровых поверхностей 0 означает черный цвет, потому что по умолчанию он стоит в палитре на первом месте; для беспалитровых поверхностей 0 всегда соответствует черному цвету.