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
The first thing that we will do is declare three(3) variables:
Code:
Private grafix As Graphics.GraphicsDevice = Nothing
Private s_Batch As SpriteBatch
Private sprite As Texture2D
The next step in our process is to start a boolean function. Now in this function, we will try to set up the graphics device. If for whatever reason we fail, in the form_load event an error will be thrown.
Code:
Private Function initialize(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)
initialize = True
Catch ex As Exception
initialize = False
End Try
End Function
I explained what that function does in the prior tutorial. The next step is to create a function that will return a texture2d.
Code:
Public Shared Function BitmapToTexture2D(GraphicsDevice As GraphicsDevice, image As System.Drawing.Bitmap) As Texture2D
Dim bufferSize As Integer = image.Height * image.Width * 4
Dim memoryStream As New System.IO.MemoryStream(bufferSize)
image.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png)
memoryStream.Seek(0, SeekOrigin.Begin)
Dim texture As Texture2D = Texture2D.FromStream(GraphicsDevice, memoryStream, image.Width, image.Height, False)
memoryStream.Close()
Return texture
End Function
This is important because XNA isn't intended to render bitmaps, it's intended to render texture2d's. Now the main method going on in that function is the Texture2d.FromStream. Now if you aren't paying attention to the prerequisites and using a former version of XNA I believe the method used is the Texture2d.FromFile, the parameters are a bit different, but the concepts the same.
The next step is to actually convert the bitmap to a texture2d:
Code:
Private Sub Load_Content()
If IsNothing(grafix) = False Then
s_Batch = New SpriteBatch(grafix)
sprite = BitmapToTexture2D(grafix, My.Resources.my_image)
Else
Throw New ArgumentNullException("Grafix")
Exit Sub
End If
End Sub
Finally we will use a backgroundworker to continually display our sprite:
Code:
Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Do Until True = False
grafix.Clear(Color.CornflowerBlue)
With s_Batch
.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend)
.Draw(sprite, New Rectangle(0, 0, My.Resources.my_image.Width, My.Resources.my_image.Height), Color.CornflowerBlue)
.End()
End With
grafix.Present()
Loop
End Sub
This is where all the action happens. The spritebatch.begin starts the whole process. The spritebatch.draw actually does the rendering. Finally the spritebatch.end brings the state of our device back to the state it was in before we called .Begin. You can think of spritebatch.end as FileStream.Close. The last thing we do is call graphicsdevice.Present, this actually shows the sprite. All in all in the end, it should look like this:
Code:
Option Strict On
Option Explicit On
Imports System.IO
Imports Microsoft.Xna.Framework
Imports Microsoft.Xna.Framework.Graphics
Public Class Form1
Private grafix As Graphics.GraphicsDevice = Nothing
Private s_Batch As SpriteBatch
Private sprite As Texture2D
Private Function initialize(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)
initialize = True
Catch ex As Exception
initialize = False
End Try
End Function
Public Shared Function BitmapToTexture2D(GraphicsDevice As GraphicsDevice, image As System.Drawing.Bitmap) As Texture2D
Dim bufferSize As Integer = image.Height * image.Width * 4
' Create new memory stream and save image to stream so
' we don't have to save and read file
Dim memoryStream As New System.IO.MemoryStream(bufferSize)
image.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png)
' Creates a texture from IO.Stream - our memory stream
memoryStream.Seek(0, SeekOrigin.Begin)
Dim texture As Texture2D = Texture2D.FromStream(GraphicsDevice, memoryStream, image.Width, image.Height, False)
memoryStream.Close()
Return texture
End Function
Private Sub Load_Content()
If IsNothing(grafix) = False Then
s_Batch = New SpriteBatch(grafix)
sprite = BitmapToTexture2D(grafix, My.Resources.my_image)
Else
Throw New ArgumentNullException("Grafix")
Exit Sub
End If
End Sub
Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Do Until True = False
grafix.Clear(Color.CornflowerBlue)
With s_Batch
.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend)
.Draw(sprite, New Rectangle(0, 0, My.Resources.my_image.Width, My.Resources.my_image.Height), Color.CornflowerBlue)
.End()
End With
grafix.Present()
Loop
End Sub
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim bool As Boolean = initialize(PictureBox1)
If bool = True Then
Call Load_Content()
BackgroundWorker1.RunWorkerAsync()
Else
MessageBox.Show("There was a problem initializing XNA.")
Me.Close()
End If
End Sub
End Class
Edit - I would like to mention that the busy loop used in this example is not very relevant. Instead, you should use a game loop like the one I made here: http://www.vbforums.com/showthread.p...aged-Game-Loop