protected virtual void Render(IRenderer renderer) { //Get the window's swap chain SwapChain swapChain = _window.SwapChain; //Primary drawing to the window, sets the backbuffer render targets and clears them swapChain.Clear(_clearColor); if (_wireFrame) { renderer.EnforcedRasterizerState = RasterizerState.CullNoneWireframe; } OnRenderPre(renderer); //Draw the scenegraph _rootNode.Draw(renderer); //Debbuging for bounding volumes if (_debugBounds) { GeometryDebugger.DrawBounds(_rootNode, renderer); } //Debugging for normals and tangents/binormals if they exist for the mesh if (_debugNormals) { GeometryDebugger.DrawTangentBasis(_rootNode, renderer); } if (_wireFrameSolid) { renderer.RenderQueue.SortAndRender(); //renderer.EnforcedRasterizerState = RasterizerState.CullNoneWireframe; RasterizerState rs = new RasterizerState(); rs.Cull = CullMode.None; rs.DepthBias = -100; rs.SlopeScaledDepthBias = 5f; rs.Fill = FillMode.WireFrame; renderer.EnforcedRasterizerState = rs; renderer.EnforcedMaterial = _wireFrameSolidMat; renderer.RenderQueue.RenderBuckets(); renderer.RenderQueue.ClearBuckets(); renderer.ClearEnforcedStates(); renderer.EnforcedMaterial = null; } else { //Finally sort the render queue and draw remaining elements renderer.RenderQueue.SortRenderClear(); } //Any extra rendering OnRenderPost(renderer); if (_wireFrame || _wireFrameSolid) { renderer.ClearEnforcedState(RenderStateType.RasterizerState); } //Lastly, draw GUI - we do this via a spritebatch and do it last //so it's rendered over everything (including anything from OnRender() DrawInstructions(renderer); //Present to the window swapChain.Present(); //Count the frame for FPS display CountFrame(); }