Skip to content

Instantly share code, notes, and snippets.

Created December 6, 2013 22:55
Show Gist options
  • Save anonymous/7833562 to your computer and use it in GitHub Desktop.
Save anonymous/7833562 to your computer and use it in GitHub Desktop.
This is a DirectX rendering loop that can be updated live with new code without closing the window. Send actions with new loop to the agent..
#r @"..\packages\SharpDX.2.5.0\lib\net40\SharpDX.dll"
#r @"..\packages\SharpDX.Direct3D11.2.5.0\lib\net40\SharpDX.Direct3D11.dll"
#r @"..\packages\SharpDX.DXGI.2.5.0\lib\net40\SharpDX.DXGI.dll"
#r @"..\packages\SharpDX.Toolkit.2.5.0\lib\net40\SharpDX.Toolkit.dll"
#r @"..\packages\SharpDX.Toolkit.Game.2.5.0\lib\net40\SharpDX.Toolkit.Game.dll"
#r @"..\packages\SharpDX.Toolkit.Graphics.2.5.0\lib\net40\SharpDX.Toolkit.Graphics.dll"
open System
open SharpDX
open SharpDX.Toolkit
open SharpDX.Toolkit.Graphics
module Time =
let sec (t: GameTime) = float32 t.TotalGameTime.TotalSeconds
let pi2 = float32 (2.0 * Math.PI)
let wave speed offset t =
let x = Time.sec t * speed + float32 (pi2 * offset)
(sin x + 1.0f) / 2.0f
type FSys(game: Game, drawF) =
inherit GameSystem(game)
let mutable draw = fun _ -> ()
override this.Initialize() =
let d = drawF this.Game.GraphicsDevice
draw <- d
this.Enabled <- true
override this.Draw t = draw t
type Action =
| Add of int * bool * (GraphicsDevice -> GameTime -> unit)
| Remove of IGameSystem
| GetChanges of ((int * bool * (GraphicsDevice -> GameTime -> unit)) list * IGameSystem list ) AsyncReplyChannel
let agent =
MailboxProcessor.Start
<| fun mailbox ->
let rec run added removed =
async {
let! message = mailbox.Receive()
match message with
| Add (order, enabled,f) ->
printfn "added"
return! run ((order, enabled, f) :: added) (removed)
| Remove g ->
printfn "removed"
return! run added (g :: removed)
| GetChanges channel -> channel.Reply (added, removed)
return! run [] []
}
run [] []
type FGame() =
inherit Game()
override this.Draw t =
let added, removed = agent.PostAndReply(fun c -> GetChanges c)
let toRemove (order,_,_) =
this.GameSystems
|> Seq.filter (fun s -> (s :?> IDrawable).DrawOrder = order)
|> Seq.toList
|> List.iter (fun s -> this.GameSystems.Remove s |> ignore)
let toGameSystem (order,visible,f) =
new FSys(this, f, Visible = visible, DrawOrder = order)
added |> List.iter toRemove
added |> Seq.map toGameSystem |> Seq.iter this.GameSystems.Add
removed |> List.iter (this.GameSystems.Remove >> ignore)
base.Draw t
let game = new FGame()
async {
let m = new GraphicsDeviceManager(game)
m.DeviceCreationFlags <- Direct3D11.DeviceCreationFlags.Debug
let form = new SharpDX.Windows.RenderForm("LiveVJ")
form.Show()
game.Run(GameContext(form))
} |> Async.Start
let fsys order visible f =
agent.Post(Add(order, visible, f))
let rand = new Random()
let back = fsys 0 true
<| fun d ->
fun t ->
d.Clear(Color4(wave 0.2f 0.0f t, wave 0.25f 0.3f t, wave 0.8f 0.6f t, 0.1f))
//let flash =
// fsys 1 true
// <| fun d ->
// 0, fun s t ->
// if s > 0 then
// //if s % 3 = 0 then
// d.Clear(Color4(0xffffffff))
// s - 1
// else
// if rand.Next(0,80) = 0 then
// d.Clear(Color4(0xffffffff))
// 10
// else
// 0
let cubeVertices =
[|
Vector3(-1.0f, -1.0f, -1.0f)
Vector3(-1.0f, -1.0f, 1.0f)
Vector3(-1.0f, 1.0f, -1.0f)
Vector3(-1.0f, 1.0f, 1.0f)
Vector3( 1.0f, -1.0f, -1.0f)
Vector3( 1.0f, -1.0f, 1.0f)
Vector3( 1.0f, 1.0f, -1.0f)
Vector3( 1.0f, 1.0f, 1.0f)
|]
let cubeVerticeIndex =
[|
0;1;2;3;2;1
4;6;5;7;5;6
0;4;1;5;1;4
2;3;6;7;6;3
1;5;3;7;3;5
0;2;4;6;4;2
|]
let vertexNormal =
seq {
for i in 0 .. 5 do
let v n = cubeVertices.[cubeVerticeIndex.[i*6+n]]
let v1 = (v 1 - v 0)
let v2 = (v 2 - v 0)
let normal = Vector3.Cross(v1 ,v2)
for n in 0 .. 5 do
yield VertexPositionNormalTexture(v n,normal, Vector2.Zero)
}
|> Seq.toArray
let cube (indexArray: int[]) =
fsys 2 true
<| fun device ->
let cubePoints =
Buffer.Vertex.New(device, cubeVertices)
let index =
Buffer.Index.New(device, indexArray)
//let p = new PrimitiveBatch<Vector4>(device)
let effect = new BasicEffect(device,
//VertexColorEnabled = true,
PreferPerPixelLighting = true,
//Alpha = 0.5f,
View = Matrix.LookAtLH(new Vector3(0.0f, 0.0f, -5.0f), new Vector3(0.0f, 0.0f, 0.0f), Vector3.UnitY),
Projection = Matrix.PerspectiveFovLH(float32 Math.PI / 4.0f, float32 device.BackBuffer.Width / float32 device.BackBuffer.Height, 0.1f, 100.0f),
World = Matrix.Translation(0.0f,0.0f,3.0f)//,
//AmbientLightColor = Color.Aqua.ToVector3()//,
//LightingEnabled = true
//DirectionalLight0 = DirectionalLight(EffectParameter)
)
effect.EnableDefaultLighting()
// let light = effect.DirectionalLight0
// light.Enabled <- true
// light.Direction <- Vector3(-3.0f, -3.0f, -3.0f )
// light.DiffuseColor <- Color.Azure.ToVector3()
let layout = VertexInputLayout.New(0,VertexElement.PositionTransformed(DXGI.Format.R32G32B32_Float))
fun t ->
effect.World <- Matrix.RotationX(Time.sec t) * Matrix.RotationY(Time.sec t * 0.3f) * Matrix.RotationZ(Time.sec t * 0.5f) * Matrix.Translation(0.0f,0.0f,3.0f)
device.SetVertexBuffer(cubePoints)
device.SetVertexInputLayout(layout)
device.SetIndexBuffer(index, true)
effect.CurrentTechnique.Passes.[0].Apply()
device.DrawIndexed(PrimitiveType.TriangleList, Array.length indexArray)
//cube cubeVerticeIndex
let cubeN scale =
fsys 2 true
<| fun device ->
let cubePoints =
Buffer.Vertex.New(device, vertexNormal)
//let p = new PrimitiveBatch<Vector4>(device)
let effect = new BasicEffect(device,
//VertexColorEnabled = true,
PreferPerPixelLighting=true,
Alpha = 1.0f,
View = Matrix.LookAtLH(new Vector3(0.0f, 0.0f, -5.0f), new Vector3(0.0f, 0.0f, 0.0f), Vector3.UnitY),
Projection = Matrix.PerspectiveFovLH(float32 Math.PI / 4.0f, float32 device.BackBuffer.Width / float32 device.BackBuffer.Height, 0.1f, 100.0f),
World = Matrix.Translation(0.0f,0.0f,3.0f),
AmbientLightColor = Color.Wheat.ToVector3(),
LightingEnabled = true
)
effect.DiffuseColor <- Color.Orange.ToVector4()
effect.SpecularColor <- Color.Red.ToVector3()
effect.SpecularPower <- 2.0f
//effect.EnableDefaultLighting()
let light = effect.DirectionalLight0
light.Enabled <- true
light.Direction <- Vector3(-3.0f, -3.0f, 3.0f )
light.DiffuseColor <- Color.Azure.ToVector3()
light.SpecularColor <- Color.Wheat.ToVector3()
let layout = VertexInputLayout.FromBuffer(0,cubePoints)
fun t ->
effect.World <- Matrix.RotationX(Time.sec t) * Matrix.RotationY(Time.sec t * 0.3f) * Matrix.RotationZ(Time.sec t * 0.5f) * (scale t) * Matrix.Translation(0.0f,0.0f,3.0f)
device.SetVertexBuffer(cubePoints)
device.SetVertexInputLayout(layout)
effect.CurrentTechnique.Passes.[0].Apply()
device.Draw(PrimitiveType.TriangleList, Array.length vertexNormal , 0)
cubeN <| fun t -> Matrix.Scaling(sin (Time.sec t * 3.0f) * 0.4f + 1.0f, sin (Time.sec t * 3.0f + 0.5f) * 0.4f + 1.0f, sin (Time.sec t * 3.0f + 0.8f) * 0.4f + 1.0f)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment