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

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

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

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

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

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

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

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

 int imagebitdepth=bmpinfohdr.biBitCount;

 int imagesize=bmpinfohdr.biSizeImage;

 if (imagesize==0) imagesize=((imagew*(imagebitdepth/8)+3) & ~3)*imageh;

 if (bmpinfohdr.biCompression!=BI_RGB) {

  TRACE("compressed BMP formatn");

  return 0;

 }

 TRACE("loading '%s': width=%d height=%d depth=%dn", filename, imagew, imageh, imagebitdepth);

 if (imagebitdepth==8) {

  int ncolors;

  if (bmpinfohdr.biClrUsed==0)   ncolors=256;

  else   ncolors=bmpinfohdr.biClrUsed;

  RGBQUAD* quad=new RGBQUAD[ncolors];

  bmp.read((char*)quad, sizeof(RGBQUAD)*ncolors);

  if (installpalette) CreatePalette(quad, ncolors);

  delete[] quad;

 }

 BYTE* buf=new BYTE[imagesize];

 bmp.read(buf, imagesize);

 if (!Copy_Bmp_Surface(surf, &bmpinfohdr, buf)) {

  TRACE("copy failedn");

  delete[] buf;

  surf->Release();

  return 0;

 }

 delete[] buf;

 return surf;

}

Сначала эта функция определяет размеры изображения из BMP-файла с помощью функции GetBmpDimensions() — простой функции класса DirectDrawWin, которая открывает BMP-файл и извлекает из заголовка ширину и высоту изображения. На основании полученных данных создается новая поверхность с использованием версии CreateSurface(), которая создает поверхность по ее размерам. Новая поверхность заполнена случайными пикселями, но мы не стираем ее, потому что вскоре значение каждого пикселя будет задано в соответствии с содержимым BMP-файла.

Затем мы открываем BMP-файл с помощью класса ifstream и извлекаем из него данные заголовка. Далее проверяется сигнатура файла; если проверка дает отрицательный результат, BMP-файл может содержать неверную информацию, поэтому функция завершает работу.

Дополнительные данные заголовка извлекаются с помощью структуры BITMAPINFOHEADER. Обратите внимание: после заполнения структуры текущая позиция в файле ifstream изменяется в соответствии со значением поля biSize. Это сделано для того, чтобы в будущем, при увеличении размера структуры BITMAPINFOHEADER, наша программа нормально работала с новыми BMP-файлами.

Ширина и высота изображения уже известны, поэтому читать значения полей biWidth и biHeight структуры BITMAPINFOHEADER не нужно. Функция CreateSurface() считывает глубину пикселей (biBitCount) и размер изображения (biSizeImage). Как упоминалось выше, поле biSizeImage часто равно нулю, поэтому мы проверяем его значение. Снова приведу соответствующий фрагмент кода:

int imagesize=bmpinfohdr.biSizeImage;

if (imagesize==0) imagesize=((imagew*(imagebitdepth/8)+3) & ~3)*imageh;

Если поле biSizeImage отлично от нуля, мы оставляем текущее значение. В противном случае его приходится вычислять самостоятельно по известному размеру и глубине пикселей изображения. Обратите внимание на то, что выравнивание по границе параграфа выполняется за счет битовых операций.

И последняя проверка: по содержимому поля biCompression мы убеждаемся, что BMP-файл не содержит сжатых данных, не поддерживаемых нами. Для сжатых файлов функция возвращает ноль, код неудачного завершения.

Если изображение является палитровым, мы загружаем палитру. Количество элементов палитры в файле определяется полем biClrUsed, но это поле также может быть равно нулю. В этом случае предполагается, что присутствуют все 256 элементов палитры. Палитра загружается лишь в том случае, если параметр installpalette равен TRUE; тогда вызывается функция CreatePalette(). Вскоре мы рассмотрим код этой функции.

Следующий этап — чтение графических данных, которое в нашем случае выполняется одним вызовом функции ifstream::read(). Графические данные передаются функции Copy_Bmp_Surface(), отвечающей за пересылку данных новой поверхности. После возврата из функции Copy_Bmp_Surface() буфер с графическими данными освобождается. BMP-файл автоматически закрывается при возвращении из функции CreateSurface() (поскольку локальный объект ifstream выходит из области видимости). 

Функция CreatePalette() 

Если второй аргумент функции CreateSurface() равен TRUE, CreatePalette() создает и заполняет объект DirectDrawPalette данными, полученными из BMP-файла. Функция CreatePalette() выглядит так:

BOOL DirectDrawWin::CreatePalette(RGBQUAD* quad, int ncolors){

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

 PALETTEENTRY pe[256];

 ZeroMemory(pe, sizeof(pe));

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

  pe[i].peRed = quad[i].rgbRed;

  pe[i].peGreen = quad[i].rgbGreen;

  pe[i].peBlue = quad[i].rgbBlue;

 }

 HRESULT r=ddraw2->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256, pe, &palette, 0);

 if (r!=DD_OK) {

  TRACE("failed to reate DirectDraw paletten");

  return FALSE;

 }

 primsurf->SetPalette(palette);

 return TRUE;

}

Палитры DirectDraw создаются функцией CreatePalette() интерфейса DirectDraw, которой передается массив структур PALETTEENTRY. Чтобы выполнить это требование, приходится преобразовывать массив структур RGBQUAD, извлеченный из BMP-файла, во временный массив (структуры PALETTEENTRY и RGBQUAD очень похожи, поэтому такое преобразование оказывается тривиальным). Затем созданный массив передается функции CreatePalette(). Флаг DDPCAPS_ALLOW256 сообщает, что мы намерены задать значения всех 256 элементов палитры. Если вы пропустили главу 4 (конечно же, нет!), вернитесь к ней и ознакомьтесь с возможными аспектами использования этого флага.

Наконец, функция SetPalette() интерфейса DirectDrawSurface() присоединяет палитру к поверхности. Обратите внимание на то, что палитра присоединяется к первичной поверхности. Хотя палитры можно присоединять и к другим поверхностям, на системную палитру влияет только палитра, присоединенная к первичной поверхности. 

Передача графических данных 

Как видно из функции CreateSurface(), передача графических данных BMP-файла на поверхность осуществляется функцией Copy_Bmp_Surface(). Функция Copy_Bmp_Surface() пользуется услугами четырех вспомогательных функций, каждая из которых специализируется на пикселях определенной глубины. Код Copy_Bmp_Surface() выглядит так:

BOOL DirectDrawWin::Copy_Bmp_Surface(LPDIRECTDRAWSURFACE surf, BITMAPINFOHEADER* bmphdr, BYTE* buf) {

 if (surf==0 || bmphdr==0 || buf==0) return FALSE;

 int imagew=bmphdr->biWidth;

 int imageh=bmphdr->biHeight;

 int imagebitdepth=bmphdr->biBitCount;

 BOOL ret=FALSE;

 if (imagebitdepth==8) {

  if (displaydepth==8) ret=Copy_Bmp08_Surface08(surf, buf, imagew, imageh);

 } else if (imagebitdepth==24) {

  if (displaydepth==16) ret=Copy_Bmp24_Surface16(surf, buf, imagew, imageh);

  else if (displaydepth==24) ret=Copy_Bmp24_Surface24(surf, buf, imagew, imageh);

   else if (displaydepth==32) ret=Copy_Bmp24_Surface32(surf, buf, imagew, imageh);

 }

 return ret;

}

Вспомогательные функции предназначены для передачи графических данных в зависимости от глубины пикселей BMP-файла и текущего видеорежима. Все четыре функции получают одни и те же четыре аргумента: указатель на поверхность-приемник, буфер с графическими данными из BMP-файла, ширину и высоту изображения. Каждая функция копирует графические данные BMP-файла на поверхность-приемник. 

8-битные поверхности

Начнем с самой простой из четырех функций, Copy_Bmp08_Surface08(). Она выглядит так:

BOOL DirectDrawWin::Copy_Bmp08_Surface08(LPDIRECTDRAWSURFACE surf,      BYTE* bmpbuf, int w, int h) {

 if (surf==0 || bmpbuf==0) return FALSE;

 DDSURFACEDESC desc;

 ZeroMemory(&desc, sizeof(desc));

 desc.dwSize = sizeof(desc);

 HRESULT r=surf->Lock(0, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY, 0);

 if (r!=DD_OK) {

  TRACE("ShowBmp: Lock() failedn");

  return FALSE;

 }

 int bytesgiven=(w+3) & ~3;

 BYTE* surfbits = (BYTE*)desc.lpSurface;

 BYTE* imagebits = (BYTE*)(&bmpbuf[(h-1)*bytesgiven]);

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

  memcpy(surfbits, imagebits, w);

  surfbits += desc.lPitch;

  imagebits -= bytesgiven;

 }

 surf->Unlock(0);

 return TRUE;

}

После проверки обоих аргументов-указателей мы подготавливаем экземпляр структуры DDSURFACEDESC(desc) и используем его при вызове функции Lock() интерфейса DirectDrawSurface. После возвращения из функции Lock() поле lpSurface содержит указатель на память поверхности, и мы можем спокойно изменять содержимое поверхности через этот указатель до вызова Unlock(). Безопасная работа с поверхностью стала возможной только потому, что мы указали флаг DDLOCK_WRITEONLY. Если вы собираетесь осуществлять и чтение, и запись, не устанавливайте этот флаг.

Далее мы инициализируем целую переменную bytesgiven. Присваиваемое значение определяется шириной изображения (w), выровненного по границе параграфа. Получившаяся величина равна объему памяти, необходимой для хранения одной строки пикселей. Если ширина изображения кратна четырем, переменная bytesgiven совпадает с w.


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

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


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

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

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