Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Туториал №3. Матрицы.
В этом туториале Вы научитесь применять матрицы, необходимые для работы с 3D. Все описания этого туториала находятся в коде в виде коментариев. Сам код будет вам хорошо понятен, если вы читали предидущие два туториала
'-----------------------------------------------------------------------------
' Файл: Matrices.vb
'
' Описание: Сейчас мы знаем как создать устройство и визуализировать несколько 2D вершин,
' в этом туториале мы сделаем следующий шаг в нашем обучении - визуалируем 3D геометрию.
' Для этого нам придется использовать матрицы размером 4х4 для преобразования геометрии
' перемещением, вращением и масштабированием, а также настроим камеру.
'
' Геометрия изменяется в "модельном" пространстве. Мы можем двигать её (translation),
' вращать (rotation), или масштабировать (scaling) используя мировые преобразования.
' Вся геометрия, как говорят, находится в мировом пространстве. Далее, нам необходимо
' расположить камеру (или положение наших глаз) и задать направление взгляда (в нашем
' случае это наша геометрия). Для этого используется видовая матрица. Она определяет
' положение и вращение нашего взгляда. Последнее преобразование - преобразование геометрии
' в видовом пространстве с помошью матрицы проекций. Это преобразование проецирует
' 3D сцену в нашу 2D область обзора (т.е. в форму).
'
' Обратите внимание, что в этом туториале мы будем использовать библиотеку
' классов D3DX, которая представляет собой набор
' вспомогательных утилит для работы с D3D. В нашем случае, мы используем несколько
' полезных функций для настройки матриц. Для использования библиотеки D3DX, просто
' добавьте в проект ссылку на неё (Microsoft.DirectX.Direct3DX.dll).
'
' Copyright (c) Microsoft Corporation. Все права защищены.
'-----------------------------------------------------------------------------
Imports System
Imports System.Drawing
Imports System.Windows.Forms
Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D
Imports Direct3D = Microsoft.DirectX.Direct3D
Public Class Matrices
Inherits Form
' Наши глобальные переменные для этого проекта
Private device As device = Nothing ' Наше устройство рендеринга
Private vertexBuffer As vertexBuffer = Nothing 'Буфер вершин
'Объект, содержащий параметры устройства вывода
Private presentParams As New PresentParameters
Private pause As Boolean = False
Public Sub New()
' Устанавливаем начальный размер нашей формы
Me.ClientSize = New System.Drawing.Size(400, 300)
' и её название
Me.Text = "Direct3D Tutorial 3 - Матрицы"
End Sub
Public Function InitializeGraphics() As Boolean
Try
' Здесь давайте проинициализируем D3D устройство
presentParams.Windowed = True
presentParams.SwapEffect = SwapEffect.Discard
device = New Device(0, DeviceType.Hardware, Me, CreateFlags.SoftwareVertexProcessing, presentParams)
AddHandler device.DeviceReset, AddressOf Me.OnResetDevice
Me.OnCreateDevice(device, Nothing)
Me.OnResetDevice(device, Nothing)
pause = False
Return True
Catch e As DirectXException
Return False
End Try
End Function
Public Sub OnCreateDevice(ByVal sender As Object, ByVal e As EventArgs)
Dim dev As Device = CType(sender, Device)
' Здесь создаем буфер для 3-х вершин
vertexBuffer = New VertexBuffer(GetType(CustomVertex.PositionColored), _
3, dev, 0, CustomVertex.PositionColored.Format, Pool.Default)
AddHandler vertexBuffer.Created, AddressOf Me.OnCreateVertexBuffer
Me.OnCreateVertexBuffer(vertexBuffer, Nothing)
End Sub
Public Sub OnResetDevice(ByVal sender As Object, ByVal e As EventArgs)
Dim dev As Device = CType(sender, Device)
' Выключаем отсечение задних поверхностей геометрии
dev.RenderState.CullMode = Cull.None
' Выключаем D3D освещение т.к. мы сами устанавливаем цвета вершин
dev.RenderState.Lighting = False
End Sub
Public Sub OnCreateVertexBuffer(ByVal sender As Object, ByVal e As EventArgs)
Dim vb As VertexBuffer = CType(sender, VertexBuffer)
Dim verts As CustomVertex.PositionColored() = CType(vb.Lock(0, 0), CustomVertex.PositionColored())
verts(0).X = -1.0F
verts(0).Y = -1.0F
verts(0).Z = 0.0F
verts(0).Color = System.Drawing.Color.DarkGoldenrod.ToArgb()
verts(1).X = 1.0F
verts(1).Y = -1.0F
verts(1).Z = 0.0F
verts(1).Color = System.Drawing.Color.MediumOrchid.ToArgb()
verts(2).X = 0.0F
verts(2).Y = 1.0F
verts(2).Z = 0.0F
verts(2).Color = System.Drawing.Color.Cornsilk.ToArgb()
vb.Unlock()
End Sub
Private Sub Render()
If device Is Nothing Or pause Then Return
' Очистка заднего буфера синим цветом
device.Clear(ClearFlags.Target, System.Drawing.Color.Blue, 1.0F, 0)
device.BeginScene() ' Начало сцены
SetupMatrices() ' Настройка мировой, видовой и матрицы проекций
device.SetStreamSource(0, vertexBuffer, 0)
device.VertexFormat = CustomVertex.PositionColored.Format
device.DrawPrimitives(PrimitiveType.TriangleList, 0, 1)
device.EndScene() ' Конец сцены
device.Present() ' Смена буферов
End Sub
Private Sub SetupMatrices()
' Для нашей мировой матрицы зададим вращение объекта вокруг оси Y.
' Пусть наш объект делает один оборот в секунду.
' Рассчитаем угол поворота в зависимости от времени (в радианах)
Dim iTime As Integer = Environment.TickCount Mod 1000
Dim fAngle As Single = iTime * (2.0F * Math.PI) / 1000.0F
device.Transform.World = Matrix.RotationY(fAngle)
' Настроим видовую матрицу. Для этого необходимо знать 3 параметра: 1) точка
' наших глаз в пространстве; 2) направление нашего взгляда; 3) направление,
' которое определяет "верх". Здесь мы устанавливаем, что точка наших глаз находится
' в точке (0, 3, -5) , взгляд направлен в начало координат и определяем "верх" осью Y.
device.Transform.View = Matrix.LookAtLH(New Vector3(0.0F, 3.0F, -5.0F), _
New Vector3(0.0F, 0.0F, 0.0F), New Vector3(0.0F, 1.0F, 0.0F))
' Для матрици проекций мы установим перспективное преобразование, которое
' выполнит преобразовани геометрии из 3D пространства в 2D область обзора на экране.
' Перспективная проекция делает объеты меньше на большом расстоянии от экрана и наоборот.
' Для создания перспективного преобразования мы должны задать поле зрения(обычно 90 градусов),
' соотношение размеров нашей 2D области, ближнюю и дальнюю плоскости отсечения (они определяют
' расстояние от точки зрения, на котором будет визуализитоваться сцена).
device.Transform.Projection = Matrix.PerspectiveFovLH(CSng(Math.PI) / 4, _
4.0F / 3.0F, 1.0F, 100.0F)
End Sub
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
Me.Render() ' Визуализация сцены при событии Paint
End Sub
Protected Overrides Sub OnKeyPress(ByVal e As System.Windows.Forms.KeyPressEventArgs)
If Asc(e.KeyChar) = CInt(System.Windows.Forms.Keys.Escape) Then
Me.Close() ' Обработка клавиши Esc
End If
End Sub
Protected Overrides Sub OnResize(ByVal e As System.EventArgs)
pause = (Me.WindowState = FormWindowState.Minimized Or Not Me.Visible)
End Sub
'/ <summary>
'/ Главная точка входа в приложение.
'/ </summary>
Shared Sub Main()
Dim frm As New Matrices 'Создание экземпляга класса нашей формы формы
If Not frm.InitializeGraphics() Then ' Инициализация Direct3D
MessageBox.Show("Невозможно инициализировать Direct3D. Программа будет закрыта.")
Return
End If
frm.Show() 'Отображение нашей формы на экране
'Главнцй цикл
While frm.Created
frm.Render()
Application.DoEvents()
End While
End Sub
End Class
В аттаче скомпилированный проект и исходник этого туториала.
|