diff --git a/backends/include/pd_system/gfx_citro3d.hpp b/backends/include/pd_system/gfx_citro3d.hpp index fdddf73..0370a38 100644 --- a/backends/include/pd_system/gfx_citro3d.hpp +++ b/backends/include/pd_system/gfx_citro3d.hpp @@ -29,6 +29,7 @@ class GfxCitro3D : public GfxDriverBase { TextureFilter filter = TextureFilter::Linear) override; void DeleteTexture(const Li::Texture& tex) override; void UploadPools() override; + void ClipRect() override; private: struct Impl; diff --git a/backends/include/pd_system/gfx_directx9.hpp b/backends/include/pd_system/gfx_directx9.hpp index bc6f377..190f5ef 100644 --- a/backends/include/pd_system/gfx_directx9.hpp +++ b/backends/include/pd_system/gfx_directx9.hpp @@ -29,6 +29,7 @@ class GfxDirectX9 : public GfxDriverBase { TextureFilter filter = TextureFilter::Linear) override; void DeleteTexture(const Li::Texture& tex) override; void UploadPools() override; + void ClipRect() override; private: struct Impl; diff --git a/backends/include/pd_system/gfx_opengl2.hpp b/backends/include/pd_system/gfx_opengl2.hpp index 07a5bf3..a837354 100644 --- a/backends/include/pd_system/gfx_opengl2.hpp +++ b/backends/include/pd_system/gfx_opengl2.hpp @@ -28,6 +28,7 @@ class GfxOpenGL2 : public GfxDriverBase { TextureFilter filter = TextureFilter::Linear) override; void DeleteTexture(const Li::Texture& tex) override; void UploadPools() override; + void ClipRect() override; private: void pSetupShaderAttribs(u32 shader); diff --git a/backends/include/pd_system/gfx_opengl3.hpp b/backends/include/pd_system/gfx_opengl3.hpp index 283be0d..6b75ffd 100644 --- a/backends/include/pd_system/gfx_opengl3.hpp +++ b/backends/include/pd_system/gfx_opengl3.hpp @@ -28,6 +28,7 @@ class GfxOpenGL3 : public GfxDriverBase { TextureFilter filter = TextureFilter::Linear) override; void DeleteTexture(const Li::Texture& tex) override; void UploadPools() override; + void ClipRect() override; private: u32 pShader = 0; diff --git a/backends/source/gfx_citro3d.cpp b/backends/source/gfx_citro3d.cpp index 9486e52..c873077 100644 --- a/backends/source/gfx_citro3d.cpp +++ b/backends/source/gfx_citro3d.cpp @@ -264,6 +264,8 @@ void GfxCitro3D::UploadPools() { BufInfo_Init(buf); BufInfo_Add(buf, GetVertexBufPtr(0), sizeof(Li::Vertex), 3, 0x210); } + +void GfxCitro3D::ClipRect() {} } // namespace PD #else namespace PD { @@ -283,5 +285,6 @@ Li::Texture GfxCitro3D::LoadTexture(const std::vector& pixels, int w, } void GfxCitro3D::DeleteTexture(const Li::Texture& tex) {} void GfxCitro3D::UploadPools() {} +void GfxCitro3D::ClipRect() {} } // namespace PD #endif \ No newline at end of file diff --git a/backends/source/gfx_directx9.cpp b/backends/source/gfx_directx9.cpp index 3ca0c46..2a0ddf5 100644 --- a/backends/source/gfx_directx9.cpp +++ b/backends/source/gfx_directx9.cpp @@ -285,6 +285,8 @@ void GfxDirectX9::UploadPools() { memcpy(iptr, GetIndexBufPtr(0), GetIndexPoolSize() * sizeof(u16)); impl->IBO->Unlock(); } + +void GfxDirectX9::ClipRect() {} } // namespace PD #else namespace PD { @@ -304,5 +306,6 @@ Li::Texture GfxDirectX9::LoadTexture(const std::vector& pixels, int w, } void GfxDirectX9::DeleteTexture(const Li::Texture& tex) {} void GfxDirectX9::UploadPools() {} +void GfxDirectX9::ClipRect() {} } // namespace PD #endif \ No newline at end of file diff --git a/backends/source/gfx_opengl2.cpp b/backends/source/gfx_opengl2.cpp index 926749b..97ecfdf 100644 --- a/backends/source/gfx_opengl2.cpp +++ b/backends/source/gfx_opengl2.cpp @@ -183,6 +183,16 @@ void GfxOpenGL2::UploadPools() { glBufferData(GL_ELEMENT_ARRAY_BUFFER, GetIndexPoolSize() * sizeof(u16), 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 #else namespace PD { @@ -203,5 +213,6 @@ Li::Texture GfxOpenGL2::LoadTexture(const std::vector& pixels, int w, void GfxOpenGL2::DeleteTexture(const Li::Texture& tex) {} void GfxOpenGL2::pSetupShaderAttribs(u32 shader) {} void GfxOpenGL2::UploadPools() {} +void GfxOpenGL2::ClipRect() {} } // namespace PD #endif \ No newline at end of file diff --git a/backends/source/gfx_opengl3.cpp b/backends/source/gfx_opengl3.cpp index 74b23cf..e7a5aae 100644 --- a/backends/source/gfx_opengl3.cpp +++ b/backends/source/gfx_opengl3.cpp @@ -159,6 +159,16 @@ void GfxOpenGL3::UploadPools() { 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 #else namespace PD { @@ -178,5 +188,6 @@ Li::Texture GfxOpenGL3::LoadTexture(const std::vector& pixels, int w, } void GfxOpenGL3::DeleteTexture(const Li::Texture& tex) {} void GfxOpenGL3::UploadPools() {} +void GfxOpenGL3::ClipRect() {} } // namespace PD #endif \ No newline at end of file diff --git a/include/pd/drivers/gfx.hpp b/include/pd/drivers/gfx.hpp index 06cb6cd..86f60ad 100755 --- a/include/pd/drivers/gfx.hpp +++ b/include/pd/drivers/gfx.hpp @@ -65,6 +65,7 @@ class PD_API GfxDriver : public DriverInterface { virtual void SysReset() {} virtual void Submit(size_t count, size_t start) {} virtual void UploadPools() {} // not every driver requires it + virtual void ClipRect() {} void RegisterTexture(const Li::Texture& tex); void UnregisterTexture(const Li::Texture& tex); @@ -80,6 +81,8 @@ class PD_API GfxDriver : public DriverInterface { // State Variables oder so TextureID CurrentTex = 0; bool CurrentTexIsSDF = false; + bool CurrentHasClip = false; + fvec4 CurrentClip = 0; Mat4 Projection; ivec2 ViewPort; std::unordered_map pTextureRegestry; @@ -136,7 +139,7 @@ class GfxDriverBase : public GfxDriver { for (size_t i = 0; i < commands.size(); i++) { const auto& cmd = commands[i]; if (cmd.VertexCount > 0) { - std::memcpy(pVtxPool.begin() + current_vtx, + std::memcpy(reinterpret_cast(pVtxPool.begin() + current_vtx), vpool.begin() + cmd.FirstVertex, cmd.VertexCount * sizeof(Li::Vertex)); } @@ -156,14 +159,19 @@ class GfxDriverBase : public GfxDriver { while (index < commands.size()) { CurrentTex = commands[index].Tex; CurrentTexIsSDF = commands[index].SDF; + CurrentHasClip = commands[index].ClipRectUsed; + CurrentClip = commands[index].ClipRect; if (!CurrentTex) { CurrentTex = pWhite.GetID(); } size_t num_indices = 0; + ClipRect(); while (index < commands.size() && CurrentTexIsSDF == commands[index].SDF && (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; index++; } diff --git a/include/pd/lithium/command.hpp b/include/pd/lithium/command.hpp index 6dfc018..6aec8ad 100644 --- a/include/pd/lithium/command.hpp +++ b/include/pd/lithium/command.hpp @@ -28,6 +28,9 @@ class Command { // Todo: implement size_t VertexCountMax = 0; size_t IndexCountMax = 0; + // ClipRect + PD::fvec4 ClipRect; + bool ClipRectUsed = false; }; } // namespace Li } // namespace PD \ No newline at end of file diff --git a/include/pd/lithium/drawlist.hpp b/include/pd/lithium/drawlist.hpp index 669aae7..25bd0cb 100644 --- a/include/pd/lithium/drawlist.hpp +++ b/include/pd/lithium/drawlist.hpp @@ -128,13 +128,18 @@ class PD_API Drawlist { void PrimTriangle(Command& cmd, const fvec2& a, const fvec2& b, 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: Texture pCurrentTexture; int pCurrentLayer = 0; Pool pCommands; Pool pPath; - Pool pVertices; - Pool pIndices; + std::vector pClipRects; Font* pFont = nullptr; float pFontScale = 1.f; }; diff --git a/source/lithium/command.cpp b/source/lithium/command.cpp index 9b67b19..0db4a62 100644 --- a/source/lithium/command.cpp +++ b/source/lithium/command.cpp @@ -56,6 +56,8 @@ void Command::Reset() { VertexCount = 0; VertexCountMax = 0; IndexCountMax = 0; + ClipRect = 0.f; + ClipRectUsed = false; } Command& Command::Add(const Vertex& vtx) { diff --git a/source/lithium/drawlist.cpp b/source/lithium/drawlist.cpp index d4ec540..470ff4f 100644 --- a/source/lithium/drawlist.cpp +++ b/source/lithium/drawlist.cpp @@ -43,6 +43,7 @@ PD_API void Drawlist::Clear() { pPath.ResetFast(); pCommands.NoReset(); pCurrentLayer = 0; + pClipRects.clear(); } /** Command Allocation */ @@ -51,6 +52,10 @@ PD_API Command& Drawlist::NewCommand() { cmd->Reset(); cmd->Layer = pCurrentLayer; cmd->Tex = pCurrentTexture.GetID(); + if (HasClipRect()) { + cmd->ClipRectUsed = HasClipRect(); + cmd->ClipRect = pClipRects.back(); + } return *cmd; } diff --git a/source/ui7/container/container.cpp b/source/ui7/container/container.cpp index 24a5231..6fd292f 100755 --- a/source/ui7/container/container.cpp +++ b/source/ui7/container/container.cpp @@ -44,13 +44,13 @@ PD_API void Container::HandleInternalInput() { /** Internal function */ PD_API void Container::PreDraw() { if (pCLipRectUsed) { - // list->PushClipRect(pClipRect); + list->PushClipRect(pClipRect); } } /** Internal function */ PD_API void Container::PostDraw() { if (pCLipRectUsed) { - // list->PopClipRect(); + list->PopClipRect(); } } } // namespace UI7 diff --git a/source/ui7/layout.cpp b/source/ui7/layout.cpp index d6cb1cb..acfbd33 100644 --- a/source/ui7/layout.cpp +++ b/source/ui7/layout.cpp @@ -172,7 +172,7 @@ PD_API void Layout::Update() { it->HandleInput(); it->UnlockInput(); if (Flags & UI7LayoutFlags_UseClipRect) { - it->SetClipRect(fvec4(Pos, Size)); + it->SetClipRect(fvec4(Pos.x, Pos.y, Size.x, Size.y)); } it->PreDraw(); it->Draw(); @@ -201,7 +201,7 @@ PD_API void Layout::Label(const std::string& label) { // Layout API auto r = IO.LabelPool.Allocate(); *r = UI7::Label(label, IO); - r->SetClipRect(fvec4(GetPosition(), GetPosition() + GetSize())); + // r->SetClipRect(fvec4(GetPosition(), GetSize())); AddObject(r); } diff --git a/tests/gfx/source/main.cpp b/tests/gfx/source/main.cpp index 442e5c5..eeee77f 100644 --- a/tests/gfx/source/main.cpp +++ b/tests/gfx/source/main.cpp @@ -210,6 +210,7 @@ int main(int argc, char** argv) { ui7.GetIO().Font = &font; ui7.AddViewPort("Default", PD::ivec4(0, 0, 1280, 720)); ui7.UseViewPort("Default"); + bool pMetricsWin = true; while (pOs->Mainloop()) { PD::TT::End("OSCTX::MainLoop"); pOs->ClearViewPort(); @@ -315,7 +316,8 @@ int main(int argc, char** argv) { m->PopFont(); ui7.EndMenu(); } - ui7.MetricsMenu(); + ui7.MetricsMenu(&pMetricsWin); + ui7.StyleEditor(); PD::TT::End("BuildUI7Menus"); PD::TT::Beg("UI7::Context::Update"); ui7.Update();