Инициализация объектов

<Уголок DirectX> <Предыдущая часть> <Следующая часть>


После создания окна приложения, первым объектом, который мы создадим будет объект Direct Draw. Да-да, без DirectDraw нам не обойтись, поэтому если Вы еще не изучали, что это такое, обратитесь лучше сначала к соответствующей статье Уголка DirectX. Объект DirectDraw понадобится для установки уровня приоритета приложения (cooperative level), а также он будет использован для создания буферов: главной поверхности и заднего буфера, на который будет происходить рендеринг.

Эти определения поместите в раздел Declarations:

Dim g_dx As New DirectX7
Dim g_dd As DirectDraw7
Dim g_ddsPrimary As DirectDrawSurface7
Dim g_ddsBackBuffer As DirectDrawSurface7
Dim g_ddsd As DDSURFACEDESC2
Dim pcClipper As DirectDrawClipper
Dim g_rcSrc as RECT
Dim g_rcDest
as RECT

Итак, создадим объект DirectDraw, как показано далее:

Private Sub InitDDraw()
' Создать объект DirectDraw и установить уровень отношений
' приложения с другими.

Set g_dd = g_dx.DirectDrawCreate("")

Эта строка кода создает объект DirectDraw путем вызова глобальной функции DirectDrawCreate. В качестве параметра эта функция содержит пустую строку, что означает, что создается объект DirectDraw для активного драйвера дисплея. Для оборудования, не поддерживающего GDI, например 3D ускорителей, работающих с отдельной 2D картой, необходимо точно указать глобальный уникальный идентификатор (GUID) желаемого драйвера, то есть указать, какой драйвер устройства вы хотите использовать.

Приложение Triangle устанавливает уровень совместного использования ресурсов с помощью метода DirectDraw7.SetCooperativeLevel. Так мы скажем системе о том, в каком режиме мы хотим работать - в полноэкранном или оконном. (Учтите, что некоторое оборудование не может работать в оконном режиме. Вы можете обнаружить такое оборудование через отсутсвие флага DDCAP2_CANRENDERWINDOWED при вызове DirectDraw7.GetCaps). Режим, который уже установлен перед вызовом функции также называется "нормальным". Вы можете указать его через флаг DDSCL_NORMAL, передаваемый в SetCooperativeLevel. Однако этот метод может дать сбой, если уже запущено приложение работающее в полнооконном эксклюзивном режиме.

g_dd.SetCooperativeLevel Me.hWnd, DDSCL_NORMAL

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

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

' Подготовить и создать главную поверхность
g_ddsd.lFlags = DDSD_CAPS
g_ddsd.ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE
Set g_ddsPrimary = g_dd.CreateSurface(g_ddsd)

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

' Теперь, создаем буфер для рендеринга. Мы повторно используем здесь g_ddsd
g_ddsd.lFlags = DDSD_HEIGHT Or DDSD_WIDTH Or DDSD_CAPS
g_ddsd.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN Or DDSCAPS_3DDEVICE
'Используем размер формы для установки размера буфера
g_dx.GetWindowRect Me.hWnd, g_rcDest
'Установить размерность описания поверхности
g_ddsd.lWidth = g_rcDest.Right - g_rcDest.Left
g_ddsd.lHeight = g_rcDest.Bottom - g_rcDest.Top
'Создать поверхность для рендеринга
Set g_ddsBackBuffer = g_dd.CreateSurface(g_ddsd)
'Кэшировать размеры цели рендеринга. Мы будем использовать это для
' операции блиттинга

With g_rcSrc
.Left = 0
.Top = 0
.Bottom = g_ddsd.lHeight
.Right = g_ddsd.lWidth
End With

Предыдущий код создает внеэкранную поверхность, эквивалентную по размерам окну приложения. Как показано в этом коде, вы должны включить возможность DDSCAPS_3DDEVICE для любой поверхности, которая будет использована, как целевая для рендеринга. Эта возможность дает указание системе выделить дополнительные внутренние структуры данных для 3D рендеринга.

После создания главной поверхности и поверхности для рендеринга, вы можете создать и прикрепить объект DirectDrawClipper к главной поверхности. Использование этого объекта определяет экранные границы, освобождая вас от обработки случаев, когда окно приложения частично закрыто другим окном или окно частично находится за пределами экрана. Таким образом, клипперы не являются необходимыми для полноэкранных приложений. Следующий код создает клиппер и прикрепляет его к главной поверхности:

' Создать DirectDrawClipper и прикрепить его к главной поверхности
Set pcClipper = g_dd.CreateClipper(0)
pcClipper.SetHWnd Me.hWnd
g_ddsPrimary.SetClipper pcClipper
End Sub

Создав все объекты DirectDraw вы можете приступать к созданию объектов Direct3D, которые понадобятся для рендеринга сцены.

Эти определения, относящиеся к объектам D3D, поместите в раздел Declarations

Dim d3d As Direct3D7
Dim g_d3dDevice As Direct3DDevice7
Dim VPDesc As D3DVIEWPORT7
Dim g_d3drcViewport(0 To 0) As D3DRECT
Dim ddsd As DDSURFACEDESC2

Создадим объект Direct3D:

Sub InitD3D()
' Получить ссылку на класс Direct3D7 из
' объекта DirectDraw7

Set d3d = g_dd.GetDirect3D

После создания объекта Direct3D7 вы должны создать устройство рендеринга, используя метод Direct3D7.CreateDevice. Этот метод подтверждает глобальный уникальный идентификатор (GUID) желаемого устройства и объект DirectDrawSurface7 (в нашем случае g_ddsBackBuffer), на который будет происходить рендеринг. Эта поверхность должна быть создана, как 3D устройство путем включения при его инициализации возможности DDSCAPS_3DDEVICE.

Однако перед тем, как создавать устройство рендеринга, надо проверить на совместимость с режимом дисплея. Если дисплей установлен в режиме палитры (т. е. палитра цветов количество 256 и меньше), наше приложение выйдет. Попытка создать устройство для поверхности с палитрой без ассоциирования его с палитрой приведет к краху. Пока мы не будем рассматривать режимы работы с палитрой для удобства. Нормальное приложение должно прикреплять свою палитру к поверхности для рендеринга или требовать, чтобы экран был установлен в режим не менее 16-битного цвета.

g_dd.GetDisplayMode ddsd
If ddsd.ddpfPixelFormat.lRGBBitCount <= 8 Then
MsgBox "Это приложение не может работать в режимах " & _
"цветности экрана меньше 16 бит."
End
End If

Затем, приложение создает устройство рендеринга:

Set g_d3dDevice = d3d.CreateDevice("IID_IDirect3DHALDevice", g_ddsBackBuffer)

Вызов Direct3D7.CreateDevice может дать сбой по многим причинам. Самая частая из них - это когда главная видеокарта не поддерживает свойств 3D. Другая возможность - когда оборудование, управляющее дисплеем не может совершать рендеринг в текущем режиме экрана. Все эти возможности, по-хорошему, должны быть отловлены при подготовке к созданию объекта. Однако, дял поддержания простоты кода примера, все возможности здесь не учтены.

Обратите внимание, что хотя CreateDevice и использует объект DirectDrawSurface7, он создает устройство, которое работает отдельно от объекта поверхности DirectDraw. Устройство рендеринга использует поверхность DirectDraw как цель для совершения своих операций.

После того, как устройство рендеринга создано, вы можете создать объект Viewport и назначить его устройству. Коротко, этот объект определяет, как геометрия в 3D сцене обрезается и представляется в 2D пространство экрана.

Процесс создания объекта Viewport начинается с установки параметров в тип D3DVIEWPORT7. Наше приложение устанавливает параметры Viewport соответственно размерам поверхности для рендеринга.


VPDesc.lWidth = g_rcDest.Right - g_rcDest.Left
VPDesc.lHeight = g_rcDest.Bottom - g_rcDest.Top
VPDesc.minz = 0#
VPDesc.maxz = 1#

Когда тип параметров объекта Viewport готов, надо передать параметры Viewport устройству рендеринга.

g_d3dDevice.SetViewport VPDesc

Теперь, кэшируем параметры Viewport в структуру RECT; мы будем использовать эту информацию позже.

With g_d3drcViewport(0)
.X1 = 0
.Y1 = 0
.X2 = VPDesc.lWidth
.Y2 = VPDesc.lHeight
End With
End Sub

Наконец мы создали все самые необходимые объекты DirectX, которые понадобятся нам для работы. В следующем шаге мы перейдем к объявлению объектов, которые понадобятся для рендеринга сцены.

<Вверх>