mirror of
https://github.com/MaddyThorson/StrawberryBF.git
synced 2024-11-28 16:58:56 +08:00
OpenGL rendering hooked up. Better platform layer abstraction
This commit is contained in:
parent
5d62a86947
commit
1c084b55f9
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using Strawberry.SDL2;
|
||||||
|
|
||||||
namespace Strawberry.Sample
|
namespace Strawberry.Sample
|
||||||
{
|
{
|
||||||
|
|
|
@ -423,7 +423,7 @@ namespace Strawberry
|
||||||
|
|
||||||
public void DrawHitbox(Color color)
|
public void DrawHitbox(Color color)
|
||||||
{
|
{
|
||||||
Draw.Rect(SceneHitbox, color);
|
Game.Batcher.Rect(SceneHitbox, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public int Compare(Entity a, Entity b)
|
static public int Compare(Entity a, Entity b)
|
||||||
|
|
|
@ -29,7 +29,8 @@ namespace Strawberry
|
||||||
private Dictionary<Type, List<Type>> componentAssignableLists;
|
private Dictionary<Type, List<Type>> componentAssignableLists;
|
||||||
|
|
||||||
public PlatformLayer PlatformLayer { get; private set; }
|
public PlatformLayer PlatformLayer { get; private set; }
|
||||||
public Color ClearColor = .Red;
|
public Batcher Batcher { get; private set; }
|
||||||
|
public Color ClearColor = .Black;
|
||||||
|
|
||||||
private bool* keyboardState;
|
private bool* keyboardState;
|
||||||
private int32 updateCounter;
|
private int32 updateCounter;
|
||||||
|
@ -53,6 +54,7 @@ namespace Strawberry
|
||||||
Directory.SetCurrentDirectory(exeDir);
|
Directory.SetCurrentDirectory(exeDir);
|
||||||
|
|
||||||
platformLayer.Init();
|
platformLayer.Init();
|
||||||
|
Batcher = platformLayer.CreateBatcher();
|
||||||
|
|
||||||
VirtualInputs = new List<VirtualInput>();
|
VirtualInputs = new List<VirtualInput>();
|
||||||
Input.[Friend]Init();
|
Input.[Friend]Init();
|
||||||
|
@ -83,6 +85,9 @@ namespace Strawberry
|
||||||
DisposeTypeLists();
|
DisposeTypeLists();
|
||||||
Input.[Friend]Dispose();
|
Input.[Friend]Dispose();
|
||||||
Strawberry.Console.Dispose();
|
Strawberry.Console.Dispose();
|
||||||
|
|
||||||
|
delete Batcher;
|
||||||
|
|
||||||
Game = null;
|
Game = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +102,6 @@ namespace Strawberry
|
||||||
|
|
||||||
uint32 tick = PlatformLayer.Ticks;
|
uint32 tick = PlatformLayer.Ticks;
|
||||||
msCounter += (tick - prevTick);
|
msCounter += (tick - prevTick);
|
||||||
prevTick = tick;
|
|
||||||
|
|
||||||
if (Time.FixedTimestep)
|
if (Time.FixedTimestep)
|
||||||
{
|
{
|
||||||
|
@ -112,13 +116,14 @@ namespace Strawberry
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Time.RawDelta = msCounter / 1000;
|
Time.RawDelta = (tick - prevTick) / 1000f;
|
||||||
PlatformLayer.UpdateInput();
|
PlatformLayer.UpdateInput();
|
||||||
Update();
|
Update();
|
||||||
Input.AfterUpdate();
|
Input.AfterUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
Render();
|
Render();
|
||||||
|
prevTick = tick;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,21 +162,18 @@ namespace Strawberry
|
||||||
private void Render()
|
private void Render()
|
||||||
{
|
{
|
||||||
PlatformLayer.RenderBegin();
|
PlatformLayer.RenderBegin();
|
||||||
//Draw();
|
Draw();
|
||||||
PlatformLayer.RenderEnd();
|
PlatformLayer.RenderEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Draw()
|
public virtual void Draw()
|
||||||
{
|
{
|
||||||
if (Scene != null)
|
Scene?.Draw();
|
||||||
{
|
|
||||||
Draw.PushCamera(Scene.Camera.Round());
|
|
||||||
Scene.Draw();
|
|
||||||
Draw.PopCamera();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Console.Enabled)
|
if (Console.Enabled)
|
||||||
Strawberry.Console.[Friend]Draw();
|
Strawberry.Console.[Friend]Draw();
|
||||||
|
|
||||||
|
Batcher.Draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Scene Scene
|
public Scene Scene
|
||||||
|
|
|
@ -8,7 +8,6 @@ namespace Strawberry
|
||||||
public float TimeStarted { get; private set; }
|
public float TimeStarted { get; private set; }
|
||||||
public Grid SolidGrid;
|
public Grid SolidGrid;
|
||||||
public Rect Bounds;
|
public Rect Bounds;
|
||||||
public Vector Camera;
|
|
||||||
|
|
||||||
private List<Entity> entities;
|
private List<Entity> entities;
|
||||||
private HashSet<Entity> toRemove;
|
private HashSet<Entity> toRemove;
|
||||||
|
|
|
@ -173,7 +173,7 @@ namespace Strawberry
|
||||||
for (let x < CellsX)
|
for (let x < CellsX)
|
||||||
for (let y < CellsY)
|
for (let y < CellsY)
|
||||||
if (this[x, y] != '0')
|
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()
|
public override void Draw()
|
||||||
{
|
{
|
||||||
DrawHitbox(.(255, 255, 255, 255));
|
DrawHitbox(.White);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,110 +1,20 @@
|
||||||
using System.Collections;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Strawberry
|
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!(_);
|
protected abstract void PushQuad(Vertex a, Vertex b, Vertex c, Vertex d);
|
||||||
private Batch top => batchStack.Count > 0 ? batchStack[batchStack.Count - 1] : null;
|
protected abstract void PushTri(Vertex a, Vertex b, Vertex c);
|
||||||
|
|
||||||
private List<Vertex> vertices = new .() ~ delete _;
|
public void Rect(float x, float y, float w, float h, Color color)
|
||||||
private List<uint32> indices = new .() ~ delete _;
|
|
||||||
|
|
||||||
private uint32 vaoID;
|
|
||||||
private uint32 vertexBufferID;
|
|
||||||
private uint32 indexBufferID;
|
|
||||||
|
|
||||||
public this()
|
|
||||||
{
|
{
|
||||||
GL.glGenVertexArrays(1, &vaoID);
|
PushQuad(.Shape(.(x, y), color), .Shape(.(x + w, y), color), .Shape(.(x + w, y + h), color), .Shape(.(x, y + h), color));
|
||||||
GL.glBindVertexArray(vaoID);
|
|
||||||
GL.glGenBuffers(1, &vertexBufferID);
|
|
||||||
GL.glGenBuffers(1, &indexBufferID);
|
|
||||||
GL.glBindVertexArray(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ~this()
|
public void Rect(Rect rect, Color color)
|
||||||
{
|
{
|
||||||
GL.glDeleteBuffers(1, &vertexBufferID);
|
Rect(rect.X, rect.Y, rect.Width, rect.Height, color);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,50 +23,7 @@ namespace Strawberry
|
||||||
|
|
||||||
//Graphics
|
//Graphics
|
||||||
public abstract Texture LoadTexture(String path);
|
public abstract Texture LoadTexture(String path);
|
||||||
}
|
public abstract Batcher CreateBatcher();
|
||||||
|
public abstract Shader CreateShader(ShaderDef def);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
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;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace Strawberry
|
namespace Strawberry.SDL2
|
||||||
{
|
{
|
||||||
public class SDL2PlatformLayer : PlatformLayer
|
public class SDL2PlatformLayer : PlatformLayer
|
||||||
{
|
{
|
||||||
|
@ -118,11 +118,6 @@ namespace Strawberry
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* SdlGetProcAddress(StringView string)
|
|
||||||
{
|
|
||||||
return SDL.SDL_GL_GetProcAddress(string.ToScopeCStr!());
|
|
||||||
}
|
|
||||||
|
|
||||||
public ~this()
|
public ~this()
|
||||||
{
|
{
|
||||||
delete gamepads;
|
delete gamepads;
|
||||||
|
@ -134,6 +129,11 @@ namespace Strawberry
|
||||||
SDL.Quit();
|
SDL.Quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void* SdlGetProcAddress(StringView string)
|
||||||
|
{
|
||||||
|
return SDL.SDL_GL_GetProcAddress(string.ToScopeCStr!());
|
||||||
|
}
|
||||||
|
|
||||||
public override bool Closed()
|
public override bool Closed()
|
||||||
{
|
{
|
||||||
SDL.Event event;
|
SDL.Event event;
|
||||||
|
@ -149,21 +149,12 @@ namespace Strawberry
|
||||||
GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
|
GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
|
||||||
GL.glUseProgram(glProgram);
|
GL.glUseProgram(glProgram);
|
||||||
|
|
||||||
float zNearPlane = 0;
|
Mat4x4 mat = Mat4x4.CreateOrthographic(Game.Width, Game.Height * 0.5f, 0, 1);
|
||||||
float zFarPlane = 1000;
|
mat *= Mat4x4.CreateScale(.(1, -1, 1));
|
||||||
|
mat *= Mat4x4.CreateTranslation(.(-1, 1, 0));
|
||||||
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);
|
|
||||||
|
|
||||||
let loc = GL.glGetUniformLocation(glProgram, "u_matrix");
|
let loc = GL.glGetUniformLocation(glProgram, "u_matrix");
|
||||||
GL.glUniformMatrix4fv(loc, 1, GL.GL_FALSE, &mat);
|
GL.glUniformMatrix4fv(loc, 1, GL.GL_FALSE, &mat.Values);
|
||||||
|
|
||||||
Batcher b = scope Batcher();
|
|
||||||
b.PushQuad(.(-40, -40), .(40, -40), .(40, 40), .(-40, 40), .Yellow);
|
|
||||||
b.Draw();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void RenderEnd()
|
public override void RenderEnd()
|
||||||
|
@ -219,73 +210,15 @@ namespace Strawberry
|
||||||
else
|
else
|
||||||
return val / 32768f;
|
return val / 32768f;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
class SDL2Texture : Texture
|
public override Batcher CreateBatcher()
|
||||||
{
|
|
||||||
private uint32 handle;
|
|
||||||
|
|
||||||
public this(int width, int height, uint8* pixels)
|
|
||||||
: base(width, height, pixels)
|
|
||||||
{
|
{
|
||||||
GL.glGenTextures(1, &handle);
|
return new SDL2Batcher();
|
||||||
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()
|
public override Shader CreateShader(ShaderDef def)
|
||||||
{
|
{
|
||||||
GL.glDeleteTextures(1, &handle);
|
return new SDL2Shader(def);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
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)
|
if (enabled && Open)
|
||||||
{
|
{
|
||||||
Draw.Rect(0, 0, Game.Width, Game.Height, .Black * 0.6f);
|
Game.Batcher.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, Game.Height - 14, Game.Width, 14, .Black * 0.6f);
|
||||||
|
|
||||||
//Entry
|
//Entry
|
||||||
if (entry.Length > 0)
|
if (entry.Length > 0)
|
||||||
|
@ -168,8 +168,8 @@ namespace Strawberry
|
||||||
if (row > 0)
|
if (row > 0)
|
||||||
pos.Y -= 4;
|
pos.Y -= 4;
|
||||||
|
|
||||||
Draw.Text(font, str, pos + .Down, .Black);
|
//Draw.Text(font, str, pos + .Down, .Black);
|
||||||
Draw.Text(font, str, pos, color);
|
//Draw.Text(font, str, pos, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
static private int MessageRows => (int)Math.Ceiling((Game.Height - 14) / 10f);
|
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]
|
[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);
|
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);
|
get => Invert(this);
|
||||||
|
|
||||||
|
@ -165,70 +165,70 @@ namespace Strawberry
|
||||||
|
|
||||||
//Static Helpers
|
//Static Helpers
|
||||||
|
|
||||||
public static Matrix CreateTranslation(Vector position)
|
public static Mat3x2 CreateTranslation(Vector position)
|
||||||
{
|
{
|
||||||
return Matrix(
|
return Mat3x2(
|
||||||
1, 0,
|
1, 0,
|
||||||
0, 1,
|
0, 1,
|
||||||
position.X, position.Y
|
position.X, position.Y
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Matrix CreateScale(Vector scale)
|
public static Mat3x2 CreateScale(Vector scale)
|
||||||
{
|
{
|
||||||
return Matrix(
|
return Mat3x2(
|
||||||
scale.X, 0,
|
scale.X, 0,
|
||||||
0, scale.Y,
|
0, scale.Y,
|
||||||
0, 0
|
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 tx = origin.X * (1 - scale.X);
|
||||||
float ty = origin.Y * (1 - scale.Y);
|
float ty = origin.Y * (1 - scale.Y);
|
||||||
|
|
||||||
return Matrix(
|
return Mat3x2(
|
||||||
scale.X, 0,
|
scale.X, 0,
|
||||||
0, scale.Y,
|
0, scale.Y,
|
||||||
tx, ty
|
tx, ty
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Matrix CreateScale(float scale)
|
public static Mat3x2 CreateScale(float scale)
|
||||||
{
|
{
|
||||||
return Matrix(
|
return Mat3x2(
|
||||||
scale, 0,
|
scale, 0,
|
||||||
0, scale,
|
0, scale,
|
||||||
0, 0
|
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 tx = origin.X * (1 - scale);
|
||||||
float ty = origin.Y * (1 - scale);
|
float ty = origin.Y * (1 - scale);
|
||||||
|
|
||||||
return Matrix(
|
return Mat3x2(
|
||||||
scale, 0,
|
scale, 0,
|
||||||
0, scale,
|
0, scale,
|
||||||
tx, ty
|
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 xTan = (float)Math.Tan(radiansX);
|
||||||
float yTan = (float)Math.Tan(radiansY);
|
float yTan = (float)Math.Tan(radiansY);
|
||||||
|
|
||||||
return Matrix(
|
return Mat3x2(
|
||||||
1, yTan,
|
1, yTan,
|
||||||
xTan, 1,
|
xTan, 1,
|
||||||
0, 0
|
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 xTan = (float)Math.Tan(radiansX);
|
||||||
float yTan = (float)Math.Tan(radiansY);
|
float yTan = (float)Math.Tan(radiansY);
|
||||||
|
@ -236,14 +236,14 @@ namespace Strawberry
|
||||||
float tx = -origin.Y * xTan;
|
float tx = -origin.Y * xTan;
|
||||||
float ty = -origin.X * yTan;
|
float ty = -origin.X * yTan;
|
||||||
|
|
||||||
return Matrix(
|
return Mat3x2(
|
||||||
1, yTan,
|
1, yTan,
|
||||||
xTan, 1,
|
xTan, 1,
|
||||||
tx, ty
|
tx, ty
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Matrix CreateRotation(float radians)
|
public static Mat3x2 CreateRotation(float radians)
|
||||||
{
|
{
|
||||||
let rad = (float)Math.IEEERemainder(radians, Math.PI_f * 2);
|
let rad = (float)Math.IEEERemainder(radians, Math.PI_f * 2);
|
||||||
|
|
||||||
|
@ -282,14 +282,14 @@ namespace Strawberry
|
||||||
s = (float)Math.Sin(rad);
|
s = (float)Math.Sin(rad);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Matrix(
|
return Mat3x2(
|
||||||
c, s,
|
c, s,
|
||||||
-s, c,
|
-s, c,
|
||||||
0, 0
|
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);
|
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 x = origin.X * (1 - c) + origin.Y * s;
|
||||||
float y = origin.Y * (1 - c) - origin.X * s;
|
float y = origin.Y * (1 - c) - origin.X * s;
|
||||||
|
|
||||||
return Matrix(
|
return Mat3x2(
|
||||||
c, s,
|
c, s,
|
||||||
-s, c,
|
-s, c,
|
||||||
x, y
|
x, y
|
||||||
|
@ -361,7 +361,7 @@ namespace Strawberry
|
||||||
return (M11 * M22) - (M21 * M12);
|
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);
|
let det = (matrix.M11 * matrix.M22) - (matrix.M21 * matrix.M12);
|
||||||
|
|
||||||
|
@ -370,7 +370,7 @@ namespace Strawberry
|
||||||
|
|
||||||
let invDet = 1.0f / det;
|
let invDet = 1.0f / det;
|
||||||
|
|
||||||
return Matrix(
|
return Mat3x2(
|
||||||
matrix.M22 * invDet,
|
matrix.M22 * invDet,
|
||||||
-matrix.M12 * 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.M11 + (b.M11 - a.M11) * t,
|
||||||
a.M12 + (b.M12 - a.M12) * 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.M11, -mat.M12,
|
||||||
-mat.M21, -mat.M22,
|
-mat.M21, -mat.M22,
|
||||||
-mat.M31, -mat.M32
|
-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.M11 + b.M11, a.M12 + b.M12,
|
||||||
a.M21 + b.M21, a.M22 + b.M22,
|
a.M21 + b.M21, a.M22 + b.M22,
|
||||||
a.M31 + b.M31, a.M32 + b.M32
|
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.M11 - b.M11, a.M12 - b.M12,
|
||||||
a.M21 - b.M21, a.M22 - b.M22,
|
a.M21 - b.M21, a.M22 - b.M22,
|
||||||
a.M31 - b.M31, a.M32 - b.M32
|
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.M11 + a.M12 * b.M21,
|
||||||
a.M11 * b.M12 + a.M12 * b.M22,
|
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.M11 * scale, a.M12 * scale,
|
||||||
a.M21 * scale, a.M22 * scale,
|
a.M21 * scale, a.M22 * scale,
|
||||||
a.M31 * scale, a.M32 * scale
|
a.M31 * scale, a.M32 * scale
|
||||||
|
@ -448,36 +448,36 @@ namespace Strawberry
|
||||||
|
|
||||||
// Operators
|
// Operators
|
||||||
|
|
||||||
public static Matrix operator -(Matrix mat)
|
public static Mat3x2 operator -(Mat3x2 mat)
|
||||||
{
|
{
|
||||||
return Matrix(
|
return Mat3x2(
|
||||||
-mat.M11, -mat.M12,
|
-mat.M11, -mat.M12,
|
||||||
-mat.M21, -mat.M22,
|
-mat.M21, -mat.M22,
|
||||||
-mat.M31, -mat.M32
|
-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.M11 + b.M11, a.M12 + b.M12,
|
||||||
a.M21 + b.M21, a.M22 + b.M22,
|
a.M21 + b.M21, a.M22 + b.M22,
|
||||||
a.M31 + b.M31, a.M32 + b.M32
|
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.M11 - b.M11, a.M12 - b.M12,
|
||||||
a.M21 - b.M21, a.M22 - b.M22,
|
a.M21 - b.M21, a.M22 - b.M22,
|
||||||
a.M31 - b.M31, a.M32 - b.M32
|
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.M11 + a.M12 * b.M21,
|
||||||
a.M11 * b.M12 + a.M12 * b.M22,
|
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.M11 * scale, mat.M12 * scale,
|
||||||
mat.M21 * scale, mat.M22 * scale,
|
mat.M21 * scale, mat.M22 * scale,
|
||||||
mat.M31 * scale, mat.M32 * 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.
|
return (a.M11 == b.M11 && a.M22 == b.M22 && // Check diagonal element first for early out.
|
||||||
a.M12 == b.M12 &&
|
a.M12 == b.M12 &&
|
||||||
|
@ -506,7 +506,7 @@ namespace Strawberry
|
||||||
a.M31 == b.M31 && a.M32 == b.M32);
|
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 ||
|
return (a.M11 != b.M11 || a.M12 != b.M12 ||
|
||||||
a.M21 != b.M21 || a.M22 != b.M22 ||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user