Visual Basic - мастерская разработчика
Библиотеки

DirectX

Обзоры
DirectDraw
Direct3D
DirectX Audio
DirectPlay
DirectInput
Fido Topics
SourceCode
Tools&Libs

OpenGL

Статьи и учебники
Fido Topics
SourceCode
Tools&Libs

Архив по Glide

Движки

Обзоры
Учебники
SourceCode
Downloads

Создание игр

Ваши игры

Обзорные статьи
Учебники
Fido Topics
SourceCode
Download

Stuff

Программер-Чат

Псевдо-FTP
Disclaimer
Оффтопик

 

DirectX Graphics - начнем снова

VB Edition

Часть 2 - Рендеринг более существенных вещей

[Предыдущая часть] [Следующая часть] [Приложения к этой части]

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

Треугольник у нас будет хоть и плоский, зато разноцветный. Приложение опять будет работать в окне. Когда-нть доьберемся и до полноэкранного :) Вобщем, хватит болтать, давайте начинать программировать!

Создайте новый проект и отформатируйте в нем форму так, чтобы в пиксельной системе координат ее высота и ширина были не меньше 300 пикселей. Добавьте к проекту reference DirectX 8 For Visual Basic Type Library

Сначала по плану у нас как всегда объявления:

'Объявляем объекты DirectX
Dim dx As New DirectX8 'Класс DirectX8
Dim d3d As Direct3D8 'Объект Direct3D
Dim d3dDevice As Direct3DDevice8 'Объект устройства рендеринга
Dim pVB As Direct3DVertexBuffer8 'Буфер для вершин.

'Мы еще работаем?
Dim Running As Boolean

Первые три объекта вам уже знакомы, а вот по четвертому пару слов: pVB - это буфер для хранения трехмерных вершин. Весь дальнейший разговор будет построен вокруг трехмерных вершин. Как вы увидите дальше, их формат можно будет задать самому. Сейчас скажу только, что мы создадим массив из трех вершин (у треугольника ведь три вершины, да?) и потом этот массив надо запихать в буфер вершин. Буфер вершин - это просто участок выделенной памяти, с которым можно обращаться, как с объектом. Все просто.

А вот теперь мы будем задавать формат наших вершин:

'Структура, определяющая наш формат вершины (aka FVF)
Private Type CUSTOMVERTEX
X As Single
Y As Single
Z As Single
RHW As Single
Color As Long
End Type

Вершина задана в структуре CUSTOMVERTEX. C x, y, z и color вроде все ясно. rhw расшифровывается как reciprocal homogeneous W. Не справшивайте у меня что это такое, я и сам этого слова пугаюсь :0)

'Флаговое описание нашего FVF
Private Const D3DFVF_CUSTOMVERTEX = (D3DFVF_XYZRHW Or D3DFVF_DIFFUSE)

В этой строке мы задали флаговое описание нашего формата. D3DFVF_XYZRHW означает, что мы используем трансформированные координаты по x, y, z и тому самому, который "W". D3DFVF_DIFFUSE означает, что каждая вершина имеет свой цвет (diffuse color). Здесь мы задали только определения, чье применение вы увидите ниже.

Дальше идут знакомые функции создания и уничтожения. Я не буду на них подробно останавливаться

'При загрузке формы вызываем функцию инициализации Direct3D
Private Sub Form_Load()
Me.Show 'Показать окно
InitD3D 'Инициализировать D3D
InitVB 'Создать буфер вершин
Running = True
Do While Running 'Запустить цикл рендеринга
Render
Loop
End
End Sub

'При нажатии на клавишу - конец программы
Private Sub Form_KeyPress(KeyAscii As Integer)
Running = False
End Sub

'При выходе все уничтожить
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Set pVB=Nothing
Set d3dDevice = Nothing
Set d3d = Nothing
End Sub

Здесь внимания может удостоиться только то, что теперь мы запускаем рендеринг каждый шаг цикла и то, что после инициализации Direct3D мы вызываем процедуру создания буфера вершин.

Теперь мы будем писать процедуру инифиализации буфера вершин - InitVB, которая вызывается сразу после создания объектов Direct3D. Сперва мы должны создать массив из вершин произвольного типа, который мы создали в самом начале.

Private Sub InitVB()
Dim Vertices(3) As CUSTOMVERTEX

'Указать координаты трех вершин для нашего треугольника
With Vertices(0): .X = 150: .Y = 50: .Z = 0.5: .RHW = 1: .Color = &HFFFF0000: End With
With Vertices(1): .X = 250: .Y = 250: .Z = 0.5: .RHW = 1: .Color = &HFF00FF00: End With
With Vertices(2): .X = 50: .Y = 250: .Z = 0.5: .RHW = 1: .Color = &HFF00FFFF: End With

Координаты точек заданы так, чтобы создать треугольник, расположенный параллельно плоскости обзора. Таинственный rhw задан в 1 и ни на что особо не влияет. Цвет каждая вершина имеет свой. Он задан в формате ARGB, то есть первая пара чисел задает альфа-компоненту, вторая красную и так далее.

'Создать буфер под хранение информации о вершинах
Set pVB = d3dDevice.CreateVertexBuffer(3 * Len(Vertices(0)), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT)

Здесь мы создаем буфер вершин, то есть мы занимаем память под хранение координат, но еще не вносим координаты в буфер. Первый параметр говорит сколько памяти выделять. Затем мы указываем флаговый формат вершин, говорим, что память надо выделять из источника по умолчанию (обычно видео и AGP-видеопамять.

'Скопировать информацию о вершинах в буфер
Call D3DVertexBuffer8SetData(pVB, 0, Len(Vertices(0)) * 3, 0, Vertices(0))

End Sub

После создания, буфер вершин чист и невинен, как младенец :) В этом участке кода мы поместили информацию из массива в буфер так, чтобы ее можно было использовать. На этом процедура создания закончилась.

Нам осталось написать только функцию рендеринга треугольника. Все команды рендеринга должны помещаться между функциями BeginScene и EndScene.

Private Sub Render()
Dim v As CUSTOMVERTEX
Dim sizeOfVertex As Long

DoEvents

sizeOfVertex = Len(v)

Call d3dDevice.Clear(0, ByVal 0, D3DCLEAR_TARGET, &HFF, 1, 0) 'Очистить вьюпорт
Call d3dDevice.BeginScene 'Начало рендеринга

Теперь, мы должны установить источник потока вершин для организации поточного рендеринга. Это реализовано в следующей функции:

'Выполнить рендеринг треугольника по координатам, заданным в буфере вершин
Call d3dDevice.SetStreamSource(0, pVB, sizeOfVertex)
Call d3dDevice.SetVertexShader(D3DFVF_CUSTOMVERTEX)

Первый параметр - номер потока. Второй - это буфер вершин. Наконец, третий параметр в случае FVF должен соотвествовать размеру структуры вершины. SetVertexShader дает знать D3D какой тип вершин мы используем.

Теперь мы выполняем сам рендеринг.

Call d3dDevice.DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1)

D3DPT_TRIANGLELIST указывает какой тип примитива рендерить. Мы ведь указали в буфере только координаты, откуда D3D знать что они означают?! Второй параметр означает индекс первой координаты в буфере, с которой начинать отсчитывать поток координат. Последняя единица указывает какое количество примитивов рисовать. Так как у нас всего один треугольник, то мы указали последним параметром единицу. На этом рендеринг заканчиватся. Заканчивается и наша программа.

Call d3dDevice.EndScene 'Конец рендеринга

'Показать задний буфер человечеству (aka Flip)
Call d3dDevice.Present(ByVal 0, ByVal 0, 0, ByVal 0)
End Sub

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

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

Приложение: Готовый проект (7k)

Приятного программирования, Antiloop

[Вверх]

Posted: 23.01.2k1
Autor: Antiloop
<anti_loop@mail.ru>

 


Проект
Создание Народного Учебника по OpenGL

Участвовать!
Поиск
Найдите статью или файл:


Рассылка
Новости сайта
La Vision в вашем почтовом ящике








Программирование на С++ Delphi и Паскаль
Центр демо-искусства в России