Tipp 0476 Objekte unabhängig im 3D-Raum bewegen
Autor/Einsender:
Datum:
  Alexander Csadek
03.12.2005
Entwicklungsumgebung:
DirectX-Version:
  VB 6
DirectX 8
In einer virtuellen 3D-Welt steht nicht alles still und immer an der gleichen Position. Meist sind es Türen, Aufzüge oder andere Spielfiguren, die sich in einem 3D-Raum bewegen. Die Frage ist nun, wie kann ein 3D-Objekt im 3D-Raum bewegt werden, wenn die Vertexe des Objektes an eine fixe Koordinate gebunden sind.
Die Antwort liegt in der Welt-Matrix (World-Matrix), die uns Direct3D anbietet. Mit ihr können Objekte unabhängig voneinander verschoben, gedreht und skaliert werden. Hierbei ist zu beachten, dass der restliche 3D-Raum nicht verändert wird, so müssen nicht bei jeder Veränderung alle Vertexe eines Objektes neu positioniert werden.
Damit der Tipp nicht unnötig kompliziert wird, habe ich nur Würfel als 3D-Objekte verwendet.
Es folgt nun der für diesen Tipp relevante Code...
 
'World-Koordinaten der Boxen verändern
For i = 0 To UBound(WUERFEL())
  WUERFEL(i).Rotate = WUERFEL(i).Rotate + WUERFEL(i).RotateStep
  If WUERFEL(i).Rotate > 360 Then WUERFEL(i).Rotate = 0
  Select Case WUERFEL(i).Direction
     Case 0:
       WUERFEL(i).WorldPos.Y = WUERFEL(i).WorldPos.Y + 1
       If WUERFEL(i).WorldPos.Y > 300 Then
         WUERFEL(i).Direction = 1
       End If
     Case 1:
       WUERFEL(i).WorldPos.Y = WUERFEL(i).WorldPos.Y - 1
       If WUERFEL(i).WorldPos.Y < -300 Then
         WUERFEL(i).Direction = 0
       End If
  End Select
  D3DXMatrixIdentity WUERFEL(i).WorldMatrix
  TranslateMatrix WUERFEL(i).WorldMatrix, WUERFEL(i).WorldPos
Next


Private Sub Render3D()
  Dim helpMatrix(1) As D3DMATRIX
  Dim i As Integer, j As Integer

  On Error GoTo ErrOut
  'Hilfsmatrix initialisieren
  For i = 0 To 1
    D3DXMatrixIdentity helpMatrix(i)
  Next

  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

  'VertexFormat setzen
  gD3DDevice8.SetVertexShader D3DFVF_CUSTOMVERTEX

  'Restliche Welt "normal" rendern
  gD3DDevice8.SetTransform D3DTS_WORLD, helpMatrix(0)

  'Textur setzen
  gD3DDevice8.SetTexture 0, texTextur(0)

  'TexturKoordinaten 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

  For j = 0 To UBound(WUERFEL())
    'Textur für Box setzen
    gD3DDevice8.SetTexture 0, texTextur(WUERFEL(j).Textur)

    'Objekt-Koordinaten in der WorldMatrix setzen
    For i = 0 To 1
      D3DXMatrixIdentity helpMatrix(i)
    Next i

    'Die World-Matrix der Box transformieren
    gD3DDevice8.SetTransform D3DTS_WORLD, WUERFEL(j).WorldMatrix

    'HilfsMatrix in den Mittelpunkt der Box schieben
    TranslateMatrix helpMatrix(1), WUERFEL(j).Mittelpunkt

    'Boxen entsprechend drehen
    Select Case WUERFEL(j).Achse
      Case "X":
        RotateXMatrix helpMatrix(0), WUERFEL(j).Rotate * PI / 180
      Case "Y":
        RotateYMatrix helpMatrix(0), WUERFEL(j).Rotate * PI / 180
      Case "Z":
        RotateZMatrix helpMatrix(0), WUERFEL(j).Rotate * PI / 180
    End Select

    'Hilfsmatrizen miteinander multiplizieren
    helpMatrix(1) = RetMatrixMult(helpMatrix(1), helpMatrix(0))

    'Änderungen der World-Matrix der Box durchführen
    gD3DDevice8.MultiplyTransform D3DTS_WORLD, helpMatrix(1)

    'Box rendern
    gD3DDevice8.DrawPrimitiveUP D3DPT_TRIANGLELIST, 12, _
          WUERFEL(j).vxWuerfel(0), Len(WUERFEL(j).vxWuerfel(0))
  Next j

  '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  (171 kB) Downloads bisher: [ 610 ]

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: Samstag, 27. August 2011