Показать сообщение отдельно
Старый 20.03.2006, 17:38   #4
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 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
В аттаче скомпилированный проект и исходник этого туториала.
__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо pax за это полезное сообщение:
Лit}{Ъ (02.05.2011), Nex (29.05.2009)