Implement clipping

This commit is contained in:
2026-09-08 21:15:21 +02:00
parent aec9083ebb
commit 0dbf430c0c
16 changed files with 66 additions and 9 deletions
@@ -29,6 +29,7 @@ class GfxCitro3D : public GfxDriverBase<GfxCitro3DConfig> {
TextureFilter filter = TextureFilter::Linear) override; TextureFilter filter = TextureFilter::Linear) override;
void DeleteTexture(const Li::Texture& tex) override; void DeleteTexture(const Li::Texture& tex) override;
void UploadPools() override; void UploadPools() override;
void ClipRect() override;
private: private:
struct Impl; struct Impl;
@@ -29,6 +29,7 @@ class GfxDirectX9 : public GfxDriverBase<GfxDirectX9Config> {
TextureFilter filter = TextureFilter::Linear) override; TextureFilter filter = TextureFilter::Linear) override;
void DeleteTexture(const Li::Texture& tex) override; void DeleteTexture(const Li::Texture& tex) override;
void UploadPools() override; void UploadPools() override;
void ClipRect() override;
private: private:
struct Impl; struct Impl;
@@ -28,6 +28,7 @@ class GfxOpenGL2 : public GfxDriverBase<GfxOpenGL2Config> {
TextureFilter filter = TextureFilter::Linear) override; TextureFilter filter = TextureFilter::Linear) override;
void DeleteTexture(const Li::Texture& tex) override; void DeleteTexture(const Li::Texture& tex) override;
void UploadPools() override; void UploadPools() override;
void ClipRect() override;
private: private:
void pSetupShaderAttribs(u32 shader); void pSetupShaderAttribs(u32 shader);
@@ -28,6 +28,7 @@ class GfxOpenGL3 : public GfxDriverBase<GfxOpenGL3Config> {
TextureFilter filter = TextureFilter::Linear) override; TextureFilter filter = TextureFilter::Linear) override;
void DeleteTexture(const Li::Texture& tex) override; void DeleteTexture(const Li::Texture& tex) override;
void UploadPools() override; void UploadPools() override;
void ClipRect() override;
private: private:
u32 pShader = 0; u32 pShader = 0;
+3
View File
@@ -264,6 +264,8 @@ void GfxCitro3D::UploadPools() {
BufInfo_Init(buf); BufInfo_Init(buf);
BufInfo_Add(buf, GetVertexBufPtr(0), sizeof(Li::Vertex), 3, 0x210); BufInfo_Add(buf, GetVertexBufPtr(0), sizeof(Li::Vertex), 3, 0x210);
} }
void GfxCitro3D::ClipRect() {}
} // namespace PD } // namespace PD
#else #else
namespace PD { namespace PD {
@@ -283,5 +285,6 @@ Li::Texture GfxCitro3D::LoadTexture(const std::vector<PD::u8>& pixels, int w,
} }
void GfxCitro3D::DeleteTexture(const Li::Texture& tex) {} void GfxCitro3D::DeleteTexture(const Li::Texture& tex) {}
void GfxCitro3D::UploadPools() {} void GfxCitro3D::UploadPools() {}
void GfxCitro3D::ClipRect() {}
} // namespace PD } // namespace PD
#endif #endif
+3
View File
@@ -285,6 +285,8 @@ void GfxDirectX9::UploadPools() {
memcpy(iptr, GetIndexBufPtr(0), GetIndexPoolSize() * sizeof(u16)); memcpy(iptr, GetIndexBufPtr(0), GetIndexPoolSize() * sizeof(u16));
impl->IBO->Unlock(); impl->IBO->Unlock();
} }
void GfxDirectX9::ClipRect() {}
} // namespace PD } // namespace PD
#else #else
namespace PD { namespace PD {
@@ -304,5 +306,6 @@ Li::Texture GfxDirectX9::LoadTexture(const std::vector<PD::u8>& pixels, int w,
} }
void GfxDirectX9::DeleteTexture(const Li::Texture& tex) {} void GfxDirectX9::DeleteTexture(const Li::Texture& tex) {}
void GfxDirectX9::UploadPools() {} void GfxDirectX9::UploadPools() {}
void GfxDirectX9::ClipRect() {}
} // namespace PD } // namespace PD
#endif #endif
+11
View File
@@ -183,6 +183,16 @@ void GfxOpenGL2::UploadPools() {
glBufferData(GL_ELEMENT_ARRAY_BUFFER, GetIndexPoolSize() * sizeof(u16), glBufferData(GL_ELEMENT_ARRAY_BUFFER, GetIndexPoolSize() * sizeof(u16),
GetIndexBufPtr(0), GL_DYNAMIC_DRAW); GetIndexBufPtr(0), GL_DYNAMIC_DRAW);
} }
void GfxOpenGL2::ClipRect() {
if (CurrentHasClip) {
glEnable(GL_SCISSOR_TEST);
glScissor(CurrentClip.x, ViewPort.y - (CurrentClip.y + CurrentClip.w),
CurrentClip.z, CurrentClip.w);
} else {
glDisable(GL_SCISSOR_TEST);
}
}
} // namespace PD } // namespace PD
#else #else
namespace PD { namespace PD {
@@ -203,5 +213,6 @@ Li::Texture GfxOpenGL2::LoadTexture(const std::vector<PD::u8>& pixels, int w,
void GfxOpenGL2::DeleteTexture(const Li::Texture& tex) {} void GfxOpenGL2::DeleteTexture(const Li::Texture& tex) {}
void GfxOpenGL2::pSetupShaderAttribs(u32 shader) {} void GfxOpenGL2::pSetupShaderAttribs(u32 shader) {}
void GfxOpenGL2::UploadPools() {} void GfxOpenGL2::UploadPools() {}
void GfxOpenGL2::ClipRect() {}
} // namespace PD } // namespace PD
#endif #endif
+11
View File
@@ -159,6 +159,16 @@ void GfxOpenGL3::UploadPools() {
glBindVertexArray(0); glBindVertexArray(0);
} }
void GfxOpenGL3::ClipRect() {
if (CurrentHasClip) {
glEnable(GL_SCISSOR_TEST);
glScissor(CurrentClip.x, ViewPort.y - (CurrentClip.y + CurrentClip.w),
CurrentClip.z, CurrentClip.w);
} else {
glDisable(GL_SCISSOR_TEST);
}
}
} // namespace PD } // namespace PD
#else #else
namespace PD { namespace PD {
@@ -178,5 +188,6 @@ Li::Texture GfxOpenGL3::LoadTexture(const std::vector<PD::u8>& pixels, int w,
} }
void GfxOpenGL3::DeleteTexture(const Li::Texture& tex) {} void GfxOpenGL3::DeleteTexture(const Li::Texture& tex) {}
void GfxOpenGL3::UploadPools() {} void GfxOpenGL3::UploadPools() {}
void GfxOpenGL3::ClipRect() {}
} // namespace PD } // namespace PD
#endif #endif
+10 -2
View File
@@ -65,6 +65,7 @@ class PD_API GfxDriver : public DriverInterface {
virtual void SysReset() {} virtual void SysReset() {}
virtual void Submit(size_t count, size_t start) {} virtual void Submit(size_t count, size_t start) {}
virtual void UploadPools() {} // not every driver requires it virtual void UploadPools() {} // not every driver requires it
virtual void ClipRect() {}
void RegisterTexture(const Li::Texture& tex); void RegisterTexture(const Li::Texture& tex);
void UnregisterTexture(const Li::Texture& tex); void UnregisterTexture(const Li::Texture& tex);
@@ -80,6 +81,8 @@ class PD_API GfxDriver : public DriverInterface {
// State Variables oder so // State Variables oder so
TextureID CurrentTex = 0; TextureID CurrentTex = 0;
bool CurrentTexIsSDF = false; bool CurrentTexIsSDF = false;
bool CurrentHasClip = false;
fvec4 CurrentClip = 0;
Mat4 Projection; Mat4 Projection;
ivec2 ViewPort; ivec2 ViewPort;
std::unordered_map<TextureID, Li::Texture> pTextureRegestry; std::unordered_map<TextureID, Li::Texture> pTextureRegestry;
@@ -136,7 +139,7 @@ class GfxDriverBase : public GfxDriver {
for (size_t i = 0; i < commands.size(); i++) { for (size_t i = 0; i < commands.size(); i++) {
const auto& cmd = commands[i]; const auto& cmd = commands[i];
if (cmd.VertexCount > 0) { if (cmd.VertexCount > 0) {
std::memcpy(pVtxPool.begin() + current_vtx, std::memcpy(reinterpret_cast<void*>(pVtxPool.begin() + current_vtx),
vpool.begin() + cmd.FirstVertex, vpool.begin() + cmd.FirstVertex,
cmd.VertexCount * sizeof(Li::Vertex)); cmd.VertexCount * sizeof(Li::Vertex));
} }
@@ -156,14 +159,19 @@ class GfxDriverBase : public GfxDriver {
while (index < commands.size()) { while (index < commands.size()) {
CurrentTex = commands[index].Tex; CurrentTex = commands[index].Tex;
CurrentTexIsSDF = commands[index].SDF; CurrentTexIsSDF = commands[index].SDF;
CurrentHasClip = commands[index].ClipRectUsed;
CurrentClip = commands[index].ClipRect;
if (!CurrentTex) { if (!CurrentTex) {
CurrentTex = pWhite.GetID(); CurrentTex = pWhite.GetID();
} }
size_t num_indices = 0; size_t num_indices = 0;
ClipRect();
while (index < commands.size() && while (index < commands.size() &&
CurrentTexIsSDF == commands[index].SDF && CurrentTexIsSDF == commands[index].SDF &&
(CurrentTex == commands[index].Tex || (CurrentTex == commands[index].Tex ||
(CurrentTex == pWhite.GetID() && commands[index].Tex == 0))) { (CurrentTex == pWhite.GetID() && commands[index].Tex == 0)) &&
CurrentClip == commands[index].ClipRect &&
CurrentHasClip == commands[index].ClipRectUsed) {
num_indices += commands[index].IndexCount; num_indices += commands[index].IndexCount;
index++; index++;
} }
+3
View File
@@ -28,6 +28,9 @@ class Command {
// Todo: implement // Todo: implement
size_t VertexCountMax = 0; size_t VertexCountMax = 0;
size_t IndexCountMax = 0; size_t IndexCountMax = 0;
// ClipRect
PD::fvec4 ClipRect;
bool ClipRectUsed = false;
}; };
} // namespace Li } // namespace Li
} // namespace PD } // namespace PD
+7 -2
View File
@@ -128,13 +128,18 @@ class PD_API Drawlist {
void PrimTriangle(Command& cmd, const fvec2& a, const fvec2& b, void PrimTriangle(Command& cmd, const fvec2& a, const fvec2& b,
const fvec2& c, const PD::Color& color); const fvec2& c, const PD::Color& color);
void PushClipRect(const fvec4& r) { pClipRects.push_back(r); }
void PopClipRect() {
if (!pClipRects.empty()) pClipRects.pop_back();
}
bool HasClipRect() { return !pClipRects.empty(); }
private: private:
Texture pCurrentTexture; Texture pCurrentTexture;
int pCurrentLayer = 0; int pCurrentLayer = 0;
Pool<Command> pCommands; Pool<Command> pCommands;
Pool<fvec2> pPath; Pool<fvec2> pPath;
Pool<Vertex> pVertices; std::vector<fvec4> pClipRects;
Pool<u16> pIndices;
Font* pFont = nullptr; Font* pFont = nullptr;
float pFontScale = 1.f; float pFontScale = 1.f;
}; };
+2
View File
@@ -56,6 +56,8 @@ void Command::Reset() {
VertexCount = 0; VertexCount = 0;
VertexCountMax = 0; VertexCountMax = 0;
IndexCountMax = 0; IndexCountMax = 0;
ClipRect = 0.f;
ClipRectUsed = false;
} }
Command& Command::Add(const Vertex& vtx) { Command& Command::Add(const Vertex& vtx) {
+5
View File
@@ -43,6 +43,7 @@ PD_API void Drawlist::Clear() {
pPath.ResetFast(); pPath.ResetFast();
pCommands.NoReset(); pCommands.NoReset();
pCurrentLayer = 0; pCurrentLayer = 0;
pClipRects.clear();
} }
/** Command Allocation */ /** Command Allocation */
@@ -51,6 +52,10 @@ PD_API Command& Drawlist::NewCommand() {
cmd->Reset(); cmd->Reset();
cmd->Layer = pCurrentLayer; cmd->Layer = pCurrentLayer;
cmd->Tex = pCurrentTexture.GetID(); cmd->Tex = pCurrentTexture.GetID();
if (HasClipRect()) {
cmd->ClipRectUsed = HasClipRect();
cmd->ClipRect = pClipRects.back();
}
return *cmd; return *cmd;
} }
+2 -2
View File
@@ -44,13 +44,13 @@ PD_API void Container::HandleInternalInput() {
/** Internal function */ /** Internal function */
PD_API void Container::PreDraw() { PD_API void Container::PreDraw() {
if (pCLipRectUsed) { if (pCLipRectUsed) {
// list->PushClipRect(pClipRect); list->PushClipRect(pClipRect);
} }
} }
/** Internal function */ /** Internal function */
PD_API void Container::PostDraw() { PD_API void Container::PostDraw() {
if (pCLipRectUsed) { if (pCLipRectUsed) {
// list->PopClipRect(); list->PopClipRect();
} }
} }
} // namespace UI7 } // namespace UI7
+2 -2
View File
@@ -172,7 +172,7 @@ PD_API void Layout::Update() {
it->HandleInput(); it->HandleInput();
it->UnlockInput(); it->UnlockInput();
if (Flags & UI7LayoutFlags_UseClipRect) { if (Flags & UI7LayoutFlags_UseClipRect) {
it->SetClipRect(fvec4(Pos, Size)); it->SetClipRect(fvec4(Pos.x, Pos.y, Size.x, Size.y));
} }
it->PreDraw(); it->PreDraw();
it->Draw(); it->Draw();
@@ -201,7 +201,7 @@ PD_API void Layout::Label(const std::string& label) {
// Layout API // Layout API
auto r = IO.LabelPool.Allocate(); auto r = IO.LabelPool.Allocate();
*r = UI7::Label(label, IO); *r = UI7::Label(label, IO);
r->SetClipRect(fvec4(GetPosition(), GetPosition() + GetSize())); // r->SetClipRect(fvec4(GetPosition(), GetSize()));
AddObject(r); AddObject(r);
} }
+3 -1
View File
@@ -210,6 +210,7 @@ int main(int argc, char** argv) {
ui7.GetIO().Font = &font; ui7.GetIO().Font = &font;
ui7.AddViewPort("Default", PD::ivec4(0, 0, 1280, 720)); ui7.AddViewPort("Default", PD::ivec4(0, 0, 1280, 720));
ui7.UseViewPort("Default"); ui7.UseViewPort("Default");
bool pMetricsWin = true;
while (pOs->Mainloop()) { while (pOs->Mainloop()) {
PD::TT::End("OSCTX::MainLoop"); PD::TT::End("OSCTX::MainLoop");
pOs->ClearViewPort(); pOs->ClearViewPort();
@@ -315,7 +316,8 @@ int main(int argc, char** argv) {
m->PopFont(); m->PopFont();
ui7.EndMenu(); ui7.EndMenu();
} }
ui7.MetricsMenu(); ui7.MetricsMenu(&pMetricsWin);
ui7.StyleEditor();
PD::TT::End("BuildUI7Menus"); PD::TT::End("BuildUI7Menus");
PD::TT::Beg("UI7::Context::Update"); PD::TT::Beg("UI7::Context::Update");
ui7.Update(); ui7.Update();