/// <summary> /// Performs Draw events for all objects. /// </summary> public static void Update(GameTime gameTime) { #region Canvas matrix. var windowManager = GameMgr.WindowManager; if (!windowManager.IsFullScreen || windowManager.CanvasMode == CanvasMode.None) { CanvasMatrix = Matrix.CreateTranslation(Vector3.Zero); } if (windowManager.IsFullScreen) { // Fills the display with canvas. if (windowManager.CanvasMode == CanvasMode.Fill) { CanvasMatrix = Matrix.CreateScale( new Vector3( windowManager.PreferredBackBufferWidth / (float)windowManager.CanvasWidth, windowManager.PreferredBackBufferHeight / (float)windowManager.CanvasHeight, 1 ) ); } // Fills the display with canvas. // Scales display to match canvas, but keeps aspect ratio. if (windowManager.CanvasMode == CanvasMode.KeepAspectRatio) { var backbufferSize = new Vector2( windowManager.PreferredBackBufferWidth, windowManager.PreferredBackBufferHeight ); float ratio, offsetX = 0, offsetY = 0; float backbufferRatio = windowManager.PreferredBackBufferWidth / (float)windowManager.PreferredBackBufferHeight; float canvasRatio = windowManager.CanvasWidth / (float)windowManager.CanvasHeight; if (canvasRatio > backbufferRatio) { ratio = windowManager.PreferredBackBufferWidth / (float)windowManager.CanvasWidth; offsetY = (windowManager.PreferredBackBufferHeight - (windowManager.CanvasHeight * ratio)) / 2f; } else { ratio = windowManager.PreferredBackBufferHeight / (float)windowManager.CanvasHeight; offsetX = (windowManager.PreferredBackBufferWidth - (windowManager.CanvasWidth * ratio)) / 2f; } CanvasMatrix = Matrix.CreateScale(new Vector3(ratio, ratio, 1)) * Matrix.CreateTranslation(new Vector3(offsetX, offsetY, 0)); } // Scales display to match canvas, but keeps aspect ratio. } #endregion Canvas matrix. #region Main draw events. foreach (var camera in CameraMgr.Cameras) { if (camera.Enabled) { CurrentCamera = camera; Surface.SetTarget( camera.Surface, camera.ConstructViewMatrix(), camera.ConstructProjectionMatrix() ); if (camera.ClearBackground) { Device.Clear(camera.BackgroundColor); } SceneMgr.CallDrawEvents(); VertexBatch.FlushBatch(); Surface.ResetTarget(); } } #endregion Main draw events. // Resetting camera, transform matrix and mouse position. CurrentCamera = null; VertexBatch.PushProjectionMatrix( Matrix.CreateOrthographicOffCenter( 0, GameMgr.WindowManager.PreferredBackBufferWidth, GameMgr.WindowManager.PreferredBackBufferHeight, 0, 0, 1 ) ); VertexBatch.PushViewMatrix(CanvasMatrix); // Resetting camera, transform matrix and mouse position // Drawing camera surfaces. var oldEffect = VertexBatch.Effect; VertexBatch.Effect = null; Device.Clear(Color.Transparent); // We don't need in-game rasterizer to apply to camera surfaces. var oldRasterizerState = VertexBatch.RasterizerState; var oldBlendState = VertexBatch.BlendState; VertexBatch.RasterizerState = _cameraRasterizerState; VertexBatch.BlendState = BlendState.AlphaBlend; foreach (var camera in CameraMgr.Cameras) { if (camera.Visible && camera.Enabled) { camera.Render(); } } VertexBatch.FlushBatch(); VertexBatch.RasterizerState = oldRasterizerState; VertexBatch.BlendState = oldBlendState; VertexBatch.Effect = oldEffect; // Drawing camera surfaces. // Drawing GUI stuff. SceneMgr.CallDrawGUIEvents(); VertexBatch.FlushBatch(); // Drawing GUI stuff. VertexBatch.PopViewMatrix(); VertexBatch.PopProjectionMatrix(); // Safety checks. if (!Surface.SurfaceStackEmpty) { throw new InvalidOperationException("Unbalanced surface stack! Did you forgot to reset a surface somewhere?"); } if (!VertexBatch.WorldStackEmpty) { throw new InvalidOperationException("Unbalanced World matrix stack! Did you forgot to pop a matrix somewhere?"); } if (!VertexBatch.ViewStackEmpty) { throw new InvalidOperationException("Unbalanced View matrix stack! Did you forgot to pop a matrix somewhere?"); } if (!VertexBatch.ProjectionStackEmpty) { throw new InvalidOperationException("Unbalanced Projection matrix stack! Did you forgot to pop a matrix somewhere?"); } // Safety checks. }