Exemplo n.º 1
0
        public static Vector2 getClosestPointOnBoundsToOrigin(ref Rectangle rect)
        {
            var max         = RectangleExt.getMax(ref rect);
            var minDist     = Math.Abs(rect.Location.X);
            var boundsPoint = new Vector2(rect.Location.X, 0);

            if (Math.Abs(max.X) < minDist)
            {
                minDist       = Math.Abs(max.X);
                boundsPoint.X = max.X;
                boundsPoint.Y = 0f;
            }

            if (Math.Abs(max.Y) < minDist)
            {
                minDist       = Math.Abs(max.Y);
                boundsPoint.X = 0f;
                boundsPoint.Y = max.Y;
            }

            if (Math.Abs(rect.Location.Y) < minDist)
            {
                minDist       = Math.Abs(rect.Location.Y);
                boundsPoint.X = 0;
                boundsPoint.Y = rect.Location.Y;
            }

            return(boundsPoint);
        }
Exemplo n.º 2
0
        /// <summary>
        /// given the points of a polygon calculates the bounds
        /// </summary>
        /// <returns>The from polygon points.</returns>
        /// <param name="points">Points.</param>
        public static Rectangle boundsFromPolygonPoints(Vector2[] points)
        {
            // we need to find the min/max x/y values
            var minX = float.PositiveInfinity;
            var minY = float.PositiveInfinity;
            var maxX = float.NegativeInfinity;
            var maxY = float.NegativeInfinity;

            for (var i = 0; i < points.Length; i++)
            {
                var pt = points[i];

                if (pt.X < minX)
                {
                    minX = pt.X;
                }
                if (pt.X > maxX)
                {
                    maxX = pt.X;
                }

                if (pt.Y < minY)
                {
                    minY = pt.Y;
                }
                if (pt.Y > maxY)
                {
                    maxY = pt.Y;
                }
            }

            return(RectangleExt.fromMinMaxPoints(new Point((int)minX, (int)minY), new Point((int)maxX, (int)maxY)));
        }
Exemplo n.º 3
0
        public override void Render(Graphics graphics, Camera camera)
        {
            var topLeft         = Entity.transform.position + localOffset;
            var destinationRect = RectangleExt.fromFloats(topLeft.X, topLeft.Y, _sourceRect.Width * Entity.transform.scale.X * TextureScale.X, _sourceRect.Height * Entity.transform.scale.Y * TextureScale.Y);

            graphics.batcher.draw(Subtexture, destinationRect, _sourceRect, Color, Entity.transform.rotation, Origin * _inverseTexScale, SpriteEffects, layerDepth);
        }
Exemplo n.º 4
0
        public override void render(Graphics graphics, Camera camera)
        {
            var topLeft         = entity.transform.position + _localOffset;
            var destinationRect = RectangleExt.fromFloats(topLeft.X, topLeft.Y, _sourceRect.Width * entity.transform.scale.X * textureScale.X, _sourceRect.Height * entity.transform.scale.Y * textureScale.Y);

            graphics.batcher.draw(subtexture, destinationRect, _sourceRect, color, entity.transform.rotation, origin * _inverseTexScale, spriteEffects, _layerDepth);
        }
Exemplo n.º 5
0
        void UpdateResolutionScaler()
        {
            var designSize        = _designResolutionSize;
            var screenSize        = new Point(Screen.Width, Screen.Height);
            var screenAspectRatio = (float)screenSize.X / (float)screenSize.Y;

            var renderTargetWidth  = screenSize.X;
            var renderTargetHeight = screenSize.Y;

            var resolutionScaleX = (float)screenSize.X / (float)designSize.X;
            var resolutionScaleY = (float)screenSize.Y / (float)designSize.Y;

            var rectCalculated = false;

            // calculate the scale used by the PixelPerfect variants
            PixelPerfectScale = 1;
            if (_resolutionPolicy != SceneResolutionPolicy.None)
            {
                if ((float)designSize.X / (float)designSize.Y > screenAspectRatio)
                {
                    PixelPerfectScale = screenSize.X / designSize.X;
                }
                else
                {
                    PixelPerfectScale = screenSize.Y / designSize.Y;
                }

                if (PixelPerfectScale == 0)
                {
                    PixelPerfectScale = 1;
                }
            }

            switch (_resolutionPolicy)
            {
            case SceneResolutionPolicy.None:
                _finalRenderDestinationRect.X      = _finalRenderDestinationRect.Y = 0;
                _finalRenderDestinationRect.Width  = screenSize.X;
                _finalRenderDestinationRect.Height = screenSize.Y;
                rectCalculated = true;
                break;

            case SceneResolutionPolicy.ExactFit:
                // exact design size render texture
                renderTargetWidth  = designSize.X;
                renderTargetHeight = designSize.Y;
                break;

            case SceneResolutionPolicy.NoBorder:
                // exact design size render texture
                renderTargetWidth  = designSize.X;
                renderTargetHeight = designSize.Y;

                resolutionScaleX = resolutionScaleY = Math.Max(resolutionScaleX, resolutionScaleY);
                break;

            case SceneResolutionPolicy.NoBorderPixelPerfect:
                // exact design size render texture
                renderTargetWidth  = designSize.X;
                renderTargetHeight = designSize.Y;

                // we are going to do some cropping so we need to use floats for the scale then round up
                PixelPerfectScale = 1;
                if ((float)designSize.X / (float)designSize.Y < screenAspectRatio)
                {
                    var floatScale = (float)screenSize.X / (float)designSize.X;
                    PixelPerfectScale = Mathf.CeilToInt(floatScale);
                }
                else
                {
                    var floatScale = (float)screenSize.Y / (float)designSize.Y;
                    PixelPerfectScale = Mathf.CeilToInt(floatScale);
                }

                if (PixelPerfectScale == 0)
                {
                    PixelPerfectScale = 1;
                }

                _finalRenderDestinationRect.Width  = Mathf.CeilToInt(designSize.X * PixelPerfectScale);
                _finalRenderDestinationRect.Height = Mathf.CeilToInt(designSize.Y * PixelPerfectScale);
                _finalRenderDestinationRect.X      = (screenSize.X - _finalRenderDestinationRect.Width) / 2;
                _finalRenderDestinationRect.Y      = (screenSize.Y - _finalRenderDestinationRect.Height) / 2;
                rectCalculated = true;

                break;

            case SceneResolutionPolicy.ShowAll:
                resolutionScaleX = resolutionScaleY = Math.Min(resolutionScaleX, resolutionScaleY);

                renderTargetWidth  = designSize.X;
                renderTargetHeight = designSize.Y;
                break;

            case SceneResolutionPolicy.ShowAllPixelPerfect:
                // exact design size render texture
                renderTargetWidth  = designSize.X;
                renderTargetHeight = designSize.Y;

                _finalRenderDestinationRect.Width  = Mathf.CeilToInt(designSize.X * PixelPerfectScale);
                _finalRenderDestinationRect.Height = Mathf.CeilToInt(designSize.Y * PixelPerfectScale);
                _finalRenderDestinationRect.X      = (screenSize.X - _finalRenderDestinationRect.Width) / 2;
                _finalRenderDestinationRect.Y      = (screenSize.Y - _finalRenderDestinationRect.Height) / 2;
                rectCalculated = true;

                break;

            case SceneResolutionPolicy.FixedHeight:
                resolutionScaleX = resolutionScaleY;
                designSize.X     = Mathf.CeilToInt(screenSize.X / resolutionScaleX);

                // exact design size render texture for height but not width
                renderTargetWidth  = designSize.X;
                renderTargetHeight = designSize.Y;
                break;

            case SceneResolutionPolicy.FixedHeightPixelPerfect:
                // start with exact design size render texture height. the width may change
                renderTargetHeight = designSize.Y;

                _finalRenderDestinationRect.Width  = Mathf.CeilToInt(designSize.X * resolutionScaleX);
                _finalRenderDestinationRect.Height = Mathf.CeilToInt(designSize.Y * PixelPerfectScale);
                _finalRenderDestinationRect.X      = (screenSize.X - _finalRenderDestinationRect.Width) / 2;
                _finalRenderDestinationRect.Y      = (screenSize.Y - _finalRenderDestinationRect.Height) / 2;
                rectCalculated = true;

                renderTargetWidth = (int)(designSize.X * resolutionScaleX / PixelPerfectScale);
                break;

            case SceneResolutionPolicy.FixedWidth:
                resolutionScaleY = resolutionScaleX;
                designSize.Y     = Mathf.CeilToInt(screenSize.Y / resolutionScaleY);

                // exact design size render texture for width but not height
                renderTargetWidth  = designSize.X;
                renderTargetHeight = designSize.Y;
                break;

            case SceneResolutionPolicy.FixedWidthPixelPerfect:
                // start with exact design size render texture width. the height may change
                renderTargetWidth = designSize.X;

                _finalRenderDestinationRect.Width  = Mathf.CeilToInt(designSize.X * PixelPerfectScale);
                _finalRenderDestinationRect.Height = Mathf.CeilToInt(designSize.Y * resolutionScaleY);
                _finalRenderDestinationRect.X      = (screenSize.X - _finalRenderDestinationRect.Width) / 2;
                _finalRenderDestinationRect.Y      = (screenSize.Y - _finalRenderDestinationRect.Height) / 2;
                rectCalculated = true;

                renderTargetHeight = (int)(designSize.Y * resolutionScaleY / PixelPerfectScale);

                break;

            case SceneResolutionPolicy.BestFit:
                var safeScaleX = (float)screenSize.X / (designSize.X - _designBleedSize.X);
                var safeScaleY = (float)screenSize.Y / (designSize.Y - _designBleedSize.Y);

                var resolutionScale = MathHelper.Max(resolutionScaleX, resolutionScaleY);
                var safeScale       = MathHelper.Min(safeScaleX, safeScaleY);

                resolutionScaleX = resolutionScaleY = MathHelper.Min(resolutionScale, safeScale);

                renderTargetWidth  = designSize.X;
                renderTargetHeight = designSize.Y;

                break;
            }

            // if we didnt already calculate a rect (None and all pixel perfect variants calculate it themselves) calculate it now
            if (!rectCalculated)
            {
                // calculate the display rect of the RenderTarget
                var renderWidth  = designSize.X * resolutionScaleX;
                var renderHeight = designSize.Y * resolutionScaleY;

                _finalRenderDestinationRect = RectangleExt.FromFloats((screenSize.X - renderWidth) / 2, (screenSize.Y - renderHeight) / 2, renderWidth, renderHeight);
            }


            // set some values in the Input class to translate mouse position to our scaled resolution
            var scaleX = renderTargetWidth / (float)_finalRenderDestinationRect.Width;
            var scaleY = renderTargetHeight / (float)_finalRenderDestinationRect.Height;

            Input._resolutionScale  = new Vector2(scaleX, scaleY);
            Input._resolutionOffset = _finalRenderDestinationRect.Location;

            // resize our RenderTargets
            if (_sceneRenderTarget != null)
            {
                _sceneRenderTarget.Dispose();
            }
            _sceneRenderTarget = RenderTarget.Create(renderTargetWidth, renderTargetHeight);

            // only create the destinationRenderTarget if it already exists, which would indicate we have PostProcessors
            if (_destinationRenderTarget != null)
            {
                _destinationRenderTarget.Dispose();
                _destinationRenderTarget = RenderTarget.Create(renderTargetWidth, renderTargetHeight);
            }

            // notify the Renderers, PostProcessors and FinalRenderDelegate of the change in render texture size
            for (var i = 0; i < _renderers.Length; i++)
            {
                _renderers.Buffer[i].OnSceneBackBufferSizeChanged(renderTargetWidth, renderTargetHeight);
            }

            for (var i = 0; i < _afterPostProcessorRenderers.Length; i++)
            {
                _afterPostProcessorRenderers.Buffer[i].OnSceneBackBufferSizeChanged(renderTargetWidth, renderTargetHeight);
            }

            for (var i = 0; i < _postProcessors.Length; i++)
            {
                _postProcessors.Buffer[i].OnSceneBackBufferSizeChanged(renderTargetWidth, renderTargetHeight);
            }

            if (_finalRenderDelegate != null)
            {
                _finalRenderDelegate.OnSceneBackBufferSizeChanged(renderTargetWidth, renderTargetHeight);
            }

            Camera.OnSceneRenderTargetSizeChanged(renderTargetWidth, renderTargetHeight);
        }
Exemplo n.º 6
0
        public void drawInto(
            Batcher batcher,
            ref FontCharacterSource text,
            Vector2 position,
            Color color,
            float rotation,
            Vector2 origin,
            Vector2 scale,
            SpriteEffects effect,
            float depth)
        {
            var flipAdjustment = Vector2.Zero;

            var flippedVert = (effect & SpriteEffects.FlipVertically) == SpriteEffects.FlipVertically;
            var flippedHorz = (effect & SpriteEffects.FlipHorizontally) == SpriteEffects.FlipHorizontally;

            if (flippedVert || flippedHorz)
            {
                Vector2 size;
                measureString(ref text, out size);

                if (flippedHorz)
                {
                    origin.X        *= -1;
                    flipAdjustment.X = -size.X;
                }

                if (flippedVert)
                {
                    origin.Y        *= -1;
                    flipAdjustment.Y = _font.LineSpacing - size.Y;
                }
            }

            // TODO: This looks excessive... i suspect we could do most of this with simple vector math and avoid this much matrix work.
            var requiresTransformation = flippedHorz || flippedVert || rotation != 0f || scale != Vector2.One;

            if (requiresTransformation)
            {
                Matrix2D temp;
                Matrix2D.createTranslation(-origin.X, -origin.Y, out _transformationMatrix);
                Matrix2D.createScale(flippedHorz ? -scale.X : scale.X, flippedVert ? -scale.Y : scale.Y, out temp);
                Matrix2D.multiply(ref _transformationMatrix, ref temp, out _transformationMatrix);
                Matrix2D.createTranslation(flipAdjustment.X, flipAdjustment.Y, out temp);
                Matrix2D.multiply(ref temp, ref _transformationMatrix, out _transformationMatrix);
                Matrix2D.createRotation(rotation, out temp);
                Matrix2D.multiply(ref _transformationMatrix, ref temp, out _transformationMatrix);
                Matrix2D.createTranslation(position.X, position.Y, out temp);
                Matrix2D.multiply(ref _transformationMatrix, ref temp, out _transformationMatrix);
            }

            // Get the default glyph here once.
            SpriteFont.Glyph?defaultGlyph = null;
            if (_font.DefaultCharacter.HasValue)
            {
                defaultGlyph = _glyphs[_font.DefaultCharacter.Value];
            }

            var currentGlyph     = SpriteFont.Glyph.Empty;
            var offset           = requiresTransformation ? Vector2.Zero : position - origin;
            var firstGlyphOfLine = true;

            for (var i = 0; i < text.Length; ++i)
            {
                var c = text[i];

                if (c == '\r')
                {
                    continue;
                }

                if (c == '\n')
                {
                    offset.X         = requiresTransformation ? 0f : position.X - origin.X;
                    offset.Y        += _font.LineSpacing;
                    firstGlyphOfLine = true;
                    continue;
                }

                if (!_glyphs.TryGetValue(c, out currentGlyph))
                {
                    if (!defaultGlyph.HasValue)
                    {
                        throw new ArgumentException("Errors.TextContainsUnresolvableCharacters", "text");
                    }

                    currentGlyph = defaultGlyph.Value;
                }

                // The first character on a line might have a negative left side bearing.
                // In this scenario, SpriteBatch/SpriteFont normally offset the text to the right,
                // so that text does not hang off the left side of its rectangle.
                if (firstGlyphOfLine)
                {
                    offset.X        += Math.Max(currentGlyph.LeftSideBearing, 0);
                    firstGlyphOfLine = false;
                }
                else
                {
                    offset.X += _font.Spacing + currentGlyph.LeftSideBearing;
                }

                var p = offset;

                if (flippedHorz)
                {
                    p.X += currentGlyph.BoundsInTexture.Width;
                }
                p.X += currentGlyph.Cropping.X;

                if (flippedVert)
                {
                    p.Y += currentGlyph.BoundsInTexture.Height - _font.LineSpacing;
                }
                p.Y += currentGlyph.Cropping.Y;

                // transform our point if we need to
                if (requiresTransformation)
                {
                    Vector2Ext.transform(ref p, ref _transformationMatrix, out p);
                }

                var destRect = RectangleExt.fromFloats(
                    p.X,
                    p.Y,
                    currentGlyph.BoundsInTexture.Width * scale.X,
                    currentGlyph.BoundsInTexture.Height * scale.Y);

                batcher.draw(
                    _font.Texture,
                    destRect,
                    currentGlyph.BoundsInTexture,
                    color,
                    rotation,
                    Vector2.Zero,
                    effect,
                    depth);

                offset.X += currentGlyph.Width + currentGlyph.RightSideBearing;
            }
        }