Anyone tried using DirectX as the renderer for a plugin ? I've got it working but it's slow - needs a readback from the rendertarget buffer and slow conversion to a bitmap for the return from 'render'...
pocketmoon Wrote:Anyone tried using DirectX as the renderer for a plugin ? I've got it working but it's slow - needs a readback from the rendertarget buffer and slow conversion to a bitmap for the return from 'render'...
Well I have it working fairly quickly now. I can animate a 256x256 image at about 25fps on my VIA SP13000 mobo (embedded gfx).
I'm going to write a Web Radio plugin and I'm planning to use DirectX for the interface.
The real pain is getting the Managed DirectX runtime installed on your target PC. In the end I gave up and installed the full Directx9c SDK.
Code:
Imports System
Imports GBPVR.Public
Imports System.Drawing
Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D
Imports System.Runtime.InteropServices
Namespace WebRadioPlugin
Public Class WebRadio
Implements IMenuTask
Private mobjDX9 As Microsoft.DirectX.Direct3D.Device
Private mobjPresent As Direct3D.PresentParameters
Private mobjMesh As Direct3D.Mesh
Private mobjMaterial As Direct3D.Material
Private mobjTimer As System.Windows.Forms.Timer
Private msinRotationAngle As Single
Private surf As Surface
Private initme As Boolean = True
Public Sub Activate() Implements GBPVR.Public.IMenuTask.Activate
End Sub
Public Sub Deactivate() Implements GBPVR.Public.IMenuTask.Deactivate
End Sub
Public Function GetConfigFormInstance(ByVal document As System.Xml.XmlDocument) As System.Windows.Forms.Form Implements GBPVR.Public.IMenuTask.GetConfigFormInstance
End Function
Public Function getDescription() As String Implements GBPVR.Public.IMenuTask.getDescription
Return "Listen To The Radio"
End Function
Public Function getName() As String Implements GBPVR.Public.IMenuTask.getName
Return "Web Radio"
End Function
Public Function getSkinSubdirectory() As String Implements GBPVR.Public.IMenuTask.getSkinSubdirectory
Return "WebRadio"
End Function
Public Function getTaskImage() As System.Drawing.Image Implements GBPVR.Public.IMenuTask.getTaskImage
End Function
Public Function needsRendering() As Boolean Implements GBPVR.Public.IMenuTask.needsRendering
End Function
Public Sub OnClick(ByVal location As System.Drawing.Point) Implements GBPVR.Public.IMenuTask.OnClick
End Sub
Public Sub OnDoubleClick(ByVal location As System.Drawing.Point) Implements GBPVR.Public.IMenuTask.OnDoubleClick
End Sub
Public Function OnKeyDown(ByVal e As System.Windows.Forms.KeyEventArgs) As Boolean Implements GBPVR.Public.IMenuTask.OnKeyDown
End Function
' On mouse wheel rotate the cube
Public Sub OnMouseWheel(ByVal e As System.Windows.Forms.MouseEventArgs) Implements GBPVR.Public.IMenuTask.OnMouseWheel
'rotate a bit for next time through!
msinRotationAngle += e.Delta * 0.001 ''0.05
Dim rotateZ As Matrix = Matrix.RotationZ(msinRotationAngle)
Dim rotateY As Matrix = Matrix.RotationY(msinRotationAngle)
Dim world As Matrix = Matrix.Multiply(rotateZ, rotateY)
mobjDX9.SetTransform(Direct3D.TransformType.World, world)
End Sub
Public Function render(ByRef requiresMoreRendering As Boolean) As System.Drawing.Image Implements GBPVR.Public.IMenuTask.render
requiresMoreRendering = False
If initme = True Then
OneTimeInit()
initme = False
End If
mobjDX9.SetRenderTarget(0, surf)
mobjDX9.Clear(Direct3D.ClearFlags.Target Or Direct3D.ClearFlags.ZBuffer, Color.Black.ToArgb(), 1.0, 0)
mobjDX9.BeginScene()
mobjDX9.Material = mobjMaterial
mobjMesh.DrawSubset(0)
mobjDX9.EndScene()
'mobjDX9.Present()
Dim stream As Microsoft.DirectX.GraphicsStream
stream = SurfaceLoader.SaveToStream(ImageFileFormat.Bmp, surf)
Dim img As Image = System.Drawing.Image.FromStream(stream)
Dim g As Graphics = Graphics.FromImage(img)
Dim textArea As New RectangleF(0, 0, img.Width, img.Height)
Dim strFormat As StringFormat = New StringFormat
strFormat.Alignment = StringAlignment.Center
strFormat.LineAlignment = StringAlignment.Center
g.DrawString("Hello World!", New System.Drawing.Font("Tahoma", 18), Brushes.WhiteSmoke, textArea, strFormat)
Return img
End Function
<DllImport("user32.dll", EntryPoint:="GetForegroundWindow")> Private Shared Function GetForegroundWindow() As IntPtr
End Function
Private Sub OneTimeInit()
Dim objAdapters As AdapterInformation
objAdapters = Direct3D.Manager.Adapters(0)
'
' Setup present params
'
mobjPresent = New Direct3D.PresentParameters
With mobjPresent
.Windowed = True
.SwapEffect = Direct3D.SwapEffect.Discard
.BackBufferFormat = objAdapters.CurrentDisplayMode.Format
.EnableAutoDepthStencil = True
.AutoDepthStencilFormat = Direct3D.DepthFormat.D16
.BackBufferHeight = objAdapters.CurrentDisplayMode.Height
.BackBufferWidth = objAdapters.CurrentDisplayMode.Width
End With
mobjDX9 = New Direct3D.Device(objAdapters.Adapter, Direct3D.DeviceType.Hardware, GetForegroundWindow(), _
Direct3D.CreateFlags.SoftwareVertexProcessing, mobjPresent)
'Off Screen buffer to render to.
surf = mobjDX9.CreateRenderTarget(512, 512, objAdapters.CurrentDisplayMode.Format, MultiSampleType.None, 0, False)
AddHandler mobjDX9.DeviceReset, AddressOf Me.OnDeviceReset
InitializeDirect3D()
End Sub
Private Sub CreateCube()
mobjMesh = Direct3D.Mesh.Box(mobjDX9, 10, 10, 10)
End Sub
Private Sub CreateMaterials()
mobjMaterial = New Direct3D.Material
mobjMaterial.Diffuse = Color.FromArgb(1, 255, 255, 255)
End Sub
Private Sub CreateLights()
Dim Light0 As Direct3D.Light = mobjDX9.Lights(0)
Light0.Type = Direct3D.LightType.Directional
Light0.Direction = New Vector3(0, -1, 1)
Light0.Diffuse = Color.FromArgb(0, 20, 20, 200)
Light0.Ambient = Color.FromArgb(0, 30, 30, 200)
Light0.Enabled = True
'Light0.s()
mobjDX9.RenderState.Lighting = True
mobjDX9.RenderState.Ambient = Color.FromArgb(0, 20, 20, 20)
End Sub
Private Sub InitializeView()
Dim eyePosition As New Vector3(0, 0, -30)
Dim direction As New Vector3(0, 0, 0)
Dim upDirection As New Vector3(0, 1, 0)
Dim view As Matrix = Matrix.LookAtLH(eyePosition, direction, upDirection)
mobjDX9.SetTransform(Direct3D.TransformType.View, view)
Dim fieldOfView As Single = Math.PI / 4
Dim aspectRatio As Single = 1.0
Dim nearPlane As Single = 1.0
Dim farPlane As Single = 500.0
Dim projection As Matrix = Matrix.PerspectiveFovLH(fieldOfView, aspectRatio, nearPlane, farPlane)
mobjDX9.SetTransform(Direct3D.TransformType.Projection, projection)
End Sub
Private Sub InitializeDirect3D()
CreateCube()
CreateMaterials()
CreateLights()
InitializeView()
End Sub
Private Sub OnDeviceReset(ByVal Sender As Object, ByVal e As EventArgs)
InitializeDirect3D()
End Sub
End Class
End Namespace