You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
194 lines
7.3 KiB
194 lines
7.3 KiB
using DotSDL.Interop.Core; |
|
using SdlPixels = DotSDL.Interop.Core.Pixels; |
|
using System; |
|
|
|
namespace DotSDL.Graphics { |
|
/// <summary> |
|
/// A representation of the contents of the SDL window, with a number of |
|
/// helper routines. |
|
/// </summary> |
|
public class Canvas { |
|
private int _width, _height; |
|
|
|
/// <summary> |
|
/// <c>true</c> if this <see cref="Canvas"/> has an SDL texture associated with it, otherwise <c>false</c>. |
|
/// </summary> |
|
protected bool HasTexture { get; set; } |
|
|
|
/// <summary> |
|
/// The scaling type that should be used to draw this <see cref="Canvas"/>. This field should not be |
|
/// manipulated directly--use <see cref="ScalingQuality"/> instead. |
|
/// </summary> |
|
protected ScalingQuality ScalingQualityValue; |
|
|
|
/// <summary> |
|
/// The SDL_Texture that this <see cref="Canvas"/> maintains. |
|
/// </summary> |
|
internal IntPtr Renderer; |
|
internal IntPtr Texture; |
|
|
|
/// <summary> |
|
/// The raw pixels in the <see cref="Canvas"/>. |
|
/// </summary> |
|
public Color[] Pixels; |
|
|
|
/// <summary> |
|
/// Gets an <see cref="IntPtr"/> that points to what should be displayed on the window's background. This is |
|
/// useful if you're maintaining your own ARGB framebuffer and don't plan to use DotSDL's <see cref="Canvas"/> |
|
/// object. You usually do not need to override this method. |
|
/// </summary> |
|
/// <remarks>If an invalid <see cref="IntPtr"/> is generated by this method, your application may |
|
/// crash with a segmentation fault. When in doubt, override <see cref="OnDraw"/> instead!</remarks> |
|
/// <returns>An <see cref="IntPtr"/> containing the contents of the window's background.</returns> |
|
public Func<IntPtr> GetCanvasPointer; |
|
|
|
/// <summary> |
|
/// Gets or sets the width of the <see cref="Canvas"/> texture. |
|
/// </summary> |
|
public int Width { |
|
get => _width; |
|
set { |
|
if(value <= 0) throw new ArgumentException("Width must be greater than 0."); |
|
|
|
_width = value; |
|
Resize(); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Gets or sets the height of the <see cref="Canvas"/> texture. |
|
/// </summary> |
|
public int Height { |
|
get => _height; |
|
set { |
|
if(value <= 0) throw new ArgumentException("Height must be greater than 0."); |
|
|
|
_height = value; |
|
Resize(); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Determines the method that will be used to scale this sprite when it is plotted to the |
|
/// screen. |
|
/// </summary> |
|
public virtual ScalingQuality ScalingQuality { |
|
get => ScalingQualityValue; |
|
set { |
|
ScalingQualityValue = value; |
|
|
|
if(HasTexture) |
|
CreateTexture(); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Sets the section of the <see cref="Canvas"/> that should be drawn. If the size values are set to 0, the |
|
/// <see cref="Canvas"/> will fill as much of its containing object as possible. |
|
/// </summary> |
|
public Rectangle Clipping { get; set; } |
|
|
|
/// <summary> |
|
/// Initializes a new <see cref="Canvas"/>. |
|
/// </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)) { } |
|
|
|
/// <summary> |
|
/// Initializes a new <see cref="Canvas"/>. |
|
/// </summary> |
|
/// <param name="textureWidth">The width of the <see cref="Canvas"/>.</param> |
|
/// <param name="textureHeight">The height of the <see cref="Canvas"/>.</param> |
|
/// <param name="clipping">The clipping <see cref="Rectangle"/> for the <see cref="Canvas"/>.</param> |
|
internal Canvas(int textureWidth, int textureHeight, Rectangle clipping) { |
|
_width = textureWidth; |
|
_height = textureHeight; |
|
|
|
Clipping = clipping; |
|
|
|
GetCanvasPointer = () => { |
|
unsafe { |
|
fixed(void* pixelPtr = Pixels) { |
|
return (IntPtr)pixelPtr; |
|
} |
|
} |
|
}; |
|
|
|
Resize(); |
|
} |
|
|
|
/// <summary> |
|
/// Creates a texture or recreates it if it already exists. |
|
/// </summary> |
|
internal virtual void CreateTexture() { |
|
CreateTexture(Render.TextureAccess.Streaming); |
|
} |
|
|
|
/// <summary> |
|
/// Creates a texture or recreates it if it already exists. |
|
/// </summary> |
|
/// <param name="textureAccess">The access mode for this texture.</param> |
|
internal void CreateTexture(Render.TextureAccess textureAccess) { |
|
if(Renderer == IntPtr.Zero) return; |
|
|
|
DestroyTexture(); |
|
Hints.SetHint(Hints.RenderScaleQuality, ScalingQuality.ToString()); |
|
Texture = Render.CreateTexture(Renderer, SdlPixels.PixelFormatArgb8888, textureAccess, Width, Height); |
|
HasTexture = true; |
|
|
|
} |
|
|
|
/// <summary> |
|
/// Destroys the texture associated with this <see cref="Sprite"/>. |
|
/// </summary> |
|
internal void DestroyTexture() { |
|
if(!HasTexture) return; |
|
|
|
Render.DestroyTexture(Texture); |
|
HasTexture = false; |
|
} |
|
|
|
/// <summary> |
|
/// Retrieves an array index on the <see cref="Canvas"/>. |
|
/// </summary> |
|
/// <param name="x">The Y coordinate of the desired location on the <see cref="Canvas"/>.</param> |
|
/// <param name="y">The Y coordinate of the desired location on the <see cref="Canvas"/>.</param> |
|
/// <returns>The array index for the given point.</returns> |
|
public int GetIndex(int x, int y) { |
|
return (Width * y) + x; |
|
} |
|
|
|
/// <summary> |
|
/// Retrieves an array index on the <see cref="Canvas"/>. |
|
/// </summary> |
|
/// <param name="point">A <see cref="Point"/> representing the desired location on the <see cref="Canvas"/>.</param> |
|
/// <returns>The array index for the given point.</returns> |
|
public int GetIndex(Point point) { |
|
return (Width * point.Y) + point.X; |
|
} |
|
|
|
/// <summary> |
|
/// Resizes the <see cref="Canvas"/>. Please note that this will also clear the canvas of |
|
/// its existing contents. |
|
/// </summary> |
|
protected void Resize() { |
|
Pixels = new Color[Width * Height]; |
|
|
|
if(HasTexture) |
|
CreateTexture(); |
|
} |
|
|
|
/// <summary> |
|
/// Updates the texture associated with this <see cref="Canvas"/>. This function must be called when the |
|
/// <see cref="Canvas.Pixels"/> array is changed. |
|
/// </summary> |
|
/// <returns><c>true</c> if the texture was successfully updated, otherwise <c>false</c>. This will return <c>false</c> if this <see cref="Sprite"/> hasn't been added to the sprite list.</returns> |
|
internal bool UpdateTexture() { |
|
if(!HasTexture) return false; |
|
Render.UpdateTexture(Texture, IntPtr.Zero, GetCanvasPointer(), Width * 4); |
|
return true; |
|
} |
|
} |
|
}
|
|
|