# VBForums UtilityBank > UtilityBank - Tutorials >  Drawing Primitives using XNA in VB.Net

## dday9

A few prerequisites:
Visual Basic.Net 2010 or higherMicrosoft XNA 4.0 or higher

Following my prior tutorial, go ahead and add the correct XNA references and Import:
Microsoft.Xna.FrameworkMicrosoft.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:


```
    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:



```
    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:


```
    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:


```
    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:



```
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:


```
    '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:


```
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:


```
    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:


```
            Dim foo_rect() As VertexPositionColor = Set2dRect(New Point(5, 5), New Size(50, 50), Color.Black)
            grafix.DrawUserPrimitives(PrimitiveType.LineStrip, foo_rect, 0, 4)
```

----------

