Стэн Трухильо - Графика для Windows средствами DirectDraw
- Название:Графика для Windows средствами DirectDraw
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стэн Трухильо - Графика для Windows средствами DirectDraw краткое содержание
Графика для Windows средствами DirectDraw - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
break;
}
}
r=ICDecompress(decomp, 0, srcfmt, rawdata, dstfmt, finaldata);
UpdateAviSurface();
backsurf->BltFast(x, y, avisurf, 0, DDBLTFAST_WAIT);
curframe=(curframe
primsurf->Flip(0, DDFLIP_WAIT);
}
Функция DrawScene()с помощью функции AVIStreamRead()извлекает очередной кадр из AVI-потока, после чего сохраняет полученные данные в буфере rawdata. Я оставил в ней несколько макросов TRACE(), которые пригодились мне при отладке, но надеюсь, что вам они не понадобятся.
Затем мы вызываем функцию ICDecompress()и передаем ей логический номер декомпрессора, ранее полученный от функции LoadAvi(). Аргументами функции ICDecompress()являются два буфера — первый содержит необработанные (сжатые) данные, а второй — восстановленное изображение.
Функция UpdateAviSurface()копирует восстановленный кадр на поверхность AVI. Эта функция рассматривается ниже.
Подготовленная поверхность AVI копируется во вторичный буфер функцией BltFast()интерфейса DirectDrawSurface. После этого переменная curframeувеличивается или сбрасывается в зависимости от ее значения и количества кадров в ролике. Наконец, функция Flip()интерфейса DirectDrawSurfaceвыводит кадр на экран.
Перед тем как рассматривать функцию UpdateAviSurface(), я хочу обратить ваше внимание на ее сходство с кодом класса DirectDrawWin, предназначенным для загрузки BMP-файлов на поверхность (см. главу 5). Функция UpdateAviSurface(), как и функции загрузки BMP-файлов DirectDrawWin, блокирует поверхность и затем копирует данные в ее память:
BOOL AviPlayWin::UpdateAviSurface() {
HRESULT r;
if (finaldata==0) return FALSE;
DWORD dwWidth = (srcfmt->biWidth+3) & ~3;
DWORD dwHeight = srcfmt->biHeight;
DDSURFACEDESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.dwSize = sizeof(desc);
r = avisurf->Lock(0, &desc, DDLOCK_WAIT, 0);
if (r==DD_OK) {
BYTE* src = finaldata + dwWidth * (dwHeight-1);
BYTE* dst = (BYTE *)desc.lpSurface;
for (DWORD y=0; y
memcpy(dst, src, dwWidth);
dst += desc.lPitch;
src -= dwWidth;
}
avisurf->Unlock(0);
}
return TRUE;
}
После блокировки поверхности функция UpdateAviSurface()в цикле копирует каждую строку пикселей AVI-данных в память поверхности. В формате AVI, как и в формате BMP, изображения хранятся в перевернутом виде, поэтому мы начинаем с последней строки буфера данных и двигаемся к его началу.
Все трудное осталось позади, дальше будет легко. Особенно просто реализуется функция RestoreSurfaces():
void AviPlayWin::RestoreSurfaces() {
avisurf->Restore();
}
Вспомните — функция RestoreSurfaces()вызывается только при восстановлении потерянных поверхностей, а класс DirectDrawWinавтоматически восстанавливает первичную поверхность со вторичным буфером. В программе AviPlay остается лишь восстановить поверхность AVI, а для этого достаточно вызвать функцию Restore()интерфейса DirectDrawSurface.
В некоторых программах функция RestoreSurfaces()восстанавливала не только область памяти, но и содержимое поверхности. В нашем случае можно ограничиться восстановлением памяти, потому что ее содержимое будет перезаписано следующим кадром. Если вы вдруг засомневаетесь, напомню — вызов функции Restore()для поверхности, которая не была потеряна (например, находящейся в системной памяти), не причинит никакого вреда.
В программе AviPlay ввод не играет особой роли. Программа реагирует всего на три клавиши, причем одинаково. Ввод с клавиатуры обрабатывается функцией OnKeyDown():
void AviPlayWin::OnKeyDown(UINT key, UINT nRepCnt, UINT nFlags) {
switch (key) {
case VK_ESCAPE:
case VK_SPACE:
case VK_RETURN:
ShowDialog();
break;
}
DirectDrawWin::OnKeyDown(key, nRepCnt, nFlags);
}
Все три клавиши вызывают функцию ShowDialog(). Аналогично обрабатывается и ввод от мыши, это происходит в функции OnRButtonDown():
void AviPlayWin::OnRButtonDown(UINT nFlags, CPoint point) {
ShowDialog();
DirectDrawWin::OnRButtonDown(nFlags, point);
}
Когда пользователь закрывает диалоговое окно для выбора AVI-файла, функция ShowDialog()посылает сообщение WM_CLOSE, сигнализируя о завершении приложения.
Остается лишь завершить приложение. Функция OnDestroy()занимается «уборкой мусора» — она закрывает открытые AVI-потоки, освобождает декомпрессор и буферы данных AVI:
void AviPlayWin::OnDestroy() {
DirectDrawWin::OnDestroy();
if (avistream) AVIStreamRelease(avistream), avistream=0;
if (decomp) ICClose(decomp), decomp=0;
if (srcfmt) delete [] srcfmt, srcfmt=0;
if (dstfmt) delete [] dstfmt, dstfmt=0;
if (rawdata) {
TRACE("delete [] rawdata...\n");
delete [] rawdata, rawdata=0;
}
if (finaldata) {
TRACE("delete [] finaldata...\n");
delete [] finaldata, finaldata=0;
}
if (avidialog) delete avidialog, avidialog=0;
AVIFileExit();
}
Обратите внимание на вызов функции AviFileExit()в конце OnDestroy(). Это завершает работу VFW и освобождает все используемые им ресурсы.
Наше знакомство с воспроизведением видеороликов подходит к концу. Честно говоря, чтобы превратить программу AviPlay в полноценный проигрыватель AVI-файлов, вам придется еще немало потрудиться. Необходимо организовать поддержку звука и хронометраж, не говоря уже о том, что VFW обладает многими странностями и в работе с ним приходится много экспериментировать.
И последнее замечание. По неизвестным мне причинам VFW отказывается работать с AVI-файлами, сжатыми кодеками IR32 и IR42 (возможно, есть и другие, но я заметил эти два). С другой стороны, AVI-файлы, использующие кодеки MS-CRAM и Cinepak, работают нормально.
В главе 9 мы возьмемся за проверку столкновений. Наша цель — написать код, который бы обеспечивал точность проверки на уровне пикселей при максимальной эффективности.
Глава 9. Проверка столкновений
Спрайты, переключение страниц, палитры, поверхности — это просто замечательно, и в предыдущих главах мы узнали немало полезного. Но поместить спрайты на экран и передвигать их туда-сюда — это еще не все. В большинстве приложений изображения, геометрические фигуры и символы на экране должны взаимодействовать с пользователем и друг с другом. В главе 6 при изучении DirectInput было описано взаимодействие спрайтов с пользователем. В этой главе мы узнаем, как спрайты взаимодействуют друг с другом.
Проверка столкновений (или проверка соударений) — широкий термин, описывающий алгоритмы для обнаружения столкновений между объектами. Термин относится как к плоским, так и к трехмерным объектам, но в этой книге нас интересуют только плоские объекты.
Читать дальшеИнтервал:
Закладка: