advertisement

Find Code  Advanced Search   

browse free vb code
Submit Code
ASP,  HTML, and XML
Database
Dates  and Math
Files  and Directories
Forms  and Controls
Lists,  Collections, and Arrays
Miscellaneous
Multimedia/Games
Office/VBA
Network/Internet
Registry
Screen/Graphics
String  Manipulation
System/API
Windows  2000/XP
VB.NET/ASP.NET



advertisement
Creating a Direct Draw Application (Tutorial)

Author: Jack Hoxley
Category: Multimedia/Games
Difficulty: Intermediate

Version Compatibility:  Visual Basic 5   Visual Basic 6

This code has been viewed 118645 times.

I am assuming that you have read, and understand the theory behind DirectDraw. Choose a tutorial from the table:

(1) Starting Your Project ˙
(2) Declaring the variables
(3) Create Objects and Set the Display Mode
(4) Create the Surfaces
(5) Create the BLT Code
(6) Creating the Main Loop
(7) Destroying Everything
(8) Running, Debugging and an Overview

˙

˙

˙

(1)
STARTING YOUR PROJECT
You should now have added a reference for DirectX 7 to your project. Before getting onto the coding, set these values on Form1:

autoredraw=false borderstyle=0 controlbox=false maxbutton=false minbutton=false scalemode=3 (pixels) windowstate=2 (Maximised)

This should result in a blank form with no title bar, no border, and that is maximised when run. To connect everything up, insert the following lines in the specified places.

Private Sub Form_load()
init
'Calls the initialize sequence when the form is loaded
End Sub


Private Sub Form_Paint()
blt
'Blt when windows tells your window to refresh itself
End Sub

Private Sub Form_Click()
EndIt
'End the program when the user clicks anywhere on 'the screen. Remember this.
End Sub

For preparation, make a bitmap 640 pixels wide, by 480 pixels high. This picture will be Blt'ed to the screen in this example. Save your files and go to step 2.
[TOP]

˙

(2)
DECLARE VARIABLES
Open up the code window for your Form, scroll to the top and open (Declarations) sub. You can copy and paste this code straight in there and Visual Basic will do the formatting:

Option Explicit

Dim binit As Boolean 'Used by the program to see if everythings been 'started.

Dim DirectX As New DirectX7 'Master Object, Everything is created from this.
Dim ddraw As DirectDraw7
'The DirectDraw Object, this is created from the DirectX 'Object
Dim MainSurf As DirectDrawSurface7
'The Surface that will hold our picture.

Dim Primary As DirectDrawSurface7
Dim Backbuffer As DirectDrawSurface7
'These are explained in the Theory section.
Dim ddsd1 As DDSURFACEDESC2
'Describes the Primary Surface
Dim ddsd2 As DDSURFACEDESC2
'Describes our picture
Dim ddsd4 As DDSURFACEDESC2
'holds screen information 'Descriptions: These are needed before you can create a surface. They 'describe it's initial Height, Width and other information. ddsd stands for 'Direct Draw Surface Description

Dim brunning As Boolean 'Check if the program is still running
Dim CurModeActiveStatus As Boolean
'Used to check if users computer 'supports the requested display mode
Dim bRestore As Boolean
'An error handling flag


[TOP]

˙

(3)
CREATE OBJECTS AND SET DISPLAY MODE

Before you see anything happen in your project you need to create all the objects. You will also need to create 4 "Subs". To create a sub type "Sub (Sub Name)" in the declarations section and press Return. Create these 4 subs:

Blt
Init
initsurfaces
endit

You will also need one function, do this in the same way as creating a sub, except: "Function (Function name) ". Create a function called ExModeActive() as boolean. We can now fill in these subs/functions:

Sub_INIT()
Place the following code in the Init sub you just created:

sub Init()
˙˙˙ On Local Error GoTo errOut˙˙˙˙˙ 'If there is an error, it closes the 'program

˙˙˙ Set ddraw = directx.DirectDrawCreate("") 'This is extremely important. 'Nothing can be done before you have created the DDraw object.
˙˙˙ Me.Show

˙˙˙ 'indicate that we dont need to change display depth
˙˙˙ Call ddraw.SetCooperativeLevel(Me.hWnd, DDSCL_FULLSCREEN Or DDSCL_ALLOWMODEX Or DDSCL_EXCLUSIVE)˙ 'THIS IS PART OF THE ABOVE LINE. WHEN PASTING IT, MAKE SURE ITS ALL ON 'THE SAME LINE
'***SEE NOTE(1) BELOW
˙˙˙ Call ddraw.SetDisplayMode(640, 480, 16, 0, DDSDM_DEFAULT)
'***SEE NOTE(2) BELOW

˙˙˙ 'get the screen surface and create a back buffer too
˙˙˙ ddsd1.lFlags = DDSD_CAPS Or DDSD_BACKBUFFERCOUNT
˙˙˙ ddsd1.ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE Or DDSCAPS_FLIP Or DDSCAPS_COMPLEX
˙˙˙ ddsd1.lBackBufferCount = 1
˙˙˙˙ 'ddsd1: the description for the primary buffer. It also defines that there will be 1 back buffer.
˙˙˙ Set primary = ddraw.CreateSurface(ddsd1)
˙˙˙˙ 'Creates the primary surface from the information in ddsd1
˙˙˙ Dim caps As DDSCAPS2
˙˙˙ caps.lCaps = DDSCAPS_BACKBUFFER˙˙˙˙ 'Defines it as a backbuffer
˙˙˙ Set backbuffer = primary.GetAttachedSurface(caps)˙˙˙ 'Get the primary surface to create a backbuffer from the caps 'description
˙˙˙ backbuffer.GetSurfaceDesc ddsd4
˙˙˙ 'Makes ddsd4 hold all the information on the current settings: ie height & width
˙˙˙ 'Create DrawableSurface class form backbuffer

˙˙˙ backbuffer.SetFontTransparency True˙˙˙ 'Makes any writting that appear transparent, otherwise you get a black outline to 'all the text.
˙˙˙ backbuffer.SetForeColor vbGreen˙˙˙˙ 'This makes the text green, it also makes the line/circle/box methods green. It can be 'changed at any point, and can be set by the vb****** colours, or RGB(0-255,0-255,0-255) method if you need a˙ more 'precise method.

˙˙˙ ' init the surfaces This is the sub that you made earlier, which contains nothing at the moment.
˙˙˙ InitSurfaces
˙˙˙˙ 'This sets some flags that are used else-where in the program.
˙˙˙ binit = True
˙˙˙ brunning = True
˙˙˙ 'This is the error handler, if theres an error it will end everything.
˙errOut:
˙˙˙ EndIt˙ 'Another sub that you made earlier
End Sub

˙

NOTE(1):
The Cooperative level. This lets windows know how important your program is. Windows, by default, shares the resources between all the open programs. The cooperative Level is there so you can tell windows to share resources whilst your program is running or not. The best example is in DirectSound, when you set the directSound cooperation to high it wont let any other programs play sounds when your program is, when set to low, you will get other windows sounds filtering in with yours.

Games will tend to need to be set to EXCLUSIVE, so that windows doesn't interfere with it. A simple drawing program can run NON_EXCLUSIVE, as the user is likely to be doing other things at the same time. The 3 main modes you will need to know about are:

DDSCL_NORMAL - Shares with other applications. Best used in multimedia applications. Also used for windowed mode

DDSCL_EXCLUSIVE - Doesn't share with anything else. Best used for games

DDSCL_FULLSCREEN - Fullscreen mode, opposite of windowed mode, where you can see windows in the background.

NOTE(2):
Set Display Mode. This is where you actually see some change, the example will use a 640x480 fullscreen window, with 16bit colour (65,536 colours). I chose 16 bit colour as most computers will support it, and it's the middle colour depth. The 0 refers to refresh rate - Leave this as 0, Visual Basic doesn't like this being changed and can lead to some permenant damage to your monitor if set too high. The last bit is the mode:

DDSDM_DEFAULT - This is the mode you will want to use.

DDSDM_STANDARDVGAMODE -Do not use this, it sets the display mode to DOS 320x200 in 16 colours. If you use this mode, set the height/width/colourdepth to 0.

ExModeActive function
This little function is used in the BLT code. It returns true or false depending on whether or not the user's computer supports the requested Display mode.

function ExModeActive() as Boolean
˙˙˙ Dim TestCoopRes As Long 'holds the return value of the test.

˙˙˙ TestCoopRes = ddraw.TestCooperativeLevel 'Tells DDraw to do the test

˙˙˙ If (TestCoopRes = DD_OK) Then
˙˙˙˙˙˙˙ ExModeActive = True 'everything is fine
˙˙˙ Else
˙˙˙˙˙˙˙ ExModeActive = False 'this computer doesn't support this mode
˙˙˙ End If
End Function


[TOP]

˙

(4)
CREATE SURFACES

If you run this program now, all it should do is change the resolution and show a maximised form, but dont try running it, as it will crash when you close it. Now we have the init code written, we need to do the code for initsurfaces sub. You will notice it is called towards the end of the init sub. Open up the relevent section in your code window and copy this code:

sub InitSurfaces()
˙˙˙ Dim FileX as string 'Used to hold the bitmaps file name.
˙˙˙ Set Mainsurf = Nothing˙ 'Clears the surface, as an error handler (later on) the program sometimes needs to re-init the 'surfaces, if it does this it needs a nice clean surface to start from.

˙˙˙ 'load the bitmap into a surface - a picture called demo.bmp located in the same folder as your project.
˙˙˙ ddsd2.lFlags = DDSD_CAPS Or DDSD_HEIGHT Or DDSD_WIDTH
˙˙˙ ddsd2.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN
˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ 'The above two lines should be kept the same for any surface. As DirectX is designed for C++ VB doesn't 'support many of the low level calls which are started with these lines. 99% of the time this set up will suit your project
˙˙˙ ddsd2.lWidth = ddsd4.lWidth 'Make the surface the same size as the screen
˙˙˙ ddsd2.lHeight = ddsd4.lHeight˙
˙˙˙˙˙˙˙˙˙˙˙ 'The height & width can be specified in pixels, and can be bigger than the screen. The bitmap will be 'stretched/squashed to fit these settings. NOTE: a big surface will require lots of memory, which means low performance and 'potential crashes on low-spec machines
˙˙˙ FileX = app.path & "\demo.bmp"˙ 'If you saved your file under a different name, change this line accordingly
˙˙˙ Set Mainsurf = ddraw.CreateSurfaceFromFile(fileX, ddsd2)˙ 'Create a new surface from the specified file, based on 'ddsd2's description
End Sub


Now that you have created a surface with a bitmap stored in it, we need to write something that uses it.

[TOP]

˙


(5)
CREATE THE BLTING CODE

The blt code is the heart of this program. The blt sub routine copies your picture onto the screen. On a fast computer (300Mhz+) it will do this 50-60 times a second, i can't imagine how fast it will run on the first Ghz PC (probably not too far away).This code is quite complex, so make sure you read the annotation. It also helps if you know about Paintpicture or BitBlt, this is very similiar to these functions.

Sub BLT()
˙ On Local Error GoTo errOut˙˙ 'You must have an error handler
˙˙˙ If binit = False Then Exit Sub˙ 'Simple: dont do anything unless DDraw has been initialized
˙˙˙ Dim ddrval As Long˙ 'DirectDraw returns a number when it blt's. This is just to hold that number

˙˙˙ Dim rMain As RECT
˙˙˙ '~~~~~RECTS~~~~~
˙˙˙ 'A rect is used to define an area. it has 4 properties: top,bottom,left,right. They specify the top-left corner and the 'bottom-right corner. The values are then used when blting to work out which part of a surface you want to copy. if you want 'a square 100x100 out of the top corner of a surface you would right it as so:
'rect.top=0
'rect.left=0
'rect.right=100
'rect.bottom=100
˙˙ ' this will keep us from trying to blt in case we lose the surfaces (alt-tab)
˙˙˙ bRestore = False
˙˙˙ Do Until ExModeActive 'short way of saying "do until it returns true"
˙˙˙˙˙˙˙ DoEvents 'Lets windows do other things
˙˙˙˙˙˙˙ bRestore = True
˙˙˙ Loop

˙˙˙ ' if we lost and got back the surfaces, then restore them
˙˙˙ DoEvents 'Lets windows do it's things
˙˙˙ If bRestore Then
˙˙˙˙˙˙˙ bRestore = False
˙˙˙˙˙˙˙ ddraw.RestoreAllSurfaces
˙˙˙˙˙˙˙ InitSurfaces ' must init the surfaces again if they we're lost. When this happens the first line of initsurfaces is important
˙˙˙ End If

˙˙˙ 'get the area of the bitmap we want to blt (in this case all of it)
˙˙˙ rMain.Bottom = ddsd2.lHeight
˙˙˙ rMain.Right = ddsd2.lWidth

˙˙˙ 'blt to the backbuffer from our˙ surface to
˙˙˙ 'the screen surface such that our bitmap
˙˙˙ 'appears over the window
˙˙˙ ddrval = backbuffer.BltFast(0, 0, Mainsurf, rMain, DDBLTFAST_WAIT)˙ 'This paints the area described by rMain of 'MainSurf onto the backbuffer at X=0 Y=0.

˙˙˙ 'flip the back buffer to the screen
˙˙˙ primary.Flip Nothing, DDFLIP_WAIT˙˙˙ 'This is where it actually appears to the user

errOut:˙ 'In this case the error handler doesn't close the program, it just skips redrawing the screen.
End Sub


At the moment, your program does not call this function, next we will create a loop that calls this sub.

[TOP]


(6)
CREATING THE MAIN PROGRAM LOOP

The main programming loop is part of the init sub. I didn't include it above because it needs a bit of explaining. Paste the following code into the init sub:

'˙˙˙ InitSurfaces
'˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ >>>These lines should be before it, but dont change them. Copy the black text only.˙
'˙˙˙ binit = True
'˙˙˙ brunning = True
˙˙˙ Do While brunning
˙˙˙˙˙˙˙ blt
˙˙˙˙˙˙˙ DoEvents
˙˙˙ Loop


It looks extremely simple, and it is, but I thought I should explain it properly. Basically, this loop keeps on doing blt & doevents until brunning=false. Your computer will try to do this as quickly as possible, this is the basis of a frame rate: the faster it does this loop, the higher the frame rate. You should already have completed the blt code, so I don't need to explain it. The Doevents is the most important part of a stable loop. Without this your program will crash the computer after about 5 seconds. DoEvents lets windows do everything else that it wants too - for example, the user has a word processor open, the DoEvents lets windows keep that program happy. Although it appears that we are controlling DirectDraw, we are in fact sending messages to it, such as telling it too change the resolution etc; because we keep sending it messages it can quickly become confused. Everytime we tell it to blt, DDraw has to do something. DoEvents gives it time to finish blting before doing another loop. If we didn't let it finish we would get some weird results.

I hope you understand that!
[TOP]

˙

(7)
DESTROYING EVERYTHING

To finish off your program we must "un-link" ourselves from DirectX, this is done by destroying what we have created. It is only a few lines, but they are very important for a smooth running application. Copy and paste this code into the endit sub:

Sub EndIt()
˙˙
˙ Call ddraw.RestoreDisplayMode 'sets the screen resolution back to what it was before the program was started.
˙˙˙ Call ddraw.SetCooperativeLevel(Me.hWnd, DDSCL_NORMAL) 'tells DirectX that the application is no longer 'EXCLUSIVE. If we were to just drop the program it would crash, as DirectX will still be expecting an exclusive application 'to be running
˙˙˙ End 'end the program
End Sub


Now all your code is complete you can run your application. You should be presented with your picture in a fullscreen window. Click the mouse to close the program.
[TOP]

˙


(8)
RUNNING, DEBUGGING, AND AN OVERVIEW˙

Running this program is fairly simple, just remember that you can get some weird results. I strongly suggest that you save your project AND any other applications stuff before running it. I have seen some monumetal crashes from DirectX which have cost me entire projects and artwork in another program.

You should be familiar with VB's error window (the one where it describes it, offers help, or debugs/ends it). If one of these appears during your project it wont show up - your application will just freeze. to get around this press F1 - this will minimize your application and launch the help file. you can then asses the problem. Because of the error handlers, you shouldn't get any error messages. but if it keeps on stopping remark the on error........ lines in blt and init subs. Another useful tip: to stop your program without there being an error press CTRL+BREAK then F1, this will pause your program and launch the help file - ignore the help file and check what your program is doing.....

¸2000 Jack Hoxley -˙All rights reserved.

The material on this page may be reproduced as long as credit is˙given to myself "Jack˙Hoxley"

The author can be e-mailed at jollyjeffers@greenonions.netscapeonline.co.uk. His web site is http://members.dencity.com/dx4vb/

Sponsored Links

internet.commediabistro.comJusttechjobs.comGraphics.com

Search:

WebMediaBrands Corporate Info

Legal Notices, Licensing, Permissions, Privacy Policy.
Advertise | Newsletters | Shopping | E-mail Offers | Freelance Jobs