ich beschäftige mich momentan ein bisschen mit managed D3D. Hab mir dazu ein Tutorial angesehen und die Source nachgebaut (bzw. kopiert). Hat auch alles einwandfrei funktioniert. Im Tutorial wurde mit zwei Würfeln gearbeitet (jeder bestehend aus 12 Dreiecken --> 36 Punkte).
Ich wollte dann mich mal selber testen und wollte eine sich drehende Pyramide machen. Die Pyramide besteht aus 6 Dreiecken (2 für die Grundfläche und für jede Mantelfläche je eines), also 18 Punkten. Ich habe (meines erachtens nach sogar richtig) die Koordinaten angegeben und jeden Schritt aus dem Tutorial in meine eigene Source mit eingebaut. Das Problem ist nun, dass es nicht funktioniert. Es kommt zwar der schwarze Hintergrund (Device richtig initialisiert?), aber es taucht einfach keine Pyramide auf.
Jetzt bin ich echt am verzweifeln (es gibt ja nicht einmal eine Fehlermeldung nach der man googlen könnte), weil ich einfach keinen Fehler finde.
Ich hoffe jetzt auf irgendeinen guten .net Programmierer, der den Fehler findet (wahrscheinlich ist der so einfach, dass ich mir am liebsten die Tastatur gegen den Kopf hauen würde
Tutorial Source:
Form1.vb:
clsD3D.vb:
Code:
Public Class Form1
Dim moD3D As clsD3D
Dim mbRunning As Boolean = True
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
mbRunning = False
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim oRenderThread As New Threading.Thread(AddressOf RenderLoop)
moD3D = New clsD3D(Panel1)
oRenderThread.Start()
End Sub
Private Sub RenderLoop()
While mbRunning
moD3D.UpdateFrame()
moD3D.RenderFrame()
End While
End Sub
End Class
Code:
Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D
Public Class clsD3D
Dim p_D3DDevice As Device
Dim p_Cube As VertexBuffer
Dim p_MatCube1, p_MatCube2 As Matrix
Dim mbInit As Boolean = False
Public Sub New(ByVal target As Control)
Dim oPP As New PresentParameters()
Dim D3DCaps As Caps = Manager.GetDeviceCaps(0, DeviceType.Hardware)
Dim CreateFlgs As CreateFlags
With oPP
.Windowed = True
.SwapEffect = SwapEffect.Discard
.BackBufferCount = 1
.BackBufferFormat = Manager.Adapters(0).CurrentDisplayMode().Format
.BackBufferWidth = target.Width
.BackBufferHeight = target.Height
End With
oPP.AutoDepthStencilFormat = DepthFormat.D16
oPP.EnableAutoDepthStencil = True
If D3DCaps.DeviceCaps.SupportsHardwareTransformAndLight() And _
D3DCaps.DeviceCaps.SupportsPureDevice Then
CreateFlgs = CreateFlags.HardwareVertexProcessing Or _
CreateFlags.PureDevice
ElseIf D3DCaps.DeviceCaps.SupportsHardwareTransformAndLight() Then
CreateFlgs = CreateFlags.HardwareVertexProcessing
Else
CreateFlgs = CreateFlags.SoftwareVertexProcessing
End If
CreateFlgs = CreateFlgs Or CreateFlags.MultiThreaded
Try
p_D3DDevice = New Device(0, DeviceType.Hardware, target, CreateFlgs, oPP)
p_D3DDevice.RenderState.CullMode = Cull.CounterClockwise
Catch
Exit Sub
End Try
With p_D3DDevice
.RenderState.Lighting = False
.RenderState.ZBufferEnable = True
.Transform.View = Matrix.LookAtLH(New Vector3(0, 0, -15), _
New Vector3(0, 0, 0), _
New Vector3(0, 1, 0))
.Transform.Projection = Matrix.PerspectiveFovLH(Math.PI / 4, 4 / 3, 1, 100)
.Transform.World = Matrix.Identity
End With
CreateVertexBuffer()
mbInit = True
End Sub
Private Function CreateVertexBuffer() As Boolean
Dim cube() As CustomVertex.PositionColored
Try
p_Cube = New VertexBuffer(GetType(CustomVertex.PositionColored), _
36, p_D3DDevice, 0, _
CustomVertex.PositionColored.Format, Pool.Managed)
cube = DirectCast(p_Cube.Lock(0, LockFlags.None), _
CustomVertex.PositionColored())
Catch exp As Exception
Return False
End Try
' Die obere Seite
cube(0) = New CustomVertex.PositionColored(-1, 1, 1, Color.Blue.ToArgb)
cube(1) = New CustomVertex.PositionColored(1, 1, 1, Color.Red.ToArgb)
cube(2) = New CustomVertex.PositionColored(-1, 1, -1, Color.Blue.ToArgb)
cube(3) = New CustomVertex.PositionColored(1, 1, -1, Color.Red.ToArgb)
cube(4) = New CustomVertex.PositionColored(-1, 1, -1, Color.Blue.ToArgb)
cube(5) = New CustomVertex.PositionColored(1, 1, 1, Color.Red.ToArgb)
' Die untere Seite
cube(6) = New CustomVertex.PositionColored(-1, -1, -1, Color.Blue.ToArgb)
cube(7) = New CustomVertex.PositionColored(1, -1, 1, Color.Red.ToArgb)
cube(8) = New CustomVertex.PositionColored(-1, -1, 1, Color.Blue.ToArgb)
cube(9) = New CustomVertex.PositionColored(1, -1, 1, Color.Red.ToArgb)
cube(10) = New CustomVertex.PositionColored(-1, -1, -1, Color.Blue.ToArgb)
cube(11) = New CustomVertex.PositionColored(1, -1, -1, Color.Red.ToArgb)
' Die linke Seite
cube(12) = New CustomVertex.PositionColored(-1, 1, -1, Color.Blue.ToArgb)
cube(13) = New CustomVertex.PositionColored(-1, -1, -1, Color.Blue.ToArgb)
cube(14) = New CustomVertex.PositionColored(-1, 1, 1, Color.Blue.ToArgb)
cube(15) = New CustomVertex.PositionColored(-1, 1, 1, Color.Blue.ToArgb)
cube(16) = New CustomVertex.PositionColored(-1, -1, -1, Color.Blue.ToArgb)
cube(17) = New CustomVertex.PositionColored(-1, -1, 1, Color.Blue.ToArgb)
' Die rechte Seite
cube(18) = New CustomVertex.PositionColored(1, 1, -1, Color.Red.ToArgb)
cube(19) = New CustomVertex.PositionColored(1, 1, 1, Color.Red.ToArgb)
cube(20) = New CustomVertex.PositionColored(1, -1, -1, Color.Red.ToArgb)
cube(21) = New CustomVertex.PositionColored(1, -1, 1, Color.Red.ToArgb)
cube(22) = New CustomVertex.PositionColored(1, -1, -1, Color.Red.ToArgb)
cube(23) = New CustomVertex.PositionColored(1, 1, 1, Color.Red.ToArgb)
' Die Rückseite
cube(24) = New CustomVertex.PositionColored(-1, 1, -1, Color.Blue.ToArgb)
cube(25) = New CustomVertex.PositionColored(1, 1, -1, Color.Red.ToArgb)
cube(26) = New CustomVertex.PositionColored(-1, -1, -1, Color.Blue.ToArgb)
cube(27) = New CustomVertex.PositionColored(1, -1, -1, Color.Red.ToArgb)
cube(28) = New CustomVertex.PositionColored(-1, -1, -1, Color.Blue.ToArgb)
cube(29) = New CustomVertex.PositionColored(1, 1, -1, Color.Red.ToArgb)
' Die Vorderseite
cube(30) = New CustomVertex.PositionColored(1, 1, 1, Color.Red.ToArgb)
cube(31) = New CustomVertex.PositionColored(-1, 1, 1, Color.Blue.ToArgb)
cube(32) = New CustomVertex.PositionColored(-1, -1, 1, Color.Blue.ToArgb)
cube(33) = New CustomVertex.PositionColored(-1, -1, 1, Color.Blue.ToArgb)
cube(34) = New CustomVertex.PositionColored(1, -1, 1, Color.Red.ToArgb)
cube(35) = New CustomVertex.PositionColored(1, 1, 1, Color.Red.ToArgb)
p_Cube.Unlock()
Return True
End Function
Public Sub UpdateFrame()
Static cubeangle As Single
Static lastFrameUpdate As Integer
Try
cubeangle += CSng((Environment.TickCount - lastFrameUpdate) / 1000)
If cubeangle >= Math.PI * 2 Then cubeangle = 0
p_MatCube1 = Matrix.Multiply(Matrix.RotationY(cubeangle), _
Matrix.RotationX(cubeangle))
p_MatCube2 = Matrix.Multiply(Matrix.RotationY(cubeangle), _
Matrix.Translation(-5, 0, 0))
p_MatCube2 = Matrix.Multiply(p_MatCube2, Matrix.RotationY(cubeangle))
Catch
Finally
lastFrameUpdate = Environment.TickCount
End Try
End Sub
Public Sub RenderFrame()
Try
If Not mbInit Then Return
With p_D3DDevice
.Clear(ClearFlags.ZBuffer Or ClearFlags.Target, Color.Black, 1, 0)
.BeginScene()
.SetStreamSource(0, p_Cube, 0)
.VertexFormat = CustomVertex.PositionColored.Format
.Transform.World = p_MatCube1
.DrawPrimitives(PrimitiveType.TriangleList, 0, 12)
.Transform.World = p_MatCube2
.DrawPrimitives(PrimitiveType.TriangleList, 0, 12)
.EndScene()
.Present()
End With
Catch
End Try
End Sub
End Class
Meine Source:
Form1.vb:
clsD3DPyramid.vb:
Code:
Public Class Form1
Dim mbInitialized As Boolean = False
Dim moD3DPyramid As clsD3DPyramid
Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
moD3DPyramid.StopRendering()
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
moD3DPyramid = New clsD3DPyramid(Panel1)
moD3DPyramid.StartRendering()
mbInitialized = True
End Sub
Private Sub chkXRotation_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles chkXRotation.CheckedChanged
If mbInitialized Then
moD3DPyramid.xRotation = chkXRotation.Checked
End If
End Sub
Private Sub chkYRotation_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles chkYRotation.CheckedChanged
If mbInitialized Then
moD3DPyramid.yRotation = chkYRotation.Checked
End If
End Sub
End Class
Code:
Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D
Imports System.Threading
Public Class clsD3DPyramid
Dim moRenderThread As New Thread(AddressOf RenderLoop)
Dim mo_Device As Device = Nothing
Dim mvb_Pyramid As VertexBuffer
Dim mm_Pyramid As Matrix
Dim mbOn As Boolean = True
Public Sub New(ByVal oTarget As Control)
mo_Device = InitDevice(oTarget)
With mo_Device
.RenderState.Lighting = False
.RenderState.ZBufferEnable = False
.Transform.View = Matrix.LookAtLH(New Vector3(0, 0, -10), _
New Vector3(0, 0, 0), _
New Vector3(0, 1, 0))
.Transform.Projection = Matrix.PerspectiveFovLH(Math.PI / 4, 4 / 3, 1, 100)
.Transform.World = Matrix.Identity
End With
CreateVertexBuffer_Pyramid()
mo_Device.RenderState.CullMode = Cull.None
End Sub
Private Function InitDevice(ByVal oTarget As Control) As Device
Dim oPP As New PresentParameters
Dim D3DCaps As Caps = Manager.GetDeviceCaps(0, DeviceType.Hardware)
Dim CreateFlgs As CreateFlags
With oPP
.Windowed = True
.DeviceWindow = oTarget
.SwapEffect = SwapEffect.Discard
.BackBufferCount = 1
.BackBufferFormat = Manager.Adapters(0).CurrentDisplayMode().Format
.BackBufferWidth = oTarget.Width
.BackBufferHeight = oTarget.Height
.AutoDepthStencilFormat = DepthFormat.D16
.EnableAutoDepthStencil = True
End With
If D3DCaps.DeviceCaps.SupportsHardwareTransformAndLight() And _
D3DCaps.DeviceCaps.SupportsPureDevice Then
CreateFlgs = CreateFlags.HardwareVertexProcessing Or _
CreateFlags.PureDevice
ElseIf D3DCaps.DeviceCaps.SupportsHardwareTransformAndLight() Then
CreateFlgs = CreateFlags.HardwareVertexProcessing
Else
CreateFlgs = CreateFlags.SoftwareVertexProcessing
End If
CreateFlgs = CreateFlgs Or CreateFlags.MultiThreaded
Return New Device(0, DeviceType.Hardware, oTarget, CreateFlgs, oPP)
End Function
Private Sub CreateVertexBuffer_Pyramid()
Dim oaPyramide() As CustomVertex.PositionColored
mvb_Pyramid = New VertexBuffer(GetType(CustomVertex.PositionColored), 18, mo_Device, 0, CustomVertex.PositionColored.Format, Pool.Managed)
oaPyramide = DirectCast(mvb_Pyramid.Lock(0, LockFlags.None), CustomVertex.PositionColored())
' Alle Vertices sind im Uhrzeigersinn angeordnet
'Grundfläche
oaPyramide(0) = New CustomVertex.PositionColored(-1, -1, 1, Color.Blue.ToArgb)
oaPyramide(1) = New CustomVertex.PositionColored(1, -1, 1, Color.Green.ToArgb)
oaPyramide(2) = New CustomVertex.PositionColored(1, -1, -1, Color.Yellow.ToArgb)
oaPyramide(3) = New CustomVertex.PositionColored(-1, -1, 1, Color.Blue.ToArgb)
oaPyramide(4) = New CustomVertex.PositionColored(1, -1, -1, Color.Yellow.ToArgb)
oaPyramide(5) = New CustomVertex.PositionColored(-1, -1, -1, Color.Pink.ToArgb)
'Mantelflächen
oaPyramide(6) = New CustomVertex.PositionColored(0, 1, 0, Color.Red.ToArgb)
oaPyramide(7) = New CustomVertex.PositionColored(1, -1, 1, Color.Green.ToArgb)
oaPyramide(8) = New CustomVertex.PositionColored(-1, -1, 1, Color.Blue.ToArgb)
oaPyramide(9) = New CustomVertex.PositionColored(0, 1, 0, Color.Red.ToArgb)
oaPyramide(10) = New CustomVertex.PositionColored(1, -1, -1, Color.Yellow.ToArgb)
oaPyramide(11) = New CustomVertex.PositionColored(1, -1, 1, Color.Green.ToArgb)
oaPyramide(12) = New CustomVertex.PositionColored(0, 1, 0, Color.Red.ToArgb)
oaPyramide(13) = New CustomVertex.PositionColored(-1, -1, -1, Color.Pink.ToArgb)
oaPyramide(14) = New CustomVertex.PositionColored(1, -1, -1, Color.Yellow.ToArgb)
oaPyramide(15) = New CustomVertex.PositionColored(0, 1, 0, Color.Red.ToArgb)
oaPyramide(16) = New CustomVertex.PositionColored(-1, -1, 1, Color.Blue.ToArgb)
oaPyramide(17) = New CustomVertex.PositionColored(-1, -1, -1, Color.Pink.ToArgb)
'' Alle Vertices sind im Uhrzeigersinn angeordnet
''Grundfläche
'oaPyramide(0) = New CustomVertex.PositionColored(-1, -1, 1, Color.Red.ToArgb)
'oaPyramide(1) = New CustomVertex.PositionColored(1, -1, 1, Color.Red.ToArgb)
'oaPyramide(2) = New CustomVertex.PositionColored(1, -1, -1, Color.Red.ToArgb)
'oaPyramide(3) = New CustomVertex.PositionColored(-1, -1, 1, Color.Red.ToArgb)
'oaPyramide(4) = New CustomVertex.PositionColored(1, -1, -1, Color.Red.ToArgb)
'oaPyramide(5) = New CustomVertex.PositionColored(-1, -1, -1, Color.Red.ToArgb)
''Mantelflächen
'oaPyramide(6) = New CustomVertex.PositionColored(0, 1, 0, Color.Red.ToArgb)
'oaPyramide(7) = New CustomVertex.PositionColored(1, -1, 1, Color.Red.ToArgb)
'oaPyramide(8) = New CustomVertex.PositionColored(-1, -1, 1, Color.Red.ToArgb)
'oaPyramide(9) = New CustomVertex.PositionColored(0, 1, 0, Color.Red.ToArgb)
'oaPyramide(10) = New CustomVertex.PositionColored(1, -1, -1, Color.Red.ToArgb)
'oaPyramide(11) = New CustomVertex.PositionColored(1, -1, 1, Color.Red.ToArgb)
'oaPyramide(12) = New CustomVertex.PositionColored(0, 1, 0, Color.Red.ToArgb)
'oaPyramide(13) = New CustomVertex.PositionColored(-1, -1, -1, Color.Red.ToArgb)
'oaPyramide(14) = New CustomVertex.PositionColored(1, -1, -1, Color.Red.ToArgb)
'oaPyramide(15) = New CustomVertex.PositionColored(0, 1, 0, Color.Red.ToArgb)
'oaPyramide(16) = New CustomVertex.PositionColored(-1, -1, 1, Color.Red.ToArgb)
'oaPyramide(17) = New CustomVertex.PositionColored(-1, -1, -1, Color.Red.ToArgb)
mvb_Pyramid.Unlock()
End Sub
Private Sub RenderLoop()
While mbOn
Animation()
Try
With mo_Device
.Clear(ClearFlags.ZBuffer Or ClearFlags.Target, Color.Black, 1, 0)
.BeginScene()
.SetStreamSource(0, mvb_Pyramid, 0)
.VertexFormat = CustomVertex.PositionColored.Format
.Transform.World = mm_Pyramid
.DrawPrimitives(PrimitiveType.TriangleList, 0, 6)
.EndScene()
.Present()
End With
Catch ex As Exception
mbOn = False
End Try
End While
End Sub
Private Sub Animation()
Static cubeangle As Single
Static lastFrameUpdate As Integer
Try
cubeangle += CSng((Environment.TickCount - lastFrameUpdate) / 1000)
If cubeangle >= Math.PI * 2 Then
cubeangle = 0
End If
If xRotation Then
mm_Pyramid = Matrix.Multiply(mm_Pyramid, Matrix.RotationX(cubeangle))
End If
If yRotation Then
mm_Pyramid = Matrix.Multiply(mm_Pyramid, Matrix.RotationY(cubeangle))
End If
Catch
Finally
lastFrameUpdate = Environment.TickCount
End Try
End Sub
'###Public Functions and Vars###
Public yRotation As Boolean = False
Public xRotation As Boolean = False
Public Sub StartRendering()
mbOn = True
moRenderThread.Start()
End Sub
Public Sub StopRendering()
mbOn = False
End Sub
End Class
Für beide Quellcodes wurden (je die selben) Teile der managed Developer Runtime vom DirectX SDK August 2007 als Referenz mit eingebunden.
Hoffend, dass mir jemand helfen kann
Jeoni
P.S.: Ich möchte keine Kommentare wie "VB.net suckt, nimm C#" o.ä. lesen. Die beiden Sprachen unterscheiden sich (grob) nur in der Syntax.
Desweiteren ist mir natürlich bekannt, dass managed D3D unperformanter ist, als unmanaged D3D und dass .net Sprachen blöd sind. Das muss nicht weiter erörtert oder erwähnt werden
Also bitte nur Lösungsvorschläge zum Problem posten und nichts derart Allgemeines, danke.








