Introduction
I will try in this simple tutorial to introduce you to the world of DirectX through Visual Basic, although I am a beginner of both! I will focus on some errors that you could face, and I will try to explain each step as I know, but it may be better to view MSDN also for more information.
There is some talk about the poor performance and features of managed DirectX, and that when you want to learn DirectX, you should learn the native API using C++ or another low level programming language. OK, that may be true, but if you are a novice (or thick headed!), and don't want to bother learning a low level language first, and you want to have a quick beginning in games programming, Visual Basic is a nice choice.
Also, in Visual Basic, you will generally concentrate more on the program algorithm than on the language syntax.
About the performance issue, that is the last thing you should worry about, with modern video cards, it is usually no problem. Anyway, you can't easily develop games like Metal Gear and Devil May Cry at home; if you want to develop Super Mario classic or the likes, you can use any language.
There is another important point about managed DirectX, it is no longer supported by Microsoft, and Microsoft developed another games library (XNA) which does not support Visual Basic (and will not) so you will be stuck with DirectX 9 and won't be able to develop any further. Although this is very disappointing, with some alternative SDKs like Slim SDK, there is hope, or may be in future Microsoft will change their mind!
Let's Start!
Note: Before you start, you most have DirectX SDK installed on your computer. You can download it from Microsoft's site.
In a new Windows application project, add these references:
Microsoft.DirectX
Microsoft.DirectX.Direct3D
Microsoft.DirectX.Direct3DX
Then import the following:
Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D
Declare this variable in your form class:
Dim device As Direct3D.Device Dim buffer As VertexBuffer
The first variable is the device object which will perform the drawing and transforming and all those stuff; to put it simply, it represents your video card.
But how I can create my device object? Just have a look in device Constructor:
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)
So many parameters, huh! The first one is your adapter index (if you have more than one). The default adapter number is 0. The second parameter determines the type of your device (software or hardware). After that is your window handle (the third parameter), and some options as the fourth. The last one is the PresentParameters
object .
So we most create this object first,
Sub initilizdx()
Dim present As New PresentParameters
End Sub
and set some properties:
present.BackBufferCount = 1 present.BackBufferFormat = Manager.Adapters(0).CurrentDisplayMode.Format
present.BackBufferHeight = Me.Height
present.BackBufferWidth = Me.Width
present.Windowed = True present.SwapEffect = SwapEffect.Discard
What is BackBuffer?
It is the surface where DirectX directly draws. After the drawing is completed, the drawing will be rendered to the front buffer (screen surface) through a swap chain. This method reduces screen flickering, because the picture will not be displayed in the front buffer until rendering is completed.
The swap chain has three methods: discard, copy and flip. See the explanation of each in MSDN.
Then create our device:
device = New Device(0, DeviceType.Hardware, Me.Handle, _
CreateFlags.SoftwareVertexProcessing, present)
and adjust its properties:
device.RenderState.CullMode = Cull.None
Note: We just set it to None
at this time to make it easy for you, but in practice, culling has very important performance implications.
How to Draw using this Device
Before drawing, we must clear the device.
Sub draw_me()
device.Clear(ClearFlags.Target, Color.Black, 0, 0)
End Sub
This means we cleared device using black color. Then,
device.BeginScene()
device.EndScene()
device.Present()
To see what we have done, add this line in the LoadForm
event:
Sub form1(ByVal sender As Object, ByVal e As System.EventArgs)_
Handles Me.Load
initilizdx()
draw_me()
End Sub
Press F5 and see what happens. Nothing! That is a silly mistake, you can't draw before the form is shown! So,
Sub DirectX_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Me.Load
initilizdx()
Me.Show()
draw_me()
End Sub
Press F5 again.
Congratulations!
Set Up Geometry Data
In the beginning, we have declared a variable named buffer
as VertexBuffer
. The vertex buffer is a place in memory where the system stores vertex data.
So we create our vertex buffer:
Sub creat_vertxbuffer()
buffer = New VertexBuffer(GetType(CustomVertex.TransformedColored) , _
3, device, Usage.None, CustomVertex.TransformedColored.Format, _
Pool.Managed)
End Sub
The type of this vertex buffer is TransformedColored
, so our vertices are already transformed and don't need any transformation matrix to be presented. They are also colored, meaning they bear color information. For the moment, don't bother yourself with other parameters and write it as I did!
The second parameter determines the number of vertices in the vertex buffer. It is 3 because we want to draw a triangle.
To set the triangle vertex data, we use a useful group of structures which come with DirectX:
CustomVertex
Write:
Dim ver(2) As CustomVertex.TransformedColored
ver(0) = New CustomVertex.TransformedColored(50, 10, 0, 0, Color.Red.ToArgb)
ver(1) = New CustomVertex.TransformedColored(200, 15, 0, 0, Color.Red.ToArgb)
ver(2) = New CustomVertex.TransformedColored(10, 200, 0, 0, Color.Red.ToArgb)
buffer.SetData(ver, 0, LockFlags.None)
Return to draw_me
and write:
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
First, we set device.vertexformat = our_vertex_format
. If we didn't, our vertex data would not be read properly by the device, and some data may be lost.
Then set the stream source where the device reads a data stream, and call the DrawPrimitives
method.
DrawPrimitives(Primitives_type, start_vertex, number_of_primitives_to_draw)
There are six types of Primitives
. Here we chose TriangleList
.
In this type, the first three vertices form the first triangle. If you want 2 triangles, you must have 6 vertices. See MSDN for other Primitives
types.
Now add this to Form load Event.
Sub DirectX_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Me.Load
initilizdx()
creat_vertxbuffer()
Me.Show()
draw_me()
End Sub
The press F5.
Very nice!
Try This
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)
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
You expect to see this:
but you do not!
Set the rhw
value to 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
and run it again.
Also, you can draw a square if you start by drawing 2 triangles, like this:
Conclusion
I hope I have taught you something useful. Sorry for my bad English!
If many people are interested, I will write more tutorials, and I will discuss more topics like transforming and other rendering issues.
Thank you.
Note: The project is made using Visual Studio 2008. If you have any problems, just open the Form1.vb file and copy the code to your project after adding references.
History
- 21st February, 2011: Initial post