Графика DirectX в Delphi
Шрифт:
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 подготавливаемся к работе с потоковым видео:
procedure TfrmDD.FirstFrame;
var
wrkDC : HDC;
begin
AVIFilelnit; // Инициализация библиотеки
// Открываем AVI-файл для чтения
AVIStreamOpenFromFile(AviStream, AviName, streamtypeVIDEO,
0, OF_READ, nil);
// Загружаем поток
Frame := AVIStreamGetFrameOpen(AviStream, nil);
// Получаем первый кадр видео
pbmi := AVIStreamGetFrame(Frame, CurrFrame);
// Получаем указатель на картинку кадра