65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Visual Basic .NET 入门 DirectX

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.73/5 (13投票s)

2011年2月21日

CPOL

5分钟阅读

viewsIcon

133307

downloadIcon

5231

创建 DirectX 设备并使用 VB 绘制一些图元!

引言

我将在这篇简单的教程中尝试通过 Visual Basic 向您介绍 DirectX 的世界,尽管我两者都是新手! 我将重点介绍您可能遇到的几个错误,并尽力解释每一步,但最好也查阅 MSDN 以获取更多信息。

有一些关于托管 DirectX 性能和功能较差的说法,并且当您想学习 DirectX 时,您应该使用 C++ 或其他低级编程语言学习原生 API。 好的,这可能是真的,但如果您是新手(或者头脑迟钝!),并且不想先学习低级语言,并且想快速开始游戏编程,Visual Basic 是一个不错的选择。

此外,在 Visual Basic 中,您通常会更多地关注程序算法而不是语言语法。

关于性能问题,那是您最后应该担心的事情,对于现代显卡来说,通常不成问题。 无论如何,您在家中无法轻易开发出《合金装备》和《鬼泣》之类的游戏; 如果您想开发《超级马里奥经典》或类似的,您可以使用任何语言。

关于托管 DirectX 还有另一个重要的一点,它不再受 Microsoft 支持,而且 Microsoft 开发了另一个游戏库(XNA),它不支持 Visual Basic(并且将来也不会),所以您将被困在 DirectX 9,无法进一步开发。 尽管这非常令人失望,但通过 Slim SDK 等一些替代 SDK,还是有希望的,或者也许将来 Microsoft 会改变主意!

让我们开始吧!

注意:在开始之前,您必须在计算机上安装 DirectX SDK。 您可以从 Microsoft 网站下载。

在一个新的 Windows 应用程序项目中,添加这些引用

  • Microsoft.DirectX
  • Microsoft.DirectX.Direct3D
  • Microsoft.DirectX.Direct3DX

然后导入以下内容

Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D

在您的窗体类中声明此变量

Dim device As Direct3D.Device ' this the main DirectX device    
Dim buffer As VertexBuffer    ' don't worry about this now!

第一个变量是设备对象,它将执行绘图和转换以及所有这些工作; 简单来说,它代表您的显卡。

但我如何创建我的设备对象? 只需查看设备构造函数

Public Sub New(ByVal adapter As Integer, ByVal deviceType As  _
    DeviceType, ByVal renderWindowHandle As System.IntPtr, ByVal _
    behaviorFlags As CreateFlags, ByVal ParamArray presentationParameters() _
    As PresentParameters)  

这么多参数,是吧! 第一个参数是您的适配器索引(如果您有多个)。 默认适配器号是 0。 第二个参数确定您的设备类型(软件或硬件)。 之后是您的窗口句柄(第三个参数),以及一些选项作为第四个参数。 最后一个是 PresentParameters 对象。

所以我们必须先创建这个对象,

Sub initilizdx()
Dim present As New PresentParameters
'
'
'
End Sub  

并设置一些属性

present.BackBufferCount = 1 'the number of backbuffer
 present.BackBufferFormat = Manager.Adapters(0).CurrentDisplayMode.Format
 present.BackBufferHeight = Me.Height
 present.BackBufferWidth = Me.Width
 present.Windowed = True 'If you want full screen set it to 
 'false but you should change other properties so don't try it    
 'till now
 present.SwapEffect = SwapEffect.Discard   

什么是后备缓冲区?

它是 DirectX 直接绘制的表面。 绘制完成后,通过交换链将绘制渲染到前缓冲(屏幕表面)。 这种方法减少了屏幕闪烁,因为在渲染完成之前,图片不会显示在前缓冲中。

交换链有三种方法:丢弃、复制和翻转。 请参阅 MSDN 中对每种方法的解释。

然后创建我们的设备

device = New Device(0, DeviceType.Hardware, Me.Handle, _
    CreateFlags.SoftwareVertexProcessing, present)  

并调整其属性

device.RenderState.CullMode = Cull.None 

注意:此时我们仅将其设置为 None 以便您轻松理解,但在实践中,剔除对性能有非常重要的影响。

如何使用此设备进行绘图

在绘图之前,我们必须清除设备。

Sub draw_me()
    
    device.Clear(ClearFlags.Target, Color.Black, 0, 0)
    '
    '
    '
End Sub 

这意味着我们用黑色清除了设备。 然后,

device.BeginScene()

'all drawing functions here   
        
device.EndScene()
device.Present()'present to screen 

要查看我们的成果,请在 LoadForm 事件中添加此行

Sub form1(ByVal sender As Object, ByVal e As System.EventArgs)_ 
Handles Me.Load

    initilizdx()
    draw_me()

End Sub 

按 F5 并查看发生了什么。 什么都没有! 这是一个愚蠢的错误,您不能在窗体显示之前绘制! 所以,

Sub DirectX_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Me.Load
    initilizdx()        
    Me.Show()
    draw_me()
End Sub 

再次按 F5。

blackscreen_screenshot.png

恭喜!

设置几何数据

一开始,我们声明了一个名为 buffer 的变量,类型为 VertexBuffer。 顶点缓冲区是系统存储顶点数据的一个内存区域。

所以我们创建我们的顶点缓冲区

Sub creat_vertxbuffer()

    buffer = New VertexBuffer(GetType(CustomVertex.TransformedColored) , _ 
        3, device, Usage.None, CustomVertex.TransformedColored.Format,  _ 
        Pool.Managed)  
    '
    '
    '
End Sub

此顶点缓冲区的类型为 TransformedColored,因此我们的顶点已经经过转换,无需任何转换矩阵即可显示。 它们也有颜色,这意味着它们带有颜色信息。 目前,不要纠结于其他参数,按照我写的方式做!

第二个参数决定了顶点缓冲区中的顶点数量。 它是 3,因为我们要绘制一个三角形。

要设置三角形顶点数据,我们使用 DirectX 提供的一组有用的结构

CustomVertex 

Write

Dim ver(2) As CustomVertex.TransformedColored
'The first point
ver(0) = New CustomVertex.TransformedColored(50, 10, 0, 0, Color.Red.ToArgb)

'and the others

ver(1) = New CustomVertex.TransformedColored(200, 15, 0, 0, Color.Red.ToArgb)
ver(2) = New CustomVertex.TransformedColored(10, 200, 0, 0, Color.Red.ToArgb)

'now set the vertex buffer data:
buffer.SetData(ver, 0, LockFlags.None)    

返回 draw_me 并编写

   Sub draw_me()
        device.Clear(ClearFlags.Target, Color.Black, 0, 0)
        device.BeginScene()
        device.VertexFormat = CustomVertex.TransformedColored.Format
        device.SetStreamSource(0, buffer, 0)
        device.DrawPrimitives(PrimitiveType.TriangleList, 0, 1)
        device.EndScene()
        device.Present()

    End Sub 

首先,我们设置 device.vertexformat = our_vertex_format。 如果我们不这样做,我们的顶点数据将不会被设备正确读取,并且某些数据可能会丢失。

然后设置设备读取数据流的流源,并调用 DrawPrimitives 方法。

DrawPrimitives(Primitives_type, start_vertex, number_of_primitives_to_draw)

有六种类型的 Primitives。 在这里我们选择了 TriangleList

在这种类型中,前三个顶点构成第一个三角形。 如果您想要 2 个三角形,您必须有 6 个顶点。 有关其他 Primitives 类型,请参阅 MSDN。

现在将此添加到 Form load 事件。

Sub DirectX_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Me.Load
    initilizdx()
    creat_vertxbuffer()
    Me.Show()
    draw_me()
End Sub

然后按 F5。

firstrender_screenshot.png

非常好!

尝试这个

Sub creat_vertxbuffer()
    buffer = New VertexBuffer(GetType(CustomVertex.TransformedColored), 3, _
        device, Usage.None, CustomVertex.TransformedColored.Format, Pool.Managed)
    
    Dim ver(2) As CustomVertex.TransformedColored _
        ver(0) = New CustomVertex.TransformedColored(50, 10, 0, 0, Color.Red.ToArgb)

    ' the difference is here:
    ver(1) = New CustomVertex.TransformedColored(200, 15, 0,0, Color.Green.ToArgb)
    ver(2) = New CustomVertex.TransformedColored(10, 200, 0, 0, Color.red.ToArgb)
    buffer.SetData(ver, 0, LockFlags.None)
End Sub

您期望看到这个

addgreen_screenshot.png

但您没有!

rhw 值设置为 1

Sub creat_vertxbuffer()
    buffer = New VertexBuffer(GetType(CustomVertex.TransformedColored), 3, _
        device, Usage.None, CustomVertex.TransformedColored.Format, Pool.Managed)
    Dim ver(2) As CustomVertex.TransformedColored
    ver(0) = New CustomVertex.TransformedColored(50, 10, 0, 1, Color.Red.ToArgb)
    ver(1) = New CustomVertex.TransformedColored(200, 15, 0, 1, Color.Green.ToArgb)
    ver(2) = New CustomVertex.TransformedColored(10, 200, 0, 1, Color.Blue.ToArgb)
    buffer.SetData(ver, 0, LockFlags.None)
End Sub 

然后再次运行它。

此外,您可以通过绘制 2 个三角形来绘制一个正方形,如下所示

practise.png

结论

我希望我教会了您一些有用的东西。 对我的糟糕英语感到抱歉!

如果很多人感兴趣,我将撰写更多教程,并讨论更多主题,如转换和其他渲染问题。

谢谢。

注意:该项目是使用 Visual Studio 2008 创建的。如果您有任何问题,只需打开 Form1.vb 文件,在添加引用后将代码复制到您的项目中。

历史

  • 2011 年 2 月 21 日:初始帖子
© . All rights reserved.