article

Tutorial - PROPER Graphics Loading

Email
Submitted on: 1/26/2015 7:41:00 PM
By: IRBMe (from psc cd)  
Level: Intermediate
User Rating: By 7 Users
Compatibility: VB 5.0, VB 6.0
Views: 876
 
     This is a tutorial which will show you how to load bitmaps, gifs, jpegs or whatever from a resource file into main memory and use them. Remember to download the ZIP it has some source you can use and an example. Also please vote and and give feedback.

This article has accompanying files
 
				






Tutorial – Graphics Loading
<--[if gte mso 9]>
 
 Christopher Waddell
 Christopher Waddell
 5
 76
 2002-07-21T18:46:00Z
 2002-07-21T20:40:00Z
 4
 1369
 7807
 Developement
 65
 15
 9587
 9.4402
 




Tutorial – Graphics Loading

 

PART 1 – The Resource File

 

I have seen many ways of games storing and loading their graphics.

 

One of the most common ways is to store all the graphics in separate files and load them all at runtime using the LoadPicture method. The trouble with this is that in a finished game, anybody can just steal or change the graphics with a simple bitmap editor like PAINT. This also applies to graphics which are all stored in the same bitmap file.

 

Another common way, and probably the worst, is to store all the graphics on a hidden form in picture boxes. This is probably the easiest way but definitely the worst. It makes your compiled exe file huge, it is very difficult to edit the graphics without a whole recompilation of the whole project, and it takes up a large amount of memory (lots of picture boxes), unless all the graphics are stored in one picturebox.

 

The best way, but unfortunately, not the most common, is to store them all in a resource file. This means that it isn’t so easy for other people to steal or change your graphics, you can easily update your graphics without having to recompile your project, you’re compiled exe isn’t huge, and you don’t have about 50 files, one for each graphic.

 

So the conclusion is: resource files are your friend! Use them, and use them often. You don’t just have to store your graphics in them; you can store text, graphics, sounds and anything else you want all in one file.

 

So how do you use a resource file. Well, first get a resource editor, VB has an inbuilt one and this is the one I use.

 

Click the add-ins menu, click add-in manager and load “VB 6 Resource Editor”. Press OK and now you should see a green icon on your toolbar. If not, click the Tools Menu and it should be at the bottom. Click this once and the VB6 resource editor should pop-up. On the resource editor’s toolbar, press the “Add Custom” button, it looks like 4 silver squares. Here you can add any file you want, we will store our graphics in here. Note, there is a button to add graphics, but we will need to load them into the “custom” section, you will see why later.

 

You should now see an open file dialog box. Find your graphic and load it, now you should be able to name it. If it is the first one you are loading it will be by default called “101” and I will keep it at that for ease but you should name it properly to something you will remember. You should also give your file a prefix so you remember its type.

 

E.g.

JPG_Plane

BMP_Bullet

WAV_GunShot

MP3_BackgroundMusic

 

I now have one JPEG file loaded into the custom section and called “101” in my file. Once you have added your resources, save the resource file with the same name as your project (e.g. “Project1.RES”) and now close the editor.

 

Now, how do we load our graphics from a resource file into a Picturebox? Well, if you just want to do this, you should load your resources into the picture section of your resource file and use:

 

Picture1.Picture = LoadResPicture(ID,Type)

 

But as you will now see, we don’t want to load pictures into pictureboxes for games, and also why we put our graphic in the custom section. Ok, we first have to look at a new function to load the custom graphic.

 

 

Private Sub ExtractResource(FileName As String, ResourceName As Variant)

 

Dim Buffer() As Byte

Buffer = LoadResData(ResourceName, "CUSTOM")

Open FileName For Binary As #1

Put #1, , Buffer

Close #1

Erase Buffer

End Sub

 

I wrote this function just there but it probably has many other versions on the Internet. What it does is loads the resource into a byte buffer and then loads that byte buffer into a file.

 

You call it like:

 

Call ExtractResource (“C:\MyGraphic.Jpg”,”101”)

 

It is useful to note, this function will also work for any other custom resource.

 

Now all games (I should hope) will use Bitmaps, but these make your resource files very large, so I store them in the resource files as JPEG’s. Using this function and the resource file I made earlier, I now have a file in C:\ called MyGraphic.Jpg. JPG’s are no good though, so I want to convert it to a bitmap. It took me less than 4 minutes to solve this problem, and here’s the result:

 

Private Sub ConvertToBitmap(FileName As String, Extension As String)

 

Dim Pic As IPictureDisp

 

Set Pic = New StdPicture

Set Pic = LoadPicture(FileName & "." & Extension)

Kill FileName & "." & Extension

SavePicture Pic, FileName & ".bmp"

 

End Sub

 

This is how to use it:

 

Call ConvertToBitmap(“C:\MyGraphic”,”JPG”)

 

This will turn MyGraphic.Jpg into MyGraphic.Bmp. Nice huh!

 

Ok, I have now extracted my JPEG graphic from a resource file and turned into a BMP file on the harddrive. Now we have something that’s useable. We’re half way there now.

 

PART 2 – LOADING THE GRAPHIC

 

I’m going to paste a whole lot of commented code and hopefully that should do it.

 

 

Private Declare Function GetDesktopWindow Lib "user32" () As Long

Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long

 

Private Declare Function LoadImage Lib "user32" Alias "LoadImageA" (ByVal hInst As Long, ByVal lpsz As String, ByVal un1 As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal un2 As Long) As Long

Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long

Private Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long

 

Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long

Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long

Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long

 

Private Type BITMAP

bmType As Long 'Bitmap type

bmWidth As Long 'Width/Pixels

bmHeight As Long 'Height/Pixels

bmWidthBytes As Long 'Width/Bytes

bmPlanes As Integer 'Planes

bmBitsPixel As Integer 'Bits per Pixel

bmBits As Long 'Bits

End Type

 

Public Type GRAPHIC

hGraphic As Long 'Handle

hdc As Long 'Device context

hWidth As Long 'Width/Pixels

hHeight As Long 'Height/Pixels

End Type

 

Private Const LR_LOADFROMFILE As Integer = &H10

Private Const IMAGE_BITMAP As Integer = 0

 

 

Public Sub DeleteGraphic(ByRef udtGraphic As GRAPHIC)

 

DeleteDC udtGraphic.hdc 'Delete the Device Context

DeleteObject udtGraphic.hGraphic 'Delete the object

 

End Sub

 

 

Public Function LoadBitmap(ByVal Path As String) As GRAPHIC

 

Dim hDesktop As Long

Dim bmBitmap As BITMAP

 

'Load the bitmap, this will return a handle if successful

LoadBitmap.hGraphic = LoadImage(App.hInstance, Path, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE)

 

If LoadBitmap.hGraphic = 0 Then 'If no handle, then the loadimage function must have failed _

Most probable cause is because it dousn't exist or the given path is wrong

Err.Raise _

Number:=vbObjectError + 513, _

Source:="LoadBitmap(''" & Path & "'')", _

Description:=("The graphic cannot be loaded. Please ensure that ''" & Path & "'' exists, as this is the most probable cause.")

Else 'We got a handle, the bitmap's loaded. So...

hDesktop = GetDesktopWindow 'Get desktop handle

LoadBitmap.hdc = CreateCompatibleDC(GetDC(hDesktop)) 'Create a new DC compatible with the desktop

SelectObject LoadBitmap.hdc, LoadBitmap.hGraphic 'Select the graphic, and the new DC into an object

 

GetObject LoadBitmap.hGraphic, Len(bmBitmap), bmBitmap 'Get the width and height of the graphic

LoadBitmap.hWidth = bmBitmap.bmWidth

LoadBitmap.hHeight = bmBitmap.bmHeight

End If

 

End Function

 

Ok, just in case you’re wondering, I again wrote that.

 

Just use like this:

 

Dim bmBitmap As GRAPHIC

 

BmBitmap = LoadBitmap(“C:\MyGraphic.Bmp”)

 

‘Do stuff with it

 

DeleteGraphic bmBitmap

 

You now have a UDT called bmBitmap (or whatever) which contains a handle and a Device Context to your graphic, and also its width and height in pixels. This should be all the information you need to draw your graphic using BitBlt, StretchBlt, TransparentBlt, PatBlt and any other windows GDI functions that require DC’s, Width’s or Height’s.

 

I must emphasise to you to remember to use DeleteGraphic once you are finished, otherwise you will have a memory leak. And only one thing left: delete the bitmap that was created on the hard-drive.

 

Kill “C:\MyGraphic.Bmp”

 

OK, I think that’s it.

 

Hopefully you should have learned how to:

 

Put graphics into a RES file

Load the graphics from the RES file into a file on the hard-drive

Convert the file to a bitmap (if needed)

Load the file into memory with useful information like DC

Delete the Graphic

Delete the File

 

If you download the ZIP you will find the offline html version of this tutorial, and a useful stand-alone module containing all the useful functions mentioned above + a project showing how everything in this project comes together by using the module.

 

Please remember to vote and leave feedback. And I expect to see this in your future games (Just mention my name in the credits if you use my module by the way).

 

 

winzip iconDownload article

Note: Due to the size or complexity of this submission, the author has submitted it as a .zip file to shorten your download time. Afterdownloading it, you will need a program like Winzip to decompress it.Virus note:All files are scanned once-a-day by Planet Source Code for viruses, but new viruses come out every day, so no prevention program can catch 100% of them. For your own safety, please:
  1. Re-scan downloaded files using your personal virus checker before using it.
  2. NEVER, EVER run compiled files (.exe's, .ocx's, .dll's etc.)--only run source code.
  3. Scan the source code with Minnow's Project Scanner

If you don't have a virus scanner, you can get one at many places on the net including:McAfee.com


Other 21 submission(s) by this author

 


Report Bad Submission
Use this form to tell us if this entry should be deleted (i.e contains no code, is a virus, etc.).
This submission should be removed because:

Your Vote

What do you think of this article (in the Intermediate category)?
(The article with your highest vote will win this month's coding contest!)
Excellent  Good  Average  Below Average  Poor (See voting log ...)
 

Other User Comments


 There are no comments on this submission.
 

Add Your Feedback
Your feedback will be posted below and an email sent to the author. Please remember that the author was kind enough to share this with you, so any criticisms must be stated politely, or they will be deleted. (For feedback not related to this particular article, please click here instead.)
 

To post feedback, first please login.