Beispiel #1
0
        /// <summary>Executes some code with a given scissor rectangle (drawing will be limited to the rectangle)</summary>
        /// <param name="batch">The <see cref="SpriteBatch"/> being used for drawing calls</param>
        /// <param name="scissorRect">The rectangle to limit drawing to</param>
        /// <param name="action">The function to execute with the given scissor rectangle</param>
        /// <param name="respectExistingScissor">Whether to limit the new scissor rectangle to a subrectangle of the current scissor rectangle</param>
        public static void WithScissorRect(this SpriteBatch batch, XnaRectangle scissorRect, Action <SpriteBatch> action, bool respectExistingScissor = true)
        {
            // Stop the old drawing code
            batch.End();

            // Keep track of the old scissor rectangle (this needs to come after End() so they're applied to the GraphicsDevice)
            XnaRectangle      oldScissor         = batch.GraphicsDevice.ScissorRectangle;
            BlendState        oldBlendState      = batch.GraphicsDevice.BlendState;
            DepthStencilState oldStencilState    = batch.GraphicsDevice.DepthStencilState;
            RasterizerState   oldRasterizerState = batch.GraphicsDevice.RasterizerState;

            // Trim current scissor to the existing one if necessary
            if (respectExistingScissor)
            {
                scissorRect = scissorRect.Intersection(oldScissor) ?? new XnaRectangle(0, 0, 0, 0);
            }

            // Draw with the new scissor rectangle
            using (RasterizerState rasterizerState = new RasterizerState {
                ScissorTestEnable = true
            }) {
                batch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.Default, rasterizerState);

                // Set scissor rectangle
                batch.GraphicsDevice.ScissorRectangle = scissorRect;

                // Perform the action
                action(batch);

                // Draw the batch
                batch.End();
            }

            // Reset scissor rectangle
            batch.GraphicsDevice.ScissorRectangle = oldScissor;

            // Return to last state
            batch.Begin(SpriteSortMode.BackToFront, oldBlendState, SamplerState.PointClamp, oldStencilState, oldRasterizerState);
        }
Beispiel #2
0
        /// <summary>
        /// Zeichenauruf für das Control (SpriteBatch ist bereits aktiviert)
        /// </summary>
        /// <param name="batch">Spritebatch</param>
        /// <param name="gameTime">Vergangene Spielzeit</param>
        public void Draw(SpriteBatch batch, Rectangle renderMask, GameTime gameTime)
        {
            if (!Visible) return;

            // Controlgröße ermitteln
            Rectangle controlArea = new Rectangle(AbsolutePosition, ActualSize);
            Rectangle localRenderMask = controlArea.Intersection(renderMask);

            // Scissor-Filter aktivieren
            batch.GraphicsDevice.ScissorRectangle = localRenderMask.Transform(AbsoluteTransformation);
            batch.Begin(rasterizerState: new RasterizerState() { ScissorTestEnable = true }, samplerState: SamplerState.LinearWrap, transformMatrix: AbsoluteTransformation);
            OnDraw(batch, controlArea, gameTime);
            batch.End();

            foreach (var child in Children.AgainstZOrdner())
            {
                Rectangle clientArea = ActualClientArea;
                clientArea.Location += AbsolutePosition;
                Rectangle clientRenderMask = clientArea.Intersection(renderMask);

                child.Draw(batch, clientRenderMask, gameTime);
            }

            invalidDrawing = false;
        }