DirectX Graphics - начнем снова
VB Edition
Часть 1 - Рендеринг... Ничего
[Следующая часть]
[Приложения к этой части]
Судя по проводимым мною опросам, человечество :) более всего было заинтересовано
в изучении D3D:Immediate Mode, который я упорно не освещал на своем сайте. Причина
была в том, что я ждал когда же выйдет DirectX8, чтобы не обламываться на полпути
изучения седьмой версии Direct3D:IM Как выяснилось с выходом этой самой восьмой
версии, я ждал не то чтобы не напрасно, а просто очень хорошо, что я ждал, так
как добрая Microsoft позаботилась о нас всех и сделала D3D:IM главнейшей компонентой
в DX8, обозвав ее DirectX Graphics (Туда же входит библиотека Direct3DX, по
сути являющаяся переделанным D3D:RM, но о ней мы поговорим в другой раз и в
другом месте)
О чем же пойдет речь? Так как MS серьезно переделала D3D:IM в восьмой версии,
мы со спокойной душой, что по крайней мере год ничего нового, более ужасного
не произойдет, сможем заняться изучением D3D:IM, то есть Direct Graphics или
наконец просто Direct3D. Вот сколько много названий...
Как всегда, мои последующие мысли основаны на DX SDK и в случае чего непонятного
первым делом обращайтесь туда. Ну потом можете уже и писать... :)
Начнем мы с создания простейшего приложения, как это написано в MS-туториале.
В оправдание себя скажу, что чисто по MS-туториалу без примера сделать ничего
невозможно, да к тому же я постараюсь все это дело сбавить огромным количеством
пояснений...
Так, себя похвалил... Переходим к делу.
(Немножко по организации. Я планирую сначала издавать статьи, обращенные к
Visual C++ и сразу вслед за ними переводить, ежели конечно это возможно, на
Visual Basic)
В этой части мы нарисуем окно, в котором мы создадим... Ничего!
Нет, ну что-то у нас все-таки будет и это что-то называется устройством рендеринга.
Оно нам очистит вьюпорт и мы увидим прекрасную синюшную сцену.
Для работы этого приложения, вы естесственно уже должны иметь поставленный DirectX8.
Обратите внимание, что на Visual Basic вы модете программировать DirectX и не
имея SDK! Необходимая библиотека dx8vb.dll уже есть в комплекте рунтаймов DirectX8.
Итак, создайте новый проект, нарисуйте небольшую форму и подключите к проекту
в References ссылку на библиотеку DirectX 8 for VB Type Library
Пишем код прямо в модуле кода формы
Для начала, парочка объявлений
'Объявляем объекты DirectX
Dim dx As New DirectX8 'Класс DirectX8
Dim d3d As Direct3D8 'Объект Direct3D
Dim d3dDevice As Direct3DDevice8 'Объект устройства
рендеринга
Первой функцией у нас будет функция Form_Load
'При загрузке формы вызываем функцию инициализации
Direct3D
Private Sub Form_Load()
InitD3D
End Sub
Не радуйтесь, все не так просто. Функция InitD3D отнюдь не встроенная - мы
будем писать ее сами.
'При перерисовке формы рендерить еще раз
Private Sub Form_Paint()
Render
End Sub
'При выходе все уничтожить
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Set d3dDevice = Nothing
Set d3d = Nothing
End Sub
Это процедуры больше служебные. Первая будет вызывать нам функцию Render, которая
будет выполнять рендеринг сцены. Вторая нужна для корректного уничтожения объектов
при выходе из программы.
Теперь, собственно, начинается сам D3D. Как я и обещал, мы сейчас напишем функцию,
которая все это дело инициализирует.
'Инициализация Direct3D
Private Sub InitD3D()
'Необходимые объекты и структуры
Dim DispMode As D3DDISPLAYMODE
Dim d3dpp As D3DPRESENT_PARAMETERS
'Создать объект Direct3D
Set d3d = dx.Direct3DCreate
'Получить текущий режим экрана
Call d3d.GetAdapterDisplayMode(D3DADAPTER_DEFAULT, DispMode)
Здесь мы получаем очень удобную структуру D3DDISPLAYMODE, которая будет содержать
важную информацию о текущем режиме экрана. Эта структура позже будет использоваться
для создания устройства рендеринга. Но и вы можете подчерпнуть из нее много
важного для своего приложения. Вот ее мемберы:
- Width As Long; Height As Long; RefreshRate As Long - соответственно
ширина, высота и частота обновления экрана.
- Format As CONST_D3DFORMAT;- структура D3DFORMAT, которая
описывает формат поверхности. Лазить в нее вручную довольно муторное занятие,
поэтому если вам она нужна - смотрите документацию
Так. На чем мы остановились?
Теперь нам как и в DirectDraw указать параметры создаваемого устройства рендеринга
в особой структуре:
'Установить параметры создаваемого устройства рендеринга
d3dpp.Windowed = True
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD
d3dpp.BackBufferFormat = DispMode.Format
Сначала мы обнуляем всю структуру. В параметр d3dpp.Windowed мы передаем значение
TRUE, так как будем работать в окне. Параметр d3dpp.SwapEffect означает способ
отображения заднего буфера на дисплее. Особо не волнуйтесь по поводу этого параметра,
смело устанавливая его в D3DSWAPEFFECT_DISCARD. Наконец, мы устанавливаем формат
заднего буфера в соответствии с текущим форматом поверхностей экрана.
Теперь, переходим к самому главному - созданию устройства рендеринга:
'Создать устройство рендеринга
Set d3dDevice = d3d.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, Me.hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, d3dpp)
D3DADAPTER_DEFAULT означает главный видеоадаптер. Мы не будем сейчас рассматривать
использование дополнительный видеокарт типа Voodoo, оставив это на потом. D3DDEVTYPE_HAL
означает использование HAL (Hardware Abstraction Layer) - проще говоря, аппаратного
ускорения видеокарты. Для этого случая ваша главная видеокарта должна иметь
функции аппаратного ускорения (вы скорее-всего знаете, может она это или нет)
хотя бы на уровне всенародной S3 Virge VX/GX с двумя мегами памяти :) Нам сейчас
не важна производительность карты - мы хотим заставить приложение работать.
Ежели ваша видеокарта "совсем никак", тогда ставьте вместо этого параметра
D3DDEVTYPE_REF - это применение функций Direct3D через софтварную эмуляцию.
Она хороша тем, что будет позволять выполнять все трехмерные функции вплоть
до фильтрации текстур. Кроме этого, софтварная эмуляция D3D будет использовать
при возможности специальные инструкции процессора, как говорится, takes advantages
of 3DNow! instructions set! ;0) Но в бочку меда капает то, что эта самая эмуляция
мягко говоря не быстра.... Поэтому, для продвинутых разработчиков, использующих
собственные софтовые устройства рендеринга сделали параметр D3DDEVTYPE_SW -
подключаемое софтварное устройство, которое должно быть зарегистрировано с помощью
метода Direct3D8.RegisterSoftwareDevice Но этим мы сейчас заниматься не будем.
End Sub
Так, теперь мы будем писать функцию, которая будет рендерить нам искомое Ничего
на экран. Как бы то ни было, Ничего тоже надо еще умудриться нарисовать :)
Private Sub Render()
Call d3dDevice.Clear(0, ByVal 0, D3DCLEAR_TARGET, &HFF, 1, 0) 'Очистить
вьюпорт
По хорошему, в первых двух параметрах передается массив прямоугольников. В
первом параметре их количество, а во втором указатель на массив структур D3DRECT,
которые указывают своими координатами что надо чистить. Подобным методом, вы
можете очистить только часть экрана, например если вы рисуете радар, у вас экран
уменьшен, да и просто сцена располагается не на всем экране, оставляя по боками
кусочки для отображения всяких статусов и т.п. Как бы там ни было, ма передаем
сначала 0, а потом By Val 0 - это означает, что очищать надо весь вьюпорт.
D3DCLEAR_TARGET - значит, что очищать надо только поверхность, на которую происходит
рендеринг, игнорируя всякие там глубинные буфера и проч.
&HFF - задает цвет, каким мы будем очищать (а конкретнее - заливать) указанный
участок. Тут мы очищаем синим цветом, но в большинстве случаев вы скорее всего
захотите очищать черным цветом. В конце-концов, это все равно будет потом заполнено
объектами, так что какая разница!
И наконец, последние два параметра в нашем случае неиспользования глубинных
буферов просто игнорируются.
Call d3dDevice.BeginScene 'Начало рендеринга
Все команды рендеринга идут после этого объявления, а не до
' Здесь происходит рендеринг всех объектов сцены
Следующим объявлением завершается рендеринг. После него вы не можете ставить
команды рендеринга.
Call d3dDevice.EndScene 'Конец рендеринга
Чтобы пользователь увидел, чего мы там нарендерили, надо показать это ему.
Совершаем знакомый нам по DirectDraw флиппинг поверхностей. Не забивайте себе
голову множеством NULLей в параметрах. Они нужны только для шибко хитрых случаев.
Если что - почитайте документацию :)
'Показать задний буфер человечеству (aka Flip)
Call d3dDevice.Present(ByVal 0, ByVal 0, 0, ByVal 0)
End Sub
Это все. Правда все! :)
Если вы правильно все переписали, то компилируйте программу и все должно работать!
Следующее по плану у нас - рендеринг более существенных вещей, чем просто Ничего...
Приложение: Готовый
проект (5k)
Приятного программирования, Antiloop
[Вверх]
Posted: 23.01.2k1
Autor: Antiloop
<anti_loop@mail.ru>
|