Tipp 0504 X-Files laden und rendern
Autor/Einsender:
Datum:
  Alexander Csadek
20.07.2006
Entwicklungsumgebung:
DirectX-Version:
  VB 6
DirectX 8
Das von Microsoft im DirectX bereitgestellte Dateiformat "X" für 3D-Objekte ist zwar nicht das flexibelste, aber immer noch besser, als komplexe 3D-Objekte (Meshes) via Code zu erzeugen.
Viele 3D-Programme unterstützen mittlerweile schon das X-Format, wenn nicht direkt, dann über ein Plug-In (siehe DirectX-Zubehör). Es ist also kein Problem mehr, seine Meshes einfach und schnell zu erstellen und dann mit DirectX zu rendern.
Mit DirectX 8 ist es viel einfacher geworden ein X-File zu laden.
Mit der Methode LoadMeshFromX des D3DX-Objekts kann ein X-File in ein D3DXMesh-Objekt geladen werden. Dabei wird ein D3DXBuffer angegeben, in dem die Methode die Materialdaten und Texturen aus dem X-File ablegt. Des weiteren gibt die Methode auch die Anzahl der im X-File definierten Materialien zurück.
Das D3DX-Objekt bietet noch zwei weitere nützliche Methoden. BufferGetMaterial liefert die Materialdaten aus dem D3DXBuffer. BufferGetTextureName liefert die Namen der Texturen aus dem D3DXBuffer.
So können sehr einfach die Texturen geladen und das Material eingestellt werden. Danach kann der D3DXBuffer auf Nothing gesetzt werden, es wurde ja alles geladen, außer man braucht ihn aus einem bestimmten Grund noch (z.B. zum Auslesen der Vertex-Daten).
Wichtig ist noch zu wissen, die Daten im D3DXMesh-Objekt sind in Unterelemente aufgeteilt, für jedes Material/Textur ein eigenes Element. Diese Tatsache hilft beim Rendern gewaltig.
Mit der Anzahl der Materialien werden beim Rendern die Unterelemente durchlaufen. Dazu muss jedes Mal mit der Funktion SetTexture des 3D-Device die entsprechende Textur gesetzt und die Methode DrawSubset des D3DXMesh-Objekts mit der Unterelement-Nummer aufgerufen werden.
Es folgt nun der für diesen Tipp relevante Code.
 
'3D Objekt
Public gMesh As D3DXMesh
'Array für die Material Daten
Public gMeshMaterials() As D3DMATERIAL8
'Array für die Texturen
Public gMeshTextures() As Direct3DTexture8
'Anzahl der Material-Daten im Mesh
Public gNumMaterials As Long

'X-File laden und die Texturen dazu
Public Function LoadMesh(ByVal filename As String) As Boolean
  Dim strTexturName As String

  On Error GoTo ErrOut
  Buffer für die Material-Daten im 3D-Objekt
  Dim MtrlBuffer As D3DXBuffer
  Dim i As Long

  'Laden des X Files
  'Gleichzeitig werden die Material-Daten in den Buffer geladen
  'und auch die Anzahl der Material-Daten im X-File zurückgegeben
  Set gMesh = gD3DX8.LoadMeshFromX(App.Path & "\" & filename, _
        D3DXMESH_MANAGED, gD3DDevice8, Nothing, MtrlBuffer, _
        gNumMaterials)
  If gMesh Is Nothing Then Exit Function

  'Anhand der Anzahl von Materialien im X-File Arrays
  'für die Materialdaten und Texturen dimensionieren
  ReDim gMeshMaterials(gNumMaterials - 1)
  ReDim gMeshTextures(gNumMaterials - 1)

  'Aus dem Buffer die Material-Daten und Textur-Namen auslesen
  For i = 0 To gNumMaterials - 1
    'Die Material-Daten werden in diesem Beispiel nicht gebraucht
    'aber trotzdem der passende Code dazu
 
    'Mittels dem D3DX-Objekt holen wir uns die Material-Daten
    gD3DX8.BufferGetMaterial MtrlBuffer, i, gMeshMaterials(i)

    'Umkopieren der Farbwerte für Ambient
    '(D3DX tut dies nicht von selbst)
    gMeshMaterials(i).Ambient = gMeshMaterials(i).diffuse

    'Die im XFile verwendete Textur laden
    strTexturName = gD3DX8.BufferGetTextureName(MtrlBuffer, i)
    If strTexturName <> "" Then
      Set gMeshTextures(i) = gD3DX8.CreateTextureFromFile( _
            gD3DDevice8, App.Path & "\" & strTexturName)
    End If
  Next
  'Daten-Buffer löschen
  Set MtrlBuffer = Nothing
  LoadMesh = True
  Exit Function

ErrOut:
  Debug.Print Err.Number & " - " & Err.Description
End Function

Private Sub Render3D()
  Dim i As Long

  On Error GoTo ErrOut
  If gD3DDevice8 Is Nothing Then Exit Sub

  'Bereinigen des BackBuffers und des ZBuffers
  gD3DDevice8.Clear 0, ByVal 0, D3DCLEAR_TARGET Or _
        D3DCLEAR_ZBUFFER, 0#, 1#, 0

  'Szene beginnen
  gD3DDevice8.BeginScene

  'Vertex-Format setzen
  gD3DDevice8.SetVertexShader D3DFVF_CUSTOMVERTEX

  'Textur setzen
  gD3DDevice8.SetTexture 0, texTextur

  'Textur-Koordinaten ausserhalb der Textur werden nicht gespiegelt
  gD3DDevice8.SetTextureStageState 0, D3DTSS_ADDRESSW, _
        D3DTADDRESS_WRAP

  'Bilinearen Texturfilter verwenden, damit die Skybox nicht so
  'grob gerastert wird
  gD3DDevice8.SetTextureStageState 0, D3DTSS_MAGFILTER, _
        D3DTEXF_LINEAR

  'Die Box rendern
  gD3DDevice8.DrawPrimitiveUP D3DPT_TRIANGLELIST, 12, vxBox(0), _
        Len(vxBox(0))
  gD3DDevice8.SetTextureStageState 0, D3DTSS_ADDRESSW, 0

  'Mesh Objekte sind in Unterelemente unterteilt.
  'Eines pro Material. Daher muss über eine Schleife
  'gerendert werden.
  For i = 0 To gNumMaterials - 1
    'pro Unterelement die Textur setzen
    gD3DDevice8.SetTexture 0, gMeshTextures(i)
    'Unterelement rendern
    gMesh.DrawSubset i
  Next

  'Mit der Draw-Methode des D3DX8Sprite-Objektes werden die
  'Bilder gezeichnet
  Call gD3DX8Sprite.Draw(texFadenkreuz, recFadenkreuz, _
      vecScalingDummy, vecRotationCenterDummy, 0, vecFadenkreuz, _
      lngColorDummy)

  'Text zeichnen
  myDXFont.DrawTextW strText, Len(strText), recText, _
        DT_WORDBREAK, D3DColorMake(1, 1, 1, 1)

  'Szene beenden
  gD3DDevice8.EndScene

  'Kompletten BackBuffer zum FrontBuffer kopieren
  gD3DDevice8.Present ByVal 0, ByVal 0, 0, ByVal 0
  Exit Sub

ErrOut:
  Debug.Print Err.Number & " - " & Err.Description
End Sub
 
Hinweis
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
ME
NT
2000
XP
Vista
Win 7
VB-Version
VBA 5
VBA 6
VB 4/16
VB 4/32
VB 5
VB 6


Download  (251 kB) Downloads bisher: [ 418 ]

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: Donnerstag, 25. August 2011