-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathTutorial.cs
More file actions
154 lines (134 loc) · 5.33 KB
/
Tutorial.cs
File metadata and controls
154 lines (134 loc) · 5.33 KB
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
using System.Collections.Generic;
using System.Linq;
using Fusee.Base.Core;
using Fusee.Engine.Common;
using Fusee.Engine.Core;
using Fusee.Math.Core;
using Fusee.Serialization;
using Fusee.Xene;
using static Fusee.Engine.Core.Input;
namespace Fusee.Tutorial.Core
{
class Renderer : SceneVisitor
{
public RenderContext RC;
public IShaderParam AlbedoParam;
public IShaderParam ShininessParam;
public float4x4 View;
private Dictionary<MeshComponent, Mesh> _meshes = new Dictionary<MeshComponent, Mesh>();
private CollapsingStateStack<float4x4> _model = new CollapsingStateStack<float4x4>();
private Mesh LookupMesh(MeshComponent mc)
{
Mesh mesh;
if (!_meshes.TryGetValue(mc, out mesh))
{
mesh = new Mesh
{
Vertices = mc.Vertices,
Normals = mc.Normals,
Triangles = mc.Triangles
};
_meshes[mc] = mesh;
}
return mesh;
}
public Renderer(RenderContext rc)
{
RC = rc;
// Initialize the shader(s)
var vertsh = AssetStorage.Get<string>("VertexShader.vert");
var pixsh = AssetStorage.Get<string>("PixelShader.frag");
var shader = RC.CreateShader(vertsh, pixsh);
RC.SetShader(shader);
AlbedoParam = RC.GetShaderParam(shader, "albedo");
ShininessParam = RC.GetShaderParam(shader, "shininess");
}
protected override void InitState()
{
_model.Clear();
_model.Tos = float4x4.Identity;
}
protected override void PushState()
{
_model.Push();
}
protected override void PopState()
{
_model.Pop();
RC.ModelView = View*_model.Tos;
}
[VisitMethod]
void OnMesh(MeshComponent mesh)
{
RC.Render(LookupMesh(mesh));
}
[VisitMethod]
void OnMaterial(MaterialComponent material)
{
RC.SetShaderParam(AlbedoParam, material.Diffuse.Color);
RC.SetShaderParam(ShininessParam, material.Specular.Shininess);
}
[VisitMethod]
void OnTransform(TransformComponent xform)
{
_model.Tos *= xform.Matrix();
RC.ModelView = View * _model.Tos;
}
}
[FuseeApplication(Name = "Tutorial Example", Description = "The official FUSEE Tutorial.")]
public class Tutorial : RenderCanvas
{
private Mesh _mesh;
private TransformComponent _wheelBigL;
private IShaderParam _albedoParam;
private float _alpha = 0.001f;
private float _beta;
private SceneOb _root;
private SceneContainer _wuggy;
private Renderer _renderer;
// Init is called on startup.
public override void Init()
{
// Load some meshes
_wuggy = AssetStorage.Get<SceneContainer>("wuggy.fus");
_wheelBigL = _wuggy.Children.FindNodes(n => n.Name == "WheelBigL").First().GetTransform();
_renderer = new Renderer(RC);
// Set the clear color for the backbuffer
RC.ClearColor = new float4(1, 1, 1, 1);
}
// RenderAFrame is called once a frame
public override void RenderAFrame()
{
// Clear the backbuffer
RC.Clear(ClearFlags.Color | ClearFlags.Depth);
float2 speed = Mouse.Velocity + Touch.GetVelocity(TouchPoints.Touchpoint_0);
if (Mouse.LeftButton || Touch.GetTouchActive(TouchPoints.Touchpoint_0))
{
_alpha -= speed.x*0.0001f;
_beta -= speed.y*0.0001f;
}
_wheelBigL.Rotation += new float3(-0.05f * Keyboard.WSAxis, 0, 0);
// Setup matrices
var aspectRatio = Width / (float)Height;
RC.Projection = float4x4.CreatePerspectiveFieldOfView(3.141592f * 0.25f, aspectRatio, 0.01f, 20);
float4x4 view = float4x4.CreateTranslation(0, 0, 5)*float4x4.CreateRotationY(_alpha)*float4x4.CreateRotationX(_beta)*float4x4.CreateTranslation(0, -0.5f, 0);
_renderer.View = view;
_renderer.Traverse(_wuggy.Children);
// Swap buffers: Show the contents of the backbuffer (containing the currently rendered frame) on the front buffer.
Present();
}
// Is called when the window was resized
public override void Resize()
{
// Set the new rendering area to the entire new windows size
RC.Viewport(0, 0, Width, Height);
// Create a new projection matrix generating undistorted images on the new aspect ratio.
var aspectRatio = Width/(float) Height;
// 0.25*PI Rad -> 45° Opening angle along the vertical direction. Horizontal opening angle is calculated based on the aspect ratio
// Front clipping happens at 1 (Objects nearer than 1 world unit get clipped)
// Back clipping happens at 2000 (Anything further away from the camera than 2000 world units gets clipped, polygons will be cut)
var projection = float4x4.CreatePerspectiveFieldOfView(3.141592f * 0.25f, aspectRatio, 1, 20000);
RC.Projection = projection;
}
}
}