/// <summary> /// Begins drawing the graphical user interface, which is not affected by the camera. /// </summary> /// <param name="clearBuffer">When true, the buffer will be cleared before drawing. When false, the contents of the previous /// frame will remain in the buffer, only if the last draw was also to the GUI. When the last draw call was to the /// world, then this will have no affect. Useful for when you want to draw multiple GUI screens on top of one another.</param> /// <returns> /// The <see cref="ISpriteBatch"/> to use to draw the GUI, or null if an unexpected /// error was encountered when preparing the <see cref="ISpriteBatch"/>. When null, all drawing /// should be aborted completely instead of trying to draw with a different <see cref="ISpriteBatch"/> /// or manually recovering the error. /// </returns> /// <exception cref="InvalidOperationException"><see cref="IDrawingManager.State"/> is not equal to /// <see cref="DrawingManagerState.Idle"/>.</exception> public ISpriteBatch BeginDrawGUI(bool clearBuffer = true) { if (State != DrawingManagerState.Idle) { throw new InvalidOperationException("This method cannot be called while already busy drawing."); } try { // Ensure the RenderWindow is available if (!IsRenderWindowAvailable()) { if (log.IsInfoEnabled) { log.Info("Skipping BeginDrawGUI() call - the RenderWindow is not available."); } _state = DrawingManagerState.Idle; return(null); } if (clearBuffer) { // If the last draw was also to the GUI, clear the screen if (!_lastDrawWasToWorld) { _rw.Clear(BackgroundColor); } } _lastDrawWasToWorld = false; // Ensure the buffer is set up _buffer = _rw.CreateBufferRenderImage(_buffer); _sb.RenderTarget = _buffer; if (_buffer == null) { return(null); } // Always clear the GUI with alpha = 0 since we will be copying it over the screen _buffer.Clear(_clearGUIBufferColor); // Start up the SpriteBatch _sb.Begin(BlendMode.Alpha); // Change the state _state = DrawingManagerState.DrawingGUI; } catch (AccessViolationException ex) { // More frequent and less concerning exception const string errmsg = "Failed to start drawing GUI on `{0}`. Device was probably lost. Exception: {1}"; if (log.IsInfoEnabled) { log.InfoFormat(errmsg, this, ex); } _state = DrawingManagerState.Idle; SafeEndSpriteBatch(_sb); return(null); } catch (Exception ex) { // Unexpected exception const string errmsg = "Failed to start drawing GUI on `{0}` due to unexpected exception. Exception: {1}"; if (log.IsErrorEnabled) { log.ErrorFormat(errmsg, this, ex); } Debug.Fail(string.Format(errmsg, this, ex)); _state = DrawingManagerState.Idle; SafeEndSpriteBatch(_sb); return(null); } return(_sb); }