mirror of
				https://github.com/MaddyThorson/StrawberryBF.git
				synced 2025-11-04 01:41:33 +08:00 
			
		
		
		
	OpenGL rendering hooked up. Better platform layer abstraction
This commit is contained in:
		@ -423,7 +423,7 @@ namespace Strawberry
 | 
			
		||||
 | 
			
		||||
		public void DrawHitbox(Color color)
 | 
			
		||||
		{
 | 
			
		||||
			Draw.Rect(SceneHitbox, color);
 | 
			
		||||
			Game.Batcher.Rect(SceneHitbox, color);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static public int Compare(Entity a, Entity b)
 | 
			
		||||
 | 
			
		||||
@ -29,7 +29,8 @@ namespace Strawberry
 | 
			
		||||
		private Dictionary<Type, List<Type>> componentAssignableLists;
 | 
			
		||||
 | 
			
		||||
		public PlatformLayer PlatformLayer { get; private set; }
 | 
			
		||||
		public Color ClearColor = .Red;
 | 
			
		||||
		public Batcher Batcher { get; private set; }
 | 
			
		||||
		public Color ClearColor = .Black;
 | 
			
		||||
 | 
			
		||||
		private bool* keyboardState;
 | 
			
		||||
		private int32 updateCounter;
 | 
			
		||||
@ -53,6 +54,7 @@ namespace Strawberry
 | 
			
		||||
			Directory.SetCurrentDirectory(exeDir);
 | 
			
		||||
 | 
			
		||||
			platformLayer.Init();
 | 
			
		||||
			Batcher = platformLayer.CreateBatcher();
 | 
			
		||||
 | 
			
		||||
			VirtualInputs = new List<VirtualInput>();
 | 
			
		||||
			Input.[Friend]Init();
 | 
			
		||||
@ -83,6 +85,9 @@ namespace Strawberry
 | 
			
		||||
			DisposeTypeLists();
 | 
			
		||||
			Input.[Friend]Dispose();
 | 
			
		||||
			Strawberry.Console.Dispose();
 | 
			
		||||
 | 
			
		||||
			delete Batcher;
 | 
			
		||||
 | 
			
		||||
			Game = null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -97,7 +102,6 @@ namespace Strawberry
 | 
			
		||||
 | 
			
		||||
				uint32 tick = PlatformLayer.Ticks;
 | 
			
		||||
				msCounter += (tick - prevTick);
 | 
			
		||||
				prevTick = tick;
 | 
			
		||||
 | 
			
		||||
				if (Time.FixedTimestep)
 | 
			
		||||
				{
 | 
			
		||||
@ -112,13 +116,14 @@ namespace Strawberry
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					Time.RawDelta = msCounter / 1000;
 | 
			
		||||
					Time.RawDelta = (tick - prevTick) / 1000f;
 | 
			
		||||
					PlatformLayer.UpdateInput();
 | 
			
		||||
					Update();
 | 
			
		||||
					Input.AfterUpdate();
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				Render();
 | 
			
		||||
				prevTick = tick;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -157,21 +162,18 @@ namespace Strawberry
 | 
			
		||||
		private void Render()
 | 
			
		||||
		{
 | 
			
		||||
			PlatformLayer.RenderBegin();
 | 
			
		||||
			//Draw();
 | 
			
		||||
			Draw();
 | 
			
		||||
			PlatformLayer.RenderEnd();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public virtual void Draw()
 | 
			
		||||
		{
 | 
			
		||||
			if (Scene != null)
 | 
			
		||||
			{
 | 
			
		||||
				Draw.PushCamera(Scene.Camera.Round());
 | 
			
		||||
				Scene.Draw();
 | 
			
		||||
				Draw.PopCamera();
 | 
			
		||||
			}
 | 
			
		||||
			Scene?.Draw();
 | 
			
		||||
 | 
			
		||||
			if (Console.Enabled)
 | 
			
		||||
				Strawberry.Console.[Friend]Draw();
 | 
			
		||||
 | 
			
		||||
			Batcher.Draw();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public Scene Scene
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,6 @@ namespace Strawberry
 | 
			
		||||
		public float TimeStarted { get; private set; }
 | 
			
		||||
		public Grid SolidGrid;
 | 
			
		||||
		public Rect Bounds;
 | 
			
		||||
		public Vector Camera;
 | 
			
		||||
 | 
			
		||||
		private List<Entity> entities;
 | 
			
		||||
		private HashSet<Entity> toRemove;
 | 
			
		||||
 | 
			
		||||
@ -173,7 +173,7 @@ namespace Strawberry
 | 
			
		||||
			for (let x < CellsX)
 | 
			
		||||
				for (let y < CellsY)
 | 
			
		||||
					if (this[x, y] != '0')
 | 
			
		||||
						Draw.Rect(Rect(x, y, 1, 1) * CellSize + Offset, color);
 | 
			
		||||
						Game.Batcher.Rect(Rect(x, y, 1, 1) * CellSize + Offset, color);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -88,7 +88,7 @@ namespace Strawberry
 | 
			
		||||
 | 
			
		||||
		public override void Draw()
 | 
			
		||||
		{
 | 
			
		||||
			DrawHitbox(.(255, 255, 255, 255));
 | 
			
		||||
			DrawHitbox(.White);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,110 +1,20 @@
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace Strawberry
 | 
			
		||||
{
 | 
			
		||||
	public class Batcher
 | 
			
		||||
	public abstract class Batcher
 | 
			
		||||
	{
 | 
			
		||||
		static public int VertexSize => sizeof(Vertex);
 | 
			
		||||
		public abstract void Draw();
 | 
			
		||||
 | 
			
		||||
		private List<Batch> batchStack = new List<Batch>() ~ DeleteContainerAndItems!(_); 
 | 
			
		||||
		private Batch top => batchStack.Count > 0 ? batchStack[batchStack.Count - 1] : null;
 | 
			
		||||
		protected abstract void PushQuad(Vertex a, Vertex b, Vertex c, Vertex d);
 | 
			
		||||
		protected abstract void PushTri(Vertex a, Vertex b, Vertex c);
 | 
			
		||||
 | 
			
		||||
		private List<Vertex> vertices = new .() ~ delete _;
 | 
			
		||||
		private List<uint32> indices = new .() ~ delete _;
 | 
			
		||||
 | 
			
		||||
		private uint32 vaoID;
 | 
			
		||||
		private uint32 vertexBufferID;
 | 
			
		||||
		private uint32 indexBufferID;
 | 
			
		||||
 | 
			
		||||
		public this()
 | 
			
		||||
		public void Rect(float x, float y, float w, float h, Color color)
 | 
			
		||||
		{
 | 
			
		||||
			GL.glGenVertexArrays(1, &vaoID);
 | 
			
		||||
			GL.glBindVertexArray(vaoID);
 | 
			
		||||
			GL.glGenBuffers(1, &vertexBufferID);
 | 
			
		||||
			GL.glGenBuffers(1, &indexBufferID);
 | 
			
		||||
			GL.glBindVertexArray(0);
 | 
			
		||||
			PushQuad(.Shape(.(x, y), color), .Shape(.(x + w, y), color), .Shape(.(x + w, y + h), color), .Shape(.(x, y + h), color)); 
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public ~this()
 | 
			
		||||
		public void Rect(Rect rect, Color color)
 | 
			
		||||
		{
 | 
			
		||||
			GL.glDeleteBuffers(1, &vertexBufferID);
 | 
			
		||||
			GL.glDeleteBuffers(1, &indexBufferID);
 | 
			
		||||
			GL.glDeleteVertexArrays(1, &vaoID);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void Draw()
 | 
			
		||||
		{
 | 
			
		||||
			GL.glDisable(GL.GL_CULL_FACE);
 | 
			
		||||
 | 
			
		||||
			GL.glBindVertexArray(vaoID);
 | 
			
		||||
 | 
			
		||||
			GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vertexBufferID);
 | 
			
		||||
			GL.glEnableVertexAttribArray(0);
 | 
			
		||||
			GL.glVertexAttribPointer(0, 2, GL.GL_FLOAT, GL.GL_FALSE, Batcher.VertexSize, (void*)0);
 | 
			
		||||
			GL.glEnableVertexAttribArray(1);
 | 
			
		||||
			GL.glVertexAttribPointer(1, 2, GL.GL_FLOAT, GL.GL_FALSE, Batcher.VertexSize, (void*)8);
 | 
			
		||||
			GL.glEnableVertexAttribArray(2);
 | 
			
		||||
			GL.glVertexAttribPointer(2, 4, GL.GL_UNSIGNED_BYTE, GL.GL_TRUE, Batcher.VertexSize, (void*)16);
 | 
			
		||||
			GL.glEnableVertexAttribArray(3);
 | 
			
		||||
			GL.glVertexAttribPointer(3, 3, GL.GL_UNSIGNED_BYTE, GL.GL_TRUE, Batcher.VertexSize, (void*)20);
 | 
			
		||||
			GL.glBufferData(GL.GL_ARRAY_BUFFER, vertices.Count * sizeof(Vertex), vertices.Ptr, GL.GL_DYNAMIC_DRAW);
 | 
			
		||||
 | 
			
		||||
			GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
 | 
			
		||||
			GL.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, indices.Count * sizeof(uint32), indices.Ptr, GL.GL_DYNAMIC_DRAW);
 | 
			
		||||
 | 
			
		||||
			GL.glDrawElements(GL.GL_TRIANGLES, indices.Count, GL.GL_UNSIGNED_INT, (void*)0);
 | 
			
		||||
			GL.glBindVertexArray(0);
 | 
			
		||||
 | 
			
		||||
			vertices.Clear();
 | 
			
		||||
			indices.Clear();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void PushQuad(Vector a, Vector b, Vector c, Vector d, Color color)
 | 
			
		||||
		{
 | 
			
		||||
			uint32 count = (uint32)vertices.Count;
 | 
			
		||||
 | 
			
		||||
			vertices.Add(Vertex.Shape(a, color));
 | 
			
		||||
			vertices.Add(Vertex.Shape(b, color));
 | 
			
		||||
			vertices.Add(Vertex.Shape(c, color));
 | 
			
		||||
			vertices.Add(Vertex.Shape(d, color));
 | 
			
		||||
 | 
			
		||||
			indices.Add(count + 0);
 | 
			
		||||
			indices.Add(count + 1);
 | 
			
		||||
			indices.Add(count + 2);
 | 
			
		||||
			indices.Add(count + 0);
 | 
			
		||||
			indices.Add(count + 2);
 | 
			
		||||
			indices.Add(count + 3);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private class Batch
 | 
			
		||||
		{
 | 
			
		||||
			uint32 bufferHandle;
 | 
			
		||||
 | 
			
		||||
			public this()
 | 
			
		||||
			{
 | 
			
		||||
				//GL.glGenBuffers(1, &bufferHandle);
 | 
			
		||||
				//GL.glBindBuffer(GL.GL_ARRAY_BUFFER, bufferHandle);
 | 
			
		||||
				//GL.glDeleteBuffers(1, &bufferHandle);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		[Ordered, Packed, CRepr]
 | 
			
		||||
		private struct Vertex
 | 
			
		||||
		{
 | 
			
		||||
			public Vector Position;
 | 
			
		||||
			public Vector TexCoord;
 | 
			
		||||
			public Color Color;
 | 
			
		||||
			public (uint8, uint8, uint8) Mode;
 | 
			
		||||
 | 
			
		||||
			static public Vertex Shape(Vector pos, Color color)
 | 
			
		||||
			{
 | 
			
		||||
				Vertex v = Vertex();
 | 
			
		||||
				v.Position = pos;
 | 
			
		||||
				v.Color = color;
 | 
			
		||||
				v.Mode = (0, 0, 255);
 | 
			
		||||
				return v;
 | 
			
		||||
			}
 | 
			
		||||
			Rect(rect.X, rect.Y, rect.Width, rect.Height, color);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -23,50 +23,7 @@ namespace Strawberry
 | 
			
		||||
 | 
			
		||||
		//Graphics
 | 
			
		||||
		public abstract Texture LoadTexture(String path);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public abstract class Texture
 | 
			
		||||
	{
 | 
			
		||||
		public int Width { get; private set; }
 | 
			
		||||
		public int Height { get; private set; }
 | 
			
		||||
 | 
			
		||||
		public virtual this(int width, int height, uint8* pixels)
 | 
			
		||||
		{
 | 
			
		||||
			Width = width;
 | 
			
		||||
			Height = height;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public abstract class Shader
 | 
			
		||||
	{
 | 
			
		||||
		public bool IsValid { get; protected set; }
 | 
			
		||||
 | 
			
		||||
		public this(ShaderDef def)
 | 
			
		||||
		{
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public struct ShaderDef
 | 
			
		||||
	{
 | 
			
		||||
		public String Vertex;
 | 
			
		||||
		public String Fragment;
 | 
			
		||||
 | 
			
		||||
		public this(String vertex, String fragment)
 | 
			
		||||
		{
 | 
			
		||||
			Vertex = vertex;
 | 
			
		||||
			Fragment = fragment;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public this(String[2] str)
 | 
			
		||||
		{
 | 
			
		||||
			Vertex = str[0];
 | 
			
		||||
			Fragment = str[1];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static implicit public operator ShaderDef(String[2] str)
 | 
			
		||||
		{
 | 
			
		||||
			return ShaderDef(str);
 | 
			
		||||
		}
 | 
			
		||||
		public abstract Batcher CreateBatcher();
 | 
			
		||||
		public abstract Shader CreateShader(ShaderDef def);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										88
									
								
								src/PlatformLayer/SDL2/SDL2Batcher.bf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								src/PlatformLayer/SDL2/SDL2Batcher.bf
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,88 @@
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace Strawberry.SDL2
 | 
			
		||||
{
 | 
			
		||||
	public class SDL2Batcher : Batcher
 | 
			
		||||
	{
 | 
			
		||||
		private List<Vertex> vertices = new .() ~ delete _;
 | 
			
		||||
		private List<uint32> indices = new .() ~ delete _;
 | 
			
		||||
 | 
			
		||||
		private uint32 vaoID;
 | 
			
		||||
		private uint32 vertexBufferID;
 | 
			
		||||
		private uint32 indexBufferID;
 | 
			
		||||
 | 
			
		||||
		public this()
 | 
			
		||||
		{
 | 
			
		||||
			GL.glGenVertexArrays(1, &vaoID);
 | 
			
		||||
			GL.glBindVertexArray(vaoID);
 | 
			
		||||
			GL.glGenBuffers(1, &vertexBufferID);
 | 
			
		||||
			GL.glGenBuffers(1, &indexBufferID);
 | 
			
		||||
			GL.glBindVertexArray(0);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public ~this()
 | 
			
		||||
		{
 | 
			
		||||
			GL.glDeleteBuffers(1, &vertexBufferID);
 | 
			
		||||
			GL.glDeleteBuffers(1, &indexBufferID);
 | 
			
		||||
			GL.glDeleteVertexArrays(1, &vaoID);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override void Draw()
 | 
			
		||||
		{
 | 
			
		||||
			GL.glDisable(GL.GL_CULL_FACE);
 | 
			
		||||
 | 
			
		||||
			GL.glBindVertexArray(vaoID);
 | 
			
		||||
 | 
			
		||||
			GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vertexBufferID);
 | 
			
		||||
			GL.glEnableVertexAttribArray(0);
 | 
			
		||||
			GL.glVertexAttribPointer(0, 2, GL.GL_FLOAT, GL.GL_FALSE, sizeof(Vertex), (void*)0);
 | 
			
		||||
			GL.glEnableVertexAttribArray(1);
 | 
			
		||||
			GL.glVertexAttribPointer(1, 2, GL.GL_FLOAT, GL.GL_FALSE, sizeof(Vertex), (void*)8);
 | 
			
		||||
			GL.glEnableVertexAttribArray(2);
 | 
			
		||||
			GL.glVertexAttribPointer(2, 4, GL.GL_UNSIGNED_BYTE, GL.GL_TRUE, sizeof(Vertex), (void*)16);
 | 
			
		||||
			GL.glEnableVertexAttribArray(3);
 | 
			
		||||
			GL.glVertexAttribPointer(3, 3, GL.GL_UNSIGNED_BYTE, GL.GL_TRUE, sizeof(Vertex), (void*)20);
 | 
			
		||||
			GL.glBufferData(GL.GL_ARRAY_BUFFER, vertices.Count * sizeof(Vertex), vertices.Ptr, GL.GL_DYNAMIC_DRAW);
 | 
			
		||||
 | 
			
		||||
			GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
 | 
			
		||||
			GL.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, indices.Count * sizeof(uint32), indices.Ptr, GL.GL_DYNAMIC_DRAW);
 | 
			
		||||
 | 
			
		||||
			GL.glDrawElements(GL.GL_TRIANGLES, indices.Count, GL.GL_UNSIGNED_INT, (void*)0);
 | 
			
		||||
			GL.glBindVertexArray(0);
 | 
			
		||||
 | 
			
		||||
			vertices.Clear();
 | 
			
		||||
			indices.Clear();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		protected override void PushQuad(Vertex a, Vertex b, Vertex c, Vertex d)
 | 
			
		||||
		{
 | 
			
		||||
			uint32 count = (uint32)vertices.Count;
 | 
			
		||||
 | 
			
		||||
			vertices.Add(a);
 | 
			
		||||
			vertices.Add(b);
 | 
			
		||||
			vertices.Add(c);
 | 
			
		||||
			vertices.Add(d);
 | 
			
		||||
 | 
			
		||||
			indices.Add(count + 0);
 | 
			
		||||
			indices.Add(count + 1);
 | 
			
		||||
			indices.Add(count + 2);
 | 
			
		||||
			indices.Add(count + 0);
 | 
			
		||||
			indices.Add(count + 2);
 | 
			
		||||
			indices.Add(count + 3);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		protected override void PushTri(Vertex a, Vertex b, Vertex c)
 | 
			
		||||
		{
 | 
			
		||||
			uint32 count = (uint32)vertices.Count;
 | 
			
		||||
 | 
			
		||||
			vertices.Add(a);
 | 
			
		||||
			vertices.Add(b);
 | 
			
		||||
			vertices.Add(c);
 | 
			
		||||
 | 
			
		||||
			indices.Add(count + 0);
 | 
			
		||||
			indices.Add(count + 1);
 | 
			
		||||
			indices.Add(count + 2);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -2,7 +2,7 @@ using SDL2;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
namespace Strawberry
 | 
			
		||||
namespace Strawberry.SDL2
 | 
			
		||||
{
 | 
			
		||||
	public class SDL2PlatformLayer : PlatformLayer
 | 
			
		||||
	{
 | 
			
		||||
@ -118,11 +118,6 @@ namespace Strawberry
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static void* SdlGetProcAddress(StringView string)
 | 
			
		||||
		{
 | 
			
		||||
			return SDL.SDL_GL_GetProcAddress(string.ToScopeCStr!());
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public ~this()
 | 
			
		||||
		{
 | 
			
		||||
			delete gamepads;
 | 
			
		||||
@ -134,6 +129,11 @@ namespace Strawberry
 | 
			
		||||
			SDL.Quit();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static void* SdlGetProcAddress(StringView string)
 | 
			
		||||
		{
 | 
			
		||||
			return SDL.SDL_GL_GetProcAddress(string.ToScopeCStr!());
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override bool Closed()
 | 
			
		||||
		{
 | 
			
		||||
			SDL.Event event;
 | 
			
		||||
@ -149,21 +149,12 @@ namespace Strawberry
 | 
			
		||||
			GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
 | 
			
		||||
			GL.glUseProgram(glProgram);
 | 
			
		||||
 | 
			
		||||
			float zNearPlane = 0;
 | 
			
		||||
			float zFarPlane = 1000;
 | 
			
		||||
 | 
			
		||||
			float[16] mat =
 | 
			
		||||
				.(2.0f / Game.Width, 0, 0, 0,
 | 
			
		||||
				0, 2.0f / Game.Height, 0, 0,
 | 
			
		||||
				0, 0, 1.0f / (zNearPlane - zFarPlane), zNearPlane / (zNearPlane - zFarPlane),
 | 
			
		||||
				0, 0, 0, 1);
 | 
			
		||||
			Mat4x4 mat = Mat4x4.CreateOrthographic(Game.Width, Game.Height * 0.5f, 0, 1);
 | 
			
		||||
			mat *= Mat4x4.CreateScale(.(1, -1, 1));
 | 
			
		||||
			mat *= Mat4x4.CreateTranslation(.(-1, 1, 0));
 | 
			
		||||
 | 
			
		||||
			let loc = GL.glGetUniformLocation(glProgram, "u_matrix");
 | 
			
		||||
			GL.glUniformMatrix4fv(loc, 1, GL.GL_FALSE, &mat);
 | 
			
		||||
 | 
			
		||||
			Batcher b = scope Batcher();
 | 
			
		||||
			b.PushQuad(.(-40, -40), .(40, -40), .(40, 40), .(-40, 40), .Yellow);
 | 
			
		||||
			b.Draw();
 | 
			
		||||
			GL.glUniformMatrix4fv(loc, 1, GL.GL_FALSE, &mat.Values);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override void RenderEnd()
 | 
			
		||||
@ -219,73 +210,15 @@ namespace Strawberry
 | 
			
		||||
			else
 | 
			
		||||
				return val / 32768f;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	class SDL2Texture : Texture
 | 
			
		||||
	{
 | 
			
		||||
		private uint32 handle;
 | 
			
		||||
 | 
			
		||||
		public this(int width, int height, uint8* pixels)
 | 
			
		||||
			: base(width, height, pixels)
 | 
			
		||||
		public override Batcher CreateBatcher()
 | 
			
		||||
		{
 | 
			
		||||
			GL.glGenTextures(1, &handle);
 | 
			
		||||
			GL.glBindTexture(GL.GL_TEXTURE_2D, handle);
 | 
			
		||||
			GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, width, height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, pixels);
 | 
			
		||||
			return new SDL2Batcher();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public ~this()
 | 
			
		||||
		public override Shader CreateShader(ShaderDef def)
 | 
			
		||||
		{
 | 
			
		||||
			GL.glDeleteTextures(1, &handle);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	class SDL2Shader : Shader
 | 
			
		||||
	{
 | 
			
		||||
		public uint vertexHandle;
 | 
			
		||||
		public uint fragmentHandle;
 | 
			
		||||
 | 
			
		||||
		public this(ShaderDef def)
 | 
			
		||||
			: base(def)
 | 
			
		||||
		{
 | 
			
		||||
			IsValid = true;
 | 
			
		||||
			int32 logLen = 0;
 | 
			
		||||
			char8[1024] log;
 | 
			
		||||
 | 
			
		||||
			vertexHandle = GL.glCreateShader(GL.GL_VERTEX_SHADER);
 | 
			
		||||
			{
 | 
			
		||||
				int32 len = (int32)def.Vertex.Length;
 | 
			
		||||
				char8* data = def.Vertex.CStr();
 | 
			
		||||
				GL.glShaderSource(vertexHandle, 1, &data, &len);
 | 
			
		||||
				GL.glCompileShader(vertexHandle);
 | 
			
		||||
				GL.glGetShaderInfoLog(vertexHandle, 1024, &logLen, &log);
 | 
			
		||||
 | 
			
		||||
				if (logLen > 0)
 | 
			
		||||
				{
 | 
			
		||||
					Calc.Log(&log, logLen);
 | 
			
		||||
					IsValid = false;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			fragmentHandle = GL.glCreateShader(GL.GL_FRAGMENT_SHADER);
 | 
			
		||||
			{
 | 
			
		||||
				int32 len = (int32)def.Fragment.Length;
 | 
			
		||||
				char8* data = def.Fragment.CStr();
 | 
			
		||||
				GL.glShaderSource(fragmentHandle, 1, &data, &len);
 | 
			
		||||
				GL.glCompileShader(fragmentHandle);
 | 
			
		||||
				GL.glGetShaderInfoLog(fragmentHandle, 1024, &logLen, &log);
 | 
			
		||||
 | 
			
		||||
				if (logLen > 0)
 | 
			
		||||
				{
 | 
			
		||||
					Calc.Log(&log, logLen);
 | 
			
		||||
					IsValid = false;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public ~this()
 | 
			
		||||
		{
 | 
			
		||||
			GL.glDeleteShader(vertexHandle);
 | 
			
		||||
			GL.glDeleteShader(fragmentHandle);
 | 
			
		||||
			return new SDL2Shader(def);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										52
									
								
								src/PlatformLayer/SDL2/SDL2Shader.bf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/PlatformLayer/SDL2/SDL2Shader.bf
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,52 @@
 | 
			
		||||
namespace Strawberry.SDL2
 | 
			
		||||
{
 | 
			
		||||
	class SDL2Shader : Shader
 | 
			
		||||
	{
 | 
			
		||||
		public uint vertexHandle;
 | 
			
		||||
		public uint fragmentHandle;
 | 
			
		||||
 | 
			
		||||
		public this(ShaderDef def)
 | 
			
		||||
			: base(def)
 | 
			
		||||
		{
 | 
			
		||||
			IsValid = true;
 | 
			
		||||
			int32 logLen = 0;
 | 
			
		||||
			char8[1024] log;
 | 
			
		||||
 | 
			
		||||
			vertexHandle = GL.glCreateShader(GL.GL_VERTEX_SHADER);
 | 
			
		||||
			{
 | 
			
		||||
				int32 len = (int32)def.Vertex.Length;
 | 
			
		||||
				char8* data = def.Vertex.CStr();
 | 
			
		||||
				GL.glShaderSource(vertexHandle, 1, &data, &len);
 | 
			
		||||
				GL.glCompileShader(vertexHandle);
 | 
			
		||||
				GL.glGetShaderInfoLog(vertexHandle, 1024, &logLen, &log);
 | 
			
		||||
 | 
			
		||||
				if (logLen > 0)
 | 
			
		||||
				{
 | 
			
		||||
					Calc.Log(&log, logLen);
 | 
			
		||||
					IsValid = false;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			fragmentHandle = GL.glCreateShader(GL.GL_FRAGMENT_SHADER);
 | 
			
		||||
			{
 | 
			
		||||
				int32 len = (int32)def.Fragment.Length;
 | 
			
		||||
				char8* data = def.Fragment.CStr();
 | 
			
		||||
				GL.glShaderSource(fragmentHandle, 1, &data, &len);
 | 
			
		||||
				GL.glCompileShader(fragmentHandle);
 | 
			
		||||
				GL.glGetShaderInfoLog(fragmentHandle, 1024, &logLen, &log);
 | 
			
		||||
 | 
			
		||||
				if (logLen > 0)
 | 
			
		||||
				{
 | 
			
		||||
					Calc.Log(&log, logLen);
 | 
			
		||||
					IsValid = false;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public ~this()
 | 
			
		||||
		{
 | 
			
		||||
			GL.glDeleteShader(vertexHandle);
 | 
			
		||||
			GL.glDeleteShader(fragmentHandle);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								src/PlatformLayer/SDL2/SDL2Texture.bf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/PlatformLayer/SDL2/SDL2Texture.bf
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
namespace Strawberry.SDL2
 | 
			
		||||
{
 | 
			
		||||
	class SDL2Texture : Texture
 | 
			
		||||
	{
 | 
			
		||||
		private uint32 handle;
 | 
			
		||||
 | 
			
		||||
		public this(int width, int height, uint8* pixels)
 | 
			
		||||
			: base(width, height, pixels)
 | 
			
		||||
		{
 | 
			
		||||
			GL.glGenTextures(1, &handle);
 | 
			
		||||
			GL.glBindTexture(GL.GL_TEXTURE_2D, handle);
 | 
			
		||||
			GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, width, height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, pixels);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public ~this()
 | 
			
		||||
		{
 | 
			
		||||
			GL.glDeleteTextures(1, &handle);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								src/PlatformLayer/Shader.bf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/PlatformLayer/Shader.bf
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
namespace Strawberry
 | 
			
		||||
{
 | 
			
		||||
	public abstract class Shader
 | 
			
		||||
	{
 | 
			
		||||
		public bool IsValid { get; protected set; }
 | 
			
		||||
 | 
			
		||||
		public this(ShaderDef def)
 | 
			
		||||
		{
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								src/PlatformLayer/ShaderDef.bf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/PlatformLayer/ShaderDef.bf
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,27 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace Strawberry
 | 
			
		||||
{
 | 
			
		||||
	public struct ShaderDef
 | 
			
		||||
	{
 | 
			
		||||
		public String Vertex;
 | 
			
		||||
		public String Fragment;
 | 
			
		||||
 | 
			
		||||
		public this(String vertex, String fragment)
 | 
			
		||||
		{
 | 
			
		||||
			Vertex = vertex;
 | 
			
		||||
			Fragment = fragment;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public this(String[2] str)
 | 
			
		||||
		{
 | 
			
		||||
			Vertex = str[0];
 | 
			
		||||
			Fragment = str[1];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static implicit public operator ShaderDef(String[2] str)
 | 
			
		||||
		{
 | 
			
		||||
			return ShaderDef(str);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								src/PlatformLayer/Texture.bf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/PlatformLayer/Texture.bf
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
			
		||||
namespace Strawberry
 | 
			
		||||
{
 | 
			
		||||
	public abstract class Texture
 | 
			
		||||
	{
 | 
			
		||||
		public int Width { get; private set; }
 | 
			
		||||
		public int Height { get; private set; }
 | 
			
		||||
 | 
			
		||||
		public virtual this(int width, int height, uint8* pixels)
 | 
			
		||||
		{
 | 
			
		||||
			Width = width;
 | 
			
		||||
			Height = height;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								src/PlatformLayer/Vertex.bf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/PlatformLayer/Vertex.bf
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace Strawberry
 | 
			
		||||
{
 | 
			
		||||
	[Ordered, Packed, CRepr]
 | 
			
		||||
	public struct Vertex
 | 
			
		||||
	{
 | 
			
		||||
		public Vector Position;
 | 
			
		||||
		public Vector TexCoord;
 | 
			
		||||
		public Color Color;
 | 
			
		||||
		public (uint8, uint8, uint8) Mode;
 | 
			
		||||
 | 
			
		||||
		static public Vertex Shape(Vector pos, Color color)
 | 
			
		||||
		{
 | 
			
		||||
			Vertex v = Vertex();
 | 
			
		||||
			v.Position = pos;
 | 
			
		||||
			v.Color = color;
 | 
			
		||||
			v.Mode = (0, 0, 255);
 | 
			
		||||
			return v;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -147,8 +147,8 @@ namespace Strawberry
 | 
			
		||||
		{
 | 
			
		||||
			if (enabled && Open)
 | 
			
		||||
			{
 | 
			
		||||
				Draw.Rect(0, 0, Game.Width, Game.Height, .Black * 0.6f);
 | 
			
		||||
				Draw.Rect(0, Game.Height - 14, Game.Width, 14, .Black * 0.6f);
 | 
			
		||||
				Game.Batcher.Rect(0, 0, Game.Width, Game.Height, .Black * 0.6f);
 | 
			
		||||
				Game.Batcher.Rect(0, Game.Height - 14, Game.Width, 14, .Black * 0.6f);
 | 
			
		||||
 | 
			
		||||
				//Entry
 | 
			
		||||
				if (entry.Length > 0)
 | 
			
		||||
@ -168,8 +168,8 @@ namespace Strawberry
 | 
			
		||||
			if (row > 0)
 | 
			
		||||
				pos.Y -= 4;
 | 
			
		||||
 | 
			
		||||
			Draw.Text(font, str, pos + .Down, .Black);
 | 
			
		||||
			Draw.Text(font, str, pos, color);
 | 
			
		||||
			//Draw.Text(font, str, pos + .Down, .Black);
 | 
			
		||||
			//Draw.Text(font, str, pos, color);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static private int MessageRows => (int)Math.Ceiling((Game.Height - 14) / 10f);
 | 
			
		||||
 | 
			
		||||
@ -1,161 +0,0 @@
 | 
			
		||||
using SDL2;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
 | 
			
		||||
namespace Strawberry
 | 
			
		||||
{
 | 
			
		||||
	static public class Draw
 | 
			
		||||
	{
 | 
			
		||||
		static public Point Camera => cameraStack.Count > 0 ? cameraStack.Back : Point.Zero;
 | 
			
		||||
 | 
			
		||||
		static private List<Point> cameraStack = new List<Point>() ~ delete _;
 | 
			
		||||
 | 
			
		||||
		static public void PushCamera(Point camera, bool relative = true)
 | 
			
		||||
		{
 | 
			
		||||
			if (relative)
 | 
			
		||||
				cameraStack.Add(Camera + camera);
 | 
			
		||||
			else
 | 
			
		||||
				cameraStack.Add(camera);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static public void PopCamera()
 | 
			
		||||
		{
 | 
			
		||||
			if (cameraStack.Count == 0)
 | 
			
		||||
				Runtime.FatalError("Cannot Pop empty Camera Stack!");
 | 
			
		||||
			cameraStack.PopBack();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static public void Rect(int x, int y, int w, int h, Color color)
 | 
			
		||||
		{
 | 
			
		||||
			//SDL.SetRenderDrawBlendMode(Game.Renderer, .Blend);
 | 
			
		||||
			//SDL.SetRenderDrawColor(Game.Renderer, color.R, color.G, color.B, color.A);
 | 
			
		||||
			//SDL.RenderFillRect(Game.Renderer, &SDL.Rect((int32)(x - Camera.X), (int32)(y - Camera.Y), (int32)w, (int32)h));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static public void Rect(Rect rect, Color color)
 | 
			
		||||
		{
 | 
			
		||||
			Rect(rect.X, rect.Y, rect.Width, rect.Height, color);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static public void HollowRect(int x, int y, int w, int h, Color color)
 | 
			
		||||
		{
 | 
			
		||||
			//SDL.SetRenderDrawBlendMode(Game.Renderer, .Blend);
 | 
			
		||||
			//SDL.SetRenderDrawColor(Game.Renderer, color.R, color.G, color.B, color.A);
 | 
			
		||||
			//SDL.RenderDrawRect(Game.Renderer, &SDL.Rect((int32)(x - Camera.X), (int32)(y - Camera.Y), (int32)w, (int32)h));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static public void HollowRect(Rect rect, Color color)
 | 
			
		||||
		{
 | 
			
		||||
			HollowRect(rect.X, rect.Y, rect.Width, rect.Height, color);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static public void Line(Point from, Point to, Color color)
 | 
			
		||||
		{
 | 
			
		||||
			let fromn = (Point)(from - Camera);
 | 
			
		||||
			let ton = (Point)(to - Camera);
 | 
			
		||||
 | 
			
		||||
			//SDL.SetRenderDrawBlendMode(Game.Renderer, .Blend);
 | 
			
		||||
			//SDL.SetRenderDrawColor(Game.Renderer, color.R, color.G, color.B, color.A);
 | 
			
		||||
			//SDL.RenderDrawLine(Game.Renderer, (int32)fromn.X, (int32)fromn.Y, (int32)ton.X, (int32)ton.Y);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static public void Circle(Point at, float radius, Color color, int steps = 16)
 | 
			
		||||
		{
 | 
			
		||||
			let add = at - Camera;
 | 
			
		||||
 | 
			
		||||
			SDL.Point[] points = scope SDL.Point[steps + 1];
 | 
			
		||||
			points[0] = SDL.Point((int32)(radius + add.X), (int32)add.Y);
 | 
			
		||||
			points[steps] = points[0];
 | 
			
		||||
			float slice = Calc.Circle / steps;
 | 
			
		||||
 | 
			
		||||
			for (int i = 1; i < steps; i++)
 | 
			
		||||
			{
 | 
			
		||||
				points[i] = SDL.Point(
 | 
			
		||||
					(int32)(Math.Round(Math.Cos(slice * i) * radius) + add.X),
 | 
			
		||||
					(int32)(Math.Round(Math.Sin(slice * i) * radius) + add.Y)
 | 
			
		||||
				);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			//SDL.SetRenderDrawBlendMode(Game.Renderer, .Blend);
 | 
			
		||||
			//SDL.SetRenderDrawColor(Game.Renderer, color.R, color.G, color.B, color.A);
 | 
			
		||||
			//SDL.RenderDrawLines(Game.Renderer, &points[0], (int32)steps + 1);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static public void Sprite(Sprite sprite, int frame, Point position)
 | 
			
		||||
		{
 | 
			
		||||
			SDL.Rect src = Strawberry.Rect(0, 0, sprite.Width, sprite.Height);
 | 
			
		||||
			SDL.Rect dst = Strawberry.Rect(position.X - Camera.X, position.Y - Camera.Y, sprite.Width, sprite.Height);
 | 
			
		||||
 | 
			
		||||
			//SDL.SetTextureBlendMode(sprite[frame].Texture, .Blend);
 | 
			
		||||
			//SDL.RenderCopy(Game.Renderer, sprite[frame].Texture, &src, &dst);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static public void Sprite(Sprite sprite, int frame, Point position, Point origin)
 | 
			
		||||
		{
 | 
			
		||||
			SDL.Point cnt = origin;
 | 
			
		||||
			SDL.Rect src = Strawberry.Rect(0, 0, sprite.Width, sprite.Height);
 | 
			
		||||
			SDL.Rect dst = Strawberry.Rect(position.X - origin.X - Camera.X, position.Y - origin.Y - Camera.Y, sprite.Width, sprite.Height);
 | 
			
		||||
 | 
			
		||||
			//SDL.SetTextureBlendMode(sprite[frame].Texture, .Blend);
 | 
			
		||||
			//SDL.RenderCopyEx(Game.Renderer, sprite[frame].Texture, &src, &dst, 0, &cnt, .None);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static public void Sprite(Sprite sprite, int frame, Point position, Point origin, float rotation)
 | 
			
		||||
		{
 | 
			
		||||
			SDL.Point cnt = origin;
 | 
			
		||||
			SDL.Rect src = Strawberry.Rect(0, 0, sprite.Width, sprite.Height);
 | 
			
		||||
			SDL.Rect dst = Strawberry.Rect(position.X - origin.X - Camera.X, position.Y - origin.Y - Camera.Y, sprite.Width, sprite.Height);
 | 
			
		||||
 | 
			
		||||
			//SDL.SetTextureBlendMode(sprite[frame].Texture, .Blend);
 | 
			
		||||
			//SDL.RenderCopyEx(Game.Renderer, sprite[frame].Texture, &src, &dst, rotation, &cnt, .None);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static public void SpriteCentered(Sprite sprite, int frame, Point position)
 | 
			
		||||
		{
 | 
			
		||||
			Point origin = .(sprite.Width/2, sprite.Height/2);
 | 
			
		||||
			SDL.Point cnt = origin;
 | 
			
		||||
			SDL.Rect src = Strawberry.Rect(0, 0, sprite.Width, sprite.Height);
 | 
			
		||||
			SDL.Rect dst = Strawberry.Rect(position.X - origin.X - Camera.X, position.Y - origin.Y - Camera.Y, sprite.Width, sprite.Height);
 | 
			
		||||
 | 
			
		||||
			//SDL.SetTextureBlendMode(sprite[frame].Texture, .Blend);
 | 
			
		||||
			//SDL.RenderCopyEx(Game.Renderer, sprite[frame].Texture, &src, &dst, 0, &cnt, .None);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static public void SpriteCentered(Sprite sprite, int frame, Point position, Color color)
 | 
			
		||||
		{
 | 
			
		||||
			Point origin = .(sprite.Width/2, sprite.Height/2);
 | 
			
		||||
			SDL.Point cnt = origin;
 | 
			
		||||
			SDL.Rect src = Strawberry.Rect(0, 0, sprite.Width, sprite.Height);
 | 
			
		||||
			SDL.Rect dst = Strawberry.Rect(position.X - origin.X - Camera.X, position.Y - origin.Y - Camera.Y, sprite.Width, sprite.Height);
 | 
			
		||||
 | 
			
		||||
			SDL.SetTextureBlendMode(sprite[frame].Texture, .Blend);
 | 
			
		||||
			SDL.SetTextureColorMod(sprite[frame].Texture, color.R, color.G, color.B);
 | 
			
		||||
			SDL.SetTextureAlphaMod(sprite[frame].Texture, color.A);
 | 
			
		||||
			//SDL.RenderCopyEx(Game.Renderer, sprite[frame].Texture, &src, &dst, 0, &cnt, .None);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static public void SpriteCentered(Sprite sprite, int frame, Point position, float rotation)
 | 
			
		||||
		{
 | 
			
		||||
			Point origin = .(sprite.Width/2, sprite.Height/2);
 | 
			
		||||
			SDL.Point cnt = origin;
 | 
			
		||||
			SDL.Rect src = Strawberry.Rect(0, 0, sprite.Width, sprite.Height);
 | 
			
		||||
			SDL.Rect dst = Strawberry.Rect(position.X - origin.X - Camera.X, position.Y - origin.Y - Camera.Y, sprite.Width, sprite.Height);
 | 
			
		||||
 | 
			
		||||
			SDL.SetTextureBlendMode(sprite[frame].Texture, .Blend);
 | 
			
		||||
			//SDL.RenderCopyEx(Game.Renderer, sprite[frame].Texture, &src, &dst, rotation, &cnt, .None);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static public void Text(SDL2.SDLTTF.Font* font, String text, Point position, Color color)
 | 
			
		||||
		{
 | 
			
		||||
			//SDL.SetRenderDrawColor(Game.Renderer, color.R, color.G, color.B, color.A);
 | 
			
		||||
			let surface = SDLTTF.RenderUTF8_Solid(font, text, color);
 | 
			
		||||
			//let texture = SDL.CreateTextureFromSurface(Game.Renderer, surface);
 | 
			
		||||
 | 
			
		||||
			SDL.Rect srcRect = .(0, 0, surface.w, surface.h);
 | 
			
		||||
			SDL.Rect destRect = .((int32)position.X, (int32)position.Y, surface.w, surface.h);
 | 
			
		||||
			//SDL.RenderCopy(Game.Renderer, texture, &srcRect, &destRect);
 | 
			
		||||
			SDL.FreeSurface(surface);
 | 
			
		||||
			//SDL.DestroyTexture(texture);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -10,9 +10,9 @@ namespace Strawberry
 | 
			
		||||
	*/
 | 
			
		||||
 | 
			
		||||
	[Ordered, Packed, CRepr]
 | 
			
		||||
	public struct Matrix
 | 
			
		||||
	public struct Mat3x2
 | 
			
		||||
	{
 | 
			
		||||
		static public readonly Matrix Identity = Matrix(1, 0, 0, 1, 0, 0);
 | 
			
		||||
		static public readonly Mat3x2 Identity = Mat3x2(1, 0, 0, 1, 0, 0);
 | 
			
		||||
 | 
			
		||||
		public float[6] Values = .(0, 0, 0, 0, 0, 0);
 | 
			
		||||
 | 
			
		||||
@ -153,7 +153,7 @@ namespace Strawberry
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public Result<Matrix> Inverse
 | 
			
		||||
		public Result<Mat3x2> Inverse
 | 
			
		||||
		{
 | 
			
		||||
			get => Invert(this);
 | 
			
		||||
 | 
			
		||||
@ -165,70 +165,70 @@ namespace Strawberry
 | 
			
		||||
 | 
			
		||||
		//Static Helpers
 | 
			
		||||
 | 
			
		||||
		public static Matrix CreateTranslation(Vector position)
 | 
			
		||||
		public static Mat3x2 CreateTranslation(Vector position)
 | 
			
		||||
		{
 | 
			
		||||
		    return Matrix(
 | 
			
		||||
		    return Mat3x2(
 | 
			
		||||
				1, 0,
 | 
			
		||||
				0, 1,
 | 
			
		||||
				position.X, position.Y
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Matrix CreateScale(Vector scale)
 | 
			
		||||
		public static Mat3x2 CreateScale(Vector scale)
 | 
			
		||||
		{
 | 
			
		||||
			return Matrix(
 | 
			
		||||
			return Mat3x2(
 | 
			
		||||
				scale.X, 0,
 | 
			
		||||
				0, scale.Y,
 | 
			
		||||
				0, 0
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Matrix CreateScale(Vector scale, Vector origin)
 | 
			
		||||
		public static Mat3x2 CreateScale(Vector scale, Vector origin)
 | 
			
		||||
		{
 | 
			
		||||
			float tx = origin.X * (1 - scale.X);
 | 
			
		||||
			float ty = origin.Y * (1 - scale.Y);
 | 
			
		||||
 | 
			
		||||
			return Matrix(
 | 
			
		||||
			return Mat3x2(
 | 
			
		||||
				scale.X, 0,
 | 
			
		||||
				0, scale.Y,
 | 
			
		||||
				tx, ty
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Matrix CreateScale(float scale)
 | 
			
		||||
		public static Mat3x2 CreateScale(float scale)
 | 
			
		||||
		{
 | 
			
		||||
			return Matrix(
 | 
			
		||||
			return Mat3x2(
 | 
			
		||||
				scale, 0,
 | 
			
		||||
				0, scale,
 | 
			
		||||
				0, 0
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Matrix CreateScale(float scale, Vector origin)
 | 
			
		||||
		public static Mat3x2 CreateScale(float scale, Vector origin)
 | 
			
		||||
		{
 | 
			
		||||
			float tx = origin.X * (1 - scale);
 | 
			
		||||
			float ty = origin.Y * (1 - scale);
 | 
			
		||||
 | 
			
		||||
			return Matrix(
 | 
			
		||||
			return Mat3x2(
 | 
			
		||||
				scale, 0,
 | 
			
		||||
				0, scale,
 | 
			
		||||
				tx, ty
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Matrix CreateSkew(float radiansX, float radiansY)
 | 
			
		||||
		public static Mat3x2 CreateSkew(float radiansX, float radiansY)
 | 
			
		||||
		{
 | 
			
		||||
			float xTan = (float)Math.Tan(radiansX);
 | 
			
		||||
			float yTan = (float)Math.Tan(radiansY);
 | 
			
		||||
 | 
			
		||||
			return Matrix(
 | 
			
		||||
			return Mat3x2(
 | 
			
		||||
				1, yTan,
 | 
			
		||||
				xTan, 1,
 | 
			
		||||
				0, 0
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Matrix CreateSkew(float radiansX, float radiansY, Vector origin)
 | 
			
		||||
		public static Mat3x2 CreateSkew(float radiansX, float radiansY, Vector origin)
 | 
			
		||||
		{
 | 
			
		||||
		    float xTan = (float)Math.Tan(radiansX);
 | 
			
		||||
		    float yTan = (float)Math.Tan(radiansY);
 | 
			
		||||
@ -236,14 +236,14 @@ namespace Strawberry
 | 
			
		||||
		    float tx = -origin.Y * xTan;
 | 
			
		||||
		    float ty = -origin.X * yTan;
 | 
			
		||||
 | 
			
		||||
			return Matrix(
 | 
			
		||||
			return Mat3x2(
 | 
			
		||||
				1, yTan,
 | 
			
		||||
				xTan, 1,
 | 
			
		||||
				tx, ty
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Matrix CreateRotation(float radians)
 | 
			
		||||
		public static Mat3x2 CreateRotation(float radians)
 | 
			
		||||
		{
 | 
			
		||||
			let rad = (float)Math.IEEERemainder(radians, Math.PI_f * 2);
 | 
			
		||||
 | 
			
		||||
@ -282,14 +282,14 @@ namespace Strawberry
 | 
			
		||||
		        s = (float)Math.Sin(rad);
 | 
			
		||||
		    }
 | 
			
		||||
 | 
			
		||||
			return Matrix(
 | 
			
		||||
			return Mat3x2(
 | 
			
		||||
				c, s,
 | 
			
		||||
				-s, c,
 | 
			
		||||
				0, 0
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Matrix CreateRotation(float radians, Vector origin)
 | 
			
		||||
		public static Mat3x2 CreateRotation(float radians, Vector origin)
 | 
			
		||||
		{
 | 
			
		||||
		    let rad = (float)Math.IEEERemainder(radians, Math.PI_f * 2);
 | 
			
		||||
 | 
			
		||||
@ -331,7 +331,7 @@ namespace Strawberry
 | 
			
		||||
		    float x = origin.X * (1 - c) + origin.Y * s;
 | 
			
		||||
		    float y = origin.Y * (1 - c) - origin.X * s;
 | 
			
		||||
 | 
			
		||||
			return Matrix(
 | 
			
		||||
			return Mat3x2(
 | 
			
		||||
				c, s,
 | 
			
		||||
				-s, c,
 | 
			
		||||
				x, y
 | 
			
		||||
@ -361,7 +361,7 @@ namespace Strawberry
 | 
			
		||||
		    return (M11 * M22) - (M21 * M12);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Result<Matrix> Invert(Matrix matrix)
 | 
			
		||||
		public static Result<Mat3x2> Invert(Mat3x2 matrix)
 | 
			
		||||
		{
 | 
			
		||||
		    let det = (matrix.M11 * matrix.M22) - (matrix.M21 * matrix.M12);
 | 
			
		||||
 | 
			
		||||
@ -370,7 +370,7 @@ namespace Strawberry
 | 
			
		||||
 | 
			
		||||
		    let invDet = 1.0f / det;
 | 
			
		||||
 | 
			
		||||
		    return Matrix(
 | 
			
		||||
		    return Mat3x2(
 | 
			
		||||
				matrix.M22 * invDet,
 | 
			
		||||
				-matrix.M12 * invDet,
 | 
			
		||||
 | 
			
		||||
@ -382,9 +382,9 @@ namespace Strawberry
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Matrix Lerp(Matrix a, Matrix b, float t)
 | 
			
		||||
		public static Mat3x2 Lerp(Mat3x2 a, Mat3x2 b, float t)
 | 
			
		||||
		{
 | 
			
		||||
			return Matrix(
 | 
			
		||||
			return Mat3x2(
 | 
			
		||||
				a.M11 + (b.M11 - a.M11) * t,
 | 
			
		||||
				a.M12 + (b.M12 - a.M12) * t,
 | 
			
		||||
 | 
			
		||||
@ -396,36 +396,36 @@ namespace Strawberry
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Matrix Negate(Matrix mat)
 | 
			
		||||
		public static Mat3x2 Negate(Mat3x2 mat)
 | 
			
		||||
		{
 | 
			
		||||
			return Matrix(
 | 
			
		||||
			return Mat3x2(
 | 
			
		||||
				-mat.M11, -mat.M12,
 | 
			
		||||
				-mat.M21, -mat.M22,
 | 
			
		||||
				-mat.M31, -mat.M32
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Matrix Add(Matrix a, Matrix b)
 | 
			
		||||
		public static Mat3x2 Add(Mat3x2 a, Mat3x2 b)
 | 
			
		||||
		{
 | 
			
		||||
			return Matrix(
 | 
			
		||||
			return Mat3x2(
 | 
			
		||||
				a.M11 + b.M11, a.M12 + b.M12,
 | 
			
		||||
				a.M21 + b.M21, a.M22 + b.M22,
 | 
			
		||||
				a.M31 + b.M31, a.M32 + b.M32
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Matrix Subtract(Matrix a, Matrix b)
 | 
			
		||||
		public static Mat3x2 Subtract(Mat3x2 a, Mat3x2 b)
 | 
			
		||||
		{
 | 
			
		||||
		    return Matrix(
 | 
			
		||||
		    return Mat3x2(
 | 
			
		||||
				a.M11 - b.M11, a.M12 - b.M12,
 | 
			
		||||
				a.M21 - b.M21, a.M22 - b.M22,
 | 
			
		||||
				a.M31 - b.M31, a.M32 - b.M32
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Matrix Multiply(Matrix a, Matrix b)
 | 
			
		||||
		public static Mat3x2 Multiply(Mat3x2 a, Mat3x2 b)
 | 
			
		||||
		{
 | 
			
		||||
		    return Matrix(
 | 
			
		||||
		    return Mat3x2(
 | 
			
		||||
				a.M11 * b.M11 + a.M12 * b.M21,
 | 
			
		||||
				a.M11 * b.M12 + a.M12 * b.M22,
 | 
			
		||||
 | 
			
		||||
@ -437,9 +437,9 @@ namespace Strawberry
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Matrix Multiply(Matrix a, float scale)
 | 
			
		||||
		public static Mat3x2 Multiply(Mat3x2 a, float scale)
 | 
			
		||||
		{
 | 
			
		||||
		    return Matrix(
 | 
			
		||||
		    return Mat3x2(
 | 
			
		||||
				a.M11 * scale, a.M12 * scale,
 | 
			
		||||
				a.M21 * scale, a.M22 * scale,
 | 
			
		||||
				a.M31 * scale, a.M32 * scale
 | 
			
		||||
@ -448,36 +448,36 @@ namespace Strawberry
 | 
			
		||||
 | 
			
		||||
		// Operators
 | 
			
		||||
 | 
			
		||||
		public static Matrix operator -(Matrix mat)
 | 
			
		||||
		public static Mat3x2 operator -(Mat3x2 mat)
 | 
			
		||||
		{
 | 
			
		||||
			return Matrix(
 | 
			
		||||
			return Mat3x2(
 | 
			
		||||
				-mat.M11, -mat.M12,
 | 
			
		||||
				-mat.M21, -mat.M22,
 | 
			
		||||
				-mat.M31, -mat.M32
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Matrix operator +(Matrix a, Matrix b)
 | 
			
		||||
		public static Mat3x2 operator +(Mat3x2 a, Mat3x2 b)
 | 
			
		||||
		{
 | 
			
		||||
			return Matrix(
 | 
			
		||||
			return Mat3x2(
 | 
			
		||||
				a.M11 + b.M11, a.M12 + b.M12,
 | 
			
		||||
				a.M21 + b.M21, a.M22 + b.M22,
 | 
			
		||||
				a.M31 + b.M31, a.M32 + b.M32
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Matrix operator -(Matrix a, Matrix b)
 | 
			
		||||
		public static Mat3x2 operator -(Mat3x2 a, Mat3x2 b)
 | 
			
		||||
		{
 | 
			
		||||
		    return Matrix(
 | 
			
		||||
		    return Mat3x2(
 | 
			
		||||
				a.M11 - b.M11, a.M12 - b.M12,
 | 
			
		||||
				a.M21 - b.M21, a.M22 - b.M22,
 | 
			
		||||
				a.M31 - b.M31, a.M32 - b.M32
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Matrix operator *(Matrix a, Matrix b)
 | 
			
		||||
		public static Mat3x2 operator *(Mat3x2 a, Mat3x2 b)
 | 
			
		||||
		{
 | 
			
		||||
		    return Matrix(
 | 
			
		||||
		    return Mat3x2(
 | 
			
		||||
				a.M11 * b.M11 + a.M12 * b.M21,
 | 
			
		||||
				a.M11 * b.M12 + a.M12 * b.M22,
 | 
			
		||||
 | 
			
		||||
@ -489,16 +489,16 @@ namespace Strawberry
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Matrix operator *(Matrix mat, float scale)
 | 
			
		||||
		public static Mat3x2 operator *(Mat3x2 mat, float scale)
 | 
			
		||||
		{
 | 
			
		||||
			return Matrix(
 | 
			
		||||
			return Mat3x2(
 | 
			
		||||
				mat.M11 * scale, mat.M12 * scale,
 | 
			
		||||
				mat.M21 * scale, mat.M22 * scale,
 | 
			
		||||
				mat.M31 * scale, mat.M32 * scale
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static bool operator ==(Matrix a, Matrix b)
 | 
			
		||||
		public static bool operator ==(Mat3x2 a, Mat3x2 b)
 | 
			
		||||
		{
 | 
			
		||||
		    return (a.M11 == b.M11 && a.M22 == b.M22 && // Check diagonal element first for early out.
 | 
			
		||||
		                                        a.M12 == b.M12 &&
 | 
			
		||||
@ -506,7 +506,7 @@ namespace Strawberry
 | 
			
		||||
		            a.M31 == b.M31 && a.M32 == b.M32);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static bool operator !=(Matrix a, Matrix b)
 | 
			
		||||
		public static bool operator !=(Mat3x2 a, Mat3x2 b)
 | 
			
		||||
		{
 | 
			
		||||
		    return (a.M11 != b.M11 || a.M12 != b.M12 ||
 | 
			
		||||
		            a.M21 != b.M21 || a.M22 != b.M22 ||
 | 
			
		||||
							
								
								
									
										327
									
								
								src/Struct/Mat4x4.bf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										327
									
								
								src/Struct/Mat4x4.bf
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,327 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace Strawberry
 | 
			
		||||
{
 | 
			
		||||
	/*
 | 
			
		||||
		Based on Matrix3x2.cs by Microsoft, under MIT license
 | 
			
		||||
		Source: https://github.com/microsoft/referencesource/blob/master/System.Numerics/System/Numerics/Matrix4x4.cs
 | 
			
		||||
 | 
			
		||||
		Copyright (c) Microsoft. All rights reserved.
 | 
			
		||||
		Licensed under the MIT license.
 | 
			
		||||
	*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	[Ordered, Packed, CRepr]
 | 
			
		||||
	public struct Mat4x4
 | 
			
		||||
	{
 | 
			
		||||
		static public readonly Mat4x4 Identity = Mat4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
 | 
			
		||||
 | 
			
		||||
		public float[16] Values = .(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
 | 
			
		||||
 | 
			
		||||
		public this(float m11, float m12, float m13, float m14,
 | 
			
		||||
			float m21, float m22, float m23, float m24,
 | 
			
		||||
			float m31, float m32, float m33, float m34,
 | 
			
		||||
			float m41, float m42, float m43, float m44)
 | 
			
		||||
		{
 | 
			
		||||
			Values = .(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public this()
 | 
			
		||||
		{
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public float M11
 | 
			
		||||
		{
 | 
			
		||||
			get => Values[0];
 | 
			
		||||
			set mut => Values[0] = value;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public float M12
 | 
			
		||||
		{
 | 
			
		||||
			get => Values[1];
 | 
			
		||||
			set mut => Values[1] = value;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public float M13
 | 
			
		||||
		{
 | 
			
		||||
			get => Values[2];
 | 
			
		||||
			set mut => Values[2] = value;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public float M14
 | 
			
		||||
		{
 | 
			
		||||
			get => Values[3];
 | 
			
		||||
			set mut => Values[3] = value;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public float M21
 | 
			
		||||
		{
 | 
			
		||||
			get => Values[4];
 | 
			
		||||
			set mut => Values[4] = value;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public float M22
 | 
			
		||||
		{
 | 
			
		||||
			get => Values[5];
 | 
			
		||||
			set mut => Values[5] = value;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public float M23
 | 
			
		||||
		{
 | 
			
		||||
			get => Values[6];
 | 
			
		||||
			set mut => Values[6] = value;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public float M24
 | 
			
		||||
		{
 | 
			
		||||
			get => Values[7];
 | 
			
		||||
			set mut => Values[7] = value;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public float M31
 | 
			
		||||
		{
 | 
			
		||||
			get => Values[8];
 | 
			
		||||
			set mut => Values[8] = value;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public float M32
 | 
			
		||||
		{
 | 
			
		||||
			get => Values[9];
 | 
			
		||||
			set mut => Values[9] = value;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public float M33
 | 
			
		||||
		{
 | 
			
		||||
			get => Values[10];
 | 
			
		||||
			set mut => Values[10] = value;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public float M34
 | 
			
		||||
		{
 | 
			
		||||
			get => Values[11];
 | 
			
		||||
			set mut => Values[11] = value;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public float M41
 | 
			
		||||
		{
 | 
			
		||||
			get => Values[12];
 | 
			
		||||
			set mut => Values[12] = value;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public float M42
 | 
			
		||||
		{
 | 
			
		||||
			get => Values[13];
 | 
			
		||||
			set mut => Values[13] = value;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public float M43
 | 
			
		||||
		{
 | 
			
		||||
			get => Values[14];
 | 
			
		||||
			set mut => Values[14] = value;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public float M44
 | 
			
		||||
		{
 | 
			
		||||
			get => Values[15];
 | 
			
		||||
			set mut => Values[15] = value;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static public Mat4x4 CreateTranslation(Vector3 pos)
 | 
			
		||||
		{
 | 
			
		||||
		    return .(
 | 
			
		||||
				1, 0, 0, 0,
 | 
			
		||||
				0, 1, 0, 0,
 | 
			
		||||
				0, 0, 1, 0,
 | 
			
		||||
				pos.X, pos.Y, pos.Z, 1
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Mat4x4 CreateScale(Vector3 scale)
 | 
			
		||||
		{
 | 
			
		||||
			return .(
 | 
			
		||||
				scale.X, 0, 0, 0,
 | 
			
		||||
				0, scale.Y, 0, 0,
 | 
			
		||||
				0, 0, scale.Z, 0,
 | 
			
		||||
				0, 0, 0, 1
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Mat4x4 CreateScale(Vector3 scale, Vector3 origin)
 | 
			
		||||
		{
 | 
			
		||||
			float tx = origin.X * (1 - scale.X);
 | 
			
		||||
			float ty = origin.Y * (1 - scale.Y);
 | 
			
		||||
			float tz = origin.Z * (1 - scale.Z);
 | 
			
		||||
 | 
			
		||||
			return .(
 | 
			
		||||
				scale.X, 0, 0, 0,
 | 
			
		||||
				0, scale.Y, 0, 0,
 | 
			
		||||
				0, 0, scale.Z, 0,
 | 
			
		||||
				tx, ty, tz, 1
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Mat4x4 CreateRotationX(float radians)
 | 
			
		||||
		{
 | 
			
		||||
 | 
			
		||||
		    float c = (float)Math.Cos(radians);
 | 
			
		||||
		    float s = (float)Math.Sin(radians);
 | 
			
		||||
 | 
			
		||||
		    // [  1  0  0  0 ]
 | 
			
		||||
		    // [  0  c  s  0 ]
 | 
			
		||||
		    // [  0 -s  c  0 ]
 | 
			
		||||
		    // [  0  0  0  1 ]
 | 
			
		||||
			return .(
 | 
			
		||||
				1, 0, 0, 0,
 | 
			
		||||
				0, c, s, 0,
 | 
			
		||||
				0, -s, c, 0,
 | 
			
		||||
				0, 0, 0, 1
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Mat4x4 CreateRotationX(float radians, Vector3 origin)
 | 
			
		||||
		{
 | 
			
		||||
		    float c = (float)Math.Cos(radians);
 | 
			
		||||
		    float s = (float)Math.Sin(radians);
 | 
			
		||||
 | 
			
		||||
		    float y = origin.Y * (1 - c) + origin.Z * s;
 | 
			
		||||
		    float z = origin.Z * (1 - c) - origin.Y * s;
 | 
			
		||||
 | 
			
		||||
		    // [  1  0  0  0 ]
 | 
			
		||||
		    // [  0  c  s  0 ]
 | 
			
		||||
		    // [  0 -s  c  0 ]
 | 
			
		||||
		    // [  0  y  z  1 ]
 | 
			
		||||
			return .(
 | 
			
		||||
				1, 0, 0, 0,
 | 
			
		||||
				0, c, s, 0,
 | 
			
		||||
				0, -s, c, 0,
 | 
			
		||||
				0, y, z, 1
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Mat4x4 CreateRotationY(float radians)
 | 
			
		||||
		{
 | 
			
		||||
		    float c = (float)Math.Cos(radians);
 | 
			
		||||
		    float s = (float)Math.Sin(radians);
 | 
			
		||||
 | 
			
		||||
		    // [  c  0 -s  0 ]
 | 
			
		||||
		    // [  0  1  0  0 ]
 | 
			
		||||
		    // [  s  0  c  0 ]
 | 
			
		||||
		    // [  0  0  0  1 ]
 | 
			
		||||
			return .(
 | 
			
		||||
				c, 0, -s, 0,
 | 
			
		||||
				0, 1, 0, 0,
 | 
			
		||||
				s, 0, c, 0,
 | 
			
		||||
				0, 0, 0, 1
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Mat4x4 CreateRotationY(float radians, Vector3 origin)
 | 
			
		||||
		{
 | 
			
		||||
		    float c = (float)Math.Cos(radians);
 | 
			
		||||
		    float s = (float)Math.Sin(radians);
 | 
			
		||||
 | 
			
		||||
		    float x = origin.X * (1 - c) - origin.Z * s;
 | 
			
		||||
		    float z = origin.Z * (1 - c) + origin.X * s;
 | 
			
		||||
 | 
			
		||||
		    // [  c  0 -s  0 ]
 | 
			
		||||
		    // [  0  1  0  0 ]
 | 
			
		||||
		    // [  s  0  c  0 ]
 | 
			
		||||
		    // [  x  0  z  1 ]
 | 
			
		||||
			return .(
 | 
			
		||||
				c, 0, -s, 0,
 | 
			
		||||
				0, 1, 0, 0,
 | 
			
		||||
				s, 0, c, 0,
 | 
			
		||||
				x, 0, z, 1
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Mat4x4 CreateRotationZ(float radians)
 | 
			
		||||
		{
 | 
			
		||||
		    float c = (float)Math.Cos(radians);
 | 
			
		||||
		    float s = (float)Math.Sin(radians);
 | 
			
		||||
 | 
			
		||||
		    // [  c  s  0  0 ]
 | 
			
		||||
		    // [ -s  c  0  0 ]
 | 
			
		||||
		    // [  0  0  1  0 ]
 | 
			
		||||
		    // [  0  0  0  1 ]
 | 
			
		||||
			return .(
 | 
			
		||||
				c, s, 0, 0,
 | 
			
		||||
				-s, c, 0, 0,
 | 
			
		||||
				0, 0, 1, 0,
 | 
			
		||||
				0, 0, 0, 1
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Mat4x4 CreateRotationZ(float radians, Vector3 centerPoint)
 | 
			
		||||
		{
 | 
			
		||||
		    float c = (float)Math.Cos(radians);
 | 
			
		||||
		    float s = (float)Math.Sin(radians);
 | 
			
		||||
 | 
			
		||||
		    float x = centerPoint.X * (1 - c) + centerPoint.Y * s;
 | 
			
		||||
		    float y = centerPoint.Y * (1 - c) - centerPoint.X * s;
 | 
			
		||||
 | 
			
		||||
		    // [  c  s  0  0 ]
 | 
			
		||||
		    // [ -s  c  0  0 ]
 | 
			
		||||
		    // [  0  0  1  0 ]
 | 
			
		||||
		    // [  x  y  0  1 ]
 | 
			
		||||
			return .(
 | 
			
		||||
				c, s, 0, 0,
 | 
			
		||||
				-s, c, 0, 0,
 | 
			
		||||
				0, 0, 1, 0,
 | 
			
		||||
				x, y, 0, 1
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Mat4x4 CreateOrthographic(float width, float height, float zNearPlane, float zFarPlane)
 | 
			
		||||
		{
 | 
			
		||||
			return .(
 | 
			
		||||
				2 / width, 0, 0, 0,
 | 
			
		||||
				0, 1 / height, 0, 0,
 | 
			
		||||
				0, 0, 1 / (zNearPlane - zFarPlane), 0,
 | 
			
		||||
				0, zNearPlane / (zNearPlane - zFarPlane), 0, 1
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static public implicit operator Mat4x4(Mat3x2 mat)
 | 
			
		||||
		{
 | 
			
		||||
			return Mat4x4(
 | 
			
		||||
				mat.M11, mat.M12, 0, 0,
 | 
			
		||||
				mat.M21, mat.M22, 0, 0,
 | 
			
		||||
				0, 0, 1, 0,
 | 
			
		||||
				mat.M31, mat.M32, 0, 1
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static public Mat4x4 operator *(Mat4x4 a, Mat4x4 b)
 | 
			
		||||
		{
 | 
			
		||||
			Mat4x4 m = .();
 | 
			
		||||
 | 
			
		||||
			// First row
 | 
			
		||||
			m.M11 = a.M11 * b.M11 + a.M12 * b.M21 + a.M13 * b.M31 + a.M14 * b.M41;
 | 
			
		||||
			m.M12 = a.M11 * b.M12 + a.M12 * b.M22 + a.M13 * b.M32 + a.M14 * b.M42;
 | 
			
		||||
			m.M13 = a.M11 * b.M13 + a.M12 * b.M23 + a.M13 * b.M33 + a.M14 * b.M43;
 | 
			
		||||
			m.M14 = a.M11 * b.M14 + a.M12 * b.M24 + a.M13 * b.M34 + a.M14 * b.M44;
 | 
			
		||||
 | 
			
		||||
			// Second row
 | 
			
		||||
			m.M21 = a.M21 * b.M11 + a.M22 * b.M21 + a.M23 * b.M31 + a.M24 * b.M41;
 | 
			
		||||
			m.M22 = a.M21 * b.M12 + a.M22 * b.M22 + a.M23 * b.M32 + a.M24 * b.M42;
 | 
			
		||||
			m.M23 = a.M21 * b.M13 + a.M22 * b.M23 + a.M23 * b.M33 + a.M24 * b.M43;
 | 
			
		||||
			m.M24 = a.M21 * b.M14 + a.M22 * b.M24 + a.M23 * b.M34 + a.M24 * b.M44;
 | 
			
		||||
 | 
			
		||||
			// Third row
 | 
			
		||||
			m.M31 = a.M31 * b.M11 + a.M32 * b.M21 + a.M33 * b.M31 + a.M34 * b.M41;
 | 
			
		||||
			m.M32 = a.M31 * b.M12 + a.M32 * b.M22 + a.M33 * b.M32 + a.M34 * b.M42;
 | 
			
		||||
			m.M33 = a.M31 * b.M13 + a.M32 * b.M23 + a.M33 * b.M33 + a.M34 * b.M43;
 | 
			
		||||
			m.M34 = a.M31 * b.M14 + a.M32 * b.M24 + a.M33 * b.M34 + a.M34 * b.M44;
 | 
			
		||||
 | 
			
		||||
			// Fourth row
 | 
			
		||||
			m.M41 = a.M41 * b.M11 + a.M42 * b.M21 + a.M43 * b.M31 + a.M44 * b.M41;
 | 
			
		||||
			m.M42 = a.M41 * b.M12 + a.M42 * b.M22 + a.M43 * b.M32 + a.M44 * b.M42;
 | 
			
		||||
			m.M43 = a.M41 * b.M13 + a.M42 * b.M23 + a.M43 * b.M33 + a.M44 * b.M43;
 | 
			
		||||
			m.M44 = a.M41 * b.M14 + a.M42 * b.M24 + a.M43 * b.M34 + a.M44 * b.M44;
 | 
			
		||||
 | 
			
		||||
			return m;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								src/Struct/Vector3.bf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/Struct/Vector3.bf
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
			
		||||
namespace Strawberry
 | 
			
		||||
{
 | 
			
		||||
	public struct Vector3
 | 
			
		||||
	{
 | 
			
		||||
		public float X;
 | 
			
		||||
		public float Y;
 | 
			
		||||
		public float Z;
 | 
			
		||||
 | 
			
		||||
		public this(float x, float y, float z)
 | 
			
		||||
		{
 | 
			
		||||
			X = x;
 | 
			
		||||
			Y = y;
 | 
			
		||||
			Z = z;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user