Widgets: Reuse materials to improve performance

This commit is contained in:
Jérôme Leclercq 2021-11-21 19:07:06 +01:00
parent a1b5e5b4f4
commit d0f55df3ca
6 changed files with 90 additions and 47 deletions

View File

@ -159,18 +159,18 @@ namespace Nz
std::optional<entt::entity> m_backgroundEntity; std::optional<entt::entity> m_backgroundEntity;
std::size_t m_canvasIndex; std::size_t m_canvasIndex;
std::shared_ptr<Nz::Sprite> m_backgroundSprite; std::shared_ptr<Sprite> m_backgroundSprite;
std::vector<WidgetEntity> m_entities; std::vector<WidgetEntity> m_entities;
std::vector<std::unique_ptr<BaseWidget>> m_children; std::vector<std::unique_ptr<BaseWidget>> m_children;
entt::registry* m_registry; entt::registry* m_registry;
Canvas* m_canvas; Canvas* m_canvas;
Color m_backgroundColor; Color m_backgroundColor;
Nz::Rectf m_renderingRect; Rectf m_renderingRect;
Nz::SystemCursor m_cursor; SystemCursor m_cursor;
Nz::Vector2f m_maximumSize; Vector2f m_maximumSize;
Nz::Vector2f m_minimumSize; Vector2f m_minimumSize;
Nz::Vector2f m_preferredSize; Vector2f m_preferredSize;
Nz::Vector2f m_size; Vector2f m_size;
BaseWidget* m_widgetParent; BaseWidget* m_widgetParent;
bool m_visible; bool m_visible;
}; };

View File

@ -15,6 +15,9 @@
namespace Nz namespace Nz
{ {
class Material;
class MaterialPass;
class NAZARA_WIDGETS_API Widgets : public ModuleBase<Widgets> class NAZARA_WIDGETS_API Widgets : public ModuleBase<Widgets>
{ {
friend ModuleBase; friend ModuleBase;
@ -27,9 +30,22 @@ namespace Nz
Widgets(Config config); Widgets(Config config);
~Widgets() = default; ~Widgets() = default;
inline const std::shared_ptr<Material>& GetOpaqueMaterial() const;
inline const std::shared_ptr<MaterialPass>& GetOpaqueMaterialPass() const;
inline const std::shared_ptr<Material>& GetTransparentMaterial() const;
inline const std::shared_ptr<MaterialPass>& GetTransparentMaterialPass() const;
struct Config {}; struct Config {};
private: private:
void CreateDefaultMaterials();
std::shared_ptr<Material> m_opaqueMaterial;
std::shared_ptr<Material> m_transparentMaterial;
std::shared_ptr<MaterialPass> m_opaqueMaterialPass;
std::shared_ptr<MaterialPass> m_transparentMaterialPass;
static Widgets* s_instance; static Widgets* s_instance;
}; };
} }

View File

@ -7,6 +7,25 @@
namespace Nz namespace Nz
{ {
inline const std::shared_ptr<Material>& Widgets::GetOpaqueMaterial() const
{
return m_opaqueMaterial;
}
inline const std::shared_ptr<MaterialPass>& Widgets::GetOpaqueMaterialPass() const
{
return m_opaqueMaterialPass;
}
inline const std::shared_ptr<Material>& Widgets::GetTransparentMaterial() const
{
return m_transparentMaterial;
}
inline const std::shared_ptr<MaterialPass>& Widgets::GetTransparentMaterialPass() const
{
return m_transparentMaterialPass;
}
} }
#include <Nazara/Widgets/DebugOff.hpp> #include <Nazara/Widgets/DebugOff.hpp>

View File

@ -8,6 +8,7 @@
#include <Nazara/Graphics/Components/GraphicsComponent.hpp> #include <Nazara/Graphics/Components/GraphicsComponent.hpp>
#include <Nazara/Utility/Components/NodeComponent.hpp> #include <Nazara/Utility/Components/NodeComponent.hpp>
#include <Nazara/Widgets/Canvas.hpp> #include <Nazara/Widgets/Canvas.hpp>
#include <Nazara/Widgets/Widgets.hpp>
#include <algorithm> #include <algorithm>
#include <Nazara/Widgets/Debug.hpp> #include <Nazara/Widgets/Debug.hpp>
@ -79,12 +80,8 @@ namespace Nz
if (enable) if (enable)
{ {
auto material = std::make_shared<Material>(); m_backgroundSprite = std::make_shared<Sprite>((m_backgroundColor.IsOpaque()) ? Widgets::Instance()->GetOpaqueMaterial() : Widgets::Instance()->GetTransparentMaterial());
material->AddPass("ForwardPass", std::make_shared<MaterialPass>(BasicMaterial::GetSettings()));
m_backgroundSprite = std::make_shared<Sprite>(std::move(material));
m_backgroundSprite->SetColor(m_backgroundColor); m_backgroundSprite->SetColor(m_backgroundColor);
//m_backgroundSprite->SetMaterial(Nz::Material::New((m_backgroundColor.IsOpaque()) ? "Basic2D" : "Translucent2D")); //< TODO: Use a shared material instead of creating one everytime
entt::entity backgroundEntity = CreateEntity(); entt::entity backgroundEntity = CreateEntity();
m_registry->emplace<GraphicsComponent>(backgroundEntity).AttachRenderable(m_backgroundSprite, GetCanvas()->GetRenderMask()); m_registry->emplace<GraphicsComponent>(backgroundEntity).AttachRenderable(m_backgroundSprite, GetCanvas()->GetRenderMask());
@ -115,10 +112,10 @@ namespace Nz
return m_canvas->IsKeyboardOwner(m_canvasIndex); return m_canvas->IsKeyboardOwner(m_canvasIndex);
} }
void BaseWidget::Resize(const Nz::Vector2f& size) void BaseWidget::Resize(const Vector2f& size)
{ {
// Adjust new size // Adjust new size
Nz::Vector2f newSize = size; Vector2f newSize = size;
newSize.Maximize(m_minimumSize); newSize.Maximize(m_minimumSize);
newSize.Minimize(m_maximumSize); newSize.Minimize(m_maximumSize);
@ -135,11 +132,11 @@ namespace Nz
if (m_backgroundSprite) if (m_backgroundSprite)
{ {
m_backgroundSprite->SetColor(color); m_backgroundSprite->SetColor(color);
//m_backgroundSprite->GetMaterial()->Configure((color.IsOpaque()) ? "Basic2D" : "Translucent2D"); //< Our sprite has its own material (see EnableBackground) m_backgroundSprite->SetMaterial((color.IsOpaque()) ? Widgets::Instance()->GetOpaqueMaterial() : Widgets::Instance()->GetTransparentMaterial()); //< Our sprite has its own material (see EnableBackground)
} }
} }
void BaseWidget::SetCursor(Nz::SystemCursor systemCursor) void BaseWidget::SetCursor(SystemCursor systemCursor)
{ {
m_cursor = systemCursor; m_cursor = systemCursor;
@ -167,7 +164,7 @@ namespace Nz
Layout(); Layout();
} }
void BaseWidget::SetRenderingRect(const Nz::Rectf& renderingRect) void BaseWidget::SetRenderingRect(const Rectf& renderingRect)
{ {
m_renderingRect = renderingRect; m_renderingRect = renderingRect;
@ -242,10 +239,7 @@ namespace Nz
void BaseWidget::Layout() void BaseWidget::Layout()
{ {
if (m_backgroundSprite) if (m_backgroundSprite)
{
m_registry->get<NodeComponent>(*m_backgroundEntity).SetPosition(0.f, m_size.y);
m_backgroundSprite->SetSize({ m_size.x, m_size.y }); m_backgroundSprite->SetSize({ m_size.x, m_size.y });
}
UpdatePositionAndSize(); UpdatePositionAndSize();
} }
@ -257,13 +251,13 @@ namespace Nz
UpdatePositionAndSize(); UpdatePositionAndSize();
} }
Nz::Rectf BaseWidget::GetScissorRect() const Rectf BaseWidget::GetScissorRect() const
{ {
Nz::Vector2f widgetPos = Nz::Vector2f(GetPosition(Nz::CoordSys::Global)); Vector2f widgetPos = Vector2f(GetPosition(CoordSys::Global));
Nz::Vector2f widgetSize = GetSize(); Vector2f widgetSize = GetSize();
Nz::Rectf widgetRect(widgetPos.x, widgetPos.y, widgetSize.x, widgetSize.y); Rectf widgetRect(widgetPos.x, widgetPos.y, widgetSize.x, widgetSize.y);
Nz::Rectf widgetRenderingRect(widgetPos.x + m_renderingRect.x, widgetPos.y + m_renderingRect.y, m_renderingRect.width, m_renderingRect.height); Rectf widgetRenderingRect(widgetPos.x + m_renderingRect.x, widgetPos.y + m_renderingRect.y, m_renderingRect.width, m_renderingRect.height);
widgetRect.Intersect(widgetRenderingRect, &widgetRect); widgetRect.Intersect(widgetRenderingRect, &widgetRect);
@ -283,12 +277,12 @@ namespace Nz
{ {
} }
bool BaseWidget::OnKeyPressed(const Nz::WindowEvent::KeyEvent& key) bool BaseWidget::OnKeyPressed(const WindowEvent::KeyEvent& key)
{ {
return false; return false;
} }
void BaseWidget::OnKeyReleased(const Nz::WindowEvent::KeyEvent& /*key*/) void BaseWidget::OnKeyReleased(const WindowEvent::KeyEvent& /*key*/)
{ {
} }
@ -300,11 +294,11 @@ namespace Nz
{ {
} }
void BaseWidget::OnMouseButtonPress(int /*x*/, int /*y*/, Nz::Mouse::Button /*button*/) void BaseWidget::OnMouseButtonPress(int /*x*/, int /*y*/, Mouse::Button /*button*/)
{ {
} }
void BaseWidget::OnMouseButtonRelease(int /*x*/, int /*y*/, Nz::Mouse::Button /*button*/) void BaseWidget::OnMouseButtonRelease(int /*x*/, int /*y*/, Mouse::Button /*button*/)
{ {
} }
@ -316,7 +310,7 @@ namespace Nz
{ {
} }
void BaseWidget::OnParentResized(const Nz::Vector2f& /*newSize*/) void BaseWidget::OnParentResized(const Vector2f& /*newSize*/)
{ {
} }
@ -372,17 +366,17 @@ namespace Nz
if (IsRegisteredToCanvas()) if (IsRegisteredToCanvas())
m_canvas->NotifyWidgetBoxUpdate(m_canvasIndex); m_canvas->NotifyWidgetBoxUpdate(m_canvasIndex);
Nz::Rectf scissorRect = GetScissorRect(); Rectf scissorRect = GetScissorRect();
if (m_widgetParent) if (m_widgetParent)
{ {
Nz::Rectf parentScissorRect = m_widgetParent->GetScissorRect(); Rectf parentScissorRect = m_widgetParent->GetScissorRect();
if (!scissorRect.Intersect(parentScissorRect, &scissorRect)) if (!scissorRect.Intersect(parentScissorRect, &scissorRect))
scissorRect = parentScissorRect; scissorRect = parentScissorRect;
} }
/*Nz::Recti fullBounds(scissorRect); /*Recti fullBounds(scissorRect);
for (WidgetEntity& widgetEntity : m_entities) for (WidgetEntity& widgetEntity : m_entities)
{ {
const Ndk::EntityHandle& entity = widgetEntity.handle; const Ndk::EntityHandle& entity = widgetEntity.handle;

View File

@ -4,11 +4,10 @@
#include <Nazara/Widgets/LabelWidget.hpp> #include <Nazara/Widgets/LabelWidget.hpp>
#include <Nazara/Graphics/BasicMaterial.hpp> #include <Nazara/Graphics/BasicMaterial.hpp>
#include <Nazara/Graphics/Material.hpp>
#include <Nazara/Graphics/MaterialPass.hpp>
#include <Nazara/Graphics/Components/GraphicsComponent.hpp> #include <Nazara/Graphics/Components/GraphicsComponent.hpp>
#include <Nazara/Utility/Components/NodeComponent.hpp> #include <Nazara/Utility/Components/NodeComponent.hpp>
#include <Nazara/Widgets/Canvas.hpp> #include <Nazara/Widgets/Canvas.hpp>
#include <Nazara/Widgets/Widgets.hpp>
#include <Nazara/Widgets/Debug.hpp> #include <Nazara/Widgets/Debug.hpp>
namespace Nz namespace Nz
@ -16,18 +15,7 @@ namespace Nz
LabelWidget::LabelWidget(BaseWidget* parent) : LabelWidget::LabelWidget(BaseWidget* parent) :
BaseWidget(parent) BaseWidget(parent)
{ {
auto materialPass = std::make_shared<MaterialPass>(BasicMaterial::GetSettings()); m_textSprite = std::make_shared<TextSprite>(Widgets::Instance()->GetTransparentMaterial());
materialPass->EnableFlag(MaterialPassFlag::Transparent);
materialPass->EnableDepthBuffer(true);
materialPass->EnableDepthWrite(false);
materialPass->EnableBlending(true);
materialPass->SetBlendEquation(BlendEquation::Add, BlendEquation::Add);
materialPass->SetBlendFunc(BlendFunc::SrcAlpha, BlendFunc::InvSrcAlpha, BlendFunc::One, BlendFunc::Zero);
auto material = std::make_shared<Material>();
material->AddPass("ForwardPass", std::move(materialPass));
m_textSprite = std::make_shared<TextSprite>(std::move(material));
m_textEntity = CreateEntity(); m_textEntity = CreateEntity();
GetRegistry().emplace<GraphicsComponent>(m_textEntity).AttachRenderable(m_textSprite, GetCanvas()->GetRenderMask()); GetRegistry().emplace<GraphicsComponent>(m_textEntity).AttachRenderable(m_textSprite, GetCanvas()->GetRenderMask());

View File

@ -3,6 +3,9 @@
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Widgets/Widgets.hpp> #include <Nazara/Widgets/Widgets.hpp>
#include <Nazara/Graphics/BasicMaterial.hpp>
#include <Nazara/Graphics/Material.hpp>
#include <Nazara/Graphics/MaterialPass.hpp>
#include <Nazara/Widgets/Debug.hpp> #include <Nazara/Widgets/Debug.hpp>
namespace Nz namespace Nz
@ -16,6 +19,29 @@ namespace Nz
ModuleBase("Widgets", this) ModuleBase("Widgets", this)
{ {
ECS::RegisterComponents(); ECS::RegisterComponents();
CreateDefaultMaterials();
}
void Widgets::CreateDefaultMaterials()
{
m_opaqueMaterialPass = std::make_shared<MaterialPass>(BasicMaterial::GetSettings());
m_opaqueMaterialPass->EnableDepthBuffer(true);
m_opaqueMaterialPass->EnableDepthWrite(false);
m_opaqueMaterial = std::make_shared<Material>();
m_opaqueMaterial->AddPass("ForwardPass", m_opaqueMaterialPass);
m_transparentMaterialPass = std::make_shared<MaterialPass>(BasicMaterial::GetSettings());
m_transparentMaterialPass->EnableFlag(MaterialPassFlag::Transparent);
m_transparentMaterialPass->EnableDepthBuffer(true);
m_transparentMaterialPass->EnableDepthWrite(false);
m_transparentMaterialPass->EnableBlending(true);
m_transparentMaterialPass->SetBlendEquation(BlendEquation::Add, BlendEquation::Add);
m_transparentMaterialPass->SetBlendFunc(BlendFunc::SrcAlpha, BlendFunc::InvSrcAlpha, BlendFunc::One, BlendFunc::Zero);
m_transparentMaterial = std::make_shared<Material>();
m_transparentMaterial->AddPass("ForwardPass", m_transparentMaterialPass);
} }
Widgets* Widgets::s_instance = nullptr; Widgets* Widgets::s_instance = nullptr;