Tipp 0129
|
2D mit Direct3DX
|
|
|
Autor/Einsender: Datum: |
|
Alexander Csadek 05.08.2006 |
|
Entwicklungsumgebung: |
|
VB.Net 2003 |
DirectX-Version: |
|
DirectX 9 |
|
|
Denjenigen, die gleich mit DirectX 9 begonnen haben Spiele mit Visual Basic .Net und DirectX
zu erstellen ist es vielleicht gar nicht aufgefallen. Aber die, die von DirectX 7 auf 9 umsteigen,
werden sich fragen wo DirectDraw für die Spiele in 2D geblieben ist.
|
Nun, bei DirectX 9 gibt es die Komponente DirectDraw nicht mehr, lediglich bei der
ersten
DirectX 9-Version war die Komponente enthalten. 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 sogar
mit Skalieren, Rotieren, Farbmodulation und Blendeffekten.
|
Direct3D stellt mit dem Sprite-Objekt ein Objekt für 2D-Bilder
(Sprites) zur Verfügung, das über einen gültigen 3D-Device erstellt
wird.
|
|
|
gSprite = New Direct3D.Sprite(gD3DDevice9)
|
|
|
Jetzt steht einem Spiel in 2D nichts mehr im Wege. Man erstellt ein Direct3D-Objekt und einen 3DDevice, egal ob Vollbild (FullScreen) oder im Fenster (Windowed Mode). Die Bitmaps werden über
den TextureLoader des Assembly Microsoft.DirectX.Direct3DX als normale Texturen geladen.
|
|
|
texBild = TextureLoader.FromFile(gD3DDevice9, _
Application.StartupPath & "\vbfun.bmp", 312, 208, _
0, 0, Format.A8B8G8R8, Pool.Managed, Filter.None, _
Filter.None, &HFF000000)
|
|
|
Das Zeichnen der Bilder in 2D erfolgt zwischen dem BeginScene und EndScene des 3DDevice, und zwar mit dem Sprite-Objekt.
Das angenehme dabei ist, die Position des Bildes wird in Bildschirm-Koordinaten (x, y) angegeben.
|
|
|
gD3DDevice9.Clear( _
ClearFlags.Target, System.Drawing.Color.Black, 1.0F, 0)
gD3DDevice9.BeginScene()
gSprite.Begin(SpriteFlags.AlphaBlend)
gSprite.Draw2D(texBild, recBild, szfScale, ptfRotCenter, _
sngRotation, ptfPosition, intColor)
gSprite.End()
gD3DDevice9.EndScene()
gD3DDevice9.Present()
|
|
|
Die Methode Draw2D des Sprite-Objekts erwartet folgende Parameter und bietet ein paar interessante Möglichkeiten:
|
|
srcTexture |
Das Bild aus einem Direct3D Texture-Objekt. |
srcRectangle |
Der gewünschte Ausschnitt des Bilds. Mit Rectangle.Empty wird das gesamte Bild gezeichnet. |
destinationRectangle |
Ein Drawing.Rectangle mit der gewünschten Skalierung des Bildes. Mit Rectangle.Empty wird die Original-Größe verwendet. |
rotationCenter |
Ein Drawing.PointF mit dem gewünschten Rotations-Zentrum. x = 0 und y = 0 ist immer die linke obere Ecke des Bildes. |
rotationAngle |
Angabe der Rotation in Radians. |
position |
Angabe der x- und y-Position am Bildschirm mittels eines Drawing.PointF. x = 0 und y = 0 ist die linke obere Bildschirmecke. |
color |
Farbe und Alpha-Kanal des Bildes kann hiermit verändert werden. Bei &HFFFFFFFF werden die Farben und der Alpha-Kanal vom Originalbild verwendet. |
|
Es gibt bei dem Sprite-Objekt noch eine weitere interessante Methode - Draw. Diese Methode funktioniert wie Draw2D, nur das sie keine
Rotation und Skalierung unterstützt.
|
Es folgt nun der für diesen Tipp relevante Code.
|
|
|
Private Sub Render()
Dim hlpZeile As Integer
Dim sngRotation As Double
Dim intColor As Integer
Dim i As Integer
Try
If gD3DDevice9 Is Nothing Then Exit Sub
gD3DDevice9.Clear( _
ClearFlags.Target, System.Drawing.Color.Black, 1.0F, 0)
gD3DDevice9.BeginScene()
gSprite.Begin(SpriteFlags.AlphaBlend)
For i = 0 To UBound(BILD)
If BILD(i).X < 26 Then
BILD(i).DirX = BILD(i).DirX * -1
End If
If BILD(i).Y < 26 Then
BILD(i).DirY = BILD(i).DirY * -1
End If
If BILD(i).X > (SCREENWIDTH - 26) Then
BILD(i).DirX = BILD(i).DirX * -1
End If
If BILD(i).Y > (SCREENHEIGHT - 26) Then
BILD(i).DirY = BILD(i).DirY * -1
End If
BILD(i).X = BILD(i).X + BILD(i).DirX
BILD(i).Y = BILD(i).Y + BILD(i).DirY
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
intColor = Color.FromArgb(255, 255, 255, 255).ToArgb()
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 : intColor = Color.FromArgb( _
BILD(i).Color, 255, 255, 255).ToArgb()
Case 1 : intColor = Color.FromArgb(255, 255, _
BILD(i).Color, BILD(i).Color).ToArgb()
Case 2 : intColor = Color.FromArgb(255, BILD(i).Color, _
BILD(i).Color, 255).ToArgb()
Case 3 : intColor = Color.FromArgb(255, BILD(i).Color, _
255, BILD(i).Color).ToArgb()
End Select
End If
szfScale.Width = 52 : szfScale.Height = 52
If BILD(i).bolScaling Then
BILD(i).Scaling = BILD(i).Scaling + BILD(i).ScalingStep
If BILD(i).Scaling > 2 Then
BILD(i).Scaling = 2
BILD(i).ScalingStep = BILD(i).ScalingStep * -1
End If
If BILD(i).Scaling < 1 Then
BILD(i).Scaling = 1
BILD(i).ScalingStep = BILD(i).ScalingStep * -1
End If
szfScale.Width = CSng(BildBreiteHoehe * BILD(i).Scaling)
szfScale.Height = CSng(BildBreiteHoehe * BILD(i).Scaling)
End If
hlpZeile = Int(BILD(i).AniCount) \ 6
With recBild
.X = BildBreiteHoehe * (Int(BILD(i).AniCount) - _
(hlpZeile * 6)) : .Width = BildBreiteHoehe
.Y = hlpZeile * BildBreiteHoehe : _
.Height = BildBreiteHoehe
End With
ptfPosition = New Drawing.PointF(BILD(i).X, BILD(i).Y)
gSprite.Draw2D(texBild, recBild, szfScale, ptfRotCenter, _
sngRotation, ptfPosition, intColor)
BILD(i).AniCount = BILD(i).AniCount + 0.5
If Int(BILD(i).AniCount) > 23 Then BILD(i).AniCount = 0
Next i
gSprite.End()
gSprite2.Begin(SpriteFlags.AlphaBlend)
gD3DXFont.DrawText(gSprite2, "DirectX9 und Sprites im 2D." & _
vbCrLf & "<Esc> beendet das Beispiel.", _
New System.Drawing.Point(0, 0), System.Drawing.Color.White)
gSprite2.End()
gD3DDevice9.EndScene()
gD3DDevice9.Present()
Catch ex As Exception
MessageBox.Show("Fehler beim Rendern der Szene." & vbCrLf & _
ex.Message.ToString())
Me.Close()
End Try
End Sub
|
|
|
|
Um diesen Tipp ausführen zu können, wird die DirectX 9 for Managed Code Runtime benötigt.
|
Dieses Beispiel funktioniert ab folgender DirectX 9.0 Version:
|
Update DirectX 9.0 SDK (October 2005)
|
Pfad: C:\WINDOWS\Microsoft.NET\DirectX for Managed Code\1.0.2902.0\Microsoft.DirectX.dll
Laufzeitversion: v1.1.4322
Assemblyversion: 1.0.2902.0
|
Pfad: C:\WINDOWS\Microsoft.NET\DirectX for Managed Code\1.0.2902.0\Microsoft.DirectX.Direct3D.dll
Laufzeitversion: v1.1.4322
Assemblyversion: 1.0.2902.0
|
Pfad: C:\WINDOWS\Microsoft.NET\DirectX for Managed Code\1.0.2908.0\Microsoft.DirectX.Direct3DX.dll
Laufzeitversion: v1.1.4322
Assemblyversion: 1.0.2908.0
|
|
Windows-Version |
98/SE |
|
|
ME |
|
|
NT |
|
|
2000 |
|
|
XP |
|
|
Vista |
|
|
Win
7 |
|
|
|
|
Download (122 kB)
|
Downloads bisher: [ 1034 ]
|
|
|