Implement Text Rendering

Added STB truetype
Switched AssetMgr to use Shared Ptr
This commit is contained in:
2025-12-07 23:20:15 +01:00
parent 28d2e291b3
commit 88e367a299
17 changed files with 5504 additions and 44 deletions

View File

@@ -1,9 +1,12 @@
#pragma once
#include <amethyst/types.hpp>
namespace Amy {
class Asset {
public:
Asset() = default;
virtual ~Asset() = default;
AMY_SHARED(Asset);
};
} // namespace Amy

View File

@@ -3,6 +3,7 @@
#include <amethyst/id.hpp>
#include <amethyst/texture.hpp>
#include <amethyst/types.hpp>
#include <memory>
namespace Amy {
class AssetMgr {
@@ -12,7 +13,7 @@ class AssetMgr {
void AutoLoad(const ID& name, ksr path);
void Add(const ID& id, Asset* v) {
void Add(const ID& id, Asset::Ref v) {
if (pAssets.count(id)) {
throw std::runtime_error("[amy]: assets: " + id.GetName() +
" already exists!");
@@ -27,12 +28,12 @@ class AssetMgr {
}
template <typename T>
T* Get(const ID& id) {
std::shared_ptr<T> Get(const ID& id) {
auto r = pAssets.find(id);
if (r == pAssets.end()) {
throw std::runtime_error("[amy] assets: unable to find " + id.GetName());
}
if (auto v = dynamic_cast<T*>(r->second)) {
if (auto v = std::dynamic_pointer_cast<T>(r->second)) {
return v;
} else {
throw std::runtime_error(id.GetName() + " is not of type " +
@@ -46,14 +47,14 @@ class AssetMgr {
if (r == pAssets.end()) {
throw std::runtime_error("[amy] assets: unable to find " + id.GetName());
}
return dynamic_cast<T*>(r->second) != nullptr;
return std::dynamic_pointer_cast<T>(r->second) != nullptr;
}
template <typename T>
size_t Count() const {
size_t ret = 0;
for (auto& it : pAssets) {
if (dynamic_cast<T*>(it.second)) {
if (std::dynamic_pointer_cast<T>(it.second)) {
ret++;
}
}
@@ -61,6 +62,6 @@ class AssetMgr {
}
private:
std::map<ID, Asset*> pAssets;
std::map<ID, Asset::Ref> pAssets;
};
} // namespace Amy

View File

@@ -42,6 +42,7 @@ class C3D {
Shader(ksr path);
Shader() {}
~Shader();
AMY_SHARED(Shader);
void Load(ksr path);
void Load(kvr<uc> data);

View File

@@ -8,6 +8,17 @@
#include <amethyst/texture.hpp>
#include <amethyst/types.hpp>
using AmyTextFlags = Amy::ui;
enum AmyTextFlags_ {
AmyTextFlags_None = 0, ///< Do nothing
AmyTextFlags_AlignRight = 1 << 0, ///< Align Right of position
AmyTextFlags_AlignMid = 1 << 1, ///< Align in the middle of pos and box
AmyTextFlags_Shaddow = 1 << 2, ///< Draws the text twice to create shaddow
AmyTextFlags_Wrap = 1 << 3, ///< Wrap Text: May be runs better with TMS
AmyTextFlags_Short = 1 << 4, ///< Short Text: May be runs better with TMS
AmyTextFlags_Scroll = 1 << 5, ///< Not implemented [scoll text if to long]
};
namespace Amy {
class Iron {
public:
@@ -51,7 +62,7 @@ class Iron {
bool ScissorOn = false;
int Layer = 0;
int Index = 0;
Texture* Tex = nullptr;
Texture::Ref Tex = nullptr;
};
class Font {
@@ -59,7 +70,7 @@ class Iron {
struct Codepoint {
ui Cp = 0;
fvec4 Uv;
Texture* Tex;
Texture::Ref Tex;
fvec2 Size;
float Offset = 0; // Unused??
bool Valid = true;
@@ -80,12 +91,13 @@ class Iron {
fvec2 GetTextBounds(ksr text, float scale);
void CmdTextEx(vec<Command::Ref>& cmds, const fvec2& pos, ui color,
float scale, ksr text, ui flags = 0, const fvec2& box = 0);
void pMakeAtlas(bool final, vec<uc>& pixels, int size, Texture* tex);
float scale, ksr text, AmyTextFlags flags = 0,
const fvec2& box = 0);
void pMakeAtlas(bool final, vec<uc>& pixels, int size, Texture::Ref tex);
int PxHeight;
int PxFactor = 24;
vec<Texture*> Textures;
vec<Texture::Ref> Textures;
std::map<u32, Codepoint> pCodeMap;
};
@@ -108,7 +120,8 @@ class Iron {
void Clear();
void DrawSolid();
void DrawTex(Texture* tex) { pTex = tex; }
void DrawTex(Texture::Ref tex) { pTex = tex; }
void SetFont(Font::Ref fnt) { pCurrentFont = fnt; }
/** Draw Api */
void DrawRect(const fvec2& pos, const fvec2& size, ui color,
@@ -160,10 +173,11 @@ class Iron {
void clipCmd(Command* ptr);
std::vector<Command::Ref> pData;
std::vector<fvec2> pPath;
Texture* pTex = nullptr;
Texture::Ref pTex = nullptr;
std::stack<fvec4> ClipRects;
Font* pCurrentFont;
Font::Ref pCurrentFont;
int pLayer = 0;
float pFontScale = 0.7;
};
Iron() = default;
~Iron() = default;
@@ -173,7 +187,7 @@ class Iron {
static void NewFrame();
static void DrawOn(C3D::Screen* screen);
static void Draw(const std::vector<Command::Ref>& data);
static Texture* WhiteTex() { return m_solid; }
static Texture::Ref WhiteTex() { return m_solid; }
/** Static renderer utility funcs */
@@ -185,7 +199,7 @@ class Iron {
const fvec2& c, ui clr);
static void CmdConvexPolyFilled(Command* cmd,
const std::vector<fvec2>& points, ui clr,
Texture* tex);
Texture::Ref tex);
static bool InBox(const fvec2& pos, const fvec2& size, const fvec4& area);
static bool InBox(const fvec2& pos, const fvec4& area);
static bool InBox(const fvec2& a, const fvec2& b, const fvec2& c,
@@ -206,7 +220,7 @@ class Iron {
static C3D::Shader* m_shader;
static mat4 m_mtx;
static int m_idx, m_vtx;
static Texture* m_solid;
static Texture::Ref m_solid;
static ui VertexCount;
static ui IndexCount;
};

View File

@@ -12,10 +12,22 @@ class Texture : public Asset {
public:
Texture() = default;
Texture(ksr path);
Texture(C3D_Tex* tex, const ivec2& size, const Rect& uv) {
Load(tex, size, uv);
}
~Texture();
AMY_SHARED(Texture);
void Load(ksr path);
void Load(kvr<uc> pixels, int w, int h, int bpp = 4,
Image::Format fmt = Image::RGBA);
void Load(C3D_Tex* tex, const ivec2& size, const Rect& uv) {
Unload();
pTex = tex;
pSize = size;
pUv = uv;
// Dont set as loaded as only the root tex can be loaded
}
void Unload();
int W() const { return pSize.x; }
@@ -26,7 +38,7 @@ class Texture : public Asset {
ivec2& Size() { return pSize; }
Rect& Uv() { return pUv; }
C3D_Tex* Ptr() { return pLoaded ? pTex : nullptr; }
C3D_Tex* Ptr() { return pTex; }
void Bind(int reg = 0);

View File

@@ -16,6 +16,8 @@ bool IsSingleBitNum(ui v);
ull GetTimeNano();
ull GetTimeMicro();
ull GetTimeMilli();
void String2U16(us* res, ksr src, size_t max);
std::string U16toU8(us* in, size_t max);
/**
* FNV Hash functiom (32 Bit)
* https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function