ui rendering works now

This commit is contained in:
Dynamitos
2022-04-18 18:08:38 +02:00
parent 796271f334
commit 14b816fc3c
25 changed files with 453 additions and 60 deletions
+3 -3
View File
@@ -210,12 +210,12 @@ StructuredBuffer::~StructuredBuffer()
bool StructuredBuffer::updateContents(const BulkResourceData& resourceData)
{
assert(contents.size() == resourceData.size);
if(std::memcmp(contents.data(), resourceData.data, contents.size()) == 0)
assert(contents.size() >= resourceData.size);
if(std::memcmp(contents.data(), resourceData.data, resourceData.size) == 0)
{
return false;
}
std::memcpy(contents.data(), resourceData.data, contents.size());
std::memcpy(contents.data(), resourceData.data, resourceData.size);
return true;
}
VertexBuffer::VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint32 vertexSize, QueueType startQueueType)
+2 -2
View File
@@ -362,12 +362,12 @@ class VertexBuffer : public Buffer
public:
VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint32 vertexSize, QueueType startQueueType);
virtual ~VertexBuffer();
inline uint32 getNumVertices()
constexpr uint32 getNumVertices() const
{
return numVertices;
}
// Size of one vertex in bytes
inline uint32 getVertexSize()
constexpr uint32 getVertexSize() const
{
return vertexSize;
}
+10 -7
View File
@@ -21,7 +21,7 @@ void TextPass::beginFrame()
for(TextRender& render : passData.texts)
{
FontData& fontData = getFontData(render.font);
TextResources& resources = textResources.add();
TextResources& resources = textResources[render.font].add();
Array<GlyphInstanceData> instanceData;
float x = render.position.x;
float y = render.position.y;
@@ -67,16 +67,19 @@ void TextPass::render()
{
graphics->beginRenderPass(renderPass);
Array<Gfx::PRenderCommand> commands;
for(TextResources& resources : textResources)
for(const auto& [fontAsset, resources] : textResources)
{
Gfx::PRenderCommand command = graphics->createRenderCommand("TextPassCommand");
command->setViewport(viewport);
command->bindPipeline(pipeline);
command->bindDescriptor({generalSet, resources.textureArraySet});
command->bindVertexBuffer({VertexInputStream(0, 0, resources.vertexBuffer)});
command->pushConstants(pipelineLayout, Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(TextData), &resources.textData);
command->draw(4, static_cast<uint32>(resources.vertexBuffer->getNumVertices()), 0, 0);
for(const auto& resource : resources)
{
command->bindDescriptor({generalSet, resource.textureArraySet});
command->bindVertexBuffer({VertexInputStream(0, 0, resource.vertexBuffer)});
command->pushConstants(pipelineLayout, Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(TextData), &resource.textData);
command->draw(4, static_cast<uint32>(resource.vertexBuffer->getNumVertices()), 0, 0);
}
commands.add(command);
}
graphics->executeCommands(commands);
+1 -1
View File
@@ -65,7 +65,7 @@ private:
Gfx::PDescriptorSet textureArraySet;
TextData textData;
};
Array<TextResources> textResources;
std::map<PFontAsset, Array<TextResources>> textResources;
Gfx::PRenderTargetAttachment renderTarget;
Gfx::PRenderTargetAttachment depthAttachment;
+97 -2
View File
@@ -17,6 +17,23 @@ UIPass::~UIPass()
void UIPass::beginFrame()
{
VertexBufferCreateInfo info = {
.resourceData = {
.size = (uint32)(sizeof(UI::RenderElementStyle) * passData.renderElements.size()),
.data = (uint8*)passData.renderElements.data()
},
.vertexSize = sizeof(UI::RenderElementStyle),
.numVertices = (uint32)passData.renderElements.size(),
};
elementBuffer = graphics->createVertexBuffer(info);
uint32 numTextures = passData.usedTextures.size();
numTexturesBuffer->updateContents({
.size = sizeof(uint32),
.data = (uint8*)&numTextures,
});
descriptorSet->updateBuffer(2, numTexturesBuffer);
descriptorSet->updateTextureArray(3, passData.usedTextures);
descriptorSet->writeChanges();
//co_return;
}
@@ -26,7 +43,9 @@ void UIPass::render()
Gfx::PRenderCommand command = graphics->createRenderCommand("UIPassCommand");
command->setViewport(viewport);
command->bindPipeline(pipeline);
command->draw(4, 1, 0, 0);
command->bindVertexBuffer({VertexInputStream(0, 0, elementBuffer)});
command->bindDescriptor(descriptorSet);
command->draw(4, passData.renderElements.size(), 0, 0);
graphics->executeCommands(Array<Gfx::PRenderCommand>({command}));
graphics->endRenderPass();
//co_return;
@@ -72,8 +91,84 @@ void UIPass::createRenderPass()
createInfo.name = "UIFragment";
createInfo.entryPoint = "fragmentMain";
fragmentShader = graphics->createFragmentShader(createInfo);
declaration = graphics->createVertexDeclaration({});
Array<Gfx::VertexElement> decl;
decl.add({
.streamIndex = 0,
.offset = offsetof(UI::RenderElementStyle, position),
.vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT,
.attributeIndex = 0,
.stride = sizeof(UI::RenderElementStyle),
.bInstanced = 1
});
decl.add({
.streamIndex = 0,
.offset = offsetof(UI::RenderElementStyle, backgroundImageIndex),
.vertexFormat = Gfx::SE_FORMAT_R32_UINT,
.attributeIndex = 1,
.stride = sizeof(UI::RenderElementStyle),
.bInstanced = 1
});
decl.add({
.streamIndex = 0,
.offset = offsetof(UI::RenderElementStyle, backgroundColor),
.vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT,
.attributeIndex = 2,
.stride = sizeof(UI::RenderElementStyle),
.bInstanced = 1
});
decl.add({
.streamIndex = 0,
.offset = offsetof(UI::RenderElementStyle, opacity),
.vertexFormat = Gfx::SE_FORMAT_R32_SFLOAT,
.attributeIndex = 3,
.stride = sizeof(UI::RenderElementStyle),
.bInstanced = 1
});
decl.add({
.streamIndex = 0,
.offset = offsetof(UI::RenderElementStyle, dimensions),
.vertexFormat = Gfx::SE_FORMAT_R32G32_SFLOAT,
.attributeIndex = 4,
.stride = sizeof(UI::RenderElementStyle),
.bInstanced = 1
});
declaration = graphics->createVertexDeclaration(decl);
descriptorLayout = graphics->createDescriptorLayout("UIDescriptorLayout");
descriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
descriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER);
descriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
descriptorLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 256, Gfx::SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT | Gfx::SE_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT);
descriptorLayout->create();
Matrix4 projectionMatrix = glm::ortho(0, 1, 1, 0);
UniformBufferCreateInfo info = {
.resourceData = {
.size = sizeof(Matrix4),
.data = (uint8*)&projectionMatrix,
},
.bDynamic = false,
};
Gfx::PUniformBuffer uniformBuffer = graphics->createUniformBuffer(info);
Gfx::PSamplerState backgroundSampler = graphics->createSamplerState({});
info = {
.resourceData = {
.size = sizeof(uint32),
.data = nullptr
},
.bDynamic = true,
};
numTexturesBuffer = graphics->createUniformBuffer(info);
descriptorSet = descriptorLayout->allocateDescriptorSet();
descriptorSet->updateBuffer(0, uniformBuffer);
descriptorSet->updateSampler(1, backgroundSampler);
descriptorSet->writeChanges();
pipelineLayout = graphics->createPipelineLayout();
pipelineLayout->addDescriptorLayout(0, descriptorLayout);
pipelineLayout->create();
Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(renderTarget, depthAttachment);
+8 -1
View File
@@ -9,7 +9,8 @@ DECLARE_NAME_REF(Gfx, Texture2D)
DECLARE_NAME_REF(Gfx, RenderTargetAttachment)
struct UIPassData
{
const UI::RenderHierarchy hierarchy;
Array<UI::RenderElementStyle> renderElements;
Array<Gfx::PTexture> usedTextures;
};
class UIPass : public RenderPass<UIPassData>
{
@@ -26,6 +27,12 @@ private:
Gfx::PRenderTargetAttachment depthAttachment;
Gfx::PTexture2D depthBuffer;
Gfx::PDescriptorLayout descriptorLayout;
Gfx::PDescriptorSet descriptorSet;
Gfx::PUniformBuffer numTexturesBuffer;
Gfx::PVertexBuffer elementBuffer;
Gfx::PVertexDeclaration declaration;
Gfx::PVertexShader vertexShader;
Gfx::PFragmentShader fragmentShader;
@@ -128,7 +128,7 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBu
UniformBuffer* cachedBuffer = reinterpret_cast<UniformBuffer*>(cachedData[binding]);
if(vulkanBuffer->isDataEquals(cachedBuffer))
{
std::cout << "uniform data equal, skip" << std::endl;
//std::cout << "uniform data equal, skip" << std::endl;
return;
}
bufferInfos.add(init::DescriptorBufferInfo(vulkanBuffer->getHandle(), 0, vulkanBuffer->getSize()));
+3 -1
View File
@@ -1,4 +1,6 @@
target_sources(Engine
PRIVATE
Element.h
Element.cpp)
Element.cpp
Panel.h
Panel.cpp)
+1
View File
@@ -1,5 +1,6 @@
#include "Element.h"
#include "UI/System.h"
#include "Graphics/Graphics.h"
using namespace Seele;
using namespace Seele::UI;
-1
View File
@@ -36,7 +36,6 @@ protected:
PSystem system;
PElement parent;
Array<PElement> children;
friend class Layout;
friend class RenderElement;
};
DEFINE_REF(Element)
+15
View File
@@ -0,0 +1,15 @@
#include "Panel.h"
#include "UI/Layout.h"
using namespace Seele;
using namespace Seele::UI;
Panel::Panel()
{
}
Panel::~Panel()
{
}
+4
View File
@@ -5,12 +5,16 @@ namespace Seele
{
namespace UI
{
DECLARE_REF(Layout)
class Panel : Element
{
public:
Panel();
virtual ~Panel();
private:
PLayout activeLayout;
};
DEFINE_REF(Panel);
} // namespace UI
} // namespace Seele
+1
View File
@@ -1,4 +1,5 @@
#include "HorizontalLayout.h"
#include "Elements/Element.h"
using namespace Seele;
using namespace Seele::UI;
+1
View File
@@ -1,4 +1,5 @@
#include "Layout.h"
#include "Elements/Element.h"
using namespace Seele;
using namespace Seele::UI;
+2 -1
View File
@@ -1,10 +1,11 @@
#pragma once
#include "Elements/Element.h"
#include "MinimalEngine.h"
namespace Seele
{
namespace UI
{
DECLARE_REF(Element);
class Layout
{
public:
+13 -16
View File
@@ -9,23 +9,20 @@ namespace UI
{
struct RenderElementStyle
{
Vector2 position;
Vector2 dimensions;
Vector backgroundColor;
uint32 backgroundImageIndex;
Vector4 borderBottomColor;
Vector4 borderLeftColor;
Vector4 borderRightColor;
Vector4 borderTopColor;
float borderBottomLeftRadius;
float borderBottomRightRadius;
float borderTopLeftRadius;
float borderTopRightRadius;
Vector4 fontColor;
float fontSize;
float opacity;
Vector position = Vector(0, 0, 0);
uint32 backgroundImageIndex = -1;
Vector backgroundColor = Vector(1, 1, 1);
float opacity = 1.0f;
//Vector4 borderBottomColor = Vector4(1, 1, 1, 1);
//Vector4 borderLeftColor = Vector4(1, 1, 1, 1);
//Vector4 borderRightColor = Vector4(1, 1, 1, 1);
//Vector4 borderTopColor = Vector4(1, 1, 1, 1);
//float borderBottomLeftRadius = 0;
//float borderBottomRightRadius = 0;
//float borderTopLeftRadius = 0;
//float borderTopRightRadius = 0;
Vector2 dimensions = Vector2(1, 1);
};
static_assert(sizeof(RenderElementStyle) == 34*4);
class RenderElement
{
public:
+33
View File
@@ -1,5 +1,8 @@
#include "System.h"
#include "Elements/Panel.h"
#include "Graphics/Graphics.h"
#include "Asset/AssetRegistry.h"
#include "Asset/TextureAsset.h"
using namespace Seele;
using namespace Seele::UI;
@@ -13,3 +16,33 @@ System::~System()
{
}
void System::update()
{
}
UIPassData System::getUIPassData()
{
UIPassData uiPassData;
RenderElementStyle& style = uiPassData.renderElements.add();
style.position = Vector(0, 0, -0.1);
style.dimensions = Vector2(0.4, 0.4);
style.backgroundColor = Vector(0.2, 0.3, 0.1);
style.backgroundImageIndex = 0;
uiPassData.usedTextures.add(AssetRegistry::findTexture("")->getTexture());
return uiPassData;
}
TextPassData System::getTextPassData()
{
TextPassData textPassData;
TextRender& render = textPassData.texts.add();
render.font = AssetRegistry::findFont("Calibri");
render.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus quis magna ex. Morbi ullamcorper fringilla risus eget vehicula. Praesent vel quam vel ante molestie gravida vitae ac enim. Donec vitae eleifend orci. Phasellus at sodales lorem, ac eleifend turpis. Vivamus vitae condimentum lacus, a bibendum neque. Ut et est ut felis varius vehicula. Etiam lorem magna, dapibus vitae felis in, vulputate suscipit neque. Aenean facilisis ac risus et scelerisque. Ut tincidunt eros quis posuere iaculis. Curabitur justo lacus, molestie id varius vel, sodales efficitur diam. Integer orci velit, condimentum sit amet turpis sit amet, congue blandit nisl. Donec pretium ligula id mauris pretium commodo. Mauris quis lectus mi. In blandit, dolor non accumsan venenatis, ipsum erat congue neque, quis elementum orci nunc vel justo. ";
//render.text = "Seele Engine";
render.position = Vector2(0.f, 300.f);
render.scale = 0.1f;
render.textColor = Vector4(1, 0, 0, 1);
return textPassData;
}
+6 -1
View File
@@ -1,6 +1,8 @@
#pragma once
#include "MinimalEngine.h"
#include "RenderHierarchy.h"
#include "Graphics/RenderPass/UIPass.h"
#include "Graphics/RenderPass/TextPass.h"
namespace Seele
{
@@ -12,9 +14,12 @@ class System
public:
System();
virtual ~System();
void update();
UIPassData getUIPassData();
TextPassData getTextPassData();
private:
PPanel rootPanel;
Array<RenderHierarchyUpdate*> updates;
RenderHierarchy hierarchy;
};
DEFINE_REF(System)
} // namespace UI
+1
View File
@@ -1,4 +1,5 @@
#include "VerticalLayout.h"
#include "Elements/Element.h"
using namespace Seele;
using namespace Seele::UI;
+4 -8
View File
@@ -3,6 +3,7 @@
#include "Scene/Actor/Actor.h"
#include "Window.h"
#include "Asset/AssetRegistry.h"
#include "UI/System.h"
using namespace Seele;
@@ -10,6 +11,7 @@ InspectorView::InspectorView(Gfx::PGraphics graphics, PWindow window, const View
: View(graphics, window, createInfo, "InspectorView")
, uiPass(UIPass(graphics, viewport, new Gfx::SwapchainAttachment(window->getGfxHandle())))
, textPass(TextPass(graphics, viewport, new Gfx::SwapchainAttachment(window->getGfxHandle())))
, uiSystem(new UI::System())
{
AssetRegistry::importFile("./fonts/Calibri.ttf");
PRenderGraphResources resources = new RenderGraphResources();
@@ -19,13 +21,6 @@ InspectorView::InspectorView(Gfx::PGraphics graphics, PWindow window, const View
textPass.publishOutputs();
uiPass.createRenderPass();
textPass.createRenderPass();
TextRender& render = textPassData.texts.add();
render.font = AssetRegistry::findFont("Calibri");
render.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus quis magna ex. Morbi ullamcorper fringilla risus eget vehicula. Praesent vel quam vel ante molestie gravida vitae ac enim. Donec vitae eleifend orci. Phasellus at sodales lorem, ac eleifend turpis. Vivamus vitae condimentum lacus, a bibendum neque. Ut et est ut felis varius vehicula. Etiam lorem magna, dapibus vitae felis in, vulputate suscipit neque. Aenean facilisis ac risus et scelerisque. Ut tincidunt eros quis posuere iaculis. Curabitur justo lacus, molestie id varius vel, sodales efficitur diam. Integer orci velit, condimentum sit amet turpis sit amet, congue blandit nisl. Donec pretium ligula id mauris pretium commodo. Mauris quis lectus mi. In blandit, dolor non accumsan venenatis, ipsum erat congue neque, quis elementum orci nunc vel justo. ";
//render.text = "Seele Engine";
render.position = Vector2(0.f, 300.f);
render.scale = 0.1f;
render.textColor = Vector4(1, 0, 0, 1);
}
InspectorView::~InspectorView()
@@ -48,7 +43,8 @@ void InspectorView::commitUpdate()
void InspectorView::prepareRender()
{
textPass.updateViewFrame(textPassData);
uiPass.updateViewFrame(uiSystem->getUIPassData());
textPass.updateViewFrame(uiSystem->getTextPassData());
}
void InspectorView::render()
+1 -1
View File
@@ -28,7 +28,7 @@ protected:
UIPassData uiPassData;
TextPassData textPassData;
UI::PPanel rootPanel;
UI::PSystem uiSystem;
PActor selectedActor;
virtual void keyCallback(KeyCode code, InputAction action, KeyModifier modifier) override;
+1 -1
View File
@@ -19,7 +19,7 @@ int main()
mainWindowInfo.pixelFormat = Gfx::SE_FORMAT_B8G8R8A8_UNORM;
auto window = windowManager->addWindow(mainWindowInfo);
ViewportCreateInfo sceneViewInfo;
sceneViewInfo.sizeX = 680;
sceneViewInfo.sizeX = 640;
sceneViewInfo.sizeY = 720;
sceneViewInfo.offsetX = 0;
sceneViewInfo.offsetY = 0;