Графическим выводом в программе Switch занимается функция SwitchWin::DrawScene(). Она отвечает за подготовку кадра во вторичном буфере и переключение страниц, благодаря которому новый кадр отображается на экране. Код функции DrawScene()содержится в листинге 4.4.
Листинг 4.4.Функция SwitchWin::DrawScene()
void SwitchWin::DrawScene() {
ClearSurface(backsurf, 0);
BltSurface(backsurf, bmpsurf, x, y);
x+=xinc;
y+=yinc;
const CRect& displayrect=GetDisplayRect();
if (x<-160 || x>displayrect.right-160) {
xinc=-xinc;
x+=xinc;
}
if (y<-100 || y>displayrect.bottom-100) {
yinc=-yinc;
y+=yinc;
}
backsurf->BltFast(0, 0, menusurf, 0, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT);
UpdateFPSSurface();
if (displayfps) {
int x=displayrect.right-fpsrect.right-1;
int y=displayrect.bottom-fpsrect.bottom-1;
backsurf->BltFast(x, y, fpssurf, 0, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT );
}
primsurf->Flip(0, DDFLIP_WAIT);
}
Сначала функция DrawScene()подготавливает вторичный буфер, стирая его содержимое функцией ClearSurface(). Мы заполняем вторичный буфер нулями, но, поскольку он не имеет цветового ключа, 0 в данном случае имеет иной смысл, чем для поверхностей menusurfи fpssurf. Для вторичных буферов 0 означает черный цвет (в большинстве случаев).
СОВЕТ
Черный цвет не гарантирован
По умолчанию DirectDraw резервирует два элемента палитры: для черного (индекс 0) и для белого (индекс 255). Поэтому обычно заполнение поверхности нулями равносильно ее заливке черным цветом. Тем не менее в палитрах, созданных с флагом DDSCAPS_ALLOW256, можно задавать все 256 элементов.
Функция DirectDrawWin::CreateSurface()при создании и установке палитры (когда необязательный аргумент use_paletteравен TRUE) использует флаг DDSCAPS_ALLOW256, поэтому первый элемент в палитрах наших приложений может быть отличен от черного цвета. Флаг можно удалить, но это нарушит цветопередачу при отображении BMP-файлов, у которых первый и последний элементы палитры отличны от черного и белого цветов соответственно.
В программах этой книги используются BMP-файлы, для которых положение черного и белого цвета в палитре совпадает с принятым в DirectDraw по умолчанию. В этом случае растры будут правильно отображаться независимо от флага DDSCAPS_ALLOW256.
Другая причина, по которой первому элементу палитры следует назначать черный цвет, в том, что первый элемент палитры совпадает с цветом, используемым на экране за пределами нормальной области рисования (overscan color — цвет внешней рамки). Хотя не существует никаких формальных причин, по которым этим цветом должен быть именно черный, другие варианты обычно выглядят довольно странно.
После завершения очистки поверхность bmpsurf(анимационная поверхность) копируется на вторичный буфер функцией DirectDrawWin::BltSurface()(мы используем функцию BltSurface()из-за наличия в ней встроенной поддержки отсечения, что позволяет перемещаемому растру частично выходить за пределы экрана). После выполнения блиттинга рассчитывается новое положение растра, при этом размеры текущего видеорежима используются для ограничения перемещений.
Затем копируется поверхность меню. Она всегда выводится в левом верхнем углу экрана, а ее размеры совпадают с размерами видеорежима с наименьшим разрешением (320×200), так что отсечение не понадобится. Следовательно, мы можем воспользоваться функцией BltFast()интерфейса DirectDrawSurface. Первые два аргумента BltFast()определяют область приемника для наложения копии (оба аргумента равны нулю, что означает левый верхний угол). Третий аргумент является указателем на поверхность-источник, а четвертый описывает копируемую прямоугольную область источника. Вместо прямоугольника мы передаем 0, тем самым показывая, что копироваться должна вся поверхность.
В последний аргумент функции BltFast()включены флаги DDBLTFAST_SRCCOLORKEYи DDBLTFAST_WAIT. Первый флаг активизирует цветовой ключ поверхности-источника. Если бы он не был указан, то во время блиттинга цветовой ключ поверхности menusurfбыл бы проигнорирован, а пиксели с нулевыми значениями выводились бы черным цветом. Второй флаг показывает, что выход из функции BltFast()должен произойти лишь после завершения копирования.
Вернемся к функции DrawScene(). Наша следующая задача - обновление и отображение поверхности FPS ( fpssurf). Однако, как было сказано выше, поверхность fpssurfобновляется лишь после того, как закончится очередной интервал хронометража.
Читать дальше