Tipp 0418
|
2D mit DirectX 8
|
 |
|
Autor/Einsender: Datum: |
|
Alexander Csadek 06.10.2004 |
|
Entwicklungsumgebung:
DirectX-Version: |
|
VB 6
DirectX 8 |
|
|
Wer direkt mit DirectX 8 begonnen hat, Spiele mit Visual Basic zu erstellen,
dem ist es vielleicht gar nicht aufgefallen, aber diejenigen, die von
DirectX 7 auf 8 umsteigen, fragen sich "Wo ist DirectDraw für meine Spiele in 2D?".
|
Nun, bei DirectX 8 gibt es die Komponente DirectDraw nicht mehr. Sie wurde von Microsoft unter dem Begriff
DirectGraphics mit Direct3D zusammengefasst und in die Komponente
Direct3D verschoben.
|
Möchte man nun ein Spiel in 2D erstellen, so ist es nicht unbedingt notwendig, dies ausschließlich über die Komponente
Direct3D zu tun und sich mit Matrizen und Vertexe herumzuschlagen. Es geht auch einfacher und
man kann trotzdem skalieren, rotieren und verfügt über Farb-Modulation und
Blend-Effekte. Dazu stellt das D3DX8-Objekt mit dem D3DX8-Sprite-Objekt, ein Objekt
speziell für 2D-Bilder (Sprites) zur Verfügung.
|
Das D3DX8-Objekt wird nicht wie die anderen DirectX-Komponenten über das
DirectX8-Objekt erstellt, sondern als eigenes Objekt instanziert:
|
|
|
Das D3DX8-Sprite-Objekt wird dann mit Hilfe des D3DX8 und einem gültigen 3DDevice erstellt.
|
|
|
Set gD3DX8Sprite = gD3DX8.CreateSprite(gD3DDevice8)
|
|
|
Jetzt steht einem Spiel in 2D nichts mehr im Wege. Man erstellt ein Direct3D-Objekt und einen 3DDevice, egal ob Vollbild (fullscreen mode) oder im Fenster (windowed mode).
|
Die Bitmaps werden über das D3DX8-Objekt als normale Texturen geladen, zum Beispiel:
|
|
|
Set texBild = gD3DX8.CreateTextureFromFileEx( _
gD3DDevice8, App.Path & "\vbfun.bmp", _
312, 208, 1, 0, D3DFMT_A8R8G8B8, _
D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_FILTER_NONE, _
&HFF000000, ByVal 0, ByVal 0)
|
|
|
Das Zeichnen der Bilder in 2D erfolgt zwischen dem BeginScene und EndScene vom 3DDevice, und zwar mit dem D3DX8-Objekt. Das angenehme dabei ist, die Position des Bildes wird in Bildschirm-Koordinaten (x, y) angegeben.
|
|
|
gD3DDevice8.BeginScene
gD3DX8Sprite.Begin
gD3DX8Sprite.Draw(texBild, recSource, vecScaling, _
vecRotationCenter, sngRotation, vecTranslation, lngColor)
gD3DX8Sprite.End
gD3DDevice8.EndScene
gD3DDevice8.Present ByVal 0, ByVal 0, 0, ByVal 0
|
|
|
Die D3DX8-Sprite-Objekt Methode Draw verlangt folgende Parameter und bietet
zudem ein paar interessante Möglichkeiten.
|
|
Color |
Farbe und Alpha-Kanal des Bildes kann hiermit verändert werden.
Bei &HFFFFFFFF werden die Farben und der Alpha-Kanal vom Originalbild genommen.
|
Rotation |
Angabe der Rotation in Radians entgegen dem Uhrzeigersinn
(counter-clockwise).
|
RotationCenter |
ein 2D-Vektor mit dem gewünschten Rotations-Zentrum.
x = 0 und y = 0 ist immer die linke obere Ecke des Bildes.
|
Scaling |
ein 2D-Vektor mit der gewünschten Skalierung des Bildes.
Bei x = 1 und y = 1 wird die Originalgröße verwendet.
|
SrcRect |
der gewünschte Bild-Ausschnitt.
ByVal 0
bedeutet, dass das gesamte Bild gezeichnet wird.
|
SrcTexture |
das Bild aus einem Direct3DTexture-Objekt.
|
Translation |
Angabe der x- und y-Position am Bildschirm mittels eines 2D-Vektors.
x = 0 und y = 0 ist die linke obere Bildschirmecke.
|
|
Vorbei ist die Trauer um DirectDraw. Spiele in 2D mit DirectX8 sind möglich, und noch dazu mit Skalieren, Rotieren, Farb-Modulation und Blend-Effekt.
|
Es folgt nun der für diesen Tipp relevante Code...
|
|
|
Private Sub Render()
Dim recSource As RECT
Dim hlpZeile As Integer
Dim sngRotation As Double
Dim lngColor As Long
Dim i As Integer
If gD3DDevice8 Is Nothing Then Exit Sub
'bereinigen des BackBuffers
gD3DDevice8.Clear 0, ByVal 0, D3DCLEAR_TARGET, 0, 1#, 0
'Szene beginnen
gD3DDevice8.BeginScene
'Wir teilen DirectX mit, dass wir nun 2D-Bilder zeichnen möchten
gD3DX8Sprite.Begin
'Mit der Draw-Methode des D3DX8Sprite-Objektes werden
'die Bilder gezeichnet
For i = 0 To UBound(BILD())
'prüfen ob wir aus den Screenbereich laufen
If BILD(i).X < 5 Then
BILD(i).DirX = BILD(i).DirX * -1
End If
If BILD(i).Y < 5 Then
BILD(i).DirY = BILD(i).DirY * -1
End If
If BILD(i).X + 10 > (SCREENWIDTH - BildBreiteHoehe) Then
BILD(i).DirX = BILD(i).DirX * -1
End If
If BILD(i).Y + 10 > (SCREENHEIGHT - BildBreiteHoehe) Then
BILD(i).DirY = BILD(i).DirY * -1
End If
'Ausschnitt bewegen
BILD(i).X = BILD(i).X + BILD(i).DirX
BILD(i).Y = BILD(i).Y + BILD(i).DirY
'Rotation
sngRotation = 0
If BILD(i).bolRotation Then
BILD(i).Degree = BILD(i).Degree + BILD(i).Rotation
If BILD(i).Degree > 360 Then BILD(i).Degree = 0
If BILD(i).Degree < 0 Then BILD(i).Degree = 360
sngRotation = DegToRad(BILD(i).Degree)
End If
'Color
lngColor = D3DColorARGB(255, 255, 255, 255)
If BILD(i).bolFade Then
BILD(i).Color = BILD(i).Color + BILD(i).Fade
If BILD(i).Color > 255 Then
BILD(i).Fade = BILD(i).Fade * -1
BILD(i).Color = 255
End If
If BILD(i).Color < 0 Then
BILD(i).Fade = BILD(i).Fade * -1
BILD(i).Color = 0
End If
Select Case BILD(i).xRGB
Case 0: lngColor = D3DColorARGB( _
BILD(i).Color, 255, 255, 255)
Case 1: lngColor = D3DColorARGB( _
255, 255, BILD(i).Color, BILD(i).Color)
Case 2: lngColor = D3DColorARGB( _
255, BILD(i).Color, BILD(i).Color, 255)
Case 3: lngColor = D3DColorARGB( _
255, BILD(i).Color, 255, BILD(i).Color)
End Select
End If
'Scaling
vecScaling.X = 1: vecScaling.Y = 1
If BILD(i).bolScaling Then
BILD(i).Scaling = BILD(i).Scaling + BILD(i).ScalingStep
If BILD(i).Scaling > 1.5 Then
BILD(i).Scaling = 1.5
BILD(i).ScalingStep = BILD(i).ScalingStep * -1
End If
If BILD(i).Scaling < 0.5 Then
BILD(i).Scaling = 0.5
BILD(i).ScalingStep = BILD(i).ScalingStep * -1
End If
vecScaling.X = BILD(i).Scaling
vecScaling.Y = BILD(i).Scaling
End If
'Festlegen welchen Bereich vom Bitmap wir kopieren
'möchten ... in diesem Fall nur einen Teil
hlpZeile = Int(BILD(i).AniCount) \ 6
With recSource
.Left = BildBreiteHoehe * (Int(BILD(i).AniCount) - _
(hlpZeile * 6))
.Right = .Left + BildBreiteHoehe
.Top = hlpZeile * BildBreiteHoehe
.bottom = .Top + BildBreiteHoehe
End With
'Ausschnitte in den Backbuffer zeichnen
vecTranslation.X = BILD(i).X: vecTranslation.Y = BILD(i).Y
Call gD3DX8Sprite.Draw(texBild, recSource, vecScaling, _
vecRotationCenter, sngRotation, vecTranslation, lngColor)
BILD(i).AniCount = BILD(i).AniCount + 0.5
If Int(BILD(i).AniCount) > 23 Then BILD(i).AniCount = 0
Next i
gD3DX8Sprite.End
'Szene beenden
gD3DDevice8.EndScene
'kompletten BackBuffer zum FrontBuffer kopieren
gD3DDevice8.Present ByVal 0, ByVal 0, 0, ByVal 0
End Sub
|
|
|
|
Um dieses Beispiel ausführen zu können, wird die DirectX 8
for Visual Basic Type Library
benötigt (siehe dazu die Erläuterungen in der DirectX-Rubrik).
|
|
Windows-Version |
95 |
 |
|
98/SE |
 |
|
ME |
 |
|
NT |
 |
|
2000 |
 |
|
XP |
 |
|
Vista |
 |
|
Win
7 |
 |
|
|
VB-Version |
VBA 5 |
 |
|
VBA 6 |
 |
|
VB 4/16 |
 |
|
VB 4/32 |
 |
|
VB 5 |
 |
|
VB 6 |
 |
|
|
|
Download (116
kB)
|
Downloads bisher: [ 1299 ]
|
|
|