Jumping into SharpDX’s rabbit hole.

After my first real and sort of successful experience with raw DirectX (like in not using Irrlicht)  to create the SSAO plugin for DX Studio, I decided to give a try to SharpDX.

Today, after some failings, I managed to convert to basic .net and Visual Studio 2008, and then compile the ‘minicube’ example that comes with the package:

minicube

Then i thought: How hard would it be to insert the rendering device into a standard Windows form?

Well, turns out that SharpDX RenderForm inherits from Windows form, so It Is a Windows form, right?

Since the project already had a form created by default, I just changed the definition for the render form, to create a new instance of the Windows form. Voila! DX9 window embedded into a Basic .net app, with anchors and buttons, with a single line of code (the colored panels in the bottom change on click the clearing color of the device):

mnb

mng

mnr

This is what I needed to make this on VB .net:

First, start a new “Windows service” project and add  references to:

SharpDX.Direct3D9.dll
SharpDX.dll

Found them under (SharpDX folder)\Bin\Standard-net20

On a module:

Imports System
Imports System.Diagnostics

Imports SharpDX
Imports SharpDX.Direct3D9
Imports SharpDX.Windows
Imports Color = SharpDX.Color

Module game

    Dim direct3D As Direct3D = New Direct3D()
    Dim device As Device
    Friend bgcolor As Color
    Dim effect__1
    Dim technique
    Dim clock = New Stopwatch()
    Dim viewProj
    Friend mult As Integer = 1

    ''' SharpDX MiniCube modified example
    '''
<STAThread()> _
Public Sub Main() Dim form = New Form1() 
Form.Text = "SharpDX - MiniCube Direct3D9 Sample" 
' Creates the Device device = New Device(direct3D, 0, DeviceType.Hardware, form.Panel1.Handle, CreateFlags.HardwareVertexProcessing, New PresentParameters(form.Panel1.Width, form.Panel1.Height)) 
' Creates the VertexBuffer Dim vertices = New VertexBuffer(device, Utilities.SizeOf(Of Vector4)() * 2 * 36, Usage.WriteOnly, VertexFormat.None, Pool.Managed) 
' Front 
' BACK 
' Top 
' Bottom 
' Left 
' Right
Dim g() As Vector4 = {New Vector4(-1.0F, -1.0F, -1.0F, 1.0F), New Vector4(1.0F, 0.0F, 0.0F, 1.0F), New Vector4(-1.0F, 1.0F, -1.0F, 1.0F), New Vector4(1.0F, 0.0F, 0.0F, 1.0F), New Vector4(1.0F, 1.0F, -1.0F, 1.0F), New Vector4(1.0F, 0.0F, 0.0F, 1.0F), _
New Vector4(-1.0F, -1.0F, -1.0F, 1.0F), New Vector4(1.0F, 0.0F, 0.0F, 1.0F), New Vector4(1.0F, 1.0F, -1.0F, 1.0F), New Vector4(1.0F, 0.0F, 0.0F, 1.0F), New Vector4(1.0F, -1.0F, -1.0F, 1.0F), New Vector4(1.0F, 0.0F, 0.0F, 1.0F), _
 New Vector4(-1.0F, -1.0F, 1.0F, 1.0F), New Vector4(0.0F, 1.0F, 0.0F, 1.0F), New Vector4(1.0F, 1.0F, 1.0F, 1.0F), New Vector4(0.0F, 1.0F, 0.0F, 1.0F), New Vector4(-1.0F, 1.0F, 1.0F, 1.0F), New Vector4(0.0F, 1.0F, 0.0F, 1.0F), _
New Vector4(-1.0F, -1.0F, 1.0F, 1.0F), New Vector4(0.0F, 1.0F, 0.0F, 1.0F), New Vector4(1.0F, -1.0F, 1.0F, 1.0F), New Vector4(0.0F, 1.0F, 0.0F, 1.0F), New Vector4(1.0F, 1.0F, 1.0F, 1.0F), New Vector4(0.0F, 1.0F, 0.0F, 1.0F), _
New Vector4(-1.0F, 1.0F, -1.0F, 1.0F), New Vector4(0.0F, 0.0F, 1.0F, 1.0F), New Vector4(-1.0F, 1.0F, 1.0F, 1.0F), New Vector4(0.0F, 0.0F, 1.0F, 1.0F), New Vector4(1.0F, 1.0F, 1.0F, 1.0F), New Vector4(0.0F, 0.0F, 1.0F, 1.0F), _ 
New Vector4(-1.0F, 1.0F, -1.0F, 1.0F), New Vector4(0.0F, 0.0F, 1.0F, 1.0F), New Vector4(1.0F, 1.0F, 1.0F, 1.0F), New Vector4(0.0F, 0.0F, 1.0F, 1.0F), New Vector4(1.0F, 1.0F, -1.0F, 1.0F), New Vector4(0.0F, 0.0F, 1.0F, 1.0F), _ 
New Vector4(-1.0F, -1.0F, -1.0F, 1.0F), New Vector4(1.0F, 1.0F, 0.0F, 1.0F), New Vector4(1.0F, -1.0F, 1.0F, 1.0F), New Vector4(1.0F, 1.0F, 0.0F, 1.0F), New Vector4(-1.0F, -1.0F, 1.0F, 1.0F), New Vector4(1.0F, 1.0F, 0.0F, 1.0F), _ 
New Vector4(-1.0F, -1.0F, -1.0F, 1.0F), New Vector4(1.0F, 1.0F, 0.0F, 1.0F), New Vector4(1.0F, -1.0F, -1.0F, 1.0F), New Vector4(1.0F, 1.0F, 0.0F, 1.0F), New Vector4(1.0F, -1.0F, 1.0F, 1.0F), New Vector4(1.0F, 1.0F, 0.0F, 1.0F), _ 
New Vector4(-1.0F, -1.0F, -1.0F, 1.0F), New Vector4(1.0F, 0.0F, 1.0F, 1.0F), New Vector4(-1.0F, -1.0F, 1.0F, 1.0F), New Vector4(1.0F, 0.0F, 1.0F, 1.0F), New Vector4(-1.0F, 1.0F, 1.0F, 1.0F), New Vector4(1.0F, 0.0F, 1.0F, 1.0F), _ 
New Vector4(-1.0F, -1.0F, -1.0F, 1.0F), New Vector4(1.0F, 0.0F, 1.0F, 1.0F), New Vector4(-1.0F, 1.0F, 1.0F, 1.0F), New Vector4(1.0F, 0.0F, 1.0F, 1.0F), New Vector4(-1.0F, 1.0F, -1.0F, 1.0F), New Vector4(1.0F, 0.0F, 1.0F, 1.0F), _ 
New Vector4(1.0F, -1.0F, -1.0F, 1.0F), New Vector4(0.0F, 1.0F, 1.0F, 1.0F), New Vector4(1.0F, 1.0F, 1.0F, 1.0F), New Vector4(0.0F, 1.0F, 1.0F, 1.0F), New Vector4(1.0F, -1.0F, 1.0F, 1.0F), New Vector4(0.0F, 1.0F, 1.0F, 1.0F), _ 
New Vector4(1.0F, -1.0F, -1.0F, 1.0F), New Vector4(0.0F, 1.0F, 1.0F, 1.0F), New Vector4(1.0F, 1.0F, -1.0F, 1.0F), New Vector4(0.0F, 1.0F, 1.0F, 1.0F), New Vector4(1.0F, 1.0F, 1.0F, 1.0F), New Vector4(0.0F, 1.0F, 1.0F, 1.0F)} 
vertices.Lock(0, 0, LockFlags.None).WriteRange(g) 
vertices.Unlock() 
' Compiles the effect 
Try
 effect__1 = Effect.FromFile(device, "MiniCube.fx", ShaderFlags.None) 
Catch ex As Exception
 MsgBox(ex.Message, MsgBoxStyle.OkOnly + MsgBoxStyle.Critical, "Error compiling shader") 
End
 End Try 

' Allocate Vertex Elements
 Dim vertexElems() As VertexElement = {New VertexElement(0, 0, DeclarationType.Float4, DeclarationMethod.Default, DeclarationUsage.Position, 0), New VertexElement(0, 16, DeclarationType.Float4, DeclarationMethod.[Default], DeclarationUsage.Color, 0), VertexElement.VertexDeclarationEnd} 
' Creates and sets the Vertex Declaration 
Dim vertexDecl = New VertexDeclaration(device, vertexElems) 
device.SetStreamSource(0, vertices, 0, Utilities.SizeOf(Of Vector4)() * 2) 
device.VertexDeclaration = vertexDecl
 ' Get the technique
 technique = effect__1.GetTechnique(0)
 Dim pass = effect__1.GetPass(technique, 0)
 ' Prepare matrices
Dim view = Matrix.LookAtLH(New Vector3(0, 0, -5), New Vector3(0, 0, 0), Vector3.UnitY)
 Dim proj = Matrix.PerspectiveFovLH(CSng(Math.PI) / 4.0F, form.Panel1.Width / CSng(form.Panel1.Height), 0.1F, 100.0F)
 viewProj = Matrix.Multiply(view, proj) 
'' Use clock 
clock.Start()
 RenderLoop.Run(form, AddressOf gameloop)
effect__1.Dispose() 
vertices.Dispose() 
device.Dispose()
direct3D.Dispose() 
End Sub 

Private Function gameloop() As RenderLoop.RenderCallback 
Dim time = clock.ElapsedMilliseconds / 1000.0F time *= mult

device.Clear(ClearFlags.Target Or ClearFlags.ZBuffer, bgcolor, 1.0F, 0)
device.BeginScene() 
Dim Effect2 As Effect = effect__1 
Effect2.Technique = technique 
Effect2.Begin() 
Effect2.BeginPass(0) 
Dim worldViewProj As SharpDX.Matrix = Matrix.RotationX(time) * Matrix.RotationY(time * 2) * Matrix.RotationZ(time * 0.7F) * viewProj
Effect2.SetValue("worldViewProj", worldViewProj) 
device.DrawPrimitives(PrimitiveType.TriangleList, 0, 12) 
Effect2.EndPass() 
Effect2.End() 
device.EndScene() 
device.Present() 
End Function 
End Module

Add a form called Form1 to the project and add to the form 4 panels, Panel1 bigger to contain the DX window and the others with different background colors. Also place somewhere in the form a trackbar control (not shown in the pictures, since I add it later, but the code posted includes it).

On the Form1 code:

Public Class Form1

Private Sub Panel2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Panel2.Click
Setcolor(sender.backcolor)
End Sub

Private Sub Setcolor(ByVal col As Drawing.Color)
Dim sr As Single = (1 / 255) * col.R
Dim sg As Single = (1 / 255) * col.G
Dim sb As Single = (1 / 255) * col.B
bgcolor = New SharpDX.Color(sr, sg, sb, 1)
End Sub

Private Sub Panel3_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Panel3.Click
Setcolor(sender.backcolor)
End Sub

Private Sub Panel4_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Panel4.Click
Setcolor(sender.backcolor)
End Sub

Private Sub TrackBar1_Scroll(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TrackBar1.Scroll
mult = TrackBar1.Value
End Sub
End Class

You also need the MiniCube.fx file included with the minicube example that comes with SharpDX. I have it in the release folder of the solution.
Now, I cant tell if this is the correct way to do it, speaking of performance or porting compatibility, but it works nicely 😉

Can this get more interesting?  Sure it can. I’ll keep going.

Advertisements