-
Notifications
You must be signed in to change notification settings - Fork 13
/
Program.fs
105 lines (89 loc) · 4.65 KB
/
Program.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
open System
open Aardvark.Base
open Aardvark.Rendering
open FSharp.Data.Adaptive
open Aardvark.SceneGraph
open Aardvark.Application
open Aardvark.Application.Slim
// This example illustrates how to create a simple render window.
// In contrast to the rest of the examples (beginning from 01-Triangle), we use
// the low level application API for creating a window and attaching
// mouse and keyboard inputs.
// In your application you most likely want to use this API instead of the more abstract
// show/window computation expression builders (which reduces code duplication
// in this case) to setup applications.
[<EntryPoint>]
let main argv =
// first we need to initialize Aardvark's core components
Aardvark.Init()
// create an OpenGL/Vulkan application. Use the use keyword (using in C#) in order to
// properly dipose resources on shutdown...
use app = new OpenGlApplication()
// SimpleRenderWindow is a System.Windows.Forms.Form which contains a render control
// of course you can a custum form and add a control to it.
// Note that there is also a WPF binding for OpenGL. For more complex GUIs however,
// we recommend using aardvark-media anyways..
let win = app.CreateGameWindow(samples = 8)
//win.Title <- "Hello Aardvark"
//win.Decorated <- false
//win.Floating <- true
//win.WindowState <- Glfw.WindowState.Maximized
//win.Keyboard.Down.Values.Add (fun k ->
// match k with
// | Keys.Enter ->
// match win.WindowState with
// | Glfw.WindowState.Maximized -> win.WindowState <- Glfw.WindowState.Normal
// | _ -> win.WindowState <- Glfw.WindowState.Maximized
// | Keys.Space ->
// win.Decorated <- not win.Decorated
// | _ ->
// ()
//)
// Given eye, target and sky vector we compute our initial camera pose
let initialView = CameraView.LookAt(V3d(2.0,2.0,2.0), V3d.Zero, V3d.OOI)
// the class Frustum describes camera frusta, which can be used to compute a projection matrix.
let frustum =
// the frustum needs to depend on the window size (in oder to get proper aspect ratio)
win.Sizes
// construct a standard perspective frustum (60 degrees horizontal field of view,
// near plane 0.1, far plane 50.0 and aspect ratio x/y.
|> AVal.map (fun s -> Frustum.perspective 60.0 0.1 50.0 (float s.X / float s.Y))
// create a controlled camera using the window mouse and keyboard input devices
// the window also provides a so called time mod, which serves as tick signal to create
// animations - seealso: https://github.com/aardvark-platform/aardvark.docs/wiki/animation
let cameraView = DefaultCameraController.control win.Mouse win.Keyboard win.Time initialView
// create a quad using low level primitives (IndexedGeometry is our base type for specifying
// geometries using vertices etc)
let quadSg =
let quad =
IndexedGeometry(
Mode = IndexedGeometryMode.TriangleList,
IndexArray = ([|0;1;2; 0;2;3|] :> System.Array),
IndexedAttributes =
SymDict.ofList [
DefaultSemantic.Positions, [| V3f(-1,-1,0); V3f(1,-1,0); V3f(1,1,0); V3f(-1,1,0) |] :> Array
DefaultSemantic.Normals, [| V3f.OOI; V3f.OOI; V3f.OOI; V3f.OOI |] :> Array
DefaultSemantic.DiffuseColorCoordinates, [| V2f.OO; V2f.IO; V2f.II; V2f.OI |] :> Array
]
)
// create a scenegraph, given a IndexedGeometry instance...
quad |> Sg.ofIndexedGeometry
let sg =
Sg.box' C4b.White Box3d.Unit
// here we use fshade to construct a shader: https://github.com/aardvark-platform/aardvark.docs/wiki/FShadeOverview
|> Sg.effect [
DefaultSurfaces.trafo |> toEffect
DefaultSurfaces.constantColor C4f.Red |> toEffect
DefaultSurfaces.simpleLighting |> toEffect
]
// extract our viewTrafo from the dynamic cameraView and attach it to the scene graphs viewTrafo
|> Sg.viewTrafo (cameraView |> AVal.map CameraView.viewTrafo )
// compute a projection trafo, given the frustum contained in frustum
|> Sg.projTrafo (frustum |> AVal.map Frustum.projTrafo )
let renderTask =
// compile the scene graph into a render task
app.Runtime.CompileRender(win.FramebufferSignature, sg)
// assign the render task to our window...
win.RenderTask <- renderTask
win.Run()
0