Example #1
0
        /// <inheritdoc/>
        internal override void Draw <VertexType, SpriteData>(SpriteBatchBase <VertexType, SpriteData> spriteBatch, Vector2 position, Single width, Single height, Color color, Single rotation, Vector2 origin, SpriteEffects effects, Single layerDepth, SpriteData data)
        {
            effects |= SpriteEffects.OriginRelativeToDestination;

            position -= origin;

            var realOrigin = new Vector2(
                (int)((origin.X / width) * TextureRegion.Width),
                (int)((origin.Y / height) * TextureRegion.Height));

            position += realOrigin;

            var srcRect = TextureRegion;
            var dstRect = new RectangleF(position.X, position.Y, width, height);

            spriteBatch.Draw(Texture, dstRect, srcRect, color, rotation, realOrigin, effects, layerDepth, data);
        }
        /// <summary>
        /// Draws a tiled image segment.
        /// </summary>
        /// <typeparam name="VertexType">The type of vertex used to render the batch's sprites.</typeparam>
        /// <typeparam name="SpriteData">The type of data object associated with each of the batch's sprite instances.</typeparam>
        /// <param name="spriteBatch">The sprite batch with which to draw the segment.</param>
        /// <param name="tilingMode">A <see cref="TilingMode"/> value which specifies how to tile the image.</param>
        /// <param name="tilingData">A <see cref="TilingData"/> structure which contains the tiling parameters.</param>
        /// <param name="spriteData">The segment's custom sprite data.</param>
        protected static void TileImageSegment <VertexType, SpriteData>(
            SpriteBatchBase <VertexType, SpriteData> spriteBatch, TilingMode tilingMode, ref TilingData tilingData, SpriteData spriteData)
            where VertexType : struct, IVertexType
            where SpriteData : struct
        {
            var position             = tilingData.Position;
            var origin               = tilingData.Origin;
            var destinationRectangle = tilingData.DestinationRectangle;
            var sourceRectangle      = tilingData.SourceRectangle;

            var tileHorizontally = (tilingMode & TilingMode.Horizontal) == TilingMode.Horizontal;
            var tileVertically   = (tilingMode & TilingMode.Vertical) == TilingMode.Vertical;

            var tileCountX = tileHorizontally ?
                             (Int32)Math.Ceiling(destinationRectangle.Width / sourceRectangle.Width) : 1;

            var tileCountY = tileVertically ?
                             (Int32)Math.Ceiling(destinationRectangle.Height / sourceRectangle.Height) : 1;

            var cx = 0f;
            var cy = 0f;

            for (int y = 0; y < tileCountY; y++)
            {
                for (int x = 0; x < tileCountX; x++)
                {
                    var srcTileWidth  = Math.Min(sourceRectangle.Width, destinationRectangle.Width - cx);
                    var srcTileHeight = Math.Min(sourceRectangle.Height, destinationRectangle.Height - cy);

                    var dstTileWidth  = tileHorizontally ? srcTileWidth : destinationRectangle.Width;
                    var dstTileHeight = tileVertically ? srcTileHeight : destinationRectangle.Height;

                    var tileRegion   = new RectangleF(destinationRectangle.X, destinationRectangle.Y, dstTileWidth, dstTileHeight);
                    var tileSource   = new Rectangle(sourceRectangle.X, sourceRectangle.Y, (Int32)srcTileWidth, (Int32)srcTileHeight);
                    var tilePosition = new Vector2(position.X + cx, position.Y + cy);
                    var tileOrigin   = origin - tilePosition;
                    spriteBatch.Draw(tilingData.Texture,
                                     tileRegion, tileSource, tilingData.Color, tilingData.Rotation, tileOrigin, tilingData.Effects, tilingData.LayerDepth, spriteData);

                    cx = cx + sourceRectangle.Width;
                }
                cx = 0;
                cy = cy + sourceRectangle.Height;
            }
        }
Example #3
0
        /// <summary>
        /// Draws a tiled image segment.
        /// </summary>
        /// <typeparam name="VertexType">The type of vertex used to render the batch's sprites.</typeparam>
        /// <typeparam name="SpriteData">The type of data object associated with each of the batch's sprite instances.</typeparam>
        /// <param name="mode">A <see cref="TilingMode"/> value which specifies how to tile the image.</param>
        /// <param name="spriteBatch">The sprite batch with which to draw the segment.</param>
        /// <param name="texture">The segment's texture.</param>
        /// <param name="position">The segment's position in screen coordinates.</param>
        /// <param name="destinationRectangle">A rectangle which indicates where on the screen the segment will be drawn.</param>
        /// <param name="sourceRectangle">The segment's position on its texture, or <see langword="null"/> to draw the entire texture.</param>
        /// <param name="color">The segment's tint color.</param>
        /// <param name="rotation">The segment's rotation in radians.</param>
        /// <param name="origin">The segment's origin point.</param>
        /// <param name="effects">The segment's rendering effects.</param>
        /// <param name="layerDepth">The segment's layer depth.</param>
        /// <param name="data">The segment's custom data.</param>
        protected static void TileImageSegment <VertexType, SpriteData>(TilingMode mode, SpriteBatchBase <VertexType, SpriteData> spriteBatch,
                                                                        Texture2D texture, Vector2 position, RectangleF destinationRectangle, Rectangle sourceRectangle, Color color, Single rotation, Vector2 origin, SpriteEffects effects, Single layerDepth, SpriteData data)
            where VertexType : struct, IVertexType
            where SpriteData : struct
        {
            var tileHorizontally = (mode & TilingMode.Horizontal) == TilingMode.Horizontal;
            var tileVertically   = (mode & TilingMode.Vertical) == TilingMode.Vertical;

            var tileCountX = tileHorizontally ?
                             (Int32)Math.Ceiling(destinationRectangle.Width / sourceRectangle.Width) : 1;

            var tileCountY = tileVertically ?
                             (Int32)Math.Ceiling(destinationRectangle.Height / sourceRectangle.Height) : 1;

            var cx = 0f;
            var cy = 0f;

            for (int y = 0; y < tileCountY; y++)
            {
                for (int x = 0; x < tileCountX; x++)
                {
                    var srcTileWidth  = Math.Min(sourceRectangle.Width, destinationRectangle.Width - cx);
                    var srcTileHeight = Math.Min(sourceRectangle.Height, destinationRectangle.Height - cy);

                    var dstTileWidth  = tileHorizontally ? srcTileWidth : destinationRectangle.Width;
                    var dstTileHeight = tileVertically ? srcTileHeight : destinationRectangle.Height;

                    var tileRegion   = new RectangleF(destinationRectangle.X, destinationRectangle.Y, dstTileWidth, dstTileHeight);
                    var tileSource   = new Rectangle(sourceRectangle.X, sourceRectangle.Y, (Int32)srcTileWidth, (Int32)srcTileHeight);
                    var tilePosition = new Vector2(position.X + cx, position.Y + cy);
                    var tileOrigin   = origin - tilePosition;
                    spriteBatch.Draw(texture, tileRegion, tileSource, color, rotation, tileOrigin, effects, layerDepth, data);

                    cx = cx + sourceRectangle.Width;
                }
                cx = 0;
                cy = cy + sourceRectangle.Height;
            }
        }
        /// <summary>
        /// Draws horizontal images.
        /// </summary>
        private void DrawHorizontal <VertexType, SpriteData>(SpriteBatchBase <VertexType, SpriteData> spriteBatch, Vector2 position, Single width, Single height, Color color, Single rotation, Vector2 origin, SpriteEffects effects, Single layerDepth, SpriteData data)
            where VertexType : struct, IVertexType
            where SpriteData : struct
        {
            var srcLeft  = this.Left;
            var srcRight = this.Right;
            var dstLeft  = srcLeft;
            var dstRight = srcRight;

            if (width < MinimumRecommendedSize.Width)
            {
                var scale = width / MinimumRecommendedSize.Width;
                dstLeft  = (Int32)Math.Floor(dstLeft * scale);
                dstRight = (Int32)Math.Ceiling(dstRight * scale);
            }

            var srcStretchableWidth  = this.TextureRegion.Width - (srcLeft + srcRight);
            var srcStretchableHeight = this.TextureRegion.Height;

            var dstStretchableWidth  = width - (dstLeft + dstRight);
            var dstStretchableHeight = height;

            // Center
            var centerSource   = new Rectangle(this.TextureRegion.Left + srcLeft, this.TextureRegion.Top, srcStretchableWidth, srcStretchableHeight);
            var centerRegion   = new RectangleF(position.X, position.Y, dstStretchableWidth, dstStretchableHeight);
            var centerPosition = new Vector2(dstLeft, 0);

            if (this.TileCenter)
            {
                TileImageSegment(TilingMode.Horizontal,
                                 spriteBatch, this.Texture, centerPosition, centerRegion, centerSource, color, rotation, origin, effects, layerDepth, data);
            }
            else
            {
                var centerOrigin = origin - centerPosition;
                spriteBatch.Draw(this.Texture, centerRegion, centerSource, color, rotation, centerOrigin, effects, layerDepth, data);
            }

            // Edges
            var leftSource   = new Rectangle(this.TextureRegion.Left, this.TextureRegion.Top, srcLeft, srcStretchableHeight);
            var leftRegion   = new RectangleF(position.X, position.Y, dstLeft, dstStretchableHeight);
            var leftPosition = new Vector2(0, 0);

            var rightSource   = new Rectangle(this.TextureRegion.Right - srcRight, this.TextureRegion.Top, srcRight, srcStretchableHeight);
            var rightRegion   = new RectangleF(position.X, position.Y, dstRight, dstStretchableHeight);
            var rightPosition = new Vector2(width - dstRight, 0);

            if (this.TileEdges)
            {
                TileImageSegment(TilingMode.Horizontal,
                                 spriteBatch, this.Texture, leftPosition, leftRegion, leftSource, color, rotation, origin, effects, layerDepth, data);

                TileImageSegment(TilingMode.Horizontal,
                                 spriteBatch, this.Texture, rightPosition, rightRegion, rightSource, color, rotation, origin, effects, layerDepth, data);
            }
            else
            {
                var leftOrigin = origin - leftPosition;
                spriteBatch.Draw(this.Texture, leftRegion, leftSource, color, rotation, leftOrigin, effects, layerDepth, data);
                var rightOrigin = origin - rightPosition;
                spriteBatch.Draw(this.Texture, rightRegion, rightSource, color, rotation, rightOrigin, effects, layerDepth, data);
            }
        }
        /// <summary>
        /// Draws vertical images.
        /// </summary>
        private void DrawVertical <VertexType, SpriteData>(SpriteBatchBase <VertexType, SpriteData> spriteBatch, Vector2 position, Single width, Single height, Color color, Single rotation, Vector2 origin, SpriteEffects effects, Single layerDepth, SpriteData data)
            where VertexType : struct, IVertexType
            where SpriteData : struct
        {
            var srcTop    = this.Left;
            var srcBottom = this.Right;
            var dstTop    = srcTop;
            var dstBottom = srcBottom;

            if (height < MinimumRecommendedSize.Height)
            {
                var scale = height / MinimumRecommendedSize.Height;
                dstTop    = (Int32)Math.Floor(dstTop * scale);
                dstBottom = (Int32)Math.Ceiling(dstBottom * scale);
            }

            var srcStretchableWidth  = this.TextureRegion.Width;
            var srcStretchableHeight = this.TextureRegion.Height - (srcTop + srcBottom);

            var dstStretchableWidth  = width;
            var dstStretchableHeight = height - (dstTop + dstBottom);

            // Center
            var centerSource   = new Rectangle(this.TextureRegion.Left, this.TextureRegion.Top + srcTop, srcStretchableWidth, srcStretchableHeight);
            var centerRegion   = new RectangleF(position.X, position.Y, dstStretchableWidth, dstStretchableHeight);
            var centerPosition = new Vector2(0, dstTop);

            if (this.TileCenter)
            {
                TileImageSegment(TilingMode.Vertical,
                                 spriteBatch, this.Texture, centerPosition, centerRegion, centerSource, color, rotation, origin, effects, layerDepth, data);
            }
            else
            {
                var centerOrigin = origin - centerPosition;
                spriteBatch.Draw(this.Texture, centerRegion, centerSource, color, rotation, centerOrigin, effects, layerDepth, data);
            }

            // Edges
            var topSource   = new Rectangle(this.TextureRegion.Left, this.TextureRegion.Top, srcStretchableWidth, srcTop);
            var topRegion   = new RectangleF(position.X, position.Y, dstStretchableWidth, dstTop);
            var topPosition = new Vector2(0, 0);

            var bottomSource   = new Rectangle(this.TextureRegion.Left, this.TextureRegion.Bottom - srcBottom, srcStretchableWidth, srcBottom);
            var bottomRegion   = new RectangleF(position.X, position.Y, dstStretchableWidth, dstBottom);
            var bottomPosition = new Vector2(0, height - dstBottom);

            if (this.TileEdges)
            {
                TileImageSegment(TilingMode.Vertical,
                                 spriteBatch, this.Texture, topPosition, topRegion, topSource, color, rotation, origin, effects, layerDepth, data);
                TileImageSegment(TilingMode.Vertical,
                                 spriteBatch, this.Texture, bottomPosition, bottomRegion, bottomSource, color, rotation, origin, effects, layerDepth, data);
            }
            else
            {
                var topOrigin = origin - topPosition;
                spriteBatch.Draw(this.Texture, topRegion, topSource, color, rotation, topOrigin, effects, layerDepth, data);
                var bottomOrigin = origin - bottomPosition;
                spriteBatch.Draw(this.Texture, bottomRegion, bottomSource, color, rotation, bottomOrigin, effects, layerDepth, data);
            }
        }
Example #6
0
        /// <inheritdoc/>
        internal override void Draw <VertexType, SpriteData>(SpriteBatchBase <VertexType, SpriteData> spriteBatch, Vector2 position, Single width, Single height, Color color, Single rotation, Vector2 origin, SpriteEffects effects, Single layerDepth, SpriteData data)
        {
            var tilingData = new TilingData()
            {
                Texture    = this.Texture,
                Color      = color,
                Rotation   = rotation,
                Origin     = origin,
                Effects    = effects,
                LayerDepth = layerDepth
            };

            effects |= SpriteEffects.OriginRelativeToDestination;

            var srcLeft   = this.Left;
            var srcTop    = this.Top;
            var srcRight  = this.Right;
            var srcBottom = this.Bottom;

            var dstLeft   = srcLeft;
            var dstTop    = srcTop;
            var dstRight  = srcRight;
            var dstBottom = srcBottom;

            if (width < MinimumRecommendedSize.Width)
            {
                var scale = width / MinimumRecommendedSize.Width;
                dstLeft  = (Int32)Math.Floor(dstLeft * scale);
                dstRight = (Int32)Math.Ceiling(dstRight * scale);
            }
            if (height < MinimumRecommendedSize.Height)
            {
                var scale = height / MinimumRecommendedSize.Height;
                dstTop    = (Int32)Math.Floor(dstTop * scale);
                dstBottom = (Int32)Math.Ceiling(dstBottom * scale);
            }

            var srcStretchableWidth  = this.TextureRegion.Width - (srcLeft + srcRight);
            var srcStretchableHeight = this.TextureRegion.Height - (srcTop + srcBottom);

            var dstStretchableWidth  = width - (dstLeft + dstRight);
            var dstStretchableHeight = height - (dstTop + dstBottom);

            // Center
            var centerSource   = new Rectangle(this.TextureRegion.Left + srcLeft, this.TextureRegion.Top + srcTop, srcStretchableWidth, srcStretchableHeight);
            var centerRegion   = new RectangleF(position.X, position.Y, dstStretchableWidth, dstStretchableHeight);
            var centerPosition = new Vector2(dstLeft, dstTop);

            if (this.TileCenter)
            {
                tilingData.Position             = centerPosition;
                tilingData.DestinationRectangle = centerRegion;
                tilingData.SourceRectangle      = centerSource;
                TileImageSegment(spriteBatch, TilingMode.Both, ref tilingData, data);
            }
            else
            {
                var centerOrigin = origin - centerPosition;
                spriteBatch.Draw(this.Texture, centerRegion, centerSource, color, rotation, centerOrigin, effects, layerDepth, data);
            }

            // Edges
            var leftSource   = new Rectangle(this.TextureRegion.Left, this.TextureRegion.Top + srcTop, srcLeft, srcStretchableHeight);
            var leftRegion   = new RectangleF(position.X, position.Y, dstLeft, dstStretchableHeight);
            var leftPosition = new Vector2(0, dstTop);

            var rightSource   = new Rectangle(this.TextureRegion.Right - srcRight, this.TextureRegion.Top + srcTop, srcRight, srcStretchableHeight);
            var rightRegion   = new RectangleF(position.X, position.Y, dstRight, dstStretchableHeight);
            var rightPosition = new Vector2(width - dstRight, dstTop);

            var topSource   = new Rectangle(this.TextureRegion.Left + srcLeft, this.TextureRegion.Top, srcStretchableWidth, srcTop);
            var topRegion   = new RectangleF(position.X, position.Y, dstStretchableWidth, dstTop);
            var topPosition = new Vector2(dstLeft, 0);

            var bottomSource   = new Rectangle(this.TextureRegion.Left + srcLeft, this.TextureRegion.Bottom - srcBottom, srcStretchableWidth, srcBottom);
            var bottomRegion   = new RectangleF(position.X, position.Y, dstStretchableWidth, dstBottom);
            var bottomPosition = new Vector2(dstLeft, height - dstBottom);

            if (this.TileEdges)
            {
                tilingData.Position             = leftPosition;
                tilingData.DestinationRectangle = leftRegion;
                tilingData.SourceRectangle      = leftSource;
                TileImageSegment(spriteBatch, TilingMode.Both, ref tilingData, data);

                tilingData.Position             = rightPosition;
                tilingData.DestinationRectangle = rightRegion;
                tilingData.SourceRectangle      = rightSource;
                TileImageSegment(spriteBatch, TilingMode.Both, ref tilingData, data);

                tilingData.Position             = topPosition;
                tilingData.DestinationRectangle = topRegion;
                tilingData.SourceRectangle      = topSource;
                TileImageSegment(spriteBatch, TilingMode.Both, ref tilingData, data);

                tilingData.Position             = bottomPosition;
                tilingData.DestinationRectangle = bottomRegion;
                tilingData.SourceRectangle      = bottomSource;
                TileImageSegment(spriteBatch, TilingMode.Both, ref tilingData, data);
            }
            else
            {
                var leftOrigin = origin - leftPosition;
                spriteBatch.Draw(this.Texture, leftRegion, leftSource, color, rotation, leftOrigin, effects, layerDepth, data);
                var rightOrigin = origin - rightPosition;
                spriteBatch.Draw(this.Texture, rightRegion, rightSource, color, rotation, rightOrigin, effects, layerDepth, data);
                var topOrigin = origin - topPosition;
                spriteBatch.Draw(this.Texture, topRegion, topSource, color, rotation, topOrigin, effects, layerDepth, data);
                var bottomOrigin = origin - bottomPosition;
                spriteBatch.Draw(this.Texture, bottomRegion, bottomSource, color, rotation, bottomOrigin, effects, layerDepth, data);
            }

            // Corners
            var cornerTLRegion   = new RectangleF(position.X, position.Y, dstLeft, dstTop);
            var cornerTLPosition = new Vector2(0, 0);
            var cornerTLOrigin   = origin - cornerTLPosition;
            var cornerTLSource   = new Rectangle(this.TextureRegion.Left, this.TextureRegion.Top, srcLeft, srcTop);

            spriteBatch.Draw(this.Texture, cornerTLRegion, cornerTLSource, color, rotation, cornerTLOrigin, effects, layerDepth, data);

            var cornerTRRegion   = new RectangleF(position.X, position.Y, dstRight, dstTop);
            var cornerTRPosition = new Vector2(width - dstRight, 0);
            var cornerTROrigin   = origin - cornerTRPosition;
            var cornerTRSource   = new Rectangle(this.TextureRegion.Right - srcRight, this.TextureRegion.Top, srcRight, srcTop);

            spriteBatch.Draw(this.Texture, cornerTRRegion, cornerTRSource, color, rotation, cornerTROrigin, effects, layerDepth, data);

            var cornerBLRegion   = new RectangleF(position.X, position.Y, dstLeft, dstBottom);
            var cornerBLPosition = new Vector2(0, height - dstBottom);
            var cornerBLOrigin   = origin - cornerBLPosition;
            var cornerBLSource   = new Rectangle(this.TextureRegion.Left, this.TextureRegion.Bottom - srcBottom, srcLeft, srcBottom);

            spriteBatch.Draw(this.Texture, cornerBLRegion, cornerBLSource, color, rotation, cornerBLOrigin, effects, layerDepth, data);

            var cornerBRRegion   = new RectangleF(position.X, position.Y, dstRight, dstBottom);
            var cornerBRPosition = new Vector2(width - dstRight, height - dstBottom);
            var cornerBROrigin   = origin - cornerBRPosition;
            var cornerBRSource   = new Rectangle(this.TextureRegion.Right - srcRight, this.TextureRegion.Bottom - srcBottom, srcLeft, srcBottom);

            spriteBatch.Draw(this.Texture, cornerBRRegion, cornerBRSource, color, rotation, cornerBROrigin, effects, layerDepth, data);
        }