public Viewer(Window wnd) { wnd.Paint += (sender, e) => Render(); wnd.KeyDown += delegate(object sender, KeyDownEventArgs e) { switch (e.KeySym.scancode) { case SDL.SDL_Scancode.SDL_SCANCODE_R: _rotate = Matrix.Identity(); _translate = Matrix.Identity(); _scale = Matrix.Identity(); break; case SDL.SDL_Scancode.SDL_SCANCODE_LEFTBRACKET: _scale = Matrix.Scale(1 / 1.2, 1 / 1.2, 1 / 1.2) * _scale; break; case SDL.SDL_Scancode.SDL_SCANCODE_RIGHTBRACKET: _scale = Matrix.Scale(1.2, 1.2, 1.2) * _scale; break; case SDL.SDL_Scancode.SDL_SCANCODE_KP_PLUS: _horizon *= 1.2; RefreshProjection(); break; case SDL.SDL_Scancode.SDL_SCANCODE_KP_MINUS: _horizon /= 1.2; RefreshProjection(); break; case SDL.SDL_Scancode.SDL_SCANCODE_F: _fill = !_fill; break; case SDL.SDL_Scancode.SDL_SCANCODE_W: _wireframe = !_wireframe; break; case SDL.SDL_Scancode.SDL_SCANCODE_P: switch (_currentProjection) { case Projections.Perspective: _isPerspectiveProjection = false; _pp_alpah = 45; _pp_beta = 45; _currentProjection = Projections.Isometric; break; case Projections.Isometric: _isPerspectiveProjection = false; _pp_alpah = 0.5; _pp_beta = 66.4; _currentProjection = Projections.Cabinet; break; case Projections.Cabinet: _isPerspectiveProjection = false; _pp_alpah = 1; _pp_beta = 45; _currentProjection = Projections.Cavalier; break; case Projections.Cavalier: _isPerspectiveProjection = false; _pp_alpah = 0; _pp_beta = 90; _currentProjection = Projections.Orthogonal; break; case Projections.Orthogonal: _isPerspectiveProjection = true; _currentProjection = Projections.Perspective; break; } RefreshProjection(); break; case SDL.SDL_Scancode.SDL_SCANCODE_M: _models.RemoveAt(0); _models.Add(_model); _model = _models[0]; wnd.Title = string.Format("3D Viewer ({0})", _model.Name); break; } _update = true; }; _wnd = wnd; foreach (var path in Directory.GetFiles("Models")) { _models.Add(Model.FromFile(path)); } _model = _models[0]; _renderer = wnd.CreateRenderer(); wnd.WindowResized += delegate(object sender, WindowResizedEventArgs e) { RefreshProjection(); _update = true; }; RefreshProjection(); wnd.MouseMotion += delegate(object sender, MouseMotionEventArgs e) { if (e.Button == MouseButton.Left) { var dist = _translate[2, 3]; var scale = 1 - (-dist / _horizon); _translate *= Matrix.Translation( e.RelativeX * scale, e.RelativeY * scale, 0 ); _update = true; } else if (e.Button == MouseButton.Right) { var rotx = Matrix.RotationX(-e.RelativeX * (Math.PI / 180d)); var roty = Matrix.RotationY(e.RelativeY * (Math.PI / 180d)); var rot = rotx * roty; _rotate = rot * _rotate; _update = true; } else { Lights[0, 0].X = e.X - _wnd.Width / 2; Lights[0, 0].Y = e.Y - _wnd.Height / 2; _update = true; } }; wnd.MouseWheel += delegate(object sender, MouseWheelEventArgs e) { _translate = Matrix.Translation(0, 0, 100 * e.Y) * _translate; _update = true; return; }; Render(); }