DirectDraw-Grundlagen  

Zunächst sollten erst einmal die wichtigsten Objekte und Methoden betrachtet werden, um von Windows die Erlaubnis zu bekommen, direkt in den Videospeicher zu schreiben.
 

DirectX 7 bzw. DirectX 8

Es ist das das wichtigste Objekt überhaupt. Nur über dieses DirectX 7- bzw. DirectX 8-Objekt erhält man einen Zugriff auf den gewünschten DirectX-Bereich. Egal ob DirectDraw, Direct3D, DirectSound, DirectInput oder DirectPlay. Der Weg zu diesen Objekten führt immer über das DirectX 7- bzw. das DirectX 8-Objekt.

DirectDraw 7

Dieses Objekt wird benötigt, um auf alle Funktionen und Eigenschaften von DirectDraw zugreifen zu können.

DDSURFACEDESC2

Der wichtigste Datentyp um DirectDrawSurfaces zu beschreiben. Dies gilt sowohl für den Primary- und Back-Surface als auch für die Bitmaps die in Folge darstellen möchten. Die wichtigsten Eigenschaften sind lWidth und lHeight. Man kann damit die Auflösung eines Bildes, bevor es geladen ist, festlegen. Also wenn man will, ein Bild kleiner oder größer werden lassen als es eigentlich ist.

DirectDrawSurface7

Wie der Name schon sagt, ist dies eine virtuelle Fläche auf der sich ein geladenes Bild befindet. Im Grunde ein Speicherbuffer.

DDCOLORKEY

Dieser Datentyp ist sehr hilfreiche bei Bildern mit transparenten Bereichen. Mit seinen Eigenschaften low und high wird der Farbbereich festgelegt der beim Kopieren ignoriert wird.

RECT

Die wohl wichtigste DirectDraw-Variable, ein sogenanntes Rectangle (Rechteck), dass vier Eigenschaften hat: Left, Right, Top und Bottom. Die nebenstehende Skizze zeigt die Funktionen dieser Eigenschaften auf. Dieser Variablentyp wird verwendet um Animationen darzustellen oder Bilder über den Rand des Bildschirmes zu zeichnen. Sobald ein Eigenschaftswert über das Surface hinausgeht ist es nicht mehr darstellbar.
 
Es ist noch wichtig zu wissen dass DirectDraw nur Bitmaps laden kann. Jedoch bietet die Intel-JPEG-DLL eine schnelle und effiziente Möglichkeit JPEGs in eine Surface zu laden.

Nachdem schon die Grundlagen für das Erstellen einer DirectX-Anwendung geschaffen wurden, ist es Zeit zur Tat zu schreiten, und nachfolgend kommen die wichtigsten Funktionen ...
 

DirectX7.DirectDrawCreate("")
Diese DX-Funktion erlaubt den Zugriff auf das DirectDraw.
 
DirectDraw.SetCooperativeLevel(hdl As Long, flags As CONST_DDSCLFLAGS)

Damit wird festgelegt, wie die Anwendung bzw. Spiel mit Windows zusammen arbeiten soll. hdl ist das Handle der Programm-Form und mit flags wird festgelegt, ob das Programm exklusiv und im Vollbild-Modus(Fullscreen) oder in einem normalen Fenster laufen soll, oder ob es erlaubt ist zu rebooten während das Programm läuft.

DD.SetCooperativeLevel Form.hWnd, DDSCL_EXCLUSIVE Or _
     DDSCL_FULLSCREEN Or DDSCL_ALLOWREBOOT
DirectDraw.SetDisplayMode(w As Long, h As Long, bpp As Long, ref As Long, mode As
      CONST_DDSDMFLAGS)
Mit dieser sehr wichtigen Funktion SetDisplayMode wird dem Betriebssystem mitgeteilt, in welcher Auflösung (hier 800x600) und Farbtiefe (hier 16 Bit) die Anwendung bzw. Spiel laufen soll.
DD.SetDisplayMode 800, 600, 16, 0, DDSDM_DEFAULT

Um Bilder sehen zu können, muss ein virtueller Grafikspeicher (Surface) erstellt werden, der das Videobild repräsentiert. Dieser wird meist PrimarySurface genannt wobei es durchaus möglich direkt in diesen zu zeichnen. Sinnvoller jedoch ist der Einsatz eines zweiten Surfaces das hinter dem Ersten liegt, den BackBuffer. Um den Inhalt vom BackBuffer in den PrimarySurface zu kopieren gibt es die Funktion Flip, die später noch genauer erklärt wird.

Um den PrimarySurface und den BackBuffer zu beschreiben wird der DDSURFACEDESC2-Datentyp benötigt:

With SurfaceDesc
   .lFlags = DDSD_CAPS Or DDSD_BACKBUFFERCOUNT
   .ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE Or DDSCAPS_FLIP Or _
       DDSCAPS_COMPLEX
   .lBackBufferCount = 1

End With

Hier wird ein PrimarySurface mit einem BackBuffer beschrieben. Ohne Angabe von Breite und Höhe nimmt DirectX die volle Größe wie sie bei SetDisplayMode angegeben wurde. Für den BackBuffer wird die gleiche Beschreibung, jedoch mit einer kleinen Änderung, verwendet:

SurfaceDesc.ddsCaps.lCaps = DDSCAPS_BACKBUFFER
DirectDraw.CreateSurface(dd As DDSURFACEDESC2) As DirectDrawSurface7
Übergeben wird die Beschreibung des PrimarySurfaces: 
Set PrimarySurface = DD.CreateSurface(SurfaceDesc)
PrimarySurface.GetAttachedSurface(caps As DDSCAPS2) As DirectDrawSurface7

Da der BackBuffer ein Teil vom PrimarySurface ist, wird die Funktion über die PrimarySurface aufgerufen. Es wird nicht die gesamte SurfaceBeschreibung übergeben, nur der ddsCaps:

Set BackBuffer = _
        PrimarySurface.GetAttachedSurface(SurfaceDesc.ddsCaps)
DirectDraw.RestoreDisplayMode()
Bevor die Anwendung beendet wird sollte unbedingt der Zustand des Videobildes wieder hergestellt werden:
DD.RestoreDisplayMode
DirectDraw.CreateClipper(flags As Long) As DirectDrawClipper
Diese Funktion wird nur dann benötigt wenn die Anwendung in einem normalen WindowsFenster ablaufen soll. Der Clipper benötigt den Handle vom Form oder von einem anderen Objekt auf das DirectDraw in folge zeichnen soll. Der PrimarySurface muss der Clipper zugewiesen werden:
Set ddClipper = DD.CreateClipper(0)
ddClipper.SetHWnd Me.hWnd
PrimarySurface.SetClipper ddClipper
Nun sind alle wichtigen Funktionen für eine Vollbild-Anwendung erklärt. Was aber wenn die Anwendung nicht im Vollbild, sondern in einem normalen Fenster ablaufen soll, dazu gibt es hier mehr:
Fenster
Vollbild
 
  Vollbild [ Top ]

Wie bereits erklärt, ist es nicht besonders schwer eine Vollbild-Anwendung in DirectX zu schreiben.

Auf ein paar Merkmale sollte man aber trotzdem noch verstärkt achten, wie z.B. das Verwenden von gängigen Bildschirmauflösungen. Es hat wenig Sinn ein tolles Spiel mit 1.600 x 1.200 Pixel für einen 20" Monitor zu schreiben, welches dann nur sehr wenige User zum Laufen bekommen.

Die Bildschirmauflösung immer beim Beenden eines Spiels wieder auf die ursprüngliche Auflösung zurückstellen. Es gibt nichts störenderes und schlimmeres, als eine durch ein Programm verstellte Auflösung.

'-------------  DirectDraw-Initialisations-Variablen  ------------

Dim DX7As New DirectX7
Dim DD7 As DirectDraw7
Dim SurfaceDesc As DDSURFACEDESC2
Dim PrimarySurface As DirectDrawSurface7
Dim BackBuffer As DirectDrawSurface7

Sub Initialization() 'DirectDraw wird initialisiert

     'Den Zugriff auf das DirectDraw-Objekt holen. Der leere
     'String-Parameter bedeutet, dass der aktive Bildschirmtreiber
     'benutzt werden soll
    Set DD7 = DX7.DirectDrawCreate("")

     'Die Anwendung soll im VollbildModus laufen
    DD7.SetCooperativeLevel Me.hWnd, DDSCL_EXCLUSIVE Or _
        DDSCL_FULLSCREEN Or DDSCL_ALLOWREBOOT

     'Auflösung und Farbtiefe deklarieren
    DD7.SetDisplayMode 800, 600, 16, 0, DDSDM_DEFAULT

     'Beschreibung des PrimarySurface mit einem BackBuffer
    With SurfaceDesc
       .lFlags = DDSD_CAPS Or DDSD_BACKBUFFERCOUNT
       .ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE Or _
            DDSCAPS_FLIP Or DDSCAPS_COMPLEX
       .lBackBufferCount = 1
    End With

     'PrimarySurface initialisieren, auf dem alles abgebildet wird
    Set PrimarySurface = DD7.CreateSurface(SurfaceDesc)

     'Für die Beschreibung des Backbuffers wird nur der
     'ddsCaps-Bereich benötigt
    SurfaceDesc.ddsCaps.lCaps = DDSCAPS_BACKBUFFER

     'BackBuffer initialisieren in dem alles gezeichnet und dann
     'in die PrimarySurface geflipt wird
    Set BackBuffer = _
       PrimarySurface.GetAttachedSurface(SurfaceDesc.ddsCaps)

End Sub
Ein Beispiel zur Vollbild-Darstellung von DirectDraw können Sie hier downloaden:
  Download ddfullscreen.zip Download
ddfullscreen.zip
 (7,3 kB)
Downloadzeit: <1 Min. - 28.8k / <1 Min. - ISDN Downloads bisher: [ 4040 ]
 
  Fenster [ Top ]  

Bei der Darstellung von DirectX in einem normalen Windows-Fenster sind die folgenden Merkmale zu beachten.

Da das Videobild mit dem Windows-Bild geteilt wird, kann die Auflösung nicht verstellt werden.

Es gibt keinen "normalen" BackBuffer und kein Flip'en. Im weiteren muss genau darauf geachtet werden "wohin" in die PrimarySurface gezeichnet wird. Wenn möglich, dann nur in das eigene Fenster. Die Ausgabe geht sonst ohne wenn und aber über den Desktop !!

Daher vor dem Zeichnen immer die aktuelle Fensterposition und Größe überprüfen.

'-------------  DirectDraw-Initialisations-Variablen  ------------

Dim DX7As New DirectX7
Dim DD7 As DirectDraw7
Dim SurfaceDesc As DDSURFACEDESC2
Dim PrimarySurface As DirectDrawSurface7
Dim BackBuffer As DirectDrawSurface7
Dim ddClipper As DirectDrawClipper

Sub Initialization() 'DirectDraw wird initialisiert

     'Den Zugriff auf das DirectDraw-Objekt holen. Der leere
     'String-Parameter bedeutet, dass der aktive Bildschirmtreiber
     'benutzt werden soll
    Set DD7 = DX7.DirectDrawCreate("")

     'Die Anwendung soll im Fenster laufen
    DD7.SetCooperativeLevel Me.hWnd, DDSCL_NORMAL

     'Beschreibung des PrimarySurface --> ohne einem BackBuffer !
    With SurfaceDesc
       .lFlags = DDSD_CAPS
       .ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE
    End With
     'PrimarySurface initialisieren auf dem alles abgebildet wird
    Set PrimarySurface = DD7.CreateSurface(SurfaceDesc)

     'Beschreibung des BackBuffer
    With SurfaceDesc
       .lFlags = DDSD_CAPS Or DDSD_HEIGHT Or DDSD_WIDTH
       .ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN
       .lHeight = 100
       .lWidth = 100
    End With

     'BackBuffer initialisieren auf dem gezeichnet wird
    Set BackBuffer = DD7.CreateSurface(SurfaceDesc)

     'Clipper initialisieren für den Bereich in dem gezeichnet
     'werden darf
    Set ddClipper = DD7.CreateClipper(0)
     'Clipper auf das Form setzen
    ddClipper.SetHWnd Me.hWnd
     'und auf die PrimarySurface
    PrimarySurface.SetClipper ddClipper

End Sub
Ein Beispiel zur Darstellung von DirectDraw in einem Fenster können Sie hier downloaden:
  Download ddwindow.zip Download
ddwindow.zip
(7,1 kB)
Downloadzeit: <1 Min. - 28.8k / <1 Min. - ISDN Downloads bisher: [ 4587 ]

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

Seite empfehlen Bug-Report

Letzte Aktualisierung, Sonntag, 16. September 2001