Графика для Windows средствами DirectDraw
Шрифт:
Функция ICDecompressGetPalette получает данные палитры и в цикле преобразует их в формат, который мы можем использовать. Полученный массив передается при вызове функции CreatePalette интерфейса DirectDraw. Остается лишь присоединить созданную палитру к первичной поверхности.
Наконец, все готово к отображению кадров видеоролика. Для этого мы подготавливаем и выводим очередной кадр при каждом вызове функции DrawScene
Функция DrawScene с помощью функции AVIStreamRead извлекает очередной кадр из AVI-потока, после чего сохраняет полученные данные в буфере rawdata. Я оставил в ней несколько макросов TRACE, которые пригодились мне при отладке, но надеюсь, что вам они не понадобятся.
Затем мы вызываем функцию ICDecompress и передаем ей логический номер декомпрессора, ранее полученный от функции LoadAvi. Аргументами функции ICDecompress являются два буфера — первый содержит необработанные (сжатые) данные, а второй — восстановленное изображение.
Функция UpdateAviSurface копирует восстановленный кадр на поверхность AVI. Эта функция рассматривается ниже.
Подготовленная поверхность AVI копируется во вторичный буфер функцией BltFast интерфейса DirectDrawSurface. После этого переменная curframe увеличивается или сбрасывается в зависимости от ее значения и количества кадров в ролике. Наконец, функция Flip интерфейса DirectDrawSurface выводит кадр на экран.
Перед тем как рассматривать функцию UpdateAviSurface, я хочу обратить ваше внимание на ее сходство с кодом класса DirectDrawWin, предназначенным для загрузки BMP-файлов на поверхность (см. главу 5). Функция UpdateAviSurface, как и функции загрузки BMP-файлов DirectDrawWin, блокирует поверхность и затем копирует данные в ее память:
После
блокировки поверхности функция UpdateAviSurface в цикле копирует каждую строку пикселей AVI-данных в память поверхности. В формате AVI, как и в формате BMP, изображения хранятся в перевернутом виде, поэтому мы начинаем с последней строки буфера данных и двигаемся к его началу.Все трудное осталось позади, дальше будет легко. Особенно просто реализуется функция RestoreSurfaces:
Вспомните — функция RestoreSurfaces вызывается только при восстановлении потерянных поверхностей, а класс DirectDrawWin автоматически восстанавливает первичную поверхность со вторичным буфером. В программе AviPlay остается лишь восстановить поверхность AVI, а для этого достаточно вызвать функцию Restore интерфейса DirectDrawSurface.
В некоторых программах функция RestoreSurfaces восстанавливала не только область памяти, но и содержимое поверхности. В нашем случае можно ограничиться восстановлением памяти, потому что ее содержимое будет перезаписано следующим кадром. Если вы вдруг засомневаетесь, напомню — вызов функции Restore для поверхности, которая не была потеряна (например, находящейся в системной памяти), не причинит никакого вреда.
В программе AviPlay ввод не играет особой роли. Программа реагирует всего на три клавиши, причем одинаково. Ввод с клавиатуры обрабатывается функцией OnKeyDown: