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::size_t m_canvasIndex;
std::shared_ptr<Nz::Sprite> m_backgroundSprite;
std::shared_ptr<Sprite> m_backgroundSprite;
std::vector<WidgetEntity> m_entities;
std::vector<std::unique_ptr<BaseWidget>> m_children;
entt::registry* m_registry;
Canvas* m_canvas;
Color m_backgroundColor;
Nz::Rectf m_renderingRect;
Nz::SystemCursor m_cursor;
Nz::Vector2f m_maximumSize;
Nz::Vector2f m_minimumSize;
Nz::Vector2f m_preferredSize;
Nz::Vector2f m_size;
Rectf m_renderingRect;
SystemCursor m_cursor;
Vector2f m_maximumSize;
Vector2f m_minimumSize;
Vector2f m_preferredSize;
Vector2f m_size;
BaseWidget* m_widgetParent;
bool m_visible;
};

View File

@ -15,6 +15,9 @@
namespace Nz
{
class Material;
class MaterialPass;
class NAZARA_WIDGETS_API Widgets : public ModuleBase<Widgets>
{
friend ModuleBase;
@ -27,9 +30,22 @@ namespace Nz
Widgets(Config config);
~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 {};
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;
};
}

View File

@ -7,6 +7,25 @@
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>

View File

@ -8,6 +8,7 @@
#include <Nazara/Graphics/Components/GraphicsComponent.hpp>
#include <Nazara/Utility/Components/NodeComponent.hpp>
#include <Nazara/Widgets/Canvas.hpp>
#include <Nazara/Widgets/Widgets.hpp>
#include <algorithm>
#include <Nazara/Widgets/Debug.hpp>
@ -79,12 +80,8 @@ namespace Nz
if (enable)
{
auto material = std::make_shared<Material>();
material->AddPass("ForwardPass", std::make_shared<MaterialPass>(BasicMaterial::GetSettings()));
m_backgroundSprite = std::make_shared<Sprite>(std::move(material));
m_backgroundSprite = std::make_shared<Sprite>((m_backgroundColor.IsOpaque()) ? Widgets::Instance()->GetOpaqueMaterial() : Widgets::Instance()->GetTransparentMaterial());
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();
m_registry->emplace<GraphicsComponent>(backgroundEntity).AttachRenderable(m_backgroundSprite, GetCanvas()->GetRenderMask());
@ -115,10 +112,10 @@ namespace Nz
return m_canvas->IsKeyboardOwner(m_canvasIndex);
}
void BaseWidget::Resize(const Nz::Vector2f& size)
void BaseWidget::Resize(const Vector2f& size)
{
// Adjust new size
Nz::Vector2f newSize = size;
Vector2f newSize = size;
newSize.Maximize(m_minimumSize);
newSize.Minimize(m_maximumSize);
@ -135,11 +132,11 @@ namespace Nz
if (m_backgroundSprite)
{
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;
@ -167,7 +164,7 @@ namespace Nz
Layout();
}
void BaseWidget::SetRenderingRect(const Nz::Rectf& renderingRect)
void BaseWidget::SetRenderingRect(const Rectf& renderingRect)
{
m_renderingRect = renderingRect;
@ -242,10 +239,7 @@ namespace Nz
void BaseWidget::Layout()
{
if (m_backgroundSprite)
{
m_registry->get<NodeComponent>(*m_backgroundEntity).SetPosition(0.f, m_size.y);
m_backgroundSprite->SetSize({ m_size.x, m_size.y });
}
UpdatePositionAndSize();
}
@ -257,13 +251,13 @@ namespace Nz
UpdatePositionAndSize();
}
Nz::Rectf BaseWidget::GetScissorRect() const
Rectf BaseWidget::GetScissorRect() const
{
Nz::Vector2f widgetPos = Nz::Vector2f(GetPosition(Nz::CoordSys::Global));
Nz::Vector2f widgetSize = GetSize();
Vector2f widgetPos = Vector2f(GetPosition(CoordSys::Global));
Vector2f widgetSize = GetSize();
Nz::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 widgetRect(widgetPos.x, widgetPos.y, widgetSize.x, widgetSize.y);
Rectf widgetRenderingRect(widgetPos.x + m_renderingRect.x, widgetPos.y + m_renderingRect.y, m_renderingRect.width, m_renderingRect.height);
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;
}
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())
m_canvas->NotifyWidgetBoxUpdate(m_canvasIndex);
Nz::Rectf scissorRect = GetScissorRect();
Rectf scissorRect = GetScissorRect();
if (m_widgetParent)
{
Nz::Rectf parentScissorRect = m_widgetParent->GetScissorRect();
Rectf parentScissorRect = m_widgetParent->GetScissorRect();
if (!scissorRect.Intersect(parentScissorRect, &scissorRect))
scissorRect = parentScissorRect;
}
/*Nz::Recti fullBounds(scissorRect);
/*Recti fullBounds(scissorRect);
for (WidgetEntity& widgetEntity : m_entities)
{
const Ndk::EntityHandle& entity = widgetEntity.handle;

View File

@ -4,11 +4,10 @@
#include <Nazara/Widgets/LabelWidget.hpp>
#include <Nazara/Graphics/BasicMaterial.hpp>
#include <Nazara/Graphics/Material.hpp>
#include <Nazara/Graphics/MaterialPass.hpp>
#include <Nazara/Graphics/Components/GraphicsComponent.hpp>
#include <Nazara/Utility/Components/NodeComponent.hpp>
#include <Nazara/Widgets/Canvas.hpp>
#include <Nazara/Widgets/Widgets.hpp>
#include <Nazara/Widgets/Debug.hpp>
namespace Nz
@ -16,18 +15,7 @@ namespace Nz
LabelWidget::LabelWidget(BaseWidget* parent) :
BaseWidget(parent)
{
auto materialPass = std::make_shared<MaterialPass>(BasicMaterial::GetSettings());
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_textSprite = std::make_shared<TextSprite>(Widgets::Instance()->GetTransparentMaterial());
m_textEntity = CreateEntity();
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
#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>
namespace Nz
@ -16,6 +19,29 @@ namespace Nz
ModuleBase("Widgets", this)
{
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;