Введение
Одним из самых быстро развивающихся направлений разработки программного обеспечения является производство компьютерных игр. Еще не так давно практически все они разрабатывались на языках С и С++. Но последнее время «новички» Delphi, а затем и Visual Basic, занимают все более заметные позиции в этой области. И если использование С++ при разработке больших проектов остается вне конкуренции, то для написания не очень сложных игр одному, или в компании друзей, использование Visual Basic может быть более предпочтительным, так как он прост, но при этом достаточно мощен. А если учесть, что близится эпоха NET, когда Бейсик практически уравнивается по возможностям для разработки программ в среде Windows с С (точнее C#), то становится вполне очевидным, что наши занятия имеют не плохую перспективу.

Пожалуй, самый технологичный момент при разработке игры, это написание ее графического движка, особенно если это игра трехмерная, но ведь таких игр большинство! Сейчас для программирования 3D графики применяется два API - это OpenGL и Direct3D. Но если использование OpenGL в Visual Basic довольно затруднительно - практически отсутствует поддержка, нет наработок, то в состав DirectX, начиная с седьмой версии, входит библиотека типов, облегчающая использование Direct3D и других компонентов DirectX из Visual Basic. Кроме того, разработчик DirectX корпорация Microsoft выпускает специальные справочные руководства - SDK, в том числе и для Visual Basic.

Эта книга посвящена использованию Direct3D8, входящего в состав DirectX8. Поэтому я настоятельно рекомендую скачать с сайта Microsoft соответствующий SDK, он выложен в свободный доступ.

Данная книга – не справочник, а, скорее, учебник, призванный обучить вас программировать 3D-графику на Visual Basic с самых азов. Однако вам будут необходимы начальные знания самого Visual Basic и некоторые навыки работы на нем. Так же желательно иметь некоторое представление об ООП (объектно-ориентированном программировании), ведь DirectX построен на этой основе.

1. Часть 1. Основы
1.1. Подготовка к работе

Для работы нам понадобится компьютер с операционной системой Windows не ниже Windows 98, установленный DirectX 8.1 или новее и Visual Basic версии 6. Крайне желательно иметь видеоадаптер, полностью поддерживающий DirectX 8.1. Из наиболее распространенных это ATI Radeon 8500 и выше, nVidia GeForce3, GeForce4 Ti и выше. Однако вполне возможна работа и на GeForce серии MX и, даже, Riva TNT.
Стоит остановиться на установке Microsoft DirectX 8.1 SDK for Visual Basic. В ходе установки будет выбор режима – Debug или Retail, если мы выберем Debug, у нас будет возможность эмулировать программно функции DirectX, не поддерживаемые видеоадаптером аппаратно. Особенно рекомендуется выбрать режим Debug, если видеоадаптер не имеет полной поддержки DirectX 8.1.

1.2. Инициализация Direct3D
Приступим, наконец, к нашему первому проекту. Загрузим Visual Basic и создадим новый проект, состоящий из одной формы. Теперь подключим к проекту библиотеку типов для работы с DirectX 8.1. Для этого в меню Проект откроем пункт Ссылки, найдем и отметим флажком строку DirectX 8 for Visual Basic Type Library.
Зададим глобальные переменные:
 

код на языке vb
Dim dx8 As New DirectX8
Dim d3d As Direct3D8
Dim d3dDevice As Direct3DDevice8

 
Объектные переменные dx8 и d3d содержат соответственно экземпляры классов DirectX8 и Direct3D8, которые нужны в основном на этапе инициализации, а экземпляр класса Direct3DDevice8 объектная переменная d3dDevice – это наш основной рабочий инструмент при работе с графикой.
Создадим процедуру для инициализации Direct3D:
 

код на языке vb
Private Sub D3DInit()
Dim DispMode As D3DDISPLAYMODE
Dim d3dpp As D3DPRESENT_PARAMETERS
 
  Set d3d = dx8.Direct3DCreate
  d3d.GetAdapterDisplayMode D3DADAPTER_DEFAULT, DispMode
 
  d3dpp.Windowed = True
  d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD
  d3dpp.BackBufferFormat = DispMode.Format
 
  Set d3dDevice = d3d.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, Me.hWnd _
  , D3DCREATE_SOFTWARE_VERTEXPROCESSING, d3dpp)
End Sub

 
Рассмотрим работу процедуры подробнее. С помощью функции dx8.Direct3DCreate инициализируем переменную d3d, с помощью d3d.GetAdapterDisplayMode D3DADAPTER_DEFAULT, DispMode заполняем структуру DispMode данными о текущем видеорежиме. Вторая структура d3dpp заполняется параметрами создаваемого устройства d3dDevice. Windowed говорит о том, что наша программа будет работать в оконном режиме, в этом случае формат, естественно, должен соответствовать формату видеорежима – d3dpp.BackBufferFormat = DispMode.Format.

Примечание
Вывод графики в Direct3D осуществляется не прямо на экран, а в специальную область памяти, называемую BackBuffer. Только после того, как изображение полностью сформировано, оно переносится из BackBuffer на экран.

Способ переноса BackBuffer на экран определяется полем SwapEffect структуры D3DPRESENT_PARAMETERS. Меняя значение SwapEffect можно, например, включить или выключить синхронизацию переноса изображения из BackBuffer на экран с частотой кадров.

Примечание
Для корректного освобождения ресурсов все переменные объектного типа должны перед завершением программы уничтожаться присваиванием им значения Nothing.

Исходя из вышесказанного, сразу готовим процедуру для уничтожения объектов:
 

код на языке vb
Private Sub ClearAll()
  Set d3dDevice = Nothing
  Set d3d = Nothing
  Set dx8 = Nothing
End Sub

 
Добавим к глобальным переменным новую переменную Running типа Boolean, создадим процедуры Form_Load и Form_QueryUnload и внесем в них такой код:
 

код на языке vb
Private Sub Form_Load()
  Me.Show
  D3DInit
  Running = True
  Do While Running
    DoEvents
    Render
  Loop
  Unload Me
End Sub
 
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
  If Running Then
    Cancel = 1: Running = False
  Else
    ClearAll
  End If
End Sub

 
При старте программы инициализируется Direct3D и запускается цикл с вызовом процедуры Render, в которой и будет вывод изображения, а такая структура процедуры Form_QueryUnload не дает завершить программу до выхода из цикла, ведь при завершении работы программы мы уничтожим созданные объекты, и вызов Render приведет к ошибке.
И, наконец, сама процедура Render:

код на языке vb
 
Private Sub Render()
  d3dDevice.Clear 0, ByVal 0, D3DCLEAR_TARGET, Rnd * &HFFFFFF, 1, 0
  d3dDevice.Present ByVal 0, ByVal 0, 0, ByVal 0
End Sub
 

В ней выполняется всего два действия – очистка (закраска) BackBuffer случайным цветом и вывод полученного изображения на экран.
Наша минимальная программа, использующая Direct3D, готова. Жмем клавишу <F5> – и, если мы нигде не ошиблись, видим быстро мерцающую форму. Можно заменить в процедуре D3DInit строку:

код на языке vb
 
  d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD
 
на:
 
  d3dpp.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC
 

При этом исчезнут полосы – мерцание формы станет равномерным, ведь мы засинхронизировали его с частотой кадров.