Platform SDK: DirectX

Step 3: Blit to the Primary Surface

[C++]

This section pertains only to application development in Visual Basic. See DirectDraw C/C++ Tutorials.

[Visual Basic]

There are several steps involved before the simple sprite animation is displayed on the screen. Both the sprite surface and the background image are composed to the back buffer and then the back buffer is blitted to the primary surface. The animation is achieved by constantly moving the location of the destination rectangle when blitting the sprite surface to the back buffer. In Tutorial 2, the DoFrame procedure updates the location of the sprite surface and repaints the background image while the application is running. Additionally, there is some code to display the frames per second (fps) of the animation.

First a simple timer loop is implemented to calculate the angle of where to place the sprite:

t2 = Timer
If t1 <> 0 Then
    a = a + (t2 - t1) * 100
    If a > 360 Then a = a - 360
End If
t1 = t2

Next we make sure that we still retain control of the created surfaces. Surfaces can be lost and will need to be restored if another application takes control of the display adapter. The Tutorial 2 sample contains a simple function, ExModeActive, that tests the cooperative level of the DirectDraw object to determine whether or not we will have to restore the surfaces. This is shown in the following code:

Dim bRestore As Boolean
bRestore = False
Do Until ExModeActive
    DoEvents
    bRestore = True
Loop

DoEvents
If bRestore Then
    bRestore = False
    objDD.RestoreAllSurfaces
End If

Next, a small bit of code is implemented to display the frames per second of the sprite animation. This can be useful to help streamline your application and to find potential bottlenecks in your application.

'calculate FPS
i = i + 1
If i = 30 Then
    tNow = Timer
    If tNow <> tLast Then
       fps = 30 / (Timer - tLast)
       tLast = Timer
       i = 0
       Me.Caption = "DD Transparency    Frames per Second =" + Format$(fps, "#.0")
    End If
End If

Next we calculate the x and y coordinates of where to place the sprite:

x = Cos((a / 360) * 2 * 3.141) * Picture1.Width / 8
y = Sin((a / 360) * 2 * 3.141) * Picture1.Height / 8
x = x + Picture1.Width / 2
y = y + Picture1.Height / 2

The previous position of the sprite is held in a RECT type so we can repaint only the affected portion of the background surface. This increases the performance of the application because we do not have to constantly blit the entire surface. Then we determine the new position of the sprite and blit the sprite surface to the back buffer.

'Clean up background from last frame
'by only repainting the background where it needs to
Dim rClean As RECT
If lastX <> 0 Then
    rClean.Left = lastX
    rClean.Top = lastY
    rClean.Right = lastX + ddsdSprite.lWidth
    rClean.Bottom = lastY + ddsdSprite.lHeight
    Call objDDBackBuffer.BltFast(lastX, lastY, objDDLakeSurf, rClean, DDBLTFAST_WAIT)
End If

lastX = x
lastY = y

'Blit the sprite to the backbuffer
'using the color key on the source
'wait for the blt to finish before moving one
Dim rtemp As RECT
rtemp.Left = x
rtemp.Top = y
rtemp.Right = x + ddsdSprite.lWidth
rtemp.Bottom = y + ddsdSprite.lHeight
    
objDDBackBuffer.Blt rtemp, objDDSpriteSurf, rSprite, DDBLT_KEYSRC Or DDBLT_WAIT

Finally, we obtain the rectangle coordinates of the picture box control by calling the DirectX7.GetWindowRect method and call the DirectDrawSurface7.Blt method to blit the back buffer to the primary surface.

Call objDX.GetWindowRect(Picture1.hWnd, rPrim)

Call objDDScreen.Blt(rPrim, objDDBackBuffer, rBackBuffer, DDBLT_WAIT)