Moving on with F# Development

Sunday, January 17, 2010 by gradbot

After a break from game development and finishing a work project in F#, I'm back and it's time for me to leave XNA behind and move on to a collection of specifically designed libraries. For my graphics engine I'm choosing ORGE by way of MORGE a .NET wrapper for it.

After digging into the C# SDK I figured a good start would be porting MorgeForm. To get this code to run install the SDK, create a project, set it to .NET 2.0, add a reference to Mogre_d (C:\MogreSDK\bin\Debug) and set the working directory to C:\MogreSDK\bin\Debug. The sample pulls resources through relative paths so you need to run in the SDK Debug directory.

On a side note I need to make my own custom theme for better syntax highlighting.

open System
open System.Windows.Forms
open System.Drawing

open Mogre

type OgreWindow(origin, hWnd) =
// 1 enter ogre
let root = new Root()

do //-----------------------------------------------------
// 2 configure resource paths
let cf = new ConfigFile()
cf.Load("resources.cfg", "\t:=", true)

// Go through all sections & settings in the file
let seci = cf.GetSectionIterator()

// Normally we would use the foreach syntax, which enumerates the values, but in this case we need CurrentKey too;
while seci.MoveNext() do
for pair in seci.Current do
ResourceGroupManager.Singleton.AddResourceLocation(pair.Value, pair.Key, seci.CurrentKey)

// 3 Configures the application and creates the window
root.RenderSystem <- root.GetAvailableRenderers() |> Seq.find (fun rs -> rs.Name = "Direct3D9 Rendering Subsystem")
root.RenderSystem.SetConfigOption("Full Screen", "No")
root.RenderSystem.SetConfigOption("Video Mode", "640 x 480 @ 32-bit colour")

root.Initialise(false) |> ignore
let misc = new NameValuePairList()
misc.["externalWindowHandle"] <- hWnd.ToString()
let window = root.CreateRenderWindow("Simple Mogre Form Window", 0u, 0u, false, misc.ReadOnlyInstance)

// 4 Create the SceneManager
// ST_GENERIC = octree
// ST_EXTERIOR_CLOSE = simple terrain
// ST_EXTERIOR_FAR = nature terrain (depreciated)
// ST_EXTERIOR_REAL_FAR = paging landscape
let sceneMgr = root.CreateSceneManager(SceneType.ST_GENERIC, "SceneMgr")
sceneMgr.AmbientLight <- new ColourValue(0.5f, 0.5f, 0.5f)

// 5 Create the camera
let camera = sceneMgr.CreateCamera("SimpleCamera")
camera.Position <- new Vector3(0.0f, 0.0f, 100.0f)
// Look back along -Z
camera.LookAt(new Vector3(0.0f, 0.0f, -300.0f))
camera.NearClipDistance <- 5.0f

let viewport = window.AddViewport(camera)
viewport.BackgroundColour <- new ColourValue(0.0f, 0.0f, 0.0f, 1.0f)

let ent = sceneMgr.CreateEntity("ogre", "ogrehead.mesh")
let node = sceneMgr.RootSceneNode.CreateChildSceneNode("ogreNode")

member this.Paint() =
root.RenderOneFrame() |> ignore

member this.Dispose() =
if root <> null then

type MogreForm() as this =
inherit Form()

let mogrePanel = new System.Windows.Forms.Panel()

// Between Suspend and Resume Layout is normal form Designer Code
do base.SuspendLayout()

mogrePanel.Location <- new System.Drawing.Point(0, 0)
mogrePanel.Name <- "mogrePanel"
mogrePanel.Size <- new System.Drawing.Size(483, 375)
mogrePanel.TabIndex <- 0

base.AutoScaleDimensions <- new System.Drawing.SizeF(6.0f, 13.0f)
base.AutoScaleMode <- System.Windows.Forms.AutoScaleMode.Font
base.ClientSize <- new System.Drawing.Size(483, 375)
base.Name <- "MogreForm"
base.Text <- "Simple F# Mogre Form";


let mogreWin = new OgreWindow(Point(100, 30), mogrePanel.Handle)
this.Disposed.Add(fun _ -> mogreWin.Dispose())
this.Paint.Add(fun _ -> mogreWin.Paint())

let main() =
Application.Run(new MogreForm())

do main()

Filed under , having