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); }
public static bool OnDrawString( XSpriteBatch __instance, SpriteFont spriteFont, StringBuilder text, XVector2 position, XColor color, float rotation, XVector2 origin, XVector2 scale, SpriteEffects effects, float layerDepth ) { return(Core.OnDrawStringImpl.DrawString( __instance, spriteFont, text, position, color, rotation, origin, scale, effects, layerDepth )); }
public static bool OnDrawLast( XSpriteBatch __instance, ref XTexture2D?texture, ref XRectangle destinationRectangle, ref XRectangle?sourceRectangle, ref XColor color, float rotation, ref XVector2 origin, ref SpriteEffects effects, ref float layerDepth, ref ManagedTexture2D?__state ) { if (!Config.IsEnabled) { return(true); } return(__instance.OnDraw( texture: ref texture, destination: ref destinationRectangle, source: ref sourceRectangle, color: ref color, rotation: rotation, origin: ref origin, effects: ref effects, layerDepth: ref layerDepth, __state: ref __state )); }
public static bool OnDraw(XSpriteBatch __instance, XTexture2D?texture, XVector2 position, XColor color) { return(ForwardDraw( @this: __instance, texture: texture, position: position, color: color )); }
public static bool OnDraw(XSpriteBatch __instance, XTexture2D?texture, XRectangle destinationRectangle, XColor color) { return(ForwardDraw( @this: __instance, texture: texture, destinationRectangle: destinationRectangle, color: color )); }
public static bool OnDraw(XSpriteBatch __instance, XTexture2D?texture, XVector2 position, XRectangle?sourceRectangle, XColor color, float rotation, XVector2 origin, float scale, SpriteEffects effects, float layerDepth) { return(ForwardDraw( @this: __instance, texture: texture, position: position, sourceRectangle: sourceRectangle, color: color, rotation: rotation, origin: origin, scale: new XVector2(scale), effects: effects, layerDepth: layerDepth )); }
public static bool OnDrawString(XSpriteBatch __instance, SpriteFont spriteFont, StringBuilder text, XVector2 position, XColor color) { __instance.DrawString( spriteFont: spriteFont, text: text, position: position, color: color, rotation: 0.0f, origin: XVector2.Zero, scale: XVector2.One, effects: SpriteEffects.None, layerDepth: 0.0f ); return(false); }
public static bool OnDraw(XSpriteBatch __instance, ref XTexture2D?texture, ref XVector2 position, ref XRectangle?sourceRectangle, ref XColor color, float rotation, ref XVector2 origin, ref XVector2 scale, SpriteEffects effects, float layerDepth) { if (!Config.IsEnabled) { return(true); } return(__instance.OnDraw( texture: ref texture, position: ref position, source: ref sourceRectangle, color: ref color, rotation: rotation, origin: ref origin, scale: ref scale, effects: effects, layerDepth: ref layerDepth )); }
public static void OnBegin(XSpriteBatch __instance, ref SpriteSortMode sortMode, BlendState?blendState, SamplerState?samplerState, DepthStencilState?depthStencilState, RasterizerState?rasterizerState, Effect?effect, Matrix?transformMatrix) { if (!Config.IsEnabled) { return; } /* * if (sortMode is (SpriteSortMode.Deferred or SpriteSortMode.Immediate)) { * sortMode = SpriteSortMode.Texture; * } */ DrawState.OnBegin( __instance, sortMode, blendState ?? BlendState.AlphaBlend, samplerState ?? SamplerState.PointClamp, depthStencilState ?? DepthStencilState.None, rasterizerState ?? RasterizerState.CullCounterClockwise, effect, transformMatrix ?? Matrix.Identity ); }
internal static bool OnDraw( this XSpriteBatch @this, ref XTexture2D?texture, ref XVector2 position, ref XRectangle?source, ref XColor color, float rotation, ref XVector2 origin, ref XVector2 scale, SpriteEffects effects, ref float layerDepth ) { if (texture is null) { return(false); } GetDrawParameters( texture: texture, source: source, bounds: out var sourceRectangle, scaleFactor: out var scaleFactor ); var originalSourceRect = sourceRectangle; ManagedSpriteInstance?spriteInstance; ManagedTexture2D? resampledTexture; if (texture is ManagedTexture2D texture2D) { resampledTexture = texture2D; spriteInstance = resampledTexture.SpriteInstance; sourceRectangle = resampledTexture.Dimensions; } else if (texture.FetchScaledTexture( expectedScale: EstimateScale(scale, scaleFactor), source: ref sourceRectangle, spriteInstance: out spriteInstance, create: true )) { spriteInstance.UpdateReferenceFrame(); resampledTexture = spriteInstance.Texture !; } else { resampledTexture = null; } if (spriteInstance is null || resampledTexture is null) { return(Continue); } if (originalSourceRect.X < 0) { position.X -= originalSourceRect.X * scale.X; } if (originalSourceRect.Y < 0) { position.Y -= originalSourceRect.Y * scale.Y; } var adjustedScale = (Vector2F)scale / spriteInstance.Scale; var adjustedPosition = position; var adjustedOrigin = (Vector2F)origin; if (spriteInstance.TexType == TextureType.SlicedImage) { sourceRectangle = source ?? resampledTexture.Bounds; if (source is not null) { sourceRectangle = new Bounds( (Vector2I)source.Value.Location - spriteInstance.OriginalSourceRectangle.Offset, source.Value.Size ); sourceRectangle.Offset = (sourceRectangle.OffsetF * spriteInstance.Scale).NearestInt(); sourceRectangle.Extent = (sourceRectangle.ExtentF * spriteInstance.Scale).NearestInt(); } } if (!spriteInstance.Padding.IsZero) { var paddingX = spriteInstance.Padding.X; var paddingY = spriteInstance.Padding.Y; if (effects.HasFlag(SpriteEffects.FlipHorizontally)) { paddingX = (paddingX.Y, paddingX.X); } if (effects.HasFlag(SpriteEffects.FlipVertically)) { paddingY = (paddingY.Y, paddingY.X); } var padding = new PaddingQuad(paddingX, paddingY); var textureSize = new Vector2F(sourceRectangle.Extent); var innerSize = (Vector2F)spriteInstance.UnpaddedSize; // This is the scale factor to bring the inner size to the draw size. var innerRatio = textureSize / innerSize; // spriteInstance.InnerRatio; // Scale the... scale by the scale factor. adjustedScale *= innerRatio; adjustedOrigin *= spriteInstance.Scale; adjustedOrigin /= innerRatio; adjustedOrigin += (Vector2F)padding.Offset; } else { adjustedOrigin *= spriteInstance.Scale; } if (source.HasValue) { sourceRectangle.Invert.X = source.Value.Width < 0; sourceRectangle.Invert.Y = source.Value.Height < 0; } if (Debug.Mode.RegisterDrawForSelect( instance: spriteInstance, texture: texture, originalPosition: position, originalSource: source, position: adjustedPosition, source: sourceRectangle, color: color, rotation: rotation, originalOrigin: origin, origin: adjustedOrigin, scale: adjustedScale, effects: effects, layerDepth: layerDepth )) { color = XColor.Red; } texture = resampledTexture; source = sourceRectangle; origin = adjustedOrigin; scale = adjustedScale; position = adjustedPosition; return(Continue); }
// 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); }
internal static bool OnDraw( this XSpriteBatch @this, ref XTexture2D?texture, ref XRectangle destination, ref XRectangle?source, ref XColor color, float rotation, ref XVector2 origin, ref SpriteEffects effects, ref float layerDepth, ref ManagedTexture2D?__state ) { if (texture is null) { return(false); } Bounds sourceRectangle; ManagedSpriteInstance?spriteInstance; ManagedTexture2D resampledTexture; Bounds destinationBounds = destination; var referenceSource = source.GetValueOrDefault(); if (__state is null) { GetDrawParameters( texture: texture, source: source, bounds: out sourceRectangle, scaleFactor: out var scaleFactor ); var expectedScale2D = new Vector2F(destinationBounds.Extent) / new Vector2F(sourceRectangle.Extent); var expectedScale = EstimateScale(expectedScale2D, scaleFactor); if (!texture.FetchScaledTexture( expectedScale: expectedScale, source: ref sourceRectangle, spriteInstance: out spriteInstance )) { return(Continue); } if (spriteInstance.TexType == TextureType.SlicedImage) { sourceRectangle = source ?? spriteInstance.Texture !.Bounds; } spriteInstance.UpdateReferenceFrame(); resampledTexture = spriteInstance.Texture !; } else { resampledTexture = __state; spriteInstance = resampledTexture.SpriteInstance; sourceRectangle = resampledTexture.Dimensions; if (spriteInstance.TexType == TextureType.SlicedImage) { sourceRectangle = source ?? resampledTexture.Bounds; if (source.HasValue) { sourceRectangle = new Bounds( (Vector2I)source.Value.Location - spriteInstance.OriginalSourceRectangle.Offset, source.Value.Size ); sourceRectangle.Offset = (sourceRectangle.OffsetF * spriteInstance.Scale).NearestInt(); sourceRectangle.Extent = (sourceRectangle.ExtentF * spriteInstance.Scale).NearestInt(); } } } if (referenceSource.X < 0) { destination.X -= referenceSource.X; } if (referenceSource.Y < 0) { destination.Y -= referenceSource.Y; } var scaledOrigin = (Vector2F)origin * spriteInstance.Scale; if (source.HasValue) { sourceRectangle.Invert.X = source.Value.Width < 0; sourceRectangle.Invert.Y = source.Value.Height < 0; } if (Debug.Mode.RegisterDrawForSelect( instance: spriteInstance, texture: texture, originalDestination: destinationBounds, destination: destination, source: sourceRectangle, color: color, rotation: rotation, originalOrigin: origin, origin: scaledOrigin, effects: effects, layerDepth: layerDepth )) { color = XColor.Red; } source = sourceRectangle; origin = scaledOrigin; texture = resampledTexture; return(Continue); }