Browse Source

WIP: Sprites!

* Sprite drawing has been implemented but is still untested.
    * The SdlPoint/SdlRect objects in the Point/Rectangle classes
      are now exposed to DotSDL for plotting purposes.
    * Added some rotation center support (not fully realized).
    * Sprites can now be initialized with the clipping rectangle.
    * Removed RenderFlip in favor of DotSDL's FlipDirection. The
      enums were were effective identical.
    * Started working on Sample.Sprites.
improved_timing
Ian Burgmyer 5 years ago
parent
commit
8629dc6c13
  1. 3
      DotSDL/Graphics/Canvas.cs
  2. 23
      DotSDL/Graphics/Point.cs
  3. 19
      DotSDL/Graphics/Rectangle.cs
  4. 22
      DotSDL/Graphics/SdlWindow.cs
  5. 43
      DotSDL/Graphics/Sprite.cs
  6. 26
      DotSDL/Interop/Core/Render.cs
  7. 14
      Samples/Sample.Sprites/Window.cs

3
DotSDL/Graphics/Canvas.cs

@ -50,7 +50,8 @@ namespace DotSDL.Graphics {
/// </summary>
/// <param name="textureWidth">The width of the <see cref="Canvas"/>.</param>
/// <param name="textureHeight">The height of the <see cref="Canvas"/>.</param>
internal Canvas(int textureWidth, int textureHeight) : this(textureWidth, textureHeight, new Rectangle(0, 0, textureWidth, textureHeight)) { }
internal Canvas(int textureWidth, int textureHeight)
: this(textureWidth, textureHeight, new Rectangle(0, 0, textureWidth, textureHeight)) { }
/// <summary>
/// Initializes a new <see cref="Canvas"/>.

23
DotSDL/Graphics/Point.cs

@ -5,42 +5,45 @@ namespace DotSDL.Graphics {
/// Represents a point in 2D space.
/// </summary>
public class Point {
private Rect.SdlPoint _point;
/// <summary>
/// The base <see cref="SdlPoint"/> structure that this class wraps around.
/// </summary>
internal Rect.SdlPoint SdlPoint;
/// <summary>
/// Returns a <see cref="Point"/> with the coordinates (1, 1).
/// </summary>
public static Point One = new Point(1, 1);
public static Point One => new Point(1, 1);
/// <summary>
/// Returns a <see cref="Point"/> with the coordinates (1, 0).
/// </summary>
public static Point UnitX = new Point(1, 0);
public static Point UnitX => new Point(1, 0);
/// <summary>
/// Returns a <see cref="Point"/> with the coordinates (0, 1).
/// </summary>
public static Point UnitY = new Point(0, 1);
public static Point UnitY => new Point(0, 1);
/// <summary>
/// Returns a <see cref="Point"/> with the coordinates (0, 0).
/// </summary>
public static Point Zero = new Point(0, 0);
public static Point Zero => new Point(0, 0);
/// <summary>
/// The X coordinate of the point.
/// </summary>
public int X {
get => _point.X;
set => _point.X = value;
get => SdlPoint.X;
set => SdlPoint.X = value;
}
/// <summary>
/// The Y coordinate of the point.
/// </summary>
public int Y {
get => _point.Y;
set => _point.Y = value;
get => SdlPoint.Y;
set => SdlPoint.Y = value;
}
/// <summary>
@ -49,7 +52,7 @@ namespace DotSDL.Graphics {
/// <param name="x">The X value of the new <see cref="Point"/>.</param>
/// <param name="y">The Y value of the new <see cref="Point"/>.</param>
public Point(int x = 0, int y = 0) {
_point = new Rect.SdlPoint {
SdlPoint = new Rect.SdlPoint {
X = x,
Y = y
};

19
DotSDL/Graphics/Rectangle.cs

@ -5,16 +5,19 @@ namespace DotSDL.Graphics {
/// Represents a rectangle in 2D space.
/// </summary>
public class Rectangle {
private Rect.SdlRect _rect;
/// <summary>
/// The base <see cref="SdlRect"/> structure that this class wraps around.
/// </summary>
internal Rect.SdlRect SdlRect;
/// <summary>
/// A <see cref="Point"/> representing the position of the <see cref="Rectangle"/>.
/// </summary>
public Point Position {
get => new Point(_rect.X, _rect.Y);
get => new Point(SdlRect.X, SdlRect.Y);
set {
_rect.X = value.X;
_rect.Y = value.Y;
SdlRect.X = value.X;
SdlRect.Y = value.Y;
}
}
@ -22,10 +25,10 @@ namespace DotSDL.Graphics {
/// A <see cref="Point"/> representing the size of the <see cref="Rectangle"/>.
/// </summary>
public Point Size {
get => new Point(_rect.W, _rect.H);
get => new Point(SdlRect.W, SdlRect.H);
set {
_rect.W = value.X;
_rect.H = value.Y;
SdlRect.W = value.X;
SdlRect.H = value.Y;
}
}
@ -44,7 +47,7 @@ namespace DotSDL.Graphics {
/// <param name="width">The width of the new <see cref="Rectangle"/>.</param>
/// <param name="height">The height of the new <see cref="Rectangle"/>.</param>
public Rectangle(int x, int y, int width, int height) {
_rect = new Rect.SdlRect {
SdlRect = new Rect.SdlRect {
X = x,
Y = y,
W = width,

22
DotSDL/Graphics/SdlWindow.cs

@ -207,9 +207,29 @@ namespace DotSDL.Graphics {
/// DotSDL's drawing routines and does not need to be called manually. Additionally, this method will not be
/// called if there are no sprites defined. You usually do not need to override this method.
/// </summary>
public virtual void DrawSprites() {
public virtual unsafe void DrawSprites() {
foreach(var sprite in Sprites.Where(e => e.Shown).OrderBy(e => e.ZOrder)) {
SetScalingQuality(sprite.ScalingQuality);
var srcRect = sprite.Clipping.SdlRect;
var drawSize = new Point(
(int)(srcRect.W * sprite.Scale.X),
(int)(srcRect.H * sprite.Scale.Y)
);
var destRect = new Rectangle(sprite.Position, drawSize).SdlRect;
var srcRectPtr = new IntPtr(&srcRect);
var destRectPtr = new IntPtr(&destRect);
Render.RenderCopyEx(
renderer: _renderer,
texture: _texture,
srcRect: srcRectPtr,
dstRect: destRectPtr,
angle: sprite.Rotation,
center: sprite.Position.SdlPoint,
flip: sprite.Flip
);
}
}

43
DotSDL/Graphics/Sprite.cs

@ -14,7 +14,18 @@ namespace DotSDL.Graphics {
/// The angle that the sprite is drawn, in degrees. Incrementing this will rotate the
/// sprite clockwise.
/// </summary>
public float Rotation { get; set; }
public double Rotation { get; set; }
/// <summary>
/// The point around which the sprite will be rotated. By default, this will be set to
/// the center of the sprite.
/// </summary>
public Point RotationCenter { get; set; }
/// <summary>
/// Indicates which axes this sprice should be flipped across, if any.
/// </summary>
public FlipDirection Flip { get; set; }
/// <summary>
/// The scale of the <see cref="Sprite"/>. 1.0f is 100%.
@ -58,9 +69,9 @@ namespace DotSDL.Graphics {
/// </summary>
/// <param name="width">The width of the new <see cref="Sprite"/>.</param>
/// <param name="height">The height of the new <see cref="Sprite"/>.</param>
/// <param name="zorder">A value indicating the order in which this <see cref="Sprite"/> is drawn. Higher numbered
/// <param name="zOrder">A value indicating the order in which this <see cref="Sprite"/> is drawn. Higher numbered
/// sprites are drawn on top of other sprites and, thus, will appear above them.</param>
public Sprite(int width, int height, int zorder) : this(width, height, Point.Zero, Vector2.One, zorder) { }
public Sprite(int width, int height, int zOrder) : this(width, height, Point.Zero, Vector2.One, zOrder) { }
/// <summary>
/// Initializes a new <see cref="Sprite"/>.
@ -77,9 +88,21 @@ namespace DotSDL.Graphics {
/// <param name="width">The width of the new <see cref="Sprite"/>.</param>
/// <param name="height">The height of the new <see cref="Sprite"/>.</param>
/// <param name="position">A <see cref="Vector2"/> representing the initial position of the new <see cref="Sprite"/>.</param>
/// <param name="zorder">A value indicating the order in which this <see cref="Sprite"/> is drawn. Higher numbered
/// <param name="zOrder">A value indicating the order in which this <see cref="Sprite"/> is drawn. Higher numbered
/// sprites are drawn on top of other sprites and, thus, will appear above them.</param>
public Sprite(int width, int height, Point position, int zOrder) : this(width, height, position, Vector2.One, 0) { }
/// <summary>
/// Initializes a new <see cref="Sprite"/>.
/// </summary>
/// <param name="width">The width of the new <see cref="Sprite"/>.</param>
/// <param name="height">The height of the new <see cref="Sprite"/>.</param>
/// <param name="position">A <see cref="Vector2"/> representing the initial position of the new <see cref="Sprite"/>.</param>
/// <param name="scale">A <see cref="Vector2"/> representing the initial scaling of the new <see cref="Sprite"/>.</param>
/// <param name="zOrder">A value indicating the order in which this <see cref="Sprite"/> is drawn. Higher numbered
/// sprites are drawn on top of other sprites and, thus, will appear above them.</param>
public Sprite(int width, int height, Point position, int zorder) : this(width, height, position, Vector2.One, 0) { }
public Sprite(int width, int height, Point position, Vector2 scale, int zOrder)
: this(width, height, position, new Rectangle(0, 0, width, height), scale, zOrder) { }
/// <summary>
/// Initializes a new <see cref="Sprite"/>.
@ -88,13 +111,17 @@ namespace DotSDL.Graphics {
/// <param name="height">The height of the new <see cref="Sprite"/>.</param>
/// <param name="position">A <see cref="Vector2"/> representing the initial position of the new <see cref="Sprite"/>.</param>
/// <param name="scale">A <see cref="Vector2"/> representing the initial scaling of the new <see cref="Sprite"/>.</param>
/// <param name="zorder">A value indicating the order in which this <see cref="Sprite"/> is drawn. Higher numbered
/// <param name="clipping">A rectangle specifying which part of this <see cref="Sprite"/> should be drawn.</param>
/// <param name="zOrder">A value indicating the order in which this <see cref="Sprite"/> is drawn. Higher numbered
/// sprites are drawn on top of other sprites and, thus, will appear above them.</param>
public Sprite(int width, int height, Point position, Vector2 scale, int zorder) : base(width, height) {
public Sprite(int width, int height, Point position, Rectangle clipping, Vector2 scale, int zOrder) : base(width, height, clipping) {
Position = position;
Scale = scale;
ZOrder = zorder;
ZOrder = zOrder;
Shown = false;
RotationCenter.X = clipping.Size.X / 2;
RotationCenter.Y = clipping.Size.Y / 2;
}
}
}

26
DotSDL/Interop/Core/Render.cs

@ -1,5 +1,6 @@
using System;
using System.Runtime.InteropServices;
using DotSDL.Graphics;
namespace DotSDL.Interop.Core {
/// <summary>
@ -24,21 +25,6 @@ namespace DotSDL.Interop.Core {
TargetTexture = 0x00000008
}
/// <summary>
/// An enumeration of flags that can be used in the flip parameter for
/// <see cref="RenderCopyEx"/>.
/// </summary>
internal enum RendererFlip : uint {
/// <summary>Do not flip.</summary>
None,
/// <summary>Flip horizontally.</summary>
Horizontal,
/// <summary>Flip vertically.</summary>
Vertical
}
/// <summary>
/// The access pattern allowed for a texture.
/// </summary>
@ -79,7 +65,7 @@ namespace DotSDL.Interop.Core {
/// <summary>
/// Clear the current rendering target with the drawing color.
///
///
/// This function clears the entire rendering target, ignoring the viewport and the clip rectangle.
/// </summary>
/// <param name="renderer">The renderer to clear.</param>
@ -122,9 +108,7 @@ namespace DotSDL.Interop.Core {
/// <param name="flip">A <see cref="RendererFlip"/> value indicating which flipping actions should be performed.</param>
/// <returns>0 on success, or -1 on error.</returns>
[DllImport(Meta.CoreLib, EntryPoint = "SDL_RenderCopyEx", CallingConvention = CallingConvention.Cdecl)]
internal static extern int RenderCopyEx(
IntPtr renderer, IntPtr texture, Rect.SdlRect srcRect, Rect.SdlRect dstRect, double angle, Rect.SdlPoint center,
RendererFlip flip);
internal static extern int RenderCopyEx(IntPtr renderer, IntPtr texture, Rect.SdlRect srcRect, Rect.SdlRect dstRect, double angle, Rect.SdlPoint center, FlipDirection flip);
/// <summary>
/// Copy a portion of the texture to the current rendering target.
@ -139,9 +123,7 @@ namespace DotSDL.Interop.Core {
/// <param name="flip">A <see cref="RendererFlip"/> value indicating which flipping actions should be performed.</param>
/// <returns>0 on success, or -1 on error.</returns>
[DllImport(Meta.CoreLib, EntryPoint = "SDL_RenderCopyEx", CallingConvention = CallingConvention.Cdecl)]
internal static extern int RenderCopyEx(
IntPtr renderer, IntPtr texture, IntPtr srcRect, IntPtr dstRect, double angle, Rect.SdlPoint center,
RendererFlip flip);
internal static extern int RenderCopyEx(IntPtr renderer, IntPtr texture, IntPtr srcRect, IntPtr dstRect, double angle, Rect.SdlPoint center, FlipDirection flip);
/// <summary>
/// Update the screen with the rendering performed.

14
Samples/Sample.Sprites/Window.cs

@ -1,5 +1,6 @@
using DotSDL.Events;
using DotSDL.Graphics;
using DotSDL.Input.Keyboard;
namespace Sample.Sprites {
public class Window : SdlWindow {
@ -11,15 +12,24 @@ namespace Sample.Sprites {
KeyReleased += OnKeyReleased;
}
private void GenerateBackground(ref Color[] pixels) {
for(var i = 0; i < pixels.Length; i++) {
pixels[i].R = 128;
pixels[i].G = 64;
pixels[i].B = 32;
}
}
protected override void OnDraw(ref Canvas canvas) {
GenerateBackground(ref canvas.Pixels);
}
private void OnKeyPressed(object sender, KeyboardEvent e) {
throw new System.NotImplementedException();
if(e.Keycode == Keycode.Escape)
Stop();
}
private void OnKeyReleased(object sender, KeyboardEvent e) {
throw new System.NotImplementedException();
}
protected override void OnUpdate() {

Loading…
Cancel
Save