diff --git a/src/Components/Drawing/Image.bf b/src/Components/Drawing/Image.bf new file mode 100644 index 0000000..4749d0a --- /dev/null +++ b/src/Components/Drawing/Image.bf @@ -0,0 +1,26 @@ +namespace Strawberry +{ + public class Image : Component, IDraw + { + public Texture Texture; + public Point Offset; + public Point Origin; + public float Rotation; + public Vector Scale = .One; + + public this(Texture texture, Point origin = .Zero, Point offset = .Zero) + { + Texture = texture; + Origin = origin; + Offset = offset; + } + + public Point DrawPosition => Entity.Position + Offset - Origin; + + public void Draw() + { + if (Texture != null) + Game.Batcher.Tex(Texture, DrawPosition); + } + } +} diff --git a/src/PlatformLayer/Batcher.bf b/src/PlatformLayer/Batcher.bf index 89cfac5..1185a8b 100644 --- a/src/PlatformLayer/Batcher.bf +++ b/src/PlatformLayer/Batcher.bf @@ -1,4 +1,5 @@ using System.Collections; +using System.Diagnostics; namespace Strawberry { @@ -7,8 +8,9 @@ namespace Strawberry protected List batches = new .() ~ delete _; protected List vertices = new .() ~ delete _; protected List indices = new .() ~ delete _; + private List matrixStack = new .(20) ~ delete _; - public Mat4x4 Matrix; + public Mat4x4 Matrix => matrixStack.Back; public this() { @@ -17,12 +19,30 @@ namespace Strawberry public void Reset() { - Matrix = Game.PlatformLayer.ScreenMatrix; + ClearMatrix(); + batches.Clear(); vertices.Clear(); indices.Clear(); } + public void ClearMatrix() + { + matrixStack.Clear(); + matrixStack.Add(Game.PlatformLayer.ScreenMatrix); + } + + public void PushMatrix(Mat4x4 mat) + { + matrixStack.Add(mat * matrixStack.Back); + } + + public void PopMatrix() + { + Debug.Assert(matrixStack.Count > 0, "Cannot pop the Matrix Stack when it is empty"); + matrixStack.PopBack(); + } + public abstract void Draw(); protected ref Batch GetBatch(BatchModes mode, Texture texture) @@ -71,13 +91,23 @@ namespace Strawberry .Shape(d, color)); } - public void Tex(Texture texture, float x, float y) + public void Tex(Texture texture, Vector pos) { PushQuad(.TextureTint, texture, - .Tex(.(x, y), .(0, 0), Color.White), - .Tex(.(x + texture.Width, y), .(1, 0), Color.White), - .Tex(.(x + texture.Width, y + texture.Height), .(1, 1), Color.White), - .Tex(.(x, y + texture.Height), .(0, 1), Color.White)); + .Tex(.(pos.X, pos.Y), .(0, 0), Color.White), + .Tex(.(pos.X + texture.Width, pos.Y), .(1, 0), Color.White), + .Tex(.(pos.X + texture.Width, pos.Y + texture.Height), .(1, 1), Color.White), + .Tex(.(pos.X, pos.Y + texture.Height), .(0, 1), Color.White)); + } + + public void Tex(Texture texture, Vector pos, Vector origin, Vector scale, float rotation) + { + //TODO! + PushQuad(.TextureTint, texture, + .Tex(.(pos.X, pos.Y), .(0, 0), Color.White), + .Tex(.(pos.X + texture.Width, pos.Y), .(1, 0), Color.White), + .Tex(.(pos.X + texture.Width, pos.Y + texture.Height), .(1, 1), Color.White), + .Tex(.(pos.X, pos.Y + texture.Height), .(0, 1), Color.White)); } } } diff --git a/src/Struct/Point.bf b/src/Struct/Point.bf index 3f3abc9..a8d4587 100644 --- a/src/Struct/Point.bf +++ b/src/Struct/Point.bf @@ -33,19 +33,25 @@ namespace Strawberry } + [Inline] public Point Perpendicular() { return .(-Y, X); } + [Inline] public float Length => Math.Sqrt(LengthSquared); + + [Inline] public int LengthSquared => X * X + Y * Y; + [Inline] public Vector Normalized() { return ((Vector)this).Normalized(); } + [Inline] public override void ToString(String strBuffer) { strBuffer.Set("Point [ "); @@ -55,56 +61,73 @@ namespace Strawberry strBuffer.Append(" ]"); } + [Inline] static public explicit operator Point(Vector a) { return Point((int)a.X, (int)a.Y); } + [Inline] static public implicit operator SDL2.SDL.Point(Point a) { return .((int32)a.X, (int32)a.Y); } + [Inline] static public bool operator==(Point a, Point b) { return a.X == b.X && a.Y == b.Y; } + [Inline] static public Point operator+(Point a, Point b) { return Point(a.X + b.X, a.Y + b.Y); } + [Inline] static public Point operator-(Point a, Point b) { return Point(a.X - b.X, a.Y - b.Y); } + [Inline, Commutable] static public Point operator*(Point a, int b) { return Point(a.X * b, a.Y * b); } + [Inline] static public Point operator*(Point a, Point b) { return Point(a.X * b.X, a.Y * b.Y); } + [Inline] static public Point operator/(Point a, int b) { return Point(a.X / b, a.Y / b); } + [Inline] static public Point operator/(Point a, Point b) { return Point(a.X / b.X, a.Y / b.Y); } + [Inline, Commutable] static public Point operator*(Point a, Facings f) { return .(a.X * (int)f, a.Y); } + [Inline] + static public Point operator-(Point p) + { + return .(-p.X, -p.Y); + } + + [Inline] public int GetHashCode() { return X + 9973 * Y; diff --git a/src/Struct/Vector.bf b/src/Struct/Vector.bf index 633bb7d..0f123b1 100644 --- a/src/Struct/Vector.bf +++ b/src/Struct/Vector.bf @@ -28,11 +28,13 @@ namespace Strawberry Y = y; } + [Inline] public Vector Perpendicular() { return .(-Y, X); } + [Inline] public Vector Normalized() { if (X == 0 && Y == 0) @@ -41,15 +43,31 @@ namespace Strawberry return this / Length; } + [Inline] public float Length => Math.Sqrt(LengthSquared); + + [Inline] public float LengthSquared => X * X + Y * Y; [Inline] public Point Round() { - return Point((int)Math.Round(X), (int)Math.Round(Y)); + return .((int)Math.Round(X), (int)Math.Round(Y)); } + [Inline] + public Vector Transform(Mat3x2 mat) + { + return Transform(this, mat); + } + + [Inline] + public Vector Transform(Mat4x4 mat) + { + return Transform(this, mat); + } + + [Inline] static public Vector Lerp(Vector a, Vector b, float t) { if (t == 0) @@ -60,46 +78,7 @@ namespace Strawberry return a + (b - a) * t; } - public override void ToString(String strBuffer) - { - strBuffer.Set("Vector [ "); - X.ToString(strBuffer); - strBuffer.Append(", "); - Y.ToString(strBuffer); - strBuffer.Append(" ]"); - } - - static public operator Vector(Point a) - { - return Vector(a.X, a.Y); - } - - [Commutable] - static public bool operator==(Vector a, Vector b) - { - return a.X == b.X && a.Y == b.Y; - } - - static public Vector operator+(Vector a, Vector b) - { - return Vector(a.X + b.X, a.Y + b.Y); - } - - static public Vector operator-(Vector a, Vector b) - { - return Vector(a.X - b.X, a.Y - b.Y); - } - - static public Vector operator*(Vector a, float b) - { - return Vector(a.X * b, a.Y * b); - } - - static public Vector operator/(Vector a, float b) - { - return Vector(a.X / b, a.Y / b); - } - + [Inline] static public Vector Approach(Vector value, Vector target, float maxDelta) { Vector diff = target - value; @@ -109,9 +88,92 @@ namespace Strawberry return value + diff.Normalized() * maxDelta; } + [Inline] static public void Approach(Vector* value, Vector target, float maxDelta) { *value = Approach(*value, target, maxDelta); } + + [Inline] + public static Vector Transform(Vector v, Mat3x2 matrix) + { + return .( + v.X * matrix.M11 + v.Y * matrix.M21 + matrix.M31, + v.X * matrix.M12 + v.Y * matrix.M22 + matrix.M32 + ); + } + + [Inline] + public static Vector Transform(Vector v, Mat4x4 matrix) + { + return .( + v.X * matrix.M11 + v.Y * matrix.M21 + matrix.M41, + v.X * matrix.M12 + v.Y * matrix.M22 + matrix.M42 + ); + } + + [Inline] + public override void ToString(String strBuffer) + { + strBuffer.Set("Vector [ "); + X.ToString(strBuffer); + strBuffer.Append(", "); + Y.ToString(strBuffer); + strBuffer.Append(" ]"); + } + + [Inline] + static public operator Vector(Point a) + { + return .(a.X, a.Y); + } + + [Inline] + static public bool operator==(Vector a, Vector b) + { + return a.X == b.X && a.Y == b.Y; + } + + [Inline] + static public Vector operator+(Vector a, Vector b) + { + return .(a.X + b.X, a.Y + b.Y); + } + + [Inline] + static public Vector operator-(Vector a, Vector b) + { + return .(a.X - b.X, a.Y - b.Y); + } + + [Inline, Commutable] + static public Vector operator*(Vector a, float b) + { + return .(a.X * b, a.Y * b); + } + + [Inline] + static public Vector operator/(Vector a, float b) + { + return .(a.X / b, a.Y / b); + } + + [Inline] + static public Vector operator*(Vector a, Mat3x2 b) + { + return Transform(a, b); + } + + [Inline] + static public Vector operator*(Vector a, Mat4x4 b) + { + return Transform(a, b); + } + + [Inline] + static public Vector operator-(Vector v) + { + return .(-v.X, -v.Y); + } } }