further changes, lazy loading, new modular backend system

This commit is contained in:
Booklordofthedings 2024-10-06 22:23:40 +02:00
parent c0e0c30eb8
commit c0dd04127c
68 changed files with 735 additions and 2865 deletions

View file

@ -0,0 +1,7 @@
FileVersion = 1
Dependencies = {corlib = "*", raylib-beef = "*", TheaterGui = "*"}
[Project]
Name = "raylib-backend"
TargetType = "BeefLib"
StartupObject = "raylib_backend.Program"

View file

@ -0,0 +1,45 @@
namespace raylib_backend;
using TheaterGui;
using TheaterGui.Core;
using TheaterGui.Core.Structs;
using System;
using System.Collections;
using RaylibBeef;
class PlatformRaylib : IPlatformLayer
{
private RenderTexture2D _ScreenTexture;
private TextureManager _TextureManager;
private Color _BackgroundColor = Raylib.WHITE;
private Dictionary<String, Font> _LoadedFonts = new .() ~ DeleteDictionaryAndKeys!(_);
private static uint8[?] _Texture_WindowIcon = Compiler.ReadBinary("../assets/64.png");
public void Initialize(StringView pWindowTitle, int32 pWidth, int32 pHeight)
{
Raylib.SetConfigFlags((.)(ConfigFlags.FLAG_WINDOW_RESIZABLE | ConfigFlags.FLAG_WINDOW_HIGHDPI));
String title = scope .(pWindowTitle);
Raylib.InitWindow(pWidth, pHeight, title);
Raylib.SetExitKey(0);
Raylib.SetWindowMinSize(640, 360);
Raylib.SetTargetFPS(40);
var icon = Raylib.LoadImageFromMemory(".png", (.)&_Texture_WindowIcon, _Texture_WindowIcon.Count);
Raylib.SetWindowIcon(icon);
Raylib.UnloadImage(icon);
_ScreenTexture = Raylib.LoadRenderTexture(Raylib.GetRenderWidth(), Raylib.GetRenderHeight());
_TextureManager = new .();
}
public void Deinitialize()
{
for(var i in _LoadedFonts)
Raylib.UnloadFont(i.value);
Raylib.UnloadRenderTexture(_ScreenTexture);
delete _TextureManager;
}
}

View file

@ -0,0 +1,31 @@
namespace raylib_backend;
using RaylibBeef;
using TheaterGui.Core;
using TheaterGui.Core.Structs;
extension PlatformRaylib
{
///Converts a TGColor into a raylib compatible color
private Color Convert(color pColor)
{
return .(pColor.Red, pColor.Green, pColor.Blue, pColor.Alpha);
}
///Convert a TGRect into a raylib compatible rectangle
private Rectangle Convert(rect pRect)
{
return .(pRect.x, pRect.y, pRect.width, pRect.height);
}
private float[2] Convert(Vector2 pVector)
{
return .(pVector.x, pVector.y);
}
private Vector2 Convert(int32[2] pValues)
{
return .(pValues[0], pValues[1]);
}
}

View file

@ -0,0 +1,95 @@
namespace raylib_backend;
using TheaterGui.Core.Structs;
using System;
using System.Collections;
using RaylibBeef;
extension PlatformRaylib
{
public void StartDrawing()
{
Raylib.BeginDrawing();
Raylib.ClearBackground(_BackgroundColor);
Raylib.BeginTextureMode(_ScreenTexture);
Raylib.ClearBackground(_BackgroundColor);
}
public void StopDrawing()
{
Raylib.EndTextureMode();
Raylib.DrawTexturePro(
_ScreenTexture.texture,
.(0, 0, _ScreenTexture.texture.width, -_ScreenTexture.texture.height),
.(0, 0, Raylib.GetScreenWidth(), Raylib.GetScreenHeight()),
.(0, 0),
0,
Raylib.WHITE
);
Raylib.EndDrawing();
}
public void RedrawLastFrame()
{
Raylib.BeginDrawing();
Raylib.ClearBackground(_BackgroundColor);
Raylib.DrawTexturePro(
_ScreenTexture.texture,
.(0, 0, _ScreenTexture.texture.width, -_ScreenTexture.texture.height),
.(0, 0, Raylib.GetScreenWidth(), Raylib.GetScreenHeight()),
.(0, 0),
0,
Raylib.WHITE
);
Raylib.EndDrawing();
}
public void ChangeBackgroundColor(color pTint)
{
_BackgroundColor = Convert(pTint);
}
public void LoadTexture(Span<uint8> pData, StringView pName)
{
_TextureManager.[Friend]LoadAsset(pData, pName);
}
public void DrawTexture(StringView pName, rect pTarget, color pTints)
{
if(_TextureManager.GetAsset(pName) case .Ok(let val))
{
Raylib.DrawTexturePro(
*val.Source,
val.SourceRect,
Convert(pTarget),
.(0,0), 0,
Convert(pTints)
);
}
else
Raylib.DrawRectangle(pTarget.x, pTarget.y, pTarget.width, pTarget.height, Raylib.PINK);
}
public int32[2] MeasureTextureSize(StringView pName)
{
if(_TextureManager.GetAsset(pName) case .Ok(let val))
{
return .(val.Width, val.Height);
}
return .(0,0);
}
public void DrawColorRect(rect pTarget, color pTint)
{
Raylib.DrawRectangleRec(Convert(pTarget), Convert(pTint));
}
public void DrawColorRectOutlined(rect pTarget, color pTint, color pOutlineTint)
{
Raylib.DrawRectangleRec(Convert(pTarget), Convert(pTint));
Raylib.DrawRectangleLinesEx(Convert(pTarget), 1, Convert(pOutlineTint));
}
}

View file

@ -0,0 +1,31 @@
namespace raylib_backend;
using RaylibBeef;
extension PlatformRaylib
{
public bool ShouldClose() => Raylib.WindowShouldClose();
public float[2] MousePosition() => Convert(Raylib.GetMousePosition());
public float[2] MouseDelta() => Convert(Raylib.GetMouseDelta());
public bool MouseLeftClick() => Raylib.IsMouseButtonDown(0);
public bool MouseRightClick() => Raylib.IsMouseButtonDown(1);
public float MouseWheel() => Raylib.GetMouseWheelMoveV().y;
public int32[2] ScreenSize()
{
int32[2] ScreenSize = .();
ScreenSize[0] = Raylib.GetScreenWidth();
ScreenSize[1] = Raylib.GetScreenHeight();
//The size of the render texture is also automatically changed to always fit
if(ScreenSize[0] != _ScreenTexture.texture.width || ScreenSize[1] != _ScreenTexture.texture.height)
{
Raylib.UnloadRenderTexture(_ScreenTexture);
_ScreenTexture = Raylib.LoadRenderTexture(ScreenSize[0], ScreenSize[1]);
}
return ScreenSize;
}
}

View file

@ -0,0 +1,42 @@
namespace raylib_backend;
using TheaterGui.Core.Structs;
using System;
using RaylibBeef;
extension PlatformRaylib
{
public void LoadFont(Span<uint8> pData, StringView pName, uint8 pFontSize)
{
var font = Raylib.LoadFontFromMemory(".ttf", (.)pData.Ptr, (.)pData.Length, pFontSize, null, 256);
if(_LoadedFonts.ContainsKeyAlt<StringView>(pName))
{
Raylib.UnloadFont(_LoadedFonts[scope .(pName)]);
_LoadedFonts[scope .(pName)] = font;
}
else
_LoadedFonts.Add(new .(pName), font);
}
public void DrawText(StringView pText, StringView pFont, int32[2] pPosition, color pTint)
{
if(_LoadedFonts.GetValue(scope .(pFont)) case .Ok(let val))
Raylib.DrawTextEx(val, scope String(pText), Convert(pPosition), val.baseSize, 1, Convert(pTint));
else
Raylib.DrawText(scope String(pText), pPosition[0], pPosition[1], 10, Raylib.PINK);
}
public int32[2] MeasureTextSize(StringView pText, StringView pFont)
{
if(_LoadedFonts.GetValue(scope .(pFont)) case .Ok(let val))
{
var res = Raylib.MeasureTextEx(val, scope String(pText), val.baseSize, 1);
return .((.)res.x, (.)res.y);
}
else
return .(Raylib.MeasureText(scope String(pText), 10), 10);
}
}

View file

@ -0,0 +1,145 @@
namespace raylib_backend;
using System;
using System.Collections;
using RaylibBeef;
class TextureManager
{
private List<Node> _Containers = new .() ~ DeleteContainerAndItems!(_);
private List<RenderTexture> _Textures = new .() ~ delete _;
private Dictionary<String, sprite> _TileMap = new .() ~ DeleteDictionaryAndKeys!(_);
///Attempt to get a existing asset by StringView
public Result<sprite> GetAsset(StringView acess)
{
if (!_TileMap.ContainsKeyAlt<StringView>(acess))
return .Err;
return .Ok(_TileMap[scope .(acess)]);
}
private void LoadAsset(Span<uint8> data, StringView name)
{
var img = Raylib.LoadImageFromMemory(".png", (.)data.Ptr, (.)data.Length);
defer Raylib.UnloadImage(img);
var s = Insert(img);
_TileMap.Add(new .(name), s);
}
private sprite Insert(Image toInsert)
{
for (var i in _Containers)
{
var res = i.Insert(toInsert);
if (res != null)
{
Raylib.BeginDrawing();
Raylib.BeginTextureMode(_Textures[@i.Index]);
#if BF_PLATFORM_WINDOWS || BF_PLATFORM_LINUX
var img = Raylib.LoadTextureFromImage((.)res.id);
#elif BF_PLATFORM_WASM
var img = Raylib.LoadTextureFromImage((Image)res.id);
#endif
Raylib.DrawTexturePro(img, Rectangle(0, 0, img.width, -img.height), Rectangle((.)res.rc[0], 2048 - res.rc[1] - (.)res.rc[3], img.width, img.height), Vector2(0, 0), 0, Raylib.WHITE);
Raylib.EndTextureMode();
Raylib.EndDrawing();
Raylib.UnloadTexture(img);
sprite toReturn = .();
toReturn.Source = &_Textures[@i.Index].texture;
toReturn.Height = (.)res.rc[3];
toReturn.Width = (.)res.rc[2];
toReturn.SourceRect = .(res.rc[0], res.rc[1], res.rc[2], res.rc[3]);
return toReturn;
}
}
_Containers.Add(new .());
_Textures.Add(Raylib.LoadRenderTexture(2048, 2048));
Raylib.BeginDrawing();
Raylib.BeginTextureMode(_Textures[_Textures.Count - 1]);
Raylib.ClearBackground(Raylib.BLANK);
Raylib.EndTextureMode();
Raylib.EndDrawing();
return Insert(toInsert);
}
class Node
{
public Node[2] childs = .(null, null);
public uint64[4] rc = .(0, 0, 2048, 2048); //x,y, width, height
public Image? id;
public Node Insert(Image toInsert)
{
if (!(childs[0] == null && childs[1] == null))
{
var newNode = childs[0].Insert(toInsert);
if (newNode != null) return newNode;
newNode = childs[1].Insert(toInsert);
if (newNode != null) return newNode;
}
else //Insert
{
if (id != null)
return null;
if (toInsert.width > (.)rc[2] || toInsert.height > (.)rc[3])
return null;
if (toInsert.width == (.)rc[2] && toInsert.height == (.)rc[3])
{
id = toInsert;
return this;
}
childs[0] = new .();
childs[1] = new .();
var dw = rc[2] - (.)toInsert.width;
var dh = rc[3] - (.)toInsert.height;
if (dw > dh)
{
childs[0].rc = .(rc[0], rc[1], (.)toInsert.width, rc[3]);
childs[1].rc = .(rc[0] + (.)toInsert.width, rc[1],
rc[2] - (.)toInsert.width, rc[3]);
}
else
{
childs[0].rc = .(rc[0], rc[1],
rc[2], (.)toInsert.height);
childs[1].rc = .(rc[0], rc[1] + (.)toInsert.height,
rc[2], rc[3] - (.)toInsert.height);
}
return childs[0].Insert(toInsert);
}
return null;
}
public ~this()
{
if (childs[0] != null)
delete childs[0];
if (childs[1] != null)
delete childs[1];
}
}
}
struct sprite
{
public Texture2D* Source;
public Rectangle SourceRect;
public int32 Width = 0;
public int32 Height = 0;
public float Rotation = 0;
public void Render(float x, float y, Color color = Raylib.WHITE)
{
Raylib.DrawTexturePro(*Source, SourceRect, Rectangle(x + Width / 2, y + Height / 2, Width, Height), Vector2(Width / 2, Height / 2), Rotation, color);
}
}