Чтение онлайн

на главную - закладки

Жанры

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

Трухильо Стэн

Шрифт:

Наконец, функция 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 failed\n");

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.

Указатель на поверхность (surfbits) инициализируется значением поля lpSurface. Этот указатель используется для обращений к памяти поверхности. Указатель на графические данные (imagebits) инициализируется адресом последней строки пикселей BMP-файла, поскольку в формате BMP изображение хранится в перевернутом виде.

Затем мы в цикле перебираем все строки пикселей изображения. Благодаря тому, что формат графических данных BMP-файла совпадает с форматом поверхности, для копирования можно воспользоваться функцией memcopy. Для поверхностей остальных типов такая удобная возможность часто отсутствует. Поле lPitch определяет смещение для указателя на поверхность при переходе к следующей строке. Вспомните, что в этом поле хранится шаг поверхности, который может не совпадать с ее шириной. Целая переменная bytesgiven аналогичным образом используется для перехода к следующей строке буфера графических данных. Поскольку чтение начинается с конца буфера, указатель imagebits уменьшается с каждой очередной итерацией.

Наконец, мы вызываем функцию Unlock интерфейса DirectDrawSurface и в качестве аргумента передаем ей ноль. С помощью этого аргумента можно сбалансировать вызовы Lock и Unlock при многократной блокировке одной поверхности. Для сценариев с однократной блокировкой (включая наш) можно просто передать ноль. 

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

Загрузка 8-битных изображений выполняется достаточно просто. Давайте перейдем к 16-битным поверхностям, с ними дело обстоит значительно сложнее. Помимо учета разных типов 16-битных форматов пикселей нам придется сокращать количество цветов. 24-битные данные передаются на 16-битную поверхность, поэтому во время передачи необходимо «урезать» каждую цветовую составляющую. Функция Copy_Bmp24_Surface16 приведена в листинге 5.2.

Листинг 5.2. Функция Copy_Bmp24_Surface16

BOOL DirectDrawWin::Copy_Bmp24_Surface16(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);

Поделиться:
Популярные книги

Маршал Советского Союза. Трилогия

Ланцов Михаил Алексеевич
Маршал Советского Союза
Фантастика:
альтернативная история
8.37
рейтинг книги
Маршал Советского Союза. Трилогия

Повелитель механического легиона. Том VI

Лисицин Евгений
6. Повелитель механического легиона
Фантастика:
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Повелитель механического легиона. Том VI

Фронтовик

Поселягин Владимир Геннадьевич
3. Красноармеец
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Фронтовик

Кротовский, может, хватит?

Парсиев Дмитрий
3. РОС: Изнанка Империи
Фантастика:
попаданцы
альтернативная история
аниме
7.50
рейтинг книги
Кротовский, может, хватит?

Мама для дракончика или Жена к вылуплению

Максонова Мария
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Мама для дракончика или Жена к вылуплению

Боги, пиво и дурак. Том 4

Горина Юлия Николаевна
4. Боги, пиво и дурак
Фантастика:
фэнтези
героическая фантастика
попаданцы
5.00
рейтинг книги
Боги, пиво и дурак. Том 4

Тайны ордена

Каменистый Артем
6. Девятый
Фантастика:
боевая фантастика
попаданцы
7.48
рейтинг книги
Тайны ордена

Вперед в прошлое 3

Ратманов Денис
3. Вперёд в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 3

Охота на разведенку

Зайцева Мария
Любовные романы:
современные любовные романы
эро литература
6.76
рейтинг книги
Охота на разведенку

Идеальный мир для Лекаря 27

Сапфир Олег
27. Лекарь
Фантастика:
аниме
фэнтези
5.00
рейтинг книги
Идеальный мир для Лекаря 27

Имперский Курьер. Том 4

Бо Вова
4. Запечатанный мир
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Имперский Курьер. Том 4

Газлайтер. Том 17

Володин Григорий Григорьевич
17. История Телепата
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Газлайтер. Том 17

Эволюционер из трущоб. Том 7

Панарин Антон
7. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб. Том 7

Идеальный мир для Лекаря 12

Сапфир Олег
12. Лекарь
Фантастика:
боевая фантастика
юмористическая фантастика
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 12