示例#1
0
        /// <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);
        }