Click here to Skip to main content
15,886,570 members
Articles / Programming Languages / Visual Basic

Mathemathics Framework

Rate me:
Please Sign up or sign in to vote.
4.76/5 (56 votes)
16 Sep 2008CPOL6 min read 75.3K   6.2K   171  
.NET Mathematical Framework
Imports System
Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D
Imports Microsoft.Samples.DirectX.UtilityToolkit
Imports MidRange
Imports BV.Math
Imports System.ComponentModel

Public Class Form4
    Implements IFrameworkCallback
    Implements IDeviceCreation

    ' Constants
    Private Const VerticesPerEdge As Integer = 64
    Private Const NumberVertices As Integer = VerticesPerEdge * VerticesPerEdge
    Private Const NumberIndices As Integer = 6 * (VerticesPerEdge - 1) * (VerticesPerEdge - 1)
    Private Shared ReadOnly ClearColor As Integer = System.Drawing.Color.FromArgb(45, 50, 170).ToArgb()
    ' Variables
    Private sampleFramework As Framework
    ' Framework for samples
    Private drawingFont As Font
    ' Font for drawing text
    Private textSprite As Sprite
    ' Sprite for batching text calls
    Private isHelpShowing As Boolean
    ' If true, show the help ui
    Private camera As New ModelViewerCamera()
    ' A model viewing camera
    Private hud As Dialog
    ' dialog for standard controls
    Private worldViewHandle As EffectHandle
    ' Effect Handle for the 'world view' matrix
    Private DxHandle As Microsoft.DirectX.Direct3D.EffectHandle
    ' Effect Handle for the time variable
    Private MinXHandle As EffectHandle
    ' Effect Handle for the time variable
    ' Scene variables
    Private vb As VertexBuffer
    Private ib As IndexBuffer
    Private shader As VertexShader
    Private constantTable As ConstantTable
    Private vertexDecl As VertexDeclaration

    Private intPlanoComplejo As Double(,)


#Region "contructor"

    Public Sub New(ByVal f As Framework)
        ' Store framework
        sampleFramework = f

        Me.InitializeComponent()
        intPlanoComplejo = New Double(VerticesPerEdge, VerticesPerEdge) {}
        ' Create dialogs
        hud = New Dialog(sampleFramework)
    End Sub

#End Region

    ' Called during device initialization, this code checks the device for some 
    ' minimum set of capabilities, and rejects those that don't pass by returning false.
    Public Function IsDeviceAcceptable(ByVal caps As Caps, ByVal adapterFormat As Format, ByVal backBufferFormat As Format, ByVal windowed As Boolean) As Boolean Implements IDeviceCreation.IsDeviceAcceptable
        ' Skip back buffer formats that don't support alpha blending
        If Not Manager.CheckDeviceFormat(caps.AdapterOrdinal, caps.DeviceType, adapterFormat, Usage.QueryPostPixelShaderBlending, ResourceType.Textures, backBufferFormat) Then
            Return False
        End If
        Return True
    End Function


    ' This callback function is called immediately before a device is created to allow the 
    ' application to modify the device settings. The supplied settings parameter 
    ' contains the settings that the framework has selected for the new device, and the 
    ' application can make any desired changes directly to this structure.  Note however that 
    ' the sample framework will not correct invalid device settings so care must be taken 
    ' to return valid device settings, otherwise creating the Device will fail.  
    Public Sub ModifyDeviceSettings(ByVal settings As DeviceSettings, ByVal caps As Caps) Implements IDeviceCreation.ModifyDeviceSettings
        ' If device doesn't support HW T&L or doesn't support 1.1 vertex shaders in HW 
        ' then switch to SWVP.
        If (Not caps.DeviceCaps.SupportsHardwareTransformAndLight) OrElse (caps.VertexShaderVersion < New Version(1, 1)) Then
            settings.BehaviorFlags = CreateFlags.SoftwareVertexProcessing
        Else
            settings.BehaviorFlags = CreateFlags.HardwareVertexProcessing
        End If
        ' This application is designed to work on a pure device by not using 
        ' any get methods, so create a pure device if supported and using HWVP.
        If (caps.DeviceCaps.SupportsPureDevice) AndAlso ((settings.BehaviorFlags And CreateFlags.HardwareVertexProcessing) <> 0) Then
            settings.BehaviorFlags = settings.BehaviorFlags Or CreateFlags.PureDevice
        End If
        ' Debugging vertex shaders requires either REF or software vertex processing 
        ' and debugging pixel shaders requires REF.  
#If (DEBUG_VS) Then
			If settings.DeviceType <> DeviceType.Reference Then
				settings.BehaviorFlags = settings.BehaviorFlags And Not CreateFlags.HardwareVertexProcessing
				settings.BehaviorFlags = settings.BehaviorFlags Or CreateFlags.SoftwareVertexProcessing
			End If
#End If
#If (DEBUG_PS) Then
			settings.DeviceType = DeviceType.Reference
#End If
        ' For the first device created if its a REF device, optionally display a warning dialog box
        If settings.DeviceType = DeviceType.Reference Then
            Utility.DisplaySwitchingToRefWarning(sampleFramework, "HLSLwithoutEffects")
        End If
    End Sub


    ' This event will be fired immediately after the Direct3D device has been 
    ' created, which will happen during application initialization and windowed/full screen 
    ' toggles. This is the best location to create Pool.Managed resources since these 
    ' resources need to be reloaded whenever the device is destroyed. Resources created  
    ' here should be released in the Disposing event. 
    Private Sub OnCreateDevice(ByVal sender As Object, ByVal e As DeviceEventArgs)
        ' Initialize the font
        drawingFont = ResourceCache.GetGlobalInstance().CreateFont(e.Device, 15, 0, FontWeight.Bold, 1, False, _
         CharacterSet.[Default], Precision.[Default], FontQuality.[Default], PitchAndFamily.FamilyDoNotCare Or PitchAndFamily.DefaultPitch, "Arial")
        ' Create the vertex shader and declaration
        'new VertexElement(0, 0, DeclarationType.Float2, DeclarationMethod.Default, 
        Dim elements As VertexElement() = New VertexElement() {New VertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.[Default], DeclarationUsage.Position, 0), VertexElement.VertexDeclarationEnd}
        vertexDecl = New VertexDeclaration(e.Device, elements)
        ' Find the shader file
        Dim path As String = Utility.FindMediaFile("HLSLwithoutEffects.vsh")
        ' Define DEBUG_VS and/or DEBUG_PS to debug vertex and/or pixel shaders with the 
        ' shader debugger. Debugging vertex shaders requires either REF or software vertex 
        ' processing, and debugging pixel shaders requires REF.  The 
        ' ShaderFlags.Force*SoftwareNoOptimizations flag improves the debug experience in the 
        ' shader debugger.  It enables source level debugging, prevents instruction 
        ' reordering, prevents dead code elimination, and forces the compiler to compile 
        ' against the next higher available software target, which ensures that the 
        ' unoptimized shaders do not exceed the shader model limitations.  Setting these 
        ' flags will cause slower rendering since the shaders will be unoptimized and 
        ' forced into software.  See the DirectX documentation for more information about 
        ' using the shader debugger.
        Dim shaderFlags As ShaderFlags = 0
#If (DEBUG_VS) Then
			shaderFlags = shaderFlags Or ShaderFlags.ForceVertexShaderSoftwareNoOptimizations
#End If
#If (DEBUG_PS) Then
			shaderFlags = shaderFlags Or ShaderFlags.ForcePixelShaderSoftwareNoOptimizations
#End If
        Dim errors As String = ""
        Using code As GraphicsStream = ShaderLoader.CompileShaderFromFile(path, "Ripple", Nothing, Nothing, "vs_1_1", shaderFlags, _
         errors, constantTable)
            ' We will store these constants in an effect handle here for performance reasons.
            ' You could simply use the string value (i.e., "worldViewProj") in the SetValue call
            ' and it would work just as well, but that actually requires an allocation to be made
            ' and can actually slow your performance down.  It's much more efficient to simply
            ' cache these handles for use later
            worldViewHandle = constantTable.GetConstant(Nothing, "worldViewProj")
            DxHandle = constantTable.GetConstant(Nothing, "Dx")
            MinXHandle = constantTable.GetConstant(Nothing, "MinX")
            ' Create the shader
            shader = New VertexShader(e.Device, code)
        End Using
        ' Setup the camera's view parameters
        camera.SetViewQuat(New Quaternion(-0.275F, 0.3F, 0.0F, 0.7F))
    End Sub


    ' This event will be fired immediately after the Direct3D device has been 
    ' reset, which will happen after a lost device scenario. This is the best location to 
    ' create Pool.Default resources since these resources need to be reloaded whenever 
    ' the device is lost. Resources created here should be released in the OnLostDevice 
    ' event. 
    Private Sub OnResetDevice(ByVal sender As Object, ByVal e As DeviceEventArgs)
        Dim desc As SurfaceDescription = e.BackBufferDescription
        ' Create a sprite to help batch calls when drawing many lines of text
        textSprite = New Sprite(e.Device)
        ' Setup render states
        e.Device.RenderState.Lighting = False
        e.Device.RenderState.CullMode = Cull.None
        ' Create and initialize index buffer
        ib = New IndexBuffer(GetType(Short), NumberIndices, e.Device, Usage.None, Pool.[Default])
        Dim data As GraphicsStream = ib.Lock(0, 0, LockFlags.None)
        For y As Integer = 1 To VerticesPerEdge - 1
            For x As Integer = 1 To VerticesPerEdge - 1
                data.Write(CType(((y - 1) * VerticesPerEdge + (x - 1)), Short))
                data.Write(CType(((y - 0) * VerticesPerEdge + (x - 1)), Short))
                data.Write(CType(((y - 1) * VerticesPerEdge + (x - 0)), Short))
                data.Write(CType(((y - 1) * VerticesPerEdge + (x - 0)), Short))
                data.Write(CType(((y - 0) * VerticesPerEdge + (x - 1)), Short))
                data.Write(CType(((y - 0) * VerticesPerEdge + (x - 0)), Short))
            Next
        Next
        ib.Unlock()
        vb = New VertexBuffer(GetType(Vector3), NumberVertices, e.Device, Usage.None, VertexFormats.None, Pool.[Default])

        UpdateVertexBuffer(e.Device)
        ' Setup the camera's projection parameters
        Dim aspectRatio As Single = CType(desc.Width, Single) / CType(desc.Height, Single)
        camera.SetProjectionParameters(CType(Math.PI, Single) / 4.0F, aspectRatio, 0.1F, 1000.0F)
        camera.SetWindow(desc.Width, desc.Height)
        camera.MaximumRadius = 30.0F
        ' Resize the hud
        hud.SetLocation(desc.Width - 170, 0)
        hud.SetSize(170, 170)
    End Sub

    Private Sub UpdateVertexBuffer(ByVal device As Device)
        Dim data As GraphicsStream
        ' Create and initialize vertex buffer
        If vb Is Nothing Then
            vb = New VertexBuffer(GetType(Vector3), NumberVertices, device, Usage.None, VertexFormats.None, Pool.[Default])
        End If
        'Dim cv As CustomVertex.PositionColored

        'vb = New VertexBuffer(GetType(CustomVertex.PositionColored), NumberVertices, device, Usage.None, VertexFormats.None, Pool.[Default])
        data = vb.Lock(0, 0, LockFlags.None)
        For y As Integer = 0 To VerticesPerEdge - 1
            For x As Integer = 0 To VerticesPerEdge - 1
                'cv.Position = New Vector3((CType(x, Single) / CType((VerticesPerEdge - 1), Single) - 0.5F) * CType(Math.PI, Single), _
                '                        (CType(y, Single) / CType((VerticesPerEdge - 1), Single) - 0.5F) * CType(Math.PI, Single), _
                '                        CType(intPlanoComplejo(x, y), Single))
                'cv.Color = System.Drawing.Color.SteelBlue.ToArgb
                'data.Write(cv)
                data.Write(New Vector3((CType(x, Single) / CType((VerticesPerEdge - 1), Single) - 0.5F) * CType(Math.PI, Single), _
                                        (CType(y, Single) / CType((VerticesPerEdge - 1), Single) - 0.5F) * CType(Math.PI, Single), _
                                        CType(intPlanoComplejo(x, y), Single)))
            Next
        Next
        vb.Unlock()
    End Sub


    ' This event function will be called fired after the Direct3D device has 
    ' entered a lost state and before Device.Reset() is called. Resources created
    ' in the OnResetDevice callback should be released here, which generally includes all 
    ' Pool.Default resources. See the "Lost Devices" section of the documentation for 
    ' information about lost devices.
    Private Sub OnLostDevice(ByVal sender As Object, ByVal e As EventArgs)
        If vb IsNot Nothing Then
            vb.Dispose()
        End If
        If ib IsNot Nothing Then
            ib.Dispose()
        End If
        If textSprite IsNot Nothing Then
            textSprite.Dispose()
        End If
    End Sub


    ' This event will be fired immediately after the Direct3D device has 
    ' been destroyed, which generally happens as a result of application termination or 
    ' windowed/full screen toggles. Resources created in the OnCreateDevice event 
    ' should be released here, which generally includes all Pool.Managed resources. 
    Private Sub OnDestroyDevice(ByVal sender As Object, ByVal e As EventArgs)
        If shader IsNot Nothing Then
            shader.Dispose()
        End If
        If constantTable IsNot Nothing Then
            constantTable.Dispose()
        End If
        If vertexDecl IsNot Nothing Then
            vertexDecl.Dispose()
        End If
    End Sub


    ' This callback function will be called once at the beginning of every frame. This is the
    ' best location for your application to handle updates to the scene, but is not 
    ' intended to contain actual rendering calls, which should instead be placed in the 
    ' OnFrameRender callback.  
    Public Sub OnFrameMove(ByVal device As Device, ByVal appTime As Double, ByVal elapsedTime As Single) Implements IFrameworkCallback.OnFrameMove
        ' Update the camera's position based on user input 
        camera.FrameMove(elapsedTime)
        ' Setup vertex shader constants
        Dim worldViewProj As Matrix, world As Matrix, view As Matrix, proj As Matrix
        world = camera.WorldMatrix
        view = camera.ViewMatrix
        proj = camera.ProjectionMatrix
        worldViewProj = world * view * proj
        constantTable.SetValue(device, worldViewHandle, worldViewProj)
        'constantTable.SetValue(device, timeHandle, (float)appTime);
        constantTable.SetValue(device, DxHandle, 1)
        constantTable.SetValue(device, MinXHandle, 0)

        'If Me.mustUpdate Then
        '    Me.UpdateVertexBuffer(Me.sampleFramework.Device)
        '    mustUpdate = False
        'End If
    End Sub


    ' This callback function will be called at the end of every frame to perform all the 
    ' rendering calls for the scene, and it will also be called if the window needs to be 
    ' repainted. After this function has returned, the sample framework will call 
    ' Device.Present to display the contents of the next buffer in the swap chain
    Public Sub OnFrameRender(ByVal device As Device, ByVal appTime As Double, ByVal elapsedTime As Single) Implements IFrameworkCallback.OnFrameRender
        Dim beginSceneCalled As Boolean = False
        ' Clear the render target and the zbuffer 
        device.Clear(ClearFlags.ZBuffer Or ClearFlags.Target, ClearColor, 1.0F, 0)
        Try
            device.BeginScene()
            beginSceneCalled = True
            device.VertexDeclaration = vertexDecl
            device.VertexShader = shader
            device.SetStreamSource(0, vb, 0)
            device.Indices = ib
            device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, NumberVertices, 0, CInt(NumberIndices / 3))
            RenderText()
            ' Render the HUD
            hud.OnRender(elapsedTime)
        Finally
            If beginSceneCalled Then
                device.EndScene()
            End If
        End Try
    End Sub


    ' As a convenience, the sample framework inspects the incoming windows messages for
    ' keystroke messages and decodes the message parameters to pass relevant keyboard
    ' messages to the application.  The framework does not remove the underlying keystroke 
    ' messages, which are still passed to the application's MsgProc callback.
    Private Sub OnKeyEvent(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs)
        Select Case e.KeyCode
            Case System.Windows.Forms.Keys.F1
                isHelpShowing = Not isHelpShowing
                Exit Select
        End Select
    End Sub


    ' Render the help and statistics text. This function uses the Font object for 
    ' efficient text rendering.
    Private Sub RenderText()
        Dim txtHelper As New TextHelper(drawingFont, textSprite, 15)
        ' Output statistics
        txtHelper.Begin()
        txtHelper.SetInsertionPoint(5, 5)
        txtHelper.SetForegroundColor(New ColorValue(1.0F, 1.0F, 0.0F, 1.0F).ToArgb())
        txtHelper.DrawTextLine(sampleFramework.FrameStats)
        txtHelper.DrawTextLine(sampleFramework.DeviceStats)
        ' Draw help
        If isHelpShowing Then
            txtHelper.SetInsertionPoint(10, sampleFramework.BackBufferSurfaceDescription.Height - 15 * 6)
            txtHelper.SetForegroundColor(New ColorValue(1.0F, 0.75F, 0.0F, 1.0F).ToArgb())
            txtHelper.DrawTextLine("Controls (F1 to hide):")
            txtHelper.SetInsertionPoint(40, sampleFramework.BackBufferSurfaceDescription.Height - 15 * 5)
            txtHelper.DrawTextLine("Rotate model: Left mouse button")
            txtHelper.DrawTextLine("Rotate camera: Right mouse button")
            txtHelper.DrawTextLine("Zoom camera: Mouse wheel scroll")
            txtHelper.DrawTextLine("Hide help: F1")
        Else
            txtHelper.SetForegroundColor(New ColorValue(1.0F, 1.0F, 1.0F, 1.0F).ToArgb())
            txtHelper.DrawTextLine("Press F1 for help")
        End If
        txtHelper.[End]()
    End Sub


    ' Before handling window messages, the sample framework passes incoming windows 
    ' messages to the application through this callback function. If the application sets 
    ' noFurtherProcessing to true, the sample framework will not process the message
    Public Function OnMsgProc(ByVal hWnd As IntPtr, ByVal msg As NativeMethods.WindowMessage, ByVal wParam As IntPtr, ByVal lParam As IntPtr, ByRef noFurtherProcessing As Boolean) As IntPtr
        ' Give the dialog a chance to handle the message first
        If Not hud.MessageProc(hWnd, msg, wParam, lParam) Then
            ' Pass all remaining windows messages to camera so it can respond to user input
            camera.HandleMessages(hWnd, msg, wParam, lParam)
        End If
        Return IntPtr.Zero
    End Function


    ' Adds the guid stuff to the application
    Public Sub InitializeApplication()
        Dim y As Integer = 10
        ' Create the buttons
        Dim fullScreen As Button = hud.AddButton(2, "Toggle full screen", 35, y, 125, 22)
        y += 24
        Dim toggleRef As Button = hud.AddButton(3, "Toggle reference (F3)", 35, y, 125, 22)
        'y += 24
        'Dim changeDevice As Button = hud.AddButton(4, "Change Device (F2)", 35, y, 125, 22)
        AddHandler fullScreen.Click, AddressOf OnFullscreenClicked
        AddHandler toggleRef.Click, AddressOf OnRefClicked
        'AddHandler changeDevice.Click, AddressOf OnChangeDevicClicked
        ' Hook the button events for when these items are clicked
    End Sub

    'Called when the change device button is clicked
    Private Sub OnChangeDevicClicked(ByVal sender As Object, ByVal e As EventArgs)
        sampleFramework.ShowSettingsDialog(Not sampleFramework.IsD3DSettingsDialogShowing)
    End Sub

    'Called when the full screen button is clicked
    Private Sub OnFullscreenClicked(ByVal sender As Object, ByVal e As EventArgs)
        sampleFramework.ToggleFullscreen()
    End Sub

    'Called when the ref button is clicked
    Private Sub OnRefClicked(ByVal sender As Object, ByVal e As EventArgs)
        sampleFramework.ToggleReference()
    End Sub


    ' Entry point to the program. Initializes everything and goes into a message processing 
    ' loop. Idle time is used to render the scene.
    Public Shared Function Main() As Integer
        System.Windows.Forms.Application.EnableVisualStyles()
        Using sampleFramework As New Framework()
            Dim FrmD3DWindowedInControl As New Form4(sampleFramework)
            ' Set the callback functions. These functions allow the sample framework to notify
            ' the application about device changes, user input, and windows messages.  The 
            ' callbacks are optional so you need only set callbacks for events you're interested 
            ' in. However, if you don't handle the device reset/lost callbacks then the sample 
            ' framework won't be able to reset your device since the application must first 
            ' release all device resources before resetting.  Likewise, if you don't handle the 
            ' device created/destroyed callbacks then the sample framework won't be able to 
            ' recreate your device resources.
            AddHandler sampleFramework.Disposing, AddressOf FrmD3DWindowedInControl.OnDestroyDevice
            AddHandler sampleFramework.DeviceLost, AddressOf FrmD3DWindowedInControl.OnLostDevice
            AddHandler sampleFramework.DeviceCreated, AddressOf FrmD3DWindowedInControl.OnCreateDevice
            AddHandler sampleFramework.DeviceReset, AddressOf FrmD3DWindowedInControl.OnResetDevice
            sampleFramework.SetWndProcCallback(New WndProcCallback(AddressOf FrmD3DWindowedInControl.OnMsgProc))
            sampleFramework.SetCallbackInterface(FrmD3DWindowedInControl)
            Try
                ' Show the cursor and clip it when in full screen
                sampleFramework.SetCursorSettings(True, True)
                ' Initialize
                FrmD3DWindowedInControl.InitializeApplication()
                ' Initialize the sample framework and create the desired window and Direct3D 
                ' device for the application. Calling each of these functions is optional, but they
                ' allow you to set several options which control the behavior of the sampleFramework.
                sampleFramework.Initialize(True, True, True)
                ' Parse the command line, handle the default hotkeys, and show msgboxes
                sampleFramework.CreateWindowInControl(FrmD3DWindowedInControl.GraphicsControlWindow1)
                ' Hook the keyboard event
                AddHandler sampleFramework.Window.KeyDown, AddressOf FrmD3DWindowedInControl.OnKeyEvent
                sampleFramework.CreateDevice(0, True, Framework.DefaultSizeWidth, Framework.DefaultSizeHeight, FrmD3DWindowedInControl)
                ' Pass control to the sample framework for handling the message pump and 
                ' dispatching render calls. The sample framework will call your FrameMove 
                ' and FrameRender callback when there is idle time between handling window messages.
                FrmD3DWindowedInControl.Show()
                sampleFramework.MainLoop()
            Catch e As Exception
                '#if(DEBUG)
                ' In debug mode show this error (maybe - depending on settings)
                '#else
                '            catch
                '            {
                '                // In release mode fail silently
                '/#endif
                '                    // Ignore any exceptions here, they would have been handled by other areas
                '                    return (sampleFramework.ExitCode == 0) ? 1 : sampleFramework.ExitCode; // Return an error code here
                sampleFramework.DisplayErrorMessage(e)
            End Try
            ' Perform any application-level cleanup here. Direct3D device resources are released within the
            ' appropriate callback functions and therefore don't require any cleanup code here.
            Return sampleFramework.ExitCode
        End Using
    End Function

End Class

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Engineer Universidad Tecnológica Nacional
Argentina Argentina
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions