Графика для Windows средствами DirectDraw
Шрифт:
Сначала
Далее функция CreateClipper интерфейса DirectDraw создает объект отсечения. CreateClipper получает три аргумента, однако первый и последний из них чаще всего равны нулю. Второй аргумент представляет собой адрес указателя на интерфейс DirectDrawClipper. В нашем случае используется переменная класса DirectDrawWin с именем clipper.
Объект отсечения нужен для ограничения вывода в программе. Поскольку наше приложение работает в окне, которое находится на рабочем столе вместе с другими окнами, при обновлении изображения необходимо учитывать присутствие этих окон. Чтобы объект отсечения автоматически выполнял свою работу, его необходимо присоединить к окну функцией SetHWnd интерфейса DirectDrawClipper. Функция SetHWnd получает два аргумента — двойное слово (DWORD), которое зарезервировано для будущего использования и пока должно быть равно нулю, и логический номер окна приложения.
Далее объект отсечения присоединяется к первичной поверхности приложения функцией SetClipper интерфейса DirectDrawSurface. После такого присоединения можно осуществлять блиттинг на первичную поверхность с помощью функции Blt
Последнее, что происходит в функции CreateFlippingSurface, - создание поверхности вторичного буфера. В идеальном варианте нам удастся найти свободную видеопамять в объеме, достаточном для создания внеэкранной поверхности, которая по ширине и высоте совпадает с первичной поверхностью. Я называю такой вариант идеальным из-за преимущества по скорости, характерного для блит-операций в пределах видеопамяти. Кроме того, поскольку вторичный буфер по размерам совпадает с первичной поверхностью, он подойдет для окна любого размера.
Функция CreateFlippingSurfaces пытается создать «идеальный» вторичный буфер, для чего используются флаг DDSCAPS_VIDEOMEMORY и функция CreateSurface. Если вызов заканчивается успешно, флаг videobacksurf получает значение TRUE, а функция завершает работу. В противном случае вторичный буфер не создается, а флагу videobacksurf присваивается значение FALSE.
В том варианте вторичный буфер создается приложением в системной памяти позднее, в обработчике OnSize. Функция OnSize вызывается при изменении размеров окна приложения. Создавая вторичный буфер по размерам клиентской области окна, мы экономим память. Функция OnSize выглядит так:
Инициализация приложения завершается вызовом функций StorePixelFormatData и CreateCustomSurfaces, происходящим в обработчике OnCreate. Обе функции ведут себя точно так же, как и в полноэкранном приложении.
Как и в полноэкранном варианте, для обновления экрана класс DirectDrawWin вызывает функцию DrawScene. Ее реализация для оконных приложений отличается от полноэкранного варианта по двум причинам. Во-первых, поскольку в оконном приложении не выполняется переключение страниц, содержимое вторичного буфера приходится копировать на первичную поверхность. Во-вторых, местонахождение выводимых данных на первичной поверхности должно определяться текущим положением и размерами окна. Помните — первичная поверхность в данном случае изображает весь экран, а не только клиентскую область окна. Оконный вариант DrawScene выглядит так: