-
Oct 8th, 2013, 02:28 PM
#1
Drawing Primitives using XNA in VB.Net
A few prerequisites:
- Visual Basic.Net 2010 or higher
- Microsoft XNA 4.0 or higher
Following my prior tutorial, go ahead and add the correct XNA references and Import:
- Microsoft.Xna.Framework
- Microsoft.Xna.Framework.Graphics
For this tutorial, start by declaring and initializing the GraphicsDevice. If you're unsure on how to do that follow the link I posted above.
Next we will declare a BasicEffect and initialize that. A BasicEffect is the basic rendering effect class, perfect for primitives. The code for initializing the BasicEffect is:
Code:
Private effect As BasicEffect
Private Function InitializeEffect(ByVal graphics As GraphicsDevice) As Boolean
effect = New BasicEffect(graphics)
Try
effect.VertexColorEnabled = True
effect.Projection = Matrix.CreateOrthographicOffCenter(0, graphics.Viewport.Width, graphics.Viewport.Height, 0, 0, 1)
InitializeEffect = True
Catch ex As Exception
InitializeEffect = False
End Try
End Function
Basically what we're doing is setting up our BasicEffect class off of our GraphicsDevice, then setting some properties. The most important property I will discuss is the CreateOrthographicOffCenter. Whenever drawing primitives in XNA essentially what we're doing is drawing a 3d image, but making it appear 2d. This is the way that XNA is designed.
The form's load event will appear similar to the last tutorial on drawing an image, only it will appear a bit differently. First we will change the name of Initialize to InitializeGraphics, then when we use the conditional statement to try to set up the graphics, we will do the same for the BasicEffect. Here is how the code should look like for the Form_Load:
Code:
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
'Set up the initialize function found above
If InitializeGraphics(pbGame) AndAlso InitializeEffect(grafix) Then
BackgroundWorker1.RunWorkerAsync()
Else
MessageBox.Show("There was a problem initializing XNA.")
Me.Close()
End If
End Sub
Next I will put two(2) functions that will be able to draw a line and a triangle:
Code:
Private Function Set2dLine(ByVal x1 As Integer, ByVal y1 As Integer, ByVal z1 As Integer, _
ByVal x2 As Integer, ByVal y2 As Integer, ByVal z2 As Integer, _
ByVal color As Color) As VertexPositionColor()
Dim vertices1, vertices2 As New VertexPositionColor
vertices1.Position = New Vector3(x1, y1, z1)
vertices1.Color = color
vertices2.Position = New Vector3(x2, y2, z2)
vertices2.Color = color
Return {vertices1, vertices2}
End Function
Private Function Set2dTriangle(ByVal x1 As Integer, ByVal y1 As Integer, ByVal z1 As Integer, _
ByVal x2 As Integer, ByVal y2 As Integer, ByVal z2 As Integer, _
ByVal x3 As Integer, ByVal y3 As Integer, ByVal z3 As Integer, _
ByVal color As Color) As VertexPositionColor()
Dim vertices1, vertices2, vertices3 As New VertexPositionColor
vertices1.Position = New Vector3(x1, y1, z1)
vertices1.Color = color
vertices2.Position = New Vector3(x2, y2, z2)
vertices2.Color = color
vertices3.Position = New Vector3(x3, y3, z3)
vertices3.Color = color
Return {vertices1, vertices2, vertices3}
End Function
These two functions are almost identical, the only difference is that the triangle has one more vertices, and that's because a line has two points and a triangle has three. Remember earlier I explained that the way 2d primitives are shown are actually 3d Images only being manipulated to appear 2d? Well we do that by setting the Z coordinate of the Vector3 to 0. Consider the graphics class in System.Drawing, we have our X and Y coordinates and to draw a line we just set two points, essentially we're doing the same thing by setting the Z coordinate to 0.
Finally in our backgroundworker's DoWork event we set up our primitives and draw them:
Code:
Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Do Until quit = True
grafix.Clear(Color.CornflowerBlue)
effect.CurrentTechnique.Passes(0).Apply()
Dim newline() As VertexPositionColor = Set2dLine(50, 10, 0, 150, 10, 0, Color.Black)
Dim newtri() As VertexPositionColor = Set2dTriangle(25, 100, 0, 50, 50, 0, 75, 100, 0, Color.Black)
grafix.DrawUserPrimitives(PrimitiveType.LineList, newline, 0, 1)
grafix.DrawUserPrimitives(PrimitiveType.TriangleList, newtri, 0, 1)
grafix.Present()
Loop
End Sub
In that example I draw a line at 50, 10 and at 150, 10. I also draw a triangle at 25, 100 and 50, 50 and 75, 100. To get them to appear on the screen we call DrawUserPrimitives. All in all the code should look like this in the end:
Code:
Option Strict On
Option Explicit On
Imports Microsoft.Xna.Framework
Imports Microsoft.Xna.Framework.Graphics
Public Class Form1
Private grafix As GraphicsDevice
Private Function InitializeGraphics(ByRef surface As PictureBox) As Boolean
Try
Dim pparam As New PresentationParameters
pparam.DeviceWindowHandle = surface.Handle
pparam.IsFullScreen = False
Dim grafixAdapt As GraphicsAdapter = GraphicsAdapter.DefaultAdapter
grafix = New GraphicsDevice(grafixAdapt, GraphicsProfile.HiDef, pparam)
InitializeGraphics = True
Catch ex As Exception
InitializeGraphics = False
End Try
End Function
Private effect As BasicEffect
Private Function InitializeEffect(ByVal graphics As GraphicsDevice) As Boolean
effect = New BasicEffect(graphics)
Try
effect.VertexColorEnabled = True
effect.Projection = Matrix.CreateOrthographicOffCenter(0, graphics.Viewport.Width, graphics.Viewport.Height, 0, 0, 1)
InitializeEffect = True
Catch ex As Exception
InitializeEffect = False
End Try
End Function
Private quit As Boolean = False
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
'Set up the initialize function found above
If InitializeGraphics(pbGame) AndAlso InitializeEffect(grafix) Then
BackgroundWorker1.RunWorkerAsync()
Else
MessageBox.Show("There was a problem initializing XNA.")
Me.Close()
End If
End Sub
Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Do Until quit = True
grafix.Clear(Color.CornflowerBlue)
effect.CurrentTechnique.Passes(0).Apply()
Dim newline() As VertexPositionColor = Set2dLine(50, 10, 0, 150, 10, 0, Color.Black)
Dim newtri() As VertexPositionColor = Set2dTriangle(25, 100, 0, 50, 50, 0, 75, 100, 0, Color.Black)
grafix.DrawUserPrimitives(PrimitiveType.LineList, newline, 0, 1)
grafix.DrawUserPrimitives(PrimitiveType.TriangleList, newtri, 0, 1)
grafix.Present()
Loop
End Sub
Private Function Set2dLine(ByVal x1 As Integer, ByVal y1 As Integer, ByVal z1 As Integer, _
ByVal x2 As Integer, ByVal y2 As Integer, ByVal z2 As Integer, _
ByVal color As Color) As VertexPositionColor()
Dim vertices1, vertices2 As New VertexPositionColor
vertices1.Position = New Vector3(x1, y1, z1)
vertices1.Color = color
vertices2.Position = New Vector3(x2, y2, z2)
vertices2.Color = color
Return {vertices1, vertices2}
End Function
Private Function Set2dTriangle(ByVal x1 As Integer, ByVal y1 As Integer, ByVal z1 As Integer, _
ByVal x2 As Integer, ByVal y2 As Integer, ByVal z2 As Integer, _
ByVal x3 As Integer, ByVal y3 As Integer, ByVal z3 As Integer, _
ByVal color As Color) As VertexPositionColor()
Dim vertices1, vertices2, vertices3 As New VertexPositionColor
vertices1.Position = New Vector3(x1, y1, z1)
vertices1.Color = color
vertices2.Position = New Vector3(x2, y2, z2)
vertices2.Color = color
vertices3.Position = New Vector3(x3, y3, z3)
vertices3.Color = color
Return {vertices1, vertices2, vertices3}
End Function
End Class
I plan on adding more primitive objects such as a square and an ellipse in the future.
UPDATE
Here is the function for adding an ellipse:
Code:
'This function simply draws an ellipse
Private Function Set2dEllipse(ByVal x As Integer, ByVal y As Integer, ByVal z As Integer, _
ByVal size As Size, ByVal color As Color) As VertexPositionColor()
Dim vertices(100) As VertexPositionColor
For i As Integer = 0 To 100
Dim angle As Double = CDbl(i / 100 * Math.PI * 2)
vertices(i).Position = New Vector3(CSng(x + CDbl(Math.Cos(angle)) * size.Width), CSng(y + Math.Sin(angle) * size.Height), z)
vertices(i).Color = color
Next
Return vertices
End Function
Here is it being used in an example:
Code:
Dim ellipse() As VertexPositionColor = Set2dEllipse(10, 10, 0, New Size(25, 25), Color.Black)
grafix.DrawUserPrimitives(PrimitiveType.LineStrip, ellipse, 0, 99)
UPDATE #2
Here is the function for adding a rectangle:
Code:
Private Function Set2dRect(ByVal pt As Point, ByVal size As Size, ByVal color As Color) As VertexPositionColor()
Dim vertices1, vertices2, vertices3, vertices4 As New VertexPositionColor
vertices1.Position = New Vector3(pt.X, pt.Y, 0)
vertices1.Color = color
vertices2.Position = New Vector3(pt.X + size.Width, pt.Y, 0)
vertices2.Color = color
vertices3.Position = New Vector3(pt.X + size.Width, pt.Y + size.Height, 0)
vertices3.Color = color
vertices4.Position = New Vector3(pt.X, pt.Y + size.Height, 0)
vertices4.Color = color
Return {vertices1, vertices2, vertices3, vertices4, vertices1}
End Function
Here is an example of it being used:
Code:
Dim foo_rect() As VertexPositionColor = Set2dRect(New Point(5, 5), New Size(50, 50), Color.Black)
grafix.DrawUserPrimitives(PrimitiveType.LineStrip, foo_rect, 0, 4)
Last edited by dday9; Oct 10th, 2013 at 02:04 PM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|