Tipp 0428 Rendern in einer PictureBox (Windowed Mode)
Autor/Einsender:
Datum:
  Alexander Csadek
27.12.2004
Entwicklungsumgebung:
DirectX-Version:
  VB 6
DirectX 7
Inhaltlich ist dieser Tipp mit dem Tipp Bewegen im 3D-Raum identisch. Deshalb gehe ich hier nicht näher auf die Bewegung im 3D-Raum ein.
Dieser Tipp soll veranschaulichen, wie einfach es ist, Direct3D im Windowed Mode rendern zu lassen, also nicht im Vollbild (Fullscreen Mode). Damit die Unterschiede leichter zu erkennen sind, habe ich den gleichen Tipp als Grundlage verwendet.
Die wichtigste Änderung ist in der DirectX- und Direct3D-Initialisierung (DD3DModule.bas). Zunächst wird DirectDraw dazu veranlasst im Fenster (Windowed Mode) zu arbeiten. Der FrontBuffer (PrimarySurface) bekommt diesmal keinen Flag für einen 3D-Device. Diesen bekommt der BackBuffer. Ein Clipper-Objekt wird erstellt und an die VB-Form oder PictureBox gebunden.
 
Public Sub InitDirectDraw(ByVal PBoxHandle As Long)
  Dim SurfaceDesc As DDSURFACEDESC2

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

  'Die Anwendung soll im FensterModus laufen
  DD7.SetCooperativeLevel 0, DDSCL_NORMAL

  'Auflösung und Farbtiefe werden nicht deklariert
  'Beschreibung des PrimarySurface ist sehr einfach,
  'wir wollen eine PrimarySurface und nichts weiter
  With SurfaceDesc
    .ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE
  End With

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

  'Clipper erstellen und an die PictureBox hängen
  Set ddClipper = DD7.CreateClipper(0&)
  ddClipper.SetHWnd PBoxHandle
  PrimarySurface.SetClipper ddClipper

  'Der BackBuffer bekommt die Grösse der PictureBox und
  'das ist die grosse Änderung entgegen dem FullscreenMode
  '- er bekommt den 3DDevice
  DX7.GetWindowRect PBoxHandle, recBack
  SurfaceDesc.lFlags = DDSD_CAPS Or DDSD_HEIGHT Or DDSD_WIDTH
  SurfaceDesc.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN Or _
          DDSCAPS_3DDEVICE Or DDSCAPS_VIDEOMEMORY
  SurfaceDesc.lWidth = recBack.Right - recBack.Left
  SurfaceDesc.lHeight = recBack.Bottom - recBack.Top
  Set BackBuffer = DD7.CreateSurface(SurfaceDesc)
  BackBuffer.GetSurfaceDesc BBSurfaceDesc

  'Pixelformat der PrimarySurface auslesen
  PrimarySurface.GetPixelFormat PriSurfPX
End Sub
 
Die nächste Änderung kommt bei der Direct3D-Initialisierung. Der ZBuffer (Tiefenspeicher) und der ViewPort werden auf die Größe des BackBuffers gesetzt. Sonst sind hier keine weiteren Änderungen notwendig.
 
Public Sub InitDirect3D()
  Dim i As Integer

  'Zunächst erstellen wir ein D3D-Interface
  Set D3D7 = DD7.GetDirect3D

  'Erstellt ein 3DDevice vom BackBuffer mittels der GUID
  Set Device = D3D7.CreateDevice(DeviceGUID, BackBuffer)

  'Z-Buffer erstellen
  Set d3dEnumPFS = D3D7.GetEnumZBufferFormats(DeviceGUID)
  For i = 1 To d3dEnumPFS.GetCount
    Call d3dEnumPFS.GetItem(i, ddpfZBuffer)
    If (ddpfZBuffer.lFlags = DDPF_ZBUFFER) And _
           ddpfZBuffer.lZBufferBitDepth = 16 Then Exit For
  Next i
  ZBufferDesc.lFlags = DDSD_CAPS Or DDSD_WIDTH Or _
           DDSD_HEIGHT Or DDSD_PIXELFORMAT
  ZBufferDesc.ddsCaps.lCaps = DDSCAPS_ZBUFFER Or _
           DDSCAPS_VIDEOMEMORY

  'Wichtig: Größe des Backbuffers verwenden
  ZBufferDesc.lWidth = BBSurfaceDesc.lWidth
  ZBufferDesc.lHeight = BBSurfaceDesc.lHeight
  ZBufferDesc.ddpfPixelFormat = ddpfZBuffer
  Set ZBuffer = DD7.CreateSurface(ZBufferDesc)
  BackBuffer.AddAttachedSurface ZBuffer

  'Viewport einstellen (Kamera)
  'Wichtig: grösse des Backbuffers verwenden
  With ViewPort
    .lHeight = BBSurfaceDesc.lHeight
    .lWidth = BBSurfaceDesc.lWidth
    .lX = 0
    .lY = 0
    .maxz = 1#
    .minz = 0#
  End With
  Device.SetViewport ViewPort

  '3DRect für Clear einstellen
  ClearRec(0).X1 = ViewPort.lX
  ClearRec(0).Y1 = ViewPort.lY
  ClearRec(0).X2 = ViewPort.lWidth
  ClearRec(0).Y2 = ViewPort.lHeight

  'ViewportMatrix einstellen
  With DX7
    .IdentityMatrix View3DMatrix
    .ViewMatrix View3DMatrix, RVector(0, 0, 0), _
      RVector(0, 0, 1000), RVector(0, 1, 0), 0
  End With
  Device.SetTransform D3DTRANSFORMSTATE_VIEW, View3DMatrix

  'neuen Ursprung der ViewportMatrix einstellen
  Device.GetTransform D3DTRANSFORMSTATE_VIEW, View3DMatrix
  TranslateMatrix View3DMatrix, _
           RVector(PLAYER.x * -1, PLAYER.y * -1, PLAYER.z * -1)
  Device.SetTransform D3DTRANSFORMSTATE_VIEW, View3DMatrix

  'RenderPipeline einstellen
  Device.SetRenderState D3DRENDERSTATE_LIGHTING, False
  Device.SetRenderState D3DRENDERSTATE_SPECULARENABLE, False
  Device.SetRenderState D3DRENDERSTATE_ZENABLE, D3DZB_TRUE
  Device.SetRenderState D3DRENDERSTATE_CULLMODE, D3DCULL_CCW

  'ProjektionsMatrix einstellen
  With DX7
    .IdentityMatrix Projection3DMatrix
    .ProjectionMatrix Projection3DMatrix, 1, 1000, (3.141592 / 4)
  End With
  Device.SetTransform D3DTRANSFORMSTATE_PROJECTION, _
              Projection3DMatrix

  'Zielsurface für das Rendern setzen
  Device.SetRenderTarget BackBuffer
End Sub
 
Nun ist nur noch dafür zu sorgen, dass das fertig gerenderte Bild in die VB-Form oder PictureBox kommt. Da es im Fenster-Modus (Windowed Mode) keine Flip-Funktion gibt, wird der BackBuffer mit der Blt-Funktion in den FrontBuffer (PrimarySurface) kopiert.
 
recSource.Right = BBSurfaceDesc.lWidth
recSource.Bottom = BBSurfaceDesc.lHeight
DX7.GetWindowRect frmMain.Picture1.hWnd, recDestination
PrimarySurface.Blt recDestination, BackBuffer, recSource, _
       DDBLT_WAIT
 
Hinweis
Um dieses Beispiel ausführen zu können, wird die DirectX 7 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  (258 kB) Downloads bisher: [ 692 ]

Vorheriger Tipp Zum Seitenanfang Nächster Tipp

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

Seite empfehlen Bug-Report
Letzte Aktualisierung: Dienstag, 28. Juni 2011