Beispiel #1
0
        /// <summary>
        /// Begins drawing of the world.
        /// </summary>
        /// <param name="camera">The camera describing the the current view of the world.</param>
        /// <returns>
        /// The <see cref="ISpriteBatch"/> to use to draw the world objects, 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 BeginDrawWorld(ICamera2D camera)
        {
            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 BeginDrawWorld() call - the RenderWindow is not available.");
                    _state = DrawingManagerState.Idle;
                    return null;
                }

                _worldCamera = camera;

                // No matter what the last draw was, we clear the screen when drawing the world since the world drawing
                // always comes first or not at all (makes no sense to draw the GUI then the world)
                _rw.Clear(BackgroundColor);

                _lastDrawWasToWorld = true;

                // Ensure the buffer is set up
                _buffer = _rw.CreateBufferRenderImage(_buffer);
                _sb.RenderTarget = _buffer;

                if (_buffer == null)
                    return null;

                _buffer.Clear(BackgroundColor);

                // Start up the SpriteBatch
                _sb.Begin(BlendMode.Alpha, camera);

                // Change the state
                _state = DrawingManagerState.DrawingWorld;
            }
            catch (AccessViolationException ex)
            {
                // More frequent and less concerning exception
                const string errmsg = "Failed to start drawing world 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 world 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;
        }
        /// <summary>
        /// Makes sure the internal buffer is ready then returns a <see cref="RenderImage"/> to draw to it.
        /// </summary>
        /// <returns>The <see cref="RenderImage"/> to use, or null if the buffer could not be prepared.</returns>
        RenderImage GetRenderImage()
        {
            var oldRI = _ri;
            _ri = _window.CreateBufferRenderImage(_ri);

            if (_ri == null)
                return null;

            if (!BypassClear || _ri != oldRI)
                _ri.Clear(BufferClearColor);

            return _ri;
        }
Beispiel #3
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;
        }