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
 
Hinweis
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: [ 957 ]

Vorheriger Tipp Zum Seitenanfang Nächster Tipp

Startseite | Tipps | Projekte | Tutorials | Bücherecke | VB-/VBA-Tipps | API-Referenz | Komponenten | VB.Net-Forum | VB/VBA-Forum | DirectX-Forum | Foren-Archiv | DirectX | Chat | Spielplatz | Links | Suchen | Stichwortverzeichnis | Feedback | Impressum

Seite empfehlen Bug-Report
Letzte Aktualisierung: Sonntag, 22. Januar 2012