Add Drawlist

- Add Pool iterator support
- Add Pool Expandability
- Add Pool::Push
- Add Lithium Maths API
- Remove InitPools
- update spirv-helper
This commit is contained in:
2026-03-19 22:06:58 +01:00
parent e6cd8b7d24
commit afe30a5dbd
13 changed files with 541 additions and 42 deletions

View File

@@ -8,7 +8,7 @@ class Pool {
public:
using value_type = T;
using iterator = T*;
using const_iterator = const iterator*;
using const_iterator = const T*;
Pool() = default;
~Pool() {
@@ -36,21 +36,34 @@ class Pool {
Pool& operator=(Pool&&) = delete;
T* Allocate(size_t num = 1) {
if (CheckLimits(num)) return nullptr;
ExpandIf(num);
T* ret = &pData[pPos];
pPos += num;
return ret;
}
bool CheckLimits(size_t num) {
if ((pPos + num) >= pCap) {
throw std::runtime_error(
std::format("[PD::Pool]: Trying to allocate {} elements but this is "
"going out of range ({}/{})",
num, pPos + num, pCap));
return true;
void Push(const T& elem) {
T* e = Allocate(1);
*e = elem;
}
void ExpandIf(size_t req) {
if ((pPos + req) <= pCap) return;
size_t ncap = std::max(pCap * 2, pPos + req);
T* nu = pAlloc.allocate(ncap);
if (pData) {
for (size_t i = 0; i < pPos; i++) {
std::allocator_traits<Alloc>::construct(
pAlloc, &nu[i], std::move_if_noexcept(pData[i]));
}
pAlloc.deallocate(pData, pCap);
}
return false;
for (size_t i = pPos; i < ncap; i++) {
std::allocator_traits<Alloc>::construct(pAlloc, &nu[i]);
}
PDLOG("Pool::ExpandIf({}): {} -> {}", req, pCap, ncap);
pData = nu;
pCap = ncap;
}
void Reset() {
@@ -67,6 +80,10 @@ class Pool {
size_t capacity() const { return pCap; }
T& at(size_t idx) { return pData[idx]; }
const T& at(size_t idx) const { return pData[idx]; }
iterator begin() { return pData; }
iterator end() { return pData + pPos; }
const_iterator begin() const { return pData; }
const_iterator end() const { return pData + pPos; }
T& operator[](size_t idx) { return at(idx); }
const T& operator[](size_t idx) const { return at(idx); }

View File

@@ -34,6 +34,7 @@ class PD_API GfxDriver : public DriverInterface {
}
virtual void DeleteTexture(const Li::Texture& tex) {}
virtual void Draw(const Pool<Li::Command>& commands) {}
Li::Texture::Ptr GetWhiteTexture() { return &pWhite; }
protected:
virtual void SysDeinit() {}
@@ -55,6 +56,7 @@ class PD_API GfxDriver : public DriverInterface {
Mat4 Projection;
ivec2 ViewPort;
std::unordered_map<TextureID, Li::Texture> pTextureRegestry;
Li::Texture pWhite;
};
struct DefaultGfxConfig {
@@ -79,9 +81,11 @@ class GfxDriverBase : public GfxDriver {
virtual ~GfxDriverBase() {}
void Init() override {
pVtxPool.Init(Config::NumVertices);
pIdxPool.Init(Config::NumIndices);
// pVtxPool.Init(Config::NumVertices);
// pIdxPool.Init(Config::NumIndices);
SysInit();
std::vector<u8> img(16 * 16 * 4, 0xff);
pWhite = LoadTexture(img, 16, 16);
}
void Draw(const Pool<Li::Command>& commands) override {
@@ -90,11 +94,12 @@ class GfxDriverBase : public GfxDriver {
while (index < commands.size()) {
CurrentTex = commands[index].Tex;
if (!CurrentTex) {
index++;
continue;
CurrentTex = pWhite.GetID();
}
size_t startidx = CurrentIndex;
while (index < commands.size() && CurrentTex == commands[index].Tex) {
while (index < commands.size() &&
(CurrentTex == commands[index].Tex ||
(CurrentTex == pWhite.GetID() && commands[index].Tex == 0))) {
const auto& c = commands[index];
CountVertices += c.VertexCount;
CountIndices += c.IndexCount;
@@ -155,6 +160,9 @@ class PD_API Gfx {
static void DeleteTexture(const Li::Texture& tex) {
driver->DeleteTexture(tex);
}
static Li::Texture::Ptr GetWhiteTexture() {
return driver->GetWhiteTexture();
}
static const char* GetDriverName() { return driver->GetName(); }

View File

@@ -0,0 +1,116 @@
#pragma once
#include <pd/lithium/command.hpp>
#include <pd/lithium/texture.hpp>
using LiPathRectFlags = PD::u32;
enum LiPathRectFlags_ : PD::u32 {
LiPathRectFlags_None = 0,
LiPathRectFlags_KeepTopLeft = 1 << 0,
LiPathRectFlags_KeepTopRight = 1 << 1,
LiPathRectFlags_KeepBotRight = 1 << 2,
LiPathRectFlags_KeepBotLeft = 1 << 3,
LiPathRectFlags_KeepTop =
LiPathRectFlags_KeepTopLeft | LiPathRectFlags_KeepTopRight,
LiPathRectFlags_KeepBot =
LiPathRectFlags_KeepBotLeft | LiPathRectFlags_KeepBotRight,
LiPathRectFlags_KeepLeft =
LiPathRectFlags_KeepTopLeft | LiPathRectFlags_KeepBotLeft,
LiPathRectFlags_KeepRight =
LiPathRectFlags_KeepTopRight | LiPathRectFlags_KeepBotRight,
};
using LiDrawFlags = PD::u32;
enum LiDrawFlags_ : PD::u32 {
LiDrawFlags_None = 0,
LiDrawFlags_Close = 1 << 0,
};
using LiTextFlags = PD::u32;
enum LiTextFlags_ : PD::u32 {
LiTextFlags_None = 0, ///< Do nothing
LiTextFlags_AlignRight = 1 << 0, ///< Align Right of position
LiTextFlags_AlignMid = 1 << 1, ///< Align in the middle of pos and box
LiTextFlags_Shaddow = 1 << 2, ///< Draws the text twice to create shaddow
LiTextFlags_Wrap = 1 << 3, ///< Wrap Text: May be runs better with TMS
LiTextFlags_Short = 1 << 4, ///< Short Text: May be runs better with TMS
LiTextFlags_Scroll = 1 << 5, ///< Not implemented [scoll text if to long]
LiTextFlags_NoOOS = 1 << 6, ///< No Out of Screen Rendering
};
namespace PD {
namespace Li {
class PD_API Drawlist {
public:
Drawlist();
~Drawlist();
/** Baisc */
void Merge(Drawlist& other);
void Copy(Drawlist& other);
void Optimize();
void Clear();
/** Command Allocation */
Command& NewCommand();
/** Path API */
void PathAdd(const fvec2& point) { pPath.Push(point); }
void PathAdd(float x, float y) { pPath.Push(fvec2(x, y)); }
void PathClear() { pPath.Reset(); }
/**
* @brief Reserve memory for the next PathAdd uses
* @note As path will autoexpant and keep the size this func is
* only for special use cases
*/
void PathReserve(size_t num) { pPath.ExpandIf(num); }
void PathStroke(u32 color, int t = 1, LiDrawFlags flags = LiDrawFlags_None);
void PathFill(u32 color);
void PathArcToN(const fvec2& c, float r, float amin, float amax, int s);
void PathFastArcToN(const fvec2& c, float r, float amin, float amax, int s);
void PathRect(const fvec2& tl, const fvec2& br, float r = 0.f);
void PathRectEx(const fvec2& tl, const fvec2& br, float r = 0.f,
LiPathRectFlags flags = LiPathRectFlags_None);
/** Texture Handling */
void BindTexture(const Texture& tex);
void UnbindTexture() { pCurrentTexture = Texture(); }
/** Data geters */
const Pool<Command>& Data() const { return pCommands; }
operator const Pool<Command>&() const { return pCommands; }
/** Drawing functions */
void DrawRect(const fvec2& pos, const fvec2& size, u32 color, int t = 1);
void DrawRectFilled(const fvec2& pos, const fvec2& size, u32 color);
void DrawTriangle(const fvec2& a, const fvec2& b, const fvec2& c, u32 color,
int t = 1);
void DrawTriangleFilled(const fvec2& a, const fvec2& b, const fvec2& c,
u32 color);
void DrawCircle(const fvec2& center, float rad, u32 color, int num_segments,
int t = 1);
void DrawCircleFilled(const fvec2& center, float rad, u32 color,
int num_segments);
void DrawText(const fvec2& p, const char* text, u32 color);
void DrawTextEx(const fvec2& p, const char* text, u32 color,
LiTextFlags flags, const fvec2& box = fvec2(0.f));
void DrawPolyLine(const Pool<fvec2>& points, u32 color,
LiDrawFlags flags = LiDrawFlags_None, int t = 1);
void DrawConvexPolyFilled(const Pool<fvec2>& points, u32 color);
void PrimQuad(Command& cmd, const Rect& quad, const Rect& uv, u32 color);
void PrimTriangle(Command& cmd, const fvec2& a, const fvec2& b,
const fvec2& c, u32 color);
private:
Texture pCurrentTexture;
Pool<Command> pCommands;
Pool<fvec2> pPath;
Pool<Vertex> pVertices;
Pool<u16> pIndices;
};
} // namespace Li
} // namespace PD

View File

@@ -1,5 +1,7 @@
#pragma once
#include <pd/lithium/command.hpp>
#include <pd/lithium/drawlist.hpp>
#include <pd/lithium/math.hpp>
#include <pd/lithium/pools.hpp>
#include <pd/lithium/vertex.hpp>
#include <pd/lithium/vertex.hpp>

View File

@@ -0,0 +1,18 @@
#pragma once
#include <pd/core/core.hpp>
#include <pd/lithium/rect.hpp>
namespace PD {
namespace Li {
namespace Math {
PD_API bool InBounds(const fvec2& pos, const fvec2& size, const fvec4& rect);
PD_API bool InBounds(const fvec2& pos, const fvec4& rect);
PD_API bool InBounds(const fvec2& a, const fvec2& b, const fvec2& c,
const fvec4& rect);
PD_API void RotateCorner(fvec2& pos, float sinus, float cosinus);
PD_API Rect PrimRect(const fvec2& pos, const fvec2& size, float angle = 0.f);
PD_API Rect PrimLine(const fvec2& a, const fvec2& b, int t = 1);
} // namespace Math
} // namespace Li
} // namespace PD

View File

@@ -5,8 +5,8 @@
namespace PD {
namespace Li {
PD_API void InitPools(size_t max_vertices = 32768);
PD_API Vertex* AllocateVertices(size_t count);
PD_API u16* AllocateIndices(size_t count);
PD_API void ResetPools();
} // namespace Li
} // namespace PD

View File

@@ -18,6 +18,7 @@ enum class TextureFormat {
namespace Li {
class Texture {
public:
using Ptr = Texture*;
Texture() : pID(0), pSize(0, 0), pUV(fvec4(0, 0, 1, 1)) {}
Texture(TextureID id, ivec2 size)
: pID(id), pSize(size), pUV(fvec4(0, 0, 1, 1)) {}