Создание поверхностей
Остается лишь создать поверхности, используемые в приложении. После вызова
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. Затем он обнаруживает видеорежимы, поддерживаемые инициализированным драйвером, выбирает один из режимов и активизирует его. Далее создается первичная поверхность с возможностью переключения страниц (и вторичным буфером) и, наконец, анализируется формат пикселей для активизированного видеорежима.
Приложение почти готово к работе, но пока у него нет графических данных. Мы подходим к следующему этапу.
Содержание Назад Вперед
Forekc.ru
Рефераты, дипломы, курсовые, выпускные и квалификационные работы, диссертации, учебники, учебные пособия, лекции, методические пособия и рекомендации, программы и курсы обучения, публикации из профильных изданий