|Direct Draw 7
is a revamped DirectDraw
tutorial, this time using DirectX 7. As many of you probably know, DirectX
7 has added official support for DirectX in Visual Basic. Before we had
to make do with Patrice Scribe's 3rd party tlbs. Before you start, you
might want to download the DirectX 7 SDK from MicroSoft's site.
SDK is not necessary but it will help you with the really specific functions.
Anyway, for this tutorial all you will need is DirectX 7 installed.
exactly is DirectDraw? It's a part of the DirectX API. It deals with your
2D video card. In other words it talks directly with the hardware which
is faster than GDI which has to deal with the system first. Plus GDI can't
take advantage of any specific hardware extras that come with your video
card. The thing is, you don't have to program any hardware specific instructions.
deals with the video card through drivers that the card manufacterer has
produced, usually with help from Microsoft. DirectDraw uses the HAL and
the HEL (hardware emulation layer). First it tries to use the HAL, but
if the call or feature is not supported by the hardware it uses the HEL,
in which case it does the task through software.
is explained in this tutorial? First off, starting an Exclusive Fullscreen
mode DirectDraw session. Then using two surfaces to do some animation,
and of course using color-keying.
you start, make sure that you have the DirectX 7 type-library checked under
first part of starting DirectDraw is to declare the main DirectX and DirectDraw
objects. You should remember that the DirectX object has to be declared
with a New.
Dx As New DirectX7
DDraw As DirectDraw7
we declare our surfaces. Nothing too complicated so far!
ddsPrimary As DirectDrawSurface7
ddsBackBuffer As DirectDrawSurface7
Background As DirectDrawSurface7
s640x480rect As RECT 'RECT variable
Sprite As DirectDrawSurface7
SpriteRECT As RECT 'Sprite's RECT variable
first two were our Primary surface (ie: the screen or stuff you actually
see) and the second one is the backbuffer, which we draw to first and do
all the dirty work on. This keeps the animation smooth and flicker free.
After this we declare our background and sprite surfaces and their RECTs.
A RECT is a set of coordinates that specifies the dimensions of the surface.
Ordinarily you would have to fill this out yourself, however for this sample
we are using a subroutine that will fill out our RECT for us. This saves
a lot of time to say the least =)
we have the surface descriptions for the Primary surface and the Backbuffer.
ddsdPrimary As DDSURFACEDESC2
ddsdBackbuffer As DDSURFACEDESC2
running As Boolean
'If user clicks on form end the program
running = False
running = True 'the app is running
On Error Resume Next
we actually create the DirectDraw object.
Set DDraw = Dx.DirectDrawCreate("")
Form1.Show 'show the form
we set the display mode for DirectDraw. We set the cooperative level to
exclusive, so our app is the only one using the graphics card. We also
set it to fullscreen mode. We then set the resolution and the BPP (Bits
Per Pixel) or Colour Depth, in this case 16-bit or true colour. This is
one of the most common graphics modes at the moment.
'Setting cooperative level and display mode
'Fullscreen exclusive mode
DDraw.SetCooperativeLevel Form1.hWnd, DDSCL_FULLSCREEN Or DDSCL_ALLOWMODEX
'640x480 resolution in 16-bit colour (about 16 000 colours)
'This is the most common BPP (Bits-Per-Pixel) used today.
DDraw.SetDisplayMode 640, 480, 16, 0, DDSDM_DEFAULT
we fill out the surface description for the Primary surface. It isn't anything
too complex, we just assign flags that, well, describe what the surface
does. In this case we describe it as the primary surface with 1 backbuffer
and then we actually create the surface.
'Fill out Primary Surface Description
ddsdPrimary.lFlags = DDSD_CAPS Or DDSD_BACKBUFFERCOUNT
'Using Video Memory for the primary surface and backbuffer
ddsdPrimary.ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE Or DDSCAPS_FLIP Or DDSCAPS_COMPLEX
ddsdPrimary.lBackBufferCount = 1 'One Backbuffer
'Create the Primary Surface
Set ddsPrimary = DDraw.CreateSurface(ddsdPrimary)
we fill out the surface description for the backbuffer and attach it to
the primary surface.
Dim Caps As DDSCAPS2
Caps.lCaps = DDSCAPS_BACKBUFFER
Set ddsBackBuffer = ddsPrimary.GetAttachedSurface(Caps)
'Fill out description
we load our sprites from the disk into surfaces we declared before. Don't
let this fool you though, this isn't a DirectX call. We call a subroutine
which loads them. You might want to keep this, since with the bmp loading
sub we actually automatically fill out the RECT variable for the surface,
as opposed to doing it by hand. This saves a LOT of time in the long run.
'Load bitmap files into surfaces
DDCreateSurface Background, App.Path & "\background.bmp", s640x480rect
DDCreateSurface Sprite, App.Path & "\sprite.bmp", SpriteRECT
we actually get to the render loop. First we do a colorfill, which fills
a surface with a specified colour. This is useful to make sure there aren't
any leftover graphics on the backbuffer before we blit. Then we actually
do the blitting. First the background, and then the sprite.
background is blitted without any transparency. The sprite however, is,
so the black around it is not drawn. This is accomplished by adding the
DDBLTFAST_SRCCOLORKEY flag to the call. The actual assigning of the colour-key
is done in the bitmap loading subroutine. Then we flip the backbuffer onto
the primary surface and we are technically done!
'Colorfill the background with flat black
ddsBackBuffer.BltColorFill s640x480rect, RGB(0, 0, 0)
'Use BltFast to draw the background (no transparency)
ddsBackBuffer.BltFast 0, 0, Background, s640x480rect, DDBLTFAST_WAIT
'Use BltFast to draw the Sprite (transparent)
ddsBackBuffer.BltFast 50, 50, Sprite, SpriteRECT, DDBLTFAST_SRCCOLORKEY
'Flip the backbuffer to the primary surface
ddsPrimary.Flip Nothing, DDFLIP_WAIT
Loop Until running = False
following deals with unloading DirectDraw. We have to first destroy any
surfaces we created to free up the memory, then we restore the display
'With DirectDraw you must unload all your surfaces etc.
'to clear up memory.
Set Background = Nothing
Set Sprite = Nothing
Set ddsPrimary = Nothing
Set ddsBackBuffer = Nothing
'Restore to normal display mode
DDraw.SetCooperativeLevel Form1.hWnd, DDSCL_NORMAL
Here is the actual sub that
performs loading a bitmap from the disk into a surface. Basically we fill
out the surface's description, with the added feature of keeping the surfaces
in video memory or system memory.
Sub DDCreateSurface(surface As DirectDrawSurface7, BmpPath As String, RECTvar
As RECT, Optional TransCol As Integer = 0, Optional UseSystemMemory As
Boolean = True)
'This sub will load a bitmap from a file
'into a specified dd surface. Transparent
'colour is black (0) by default.
Dim tempddsd As DDSURFACEDESC2
Set surface = Nothing
tempddsd.lFlags = DDSD_CAPS
If UseSystemMemory = True Then
tempddsd.ddsCaps.lCaps = DDSCAPS_SYSTEMMEMORY Or DDSCAPS_OFFSCREENPLAIN
tempddsd.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN
Set surface = DDraw.CreateSurfaceFromFile(BmpPath, tempddsd)
'set the RECT dimensions
RECTvar.Right = tempddsd.lWidth
RECTvar.Bottom = tempddsd.lHeight
Dim ddckColourKey As DDCOLORKEY
ddckColourKey.low = TransCol
ddckColourKey.high = TransCol
surface.SetColorKey DDCKEY_SRCBLT, ddckColourKey
That's pretty much it for
this DirectDraw tutorial. Feel free to download
the source. If you're still having trouble with DirectDraw you can
email me or talk about it on our forum!