Example #1
0
    private static bool ForwardDraw(
        XSpriteBatch @this,
        XTexture2D?texture,
        XRectangle destinationRectangle,
        XColor color,
        XRectangle?sourceRectangle = null,
        float rotation             = 0f,
        XVector2?origin            = null,
        SpriteEffects effects      = SpriteEffects.None,
        float layerDepth           = 0f
        )
    {
        if (!Config.IsEnabled)
        {
            return(true);
        }

        @this.Draw(
            texture: texture,
            destinationRectangle: destinationRectangle,
            sourceRectangle: sourceRectangle,
            color: color,
            rotation: rotation,
            origin: origin ?? XVector2.Zero,
            effects: effects,
            layerDepth: layerDepth
            );

        return(false);
    }
Example #2
0
    // Takes the arguments, and checks to see if the texture is padded. If it is, it is forwarded to the correct draw call, avoiding
    // intervening mods altering the arguments first.
    internal static bool OnDrawFirst(
        this XSpriteBatch @this,
        ref XTexture2D?texture,
        ref XRectangle destination,
        ref XRectangle?source,
        XColor color,
        float rotation,
        ref XVector2 origin,
        ref SpriteEffects effects,
        float layerDepth,
        ref ManagedTexture2D?__state
        )
    {
        if (texture is null)
        {
            return(false);
        }

        using var watchdogScoped = WatchDog.WatchDog.ScopedWorkingState;

        /*
         * if (destination.Width < 0 || destination.Height < 0) {
         *      Debug.Trace("destination invert");
         * }
         * if (source is XRectangle sourceRect && (sourceRect.Width < 0 || sourceRect.Height < 0)) {
         *      Debug.Trace("source invert");
         * }
         */

        GetDrawParameters(
            texture: texture,
            source: source,
            bounds: out var sourceRectangle,
            scaleFactor: out var scaleFactor
            );

        var referenceRectangle = sourceRectangle;

        Bounds destinationBounds = destination;

        var expectedScale2D = destinationBounds.ExtentF / sourceRectangle.ExtentF;
        var expectedScale   = EstimateScale(expectedScale2D, scaleFactor);

        if (!texture.FetchScaledTexture(
                expectedScale: expectedScale,
                source: ref sourceRectangle,
                spriteInstance: out var spriteInstance,
                create: true
                ))
        {
            return(Continue);
        }
        spriteInstance.UpdateReferenceFrame();

        if (referenceRectangle.X < 0)
        {
            destinationBounds.Left -= referenceRectangle.X;
        }
        if (referenceRectangle.Y < 0)
        {
            destinationBounds.Top -= referenceRectangle.Y;
        }

        var resampledTexture = spriteInstance.Texture !;

        if (!spriteInstance.Padding.IsZero)
        {
            // Convert the draw into the other draw style. This has to be done because the padding potentially has
            // subpixel accuracy when scaled to the destination rectangle.

            var originalSize    = referenceRectangle.ExtentF;
            var destinationSize = destinationBounds.ExtentF;
            var newScale        = destinationSize / originalSize;
            var newPosition     = destinationBounds.OffsetF;

            if ((destinationBounds.Invert.X || destinationBounds.Invert.Y) && DrawState.CurrentRasterizerState.CullMode == CullMode.CullCounterClockwiseFace)
            {
                // Winding order is invalid
                return(Stop);
            }
            if (destinationBounds.Invert.X)
            {
                effects ^= SpriteEffects.FlipHorizontally;
            }
            if (destinationBounds.Invert.Y)
            {
                effects ^= SpriteEffects.FlipVertically;
            }

            // TODO handle culling here for inverted sprites?

            @this.Draw(
                texture: resampledTexture,
                position: newPosition,
                sourceRectangle: sourceRectangle,
                color: color,
                rotation: rotation,
                origin: origin,
                scale: newScale,
                effects: effects,
                layerDepth: layerDepth
                );
            return(Stop);
        }
        __state = resampledTexture;
        return(Continue);
    }