public void Render() { var rect = Camera.GetRenderRect(Zoom, game.RenderSize.Width, game.RenderSize.Height); var st = OpenTK.Input.Keyboard.GetState(); var needsredraw = (!_trackrect.Contains(rect.Left, rect.Top) || !_trackrect.Contains(rect.Left + rect.Width, rect.Top + rect.Height)); if (!needsredraw) { var viewport = rect.Inflate(rect.Width, rect.Height); if (viewport.Width < _trackrect.Width / 3 && viewport.Height < _trackrect.Height / 3) { needsredraw = true; } } var drawcolor = !Animating || Paused || game.SettingColorPlayback; if (game.SettingPreviewMode) { drawcolor = false; } var knob = 0; var adjustTool = game.SelectedTool as LineAdjustTool; if (adjustTool != null && (!Animating || Paused)) { knob = 1; if ((!adjustTool.Started && (st[OpenTK.Input.Key.AltLeft] || st[OpenTK.Input.Key.AltRight])) || adjustTool.LifeLock) { knob = 2; } } if (needsredraw || RequiresUpdate) { EnterTrackRead(); var viewport = rect.Inflate(rect.Width, rect.Height); var lines = _track.GetLinesInRect(viewport, false, true); _trackrect = viewport; _renderer.UpdateViewport(lines); ExitTrackRead(); } _renderer.Render(_track, drawcolor, knob, game.SettingRenderGravityWells); _sceneryrenderer.Render(drawcolor); List <RiderDrawCommand> commands = new List <RiderDrawCommand>(); EnterPlayback(); if (game.IterationsOffset != 6 && Frame != 0 && Animating && Paused) { var renderstate = _track.RiderStates[Frame - 1].Clone(); _track.TickWithIterations(renderstate); commands.Add(new RiderDrawCommand(game.IterationsOffset, renderstate, game.SettingDrawContactPoints ? 0.4f : 1, true, game.SettingDrawContactPoints, game.SettingMomentumVectors)); } else { commands.Add(new RiderDrawCommand(RiderState.Clone(), game.SettingDrawContactPoints ? 0.4f : 1, true, game.SettingDrawContactPoints, game.SettingMomentumVectors)); } if (game.SettingOnionSkinning && _track.RiderStates.Count != 0 && Animating) { const int onions = 10; Rider[] onionstates = new Rider[onions * 2]; for (int i = 0; i < onions; i++) { var frame = _track.Frame - (onions - i); if (frame > 0) { onionstates[i] = _track.RiderStates[frame].Clone(); } } Rider positivestate = _track.RiderStates[_track.Frame].Clone(); for (int i = onions + 1; i < onions * 2; i++) { _track.Tick(positivestate); onionstates[i] = positivestate.Clone(); } foreach (var state in onionstates) { if (state == null) { continue; } commands.Add(new RiderDrawCommand(state, 0.2f, false, game.SettingDrawContactPoints, game.SettingMomentumVectors)); } } if (_flag != null) { commands.Add(new RiderDrawCommand(_flag.State.Clone(), 0.6f, false, game.SettingDrawContactPoints, game.SettingMomentumVectors)); } ExitPlayback(); foreach (var v in commands) //todo rider vbo for every rider, massive improvements. { if (v.iteration != -1) { GameRenderer.DrawIteration(v.opacity, v.state, v.iteration, v.momentum, v.contactpoints); } else { GameRenderer.DrawRider(v.opacity, v.state, v.scarf, v.contactpoints, v.momentum); } } }