на главную | войти | регистрация | DMCA | контакты | справка | donate |      

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Э Ю Я


моя полка | жанры | рекомендуем | рейтинг книг | рейтинг авторов | впечатления | новое | форум | сборники | читалки | авторам | добавить



Создание поверхностей

Остается лишь создать поверхности, используемые в приложении. После вызова SetDisplayMode() функция ActivateDisplayMode() вызывает еще три функции: CreateFlippingSurfaces(), StorePixelFormatData() и CreateCustomSurfaces(). Функция CreateFlippingSurfaces() создает первичную поверхность с возможностью переключения страниц. Функция StorePixelFormatData() используется для чтения и записи сведений о формате пикселей в данном видеорежиме. Эта информация может пригодиться при работе с видеорежимами High и True Color. Функция CreateCustomSurfaces() отвечает за создание и инициализацию вспомогательных поверхностей, специфических для данного приложения. Начнем с функции CreateFlippingSurfaces():

BOOL DirectDrawWin::CreateFlippingSurfaces() {

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

 DDSURFACEDESC desc;

 ZeroMemory(&desc, sizeof(desc));

 desc.dwSize = sizeof(desc);

 desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;

 desc.ddsCaps.dwCaps =  DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;

 desc.dwBackBufferCount = 1;

 HRESULT r=ddraw2->CreateSurface(&desc, &primsurf, 0);

 if (r!=DD_OK) return FALSE;

 DDSCAPS surfcaps;

 surfcaps.dwCaps = DDSCAPS_BACKBUFFER;

 r=primsurf->GetAttachedSurface(&surfcaps, &backsurf);

 if (r!=DD_OK) return FALSE;

 return TRUE;

}

Функция CreateFlippingSurfaces() вызывается при каждой инициализации нового видеорежима, поэтому ее работа начинается с освобождения ранее созданных поверхностей функцией Release(). Затем она объявляет и инициализирует экземпляр структуры DDSURFACEDESC. Эта структура описывает тип создаваемой поверхности. В соответствии с требованиями DirectDraw необходимо установить флаги для всех инициализируемых полей. В нашем случае флаги DDSD_CAPS и DDSD_BACKBUFFERCOUNT говорят о том, что мы задаем возможности поверхности (поле dwCaps) и количество вторичных буферов (поле dwBackCount). В поле dwCaps устанавливаются три флага:

• DDSCAPS_PRIMARYSURFACE

• DDSCAPS_FLIP

DDSCAPS_COMPLEX

Флаг DDSCAPS_PRIMARYSURFACE означает, что создаваемая поверхность должна находиться в видеопамяти, а ее размеры определяются в соответствии с текущим видеорежимом. Поскольку размеры первичной поверхности зависят от видеорежима, она должна создаваться после его активизации.

Флаг DDSCAPS_FLIP сообщает DirectDraw о том, что мы собираемся выполнять переключение страниц. Переключаемые поверхности должны иметь хотя бы один вторичный буфер, так что по этому флагу DirectDraw узнает о необходимости создания вторичных буферов.

Флаг DDSCAPS_COMPLEX используется всегда, когда происходит присоединение поверхностей. В нашем случае первичная поверхность должна быть присоединена к поверхности вторичного буфера. Затем мы присваиваем полю dwBackBufferCount значение 1, показывая, что к создаваемой первичной поверхности должен быть присоединен один вторичный буфер.

Новая поверхность создается вызовом функции CreateSurface() интерфейса DirectDraw. Первым аргументом является указатель на структуру desc, а вторым - указатель на переменную DirectDrawWin::primsurf. Эта переменная объявлена защищенной (protected), поэтому мы можем использовать ее для доступа к первичной поверхности в своих программах. Третий аргумент функции CreateSurface() должен быть равен 0.

Вызов CreateSurface() создает две поверхности: первичную поверхность и вторичный буфер. Позднее указатель на вторичный буфер понадобится нам для подготовки кадров. Чтобы получить этот указатель, следует вызвать функцию GetAttachedSurface() интерфейса DirectDrawSurface и передать ей структуру DDSCAPS с описанием типа интересующей нас присоединенной поверхности. Задавая флаг DDSCAPS_BACKBUFFER, мы вызываем функцию GetAttachedSurface(), которая инициализирует переменную backsurf. Она, как и переменная primsurf, объявлена защищенной, поэтому классы, производные от DirectDrawWin, могут легко обратиться к вторичному буферу.

После того как указатели primsurf и backsurf будут инициализированы, ActivateDisplayMode() вызывает функцию StorePixelFormatData(). Эта функция с помощью функции GetPixelFormat() интерфейса DirectDrawSurface получает информацию о формате хранения цветовых RGB-составляющих для отдельных пикселей. Формат пикселей зависит от видеокарты, а иногда даже от видеорежима, так что эти сведения оказываются полезными при прямых манипуляциях с поверхностями. Функция StorePixelFormatdata() выглядит так:

BOOL DirectDrawWin::StorePixelFormatData() {

 DDPIXELFORMAT format;

 ZeroMemory(&format, sizeof(format));

 format.dwSize=sizeof(format);

 if (backsurf->GetPixelFormat(&format)!=DD_OK)  {

  return FALSE;

 }

 loREDbit = LowBitPos(format.dwRBitMask);

 WORD hiREDbit = HighBitPos(format.dwRBitMask);

 numREDbits=(WORD)(hiREDbit-loREDbit+1);

 loGREENbit = LowBitPos(format.dwGBitMask);

 WORD hiGREENbit = HighBitPos(format.dwGBitMask);

 numGREENbits=(WORD)(hiGREENbit-loGREENbit+1);

 loBLUEbit = LowBitPos(format.dwBBitMask);

 WORD hiBLUEbit = HighBitPos(format.dwBBitMask);

 numBLUEbits=(WORD)(hiBLUEbit-loBLUEbit+1);

 return TRUE;

}

Структура DDPIXELFORMAT используется в функции GetPixelFormat() для получения масок, показывающих, какие биты в каждом пикселе заняты красной, зеленой и синей цветовыми составляющими. Маски точно описывают формат пикселя, но на практике работать с ними оказывается не очень удобно. Вместо того чтобы просто сохранить полученные маски, мы на основании каждой из них инициализируем два целых числа. Первое число равно позиции младшего бита цветовой составляющей, а второе — количеству бит, необходимых для ее представления. Для поверхностей True color (24- и 32-битных) цветовые составляющие всегда представляются 8 битами, но для поверхностей High color (16-битных) это число изменяется (обычно 5, но иногда 6 для зеленой составляющей).

Класс DirectDrawWin содержит шесть переменных для описания формата пикселей: loREDbit, numREDbits, loGREENbit, numGREENbits, loBLUEbit и numBLUEbits. Они используются некоторыми функциями DirectDrawWin, однако эти переменные объявлены как защищенные (protected), поэтому к ним можно обращаться и из классов, производных от DirectDrawWin. Эти переменные будут рассмотрены в главе 5.

На этом инициализация приложения подходит к концу. Функция ActivateDisplayMode() вызывает еще одну функцию, CreateCustomSurfaces(), которая создает вспомогательные поверхности, но к этому моменту инициализация DirectDraw уже завершена. Функция CreateCustomSurfaces() будет рассмотрена в следующем разделе.

Но сначала давайте подведем итоги. Приложение состоит из двух объектов, BounceWin и BounceApp. Объект BounceApp отвечает за создание объекта BounceWin, а BounceWin в свою очередь инициализирует DirectDraw. Сначала он обнаруживает все имеющиеся драйверы DirectDraw, выбирает один из них и использует его для создания экземпляра интерфейса DirectDraw2. Затем он обнаруживает видеорежимы, поддерживаемые инициализированным драйвером, выбирает один из режимов и активизирует его. Далее создается первичная поверхность с возможностью переключения страниц (и вторичным буфером) и, наконец, анализируется формат пикселей для активизированного видеорежима.

Приложение почти готово к работе, но пока у него нет графических данных. Мы подходим к следующему этапу.


Активизация видеорежима | Графика для Windows средствами DirectDraw | Подготовка поверхностей