My-library.info
Все категории

Стэн Трухильо - Графика для Windows средствами DirectDraw

На электронном книжном портале my-library.info можно читать бесплатно книги онлайн без регистрации, в том числе Стэн Трухильо - Графика для Windows средствами DirectDraw. Жанр: Программирование издательство неизвестно, год 2004. В онлайн доступе вы получите полную версию книги с кратким содержанием для ознакомления, сможете читать аннотацию к книге (предисловие), увидеть рецензии тех, кто произведение уже прочитал и их экспертное мнение о прочитанном.
Кроме того, в библиотеке онлайн my-library.info вы найдете много новинок, которые заслуживают вашего внимания.

Название:
Графика для Windows средствами DirectDraw
Издательство:
неизвестно
ISBN:
нет данных
Год:
неизвестен
Дата добавления:
17 сентябрь 2019
Количество просмотров:
153
Читать онлайн
Стэн Трухильо - Графика для Windows средствами DirectDraw

Стэн Трухильо - Графика для Windows средствами DirectDraw краткое содержание

Стэн Трухильо - Графика для Windows средствами DirectDraw - описание и краткое содержание, автор Стэн Трухильо, читайте бесплатно онлайн на сайте электронной библиотеки My-Library.Info

Графика для Windows средствами DirectDraw читать онлайн бесплатно

Графика для Windows средствами DirectDraw - читать книгу онлайн бесплатно, автор Стэн Трухильо

 r=AVIStreamFormatSize(avistream, 0, &fmtlen);

 TRACE("AVIStreamFormatSize: %sn", r==0 ? "OK" : "failed");

 int formatsize=fmtlen+sizeof(RGBQUAD)*256;

 if (srcfmt)   delete [] srcfmt;

 srcfmt = (LPBITMAPINFOHEADER)new BYTE[formatsize];

 ZeroMemory(srcfmt, formatsize);

 if (dstfmt)   delete [] dstfmt;

 dstfmt = (LPBITMAPINFOHEADER)new BYTE[formatsize];

 ZeroMemory(dstfmt, formatsize);

 r=AVIStreamReadFormat(avistream, 0, srcfmt, &fmtlen);

 TRACE("AVIStreamReadFormat: %sn", r==0 ? "OK" : "failed");

 TRACE(" --- %s ---n", filename);

 TRACE(" biSize: %dn", srcfmt->biSize);

 TRACE(" biWidth x biHeight: %dx%dn", srcfmt->biWidth, srcfmt->biHeight);

 if (srcfmt->biPlanes != 1) TRACE(" - biPlanes: %dn", srcfmt->biPlanes);

 TRACE(" biBitCount: %dn", srcfmt->biBitCount);

 CString comp;

 switch (srcfmt->biCompression) {

 case BI_RGB:

  comp="BI_RGB";

  break;

 case BI_RLE8:

  comp="BI_RLE8";

  break;

 case BI_RLE4:

  comp="BI_RLE4";

  break;

 case BI_BITFIELDS:

  comp="BI_BITFIELDS";

  break;

 }

 TRACE(" biCompression: %sn", comp);

 TRACE(" biSizeImage: %dn", srcfmt->biSizeImage);

 TRACE(" ------------------n");

 memcpy(dstfmt, srcfmt, fmtlen);

 dstfmt->biBitCount = 8;

 dtfmt->biCompression = BI_RGB;

 dstfmt->biSizeImage = dstfmt->biWidth * dstfmt->biHeight;

 startframe = AVIStreamStart(avistream);

 TRACE("stream start: %dn", startframe);

 endframe = AVIStreamEnd(avistream);

 TRACE("stream end: %dn", endframe);

 r=AVIStreamInfo(avistream, &streaminfo, sizeof(streaminfo));

 TRACE("AVIStreamInfo: %sn", r==0 ? "OK" : "failed" );

 buflen = dstfmt->biSizeImage;

 int finalbuflen=((dstfmt->biWidth+3) & ~3) * dstfmt->biHeight;

 if (streaminfo.dwSuggestedBufferSize) if ((LONG)streaminfo.dwSuggestedBufferSize < buflen) {

  TRACE("adjusting buflen to suggested sizen");

  buflen = (LONG)streaminfo.dwSuggestedBufferSize;

 }

 if (decomp) ICClose(decomp);

 decomp = ICDecompressOpen(ICTYPE_VIDEO, streaminfo.fccHandler, srcfmt, dstfmt);

 TRACE("ICDecompressOpen: %sn", decomp ? "OK" : "failed");

 if (rawdata) {

  TRACE("delete [] rawdata...n");

  delete [] rawdata;

 }

 rawdata = new BYTE[buflen];

 if (finaldata) {

  TRACE("delete [] finaldata...n");

  delete [] finaldata;

 }

 finaldata = new BYTE[finalbuflen];

 return TRUE;

}

В функции LoadAvi() используются функции VFW. Сначала LoadAvi() закрывает открытый ранее AVI-поток функцией AVIStreamRelease(), а затем открывает новый поток функцией AVIStreamOpenFromFile(), которой в числе прочих аргументов передается имя открываемого AVI-файла.

Обратите внимание — третьим аргументом функции AVIStreamOpenFromFile() является флаг, определяющий тип открываемого потока. В нашем случае использован флаг видеопотока streamtypeVIDEO, но с помощью трех оставшихся флагов (streamtypeAUDIO, streamtypeMIDI и streamtypeTEXT) можно открывать и потоки других типов.

Затем мы получаем данные о формате потока функцией AVIStreamReadFormat() (пользуясь при этом функцией AVIStreamFormatSize()). Я специально оставил в этом фрагменте отладочные макросы TRACE(), чтобы продемонстрировать, какую информацию можно получить об AVI-файле.

На этой стадии инициализируются некоторые важные переменные класса. Например, мы присваиваем значения переменным startframe и endframe, чтобы во время извлечения кадров были известны допустимые значения их индексов.

Затем мы получаем доступ к декомпрессору. Функция ICDecompressorOpen() по структуре, описывающей AVI-файл и желательный формат вывода, возвращает логический номер модуля декомпрессии. Позднее этот модуль используется для восстановления кадров. Наконец, мы выделяем память под два буфера: в одном хранятся необработанные (сжатые) данные, извлеченные из AVI-потока, а в другом — итоговый (восстановленный) кадр.

Функция CreateAviSurface() 

Теперь у нашего приложения есть открытый AVI-поток и информация в объеме, достаточном для извлечения кадров. Но что же делать с кадром после того, как он будет прочитан и восстановлен? Нам понадобится поверхность для хранения полученных данных, и тогда воспроизведение видеоролика сведется к простому блиттингу содержимого этой поверхности во вторичный буфер приложения с последующим переключением страниц. Эта промежуточная поверхность создается функцией CreateAviSurface():

BOOL AviPlayWin::CreateAviSurface() {

 if (avisurf) avisurf->Release(), avisurf=0;

 avisurf=CreateSurface(srcfmt->biWidth, srcfmt->biHeight);

 CRect displayrect=GetDisplayRect();

 x=(displayrect.Width()-srcfmt->biWidth)/2;

 y=0;

 return TRUE;

}

После освобождения поверхности, созданной ранее, функция CreateAviSurface() с помощью функции CreateSurface() интерфейса DirectDraw создает поверхность, размеры которой совпадают с размерами кадра. Кроме того, функция CreateAviSurface() инициализирует переменные x и y, определяющие положение поверхности AVI на вторичном буфере. В нашем случае кадры будут выравниваться по центру экрана, поэтому в вычислениях применяется функция DirectDrawWin::GetDisplayRect() для определения размеров экрана.

Функция InstallPalette() 

С помощью файлового формата AVI и VFW API можно получить палитру, оптимально подходящую для просмотра видеоролика. Функция InstallPalette() извлекает необходимые данные и использует их для конструирования палитры DirectDraw. Функция InstallPalette() выглядит так:

BOOL AviPlayWin::InstallPalette() {

 ICDecompressGetPalette(decomp, srcfmt, dstfmt);

 PALETTEENTRY pe[256];

 LPBITMAPINFO info=(LPBITMAPINFO)dstfmt;

 for (int i=0; i<256; i++) {

  pe[i].peRed = info->bmiColors[i].rgbRed;

  pe[i].peGreen = info->bmiColors[i].rgbGreen;

  pe[i].peBlue = info->bmiColors[i].rgbBlue;

  pe[i].peFlags = 0;

 }

 if (avipal) avipal->Release();

 ddraw2->CreatePalette(DDPCAPS_8BIT, pe, &avipal, 0);

 primsurf->SetPalette(avipal);

 return TRUE;

}

Функция ICDecompressGetPalette() получает данные палитры и в цикле преобразует их в формат, который мы можем использовать. Полученный массив передается при вызове функции CreatePalette() интерфейса DirectDraw. Остается лишь присоединить созданную палитру к первичной поверхности.

Функция DrawScene() 

Наконец, все готово к отображению кадров видеоролика. Для этого мы подготавливаем и выводим очередной кадр при каждом вызове функции DrawScene() классом DirectDrawWin. Функция DrawScene() выглядит так:

void AviPlayWin::DrawScene() {

 long r;

 r=AVIStreamRead(avistream, curframe, 1, rawdata, buflen, 0, 0);

 if (r) {

  TRACE("AVIStreamRead failed: ");

  switch (r)  {

  case AVIERR_BUFFERTOOSMALL:

   TRACE("BUFFERTOOSMALLn");

   break;

  case AVIERR_MEMORY:

   TRACE("MEMORYn");

   break;

  case AVIERR_FILEREAD:

   TRACE("FILEREADn");

   break;

  }

 }

 r=ICDecompress(decomp, 0, srcfmt, rawdata, dstfmt, finaldata);

 UpdateAviSurface();

 backsurf->BltFast(x, y, avisurf, 0, DDBLTFAST_WAIT);

 curframe=(curframe<endframe) ? curframe+1 : startframe;

 primsurf->Flip(0, DDFLIP_WAIT);

}

Функция DrawScene() с помощью функции AVIStreamRead() извлекает очередной кадр из AVI-потока, после чего сохраняет полученные данные в буфере rawdata. Я оставил в ней несколько макросов TRACE(), которые пригодились мне при отладке, но надеюсь, что вам они не понадобятся.

Затем мы вызываем функцию ICDecompress() и передаем ей логический номер декомпрессора, ранее полученный от функции LoadAvi(). Аргументами функции ICDecompress() являются два буфера — первый содержит необработанные (сжатые) данные, а второй — восстановленное изображение.

Функция UpdateAviSurface() копирует восстановленный кадр на поверхность AVI. Эта функция рассматривается ниже.

Подготовленная поверхность AVI копируется во вторичный буфер функцией BltFast() интерфейса DirectDrawSurface. После этого переменная curframe увеличивается или сбрасывается в зависимости от ее значения и количества кадров в ролике. Наконец, функция Flip() интерфейса DirectDrawSurface выводит кадр на экран.

Функция UpdateAviSurface()

Перед тем как рассматривать функцию 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) {


Стэн Трухильо читать все книги автора по порядку

Стэн Трухильо - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки My-Library.Info.


Графика для Windows средствами DirectDraw отзывы

Отзывы читателей о книге Графика для Windows средствами DirectDraw, автор: Стэн Трухильо. Читайте комментарии и мнения людей о произведении.

Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*
Все материалы на сайте размещаются его пользователями.
Администратор сайта не несёт ответственности за действия пользователей сайта..
Вы можете направить вашу жалобу на почту librarybook.ru@gmail.com или заполнить форму обратной связи.