/// <summary> /// Renders a single frame of the game, and also ticks. /// </summary> /// <param name="sender">Irrelevant.</param> /// <param name="e">Holds the frame time (delta).</param> private void Window_RenderFrame(object sender, FrameEventArgs e) { try { StackNoteHelper.Push("GameClientWindow - Render and tick frame", this); // First step: check delta if (e.Time <= 0.0) { return; } // Mouse handling PreviousMouse = CurrentMouse; CurrentMouse = Mouse.GetState(); // Standard pre-tick PreTick(e.Time); ErrorCode ec = GL.GetError(); while (ec != ErrorCode.NoError) { SysConsole.Output(OutputType.WARNING, "Uncaught GL Error: " + ec); ec = GL.GetError(); } // Second step: clear the screen GL.ClearBuffer(ClearBuffer.Color, 0, ScreenClearColor); GL.ClearBuffer(ClearBuffer.Depth, 0, DepthClear); GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); GL.DrawBuffer(DrawBufferMode.Back); GraphicsUtil.CheckError("GameClient - Pre"); // Tick helpers Models.Update(GlobalTickTime); GraphicsUtil.CheckError("GameClient - PostModelUpdate"); // Third step: general game rendering CurrentEngine.RenderSingleFrame(); GraphicsUtil.CheckError("GameClient - PostMainEngine"); // Add the UI Layer too MainUI.Draw(); GraphicsUtil.CheckError("GameClient - PostUI"); // Fourth step: clean up! GL.BindTexture(TextureTarget.Texture2D, 0); GL.BindVertexArray(0); GL.UseProgram(0); // Semi-final step: Tick logic! GraphicsUtil.CheckError("GameClient - PreTick"); // Main instance tick. Tick(); // Primary UI tick MainUI.Tick(); Resized = false; GraphicsUtil.CheckError("GameClient - PostTick"); // Final step: Swap the render buffer onto the screen! Window.SwapBuffers(); GraphicsUtil.CheckError("GameClient - Post"); } finally { StackNoteHelper.Pop(); } }