Created
December 6, 2013 22:55
-
-
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..
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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