Графика DirectX в Delphi
Шрифт:
// Вывод курсора
GameCursor.DrawFast(CurX, CurY, GameScreen.GetAppBackBuffer);
// Вьшод текста
GameScreen.GetAppBackBuffer.TextXYUO, 10, 255,
'CDX Example for Delphi');
GameScreen.GetAppBackBuffer.TextXY(10, 30, 255, PChar('X= ' +
IntToStr(CurX))); GameScreen.GetAppBackBuffer.TextXY(10, 50, 255, PChar('Y= ' +
IntToStr(CurY)));
Result := GameScreen.Flip;
end;
Последний пример на эту тему (проект катшюга Ех17) поможет нам разобраться в организации спрайтовой анимации. Здесь вид курсора меняется со временем так, что получается
Рис. 5.16. При работе примера чудовище раскрывает и закрывает свою пасть
Фазу можно менять, используя метод setTile, как в одном из предыдущих примеров, или же напрямую задавая прямоугольник источника:
Inc (Delay);
if Delay = 10 then begin // Прошло 10 кадров
// Меняем прямоугольник в источнике
SetRect (GameCursor.SrcRect, 39 * wrkl, 0, 39 * (wrkl + 1), 36);
wrkl := (wrkl + 1) mod 3;
Delay := 0;
end;
В данном разделе мы рассмотрели лишь основные функции библиотеки CDX, все остальные остаются вам для самостоятельного изучения.
Я не думаю, что здесь вы встретите особые проблемы, т. к. после проведенного нами детального изучения механизмов DirectDraw знакомство с подобными библиотеками (и исправление ошибок в исходном коде) превращается в приятное времяпрепровождение.
Что вы узнали в этой главе
Главное, что мы смогли выяснить в данной главе, можно сформулировать следующей торжественной фразой: узнали все необходимое для программирования собственной эффектной игры.
Мы научились работать с устройствами ввода настолько быстро, что приложение мгновенно реагирует на изменение состояний устройств.
Спрайтовая анимация изучена нами до уровня, нужного для разработки игр.
Примеры несложных игр убедительно демонстрируют достигнутые нами высоты мастерства.
Мы познакомились с готовой библиотекой, использующейся профессиональными разработчиками игр.
Глава 6 Работа с AVI-файлами
Модуль VFW
Модуль DirectShow
Запись в видеофайл
Что вы узнали в этой главе
Эта небольшая глава посвящена вопросам, относящимся к воспроизведению и созданию видео. Многие аспекты напрямую не связаны с DirectX и поэтому вынесены в отдельную часть.
Примеры к главе располагаются в каталоге \Examples\Chapter06.
Модуль VFW
Существует много способов работы с видео. Предназначенные для этого компоненты Delphi не очень помогут в решении задачи воспроизведения подобных файлов на поверхностях, поэтому нам придется воспользоваться нестандартными методами.
Прежде всего мы познакомимся с модулем vfw.pas, не входящим в набор стандартных модулей Delphi, но работающим со стандартной системной библиотекой avifil32.dll.
Вместе с Delphi поставляется набор справочных файлов системного программиста, корпорации Microsoft.
С их помощью вы сможете разобраться во всех тонкостях использования этого модуля. Я же приведу конкретные решения с краткими пояснениями. Для большей части читателей этого объема должно вполне хватать.В проекте каталога ExOl на знакомом нам фоне воспроизводится AVl-файл, взятый мною из набора файлов, поставляемых в составе DirectX SDK (рис. 6.1).
В списке подключаемых модулей добавлен модуль VFW, а в установках проекта - путь к файлу ole2.dcu, в котором нуждается подключаемый модуль.
Следующие переменные связаны со спецификой примера:
var
TmpBmp : TBitmap; // Вспомогательное изображение
AviStream : PAVISTREAM; // AVI-поток
Frame : PGetFrame; // кадр видео
pbmi : PBITMAPINFOHEADER; // Указатель на заголовок растра
bits : Pointer; // Указатель на картинку растра
CurrFrame DWORD - 0; // Счетчик кадров
AVIClock DWORD; // Эмулятор таймера
AVIDelay DWORD; // Величина паузы между кадрами
AVIWidth DWORD; // Характеристики кадра
AVIHeight DWORD;
AVILength DWORD; // Количество кадров в AVI
Перед инициализацией DirectDraw нам необходимо узнать характеристики отображаемого видео, для этого используем функции рассматриваемого модуля, связанные с работой AVI как с файлом:
var
AVIFile : PAVIFile; // Обрабатываем AVI как файл
AVIlnfo : TAVIFilelnfo; // Заголовок файла, характеристики AVI
begin
TmpBmp := TBitmap.Create; // Создаем вспомогательный растр
AVIFileOpen(AVIFile, AVIName, OF_READ, nil); // Открытие AVI
// Считываем заголовочную информацию, заполняются поля AVIlnfo
AVIFilelnfo(AVIFile, AVIlnfo, SizeOf (AVIlnfo));
AVIWidth := AVIInfo.dwWidth; // Запоминаем размеры кадра
AVIHeight := AVIlnfo.dwHeight;
AVILength := AVIlnfo.dwLength; // Количество кадров
// Вычисляем паузу между очередными кадрами
AVIDelay := 1000 div (AVIInfo.dwRate div AVIInfo.dwScale);
AVIFileRelease(AVIFile); // Освобождаем AVI
Поверхность FDDSImage, на которой будет воспроизводиться видео, создается с размерами, равными размерам кадра видео:
ZeroMemory (@ddsd, SizeOf(ddsd));
with ddsd do begin
dwSize := SizeOf(ddsd);
dwFlags := DDSD_CAPS or DDSD_HEIGHT or DDSD_WIDTH;
ddsCaps.dwCaps := DDSCAPS_OFFSCREENPLAIN;
dwWidth := AviWidth;
dwHeight := AVIHeight;
end;
hRet := FDD.CreateSurface(ddsd, FDDSImage, nil);
if Failed(hRet) then ErrorOut(hRet, 'Create Second Surface');
В общем случае заводить отдельную поверхность для воспроизведения кадра, конечно, не обязательно, можно переносить содержимое вспомогательного растра прямо на первичную поверхность.
После инициализации DirectDraw подготавливаемся к работе с потоковым видео: