Files
Seele/src/Engine/Graphics/RenderPass/UIPass.cpp
T

249 lines
10 KiB
C++
Raw Normal View History

2021-09-23 10:10:39 +02:00
#include "UIPass.h"
2025-01-08 19:15:12 +01:00
#include "Asset/AssetRegistry.h"
2024-06-09 12:20:04 +02:00
#include "Graphics/Command.h"
2024-04-15 13:48:34 +02:00
#include "Graphics/Enums.h"
2021-09-23 10:10:39 +02:00
#include "Graphics/Graphics.h"
2023-10-26 18:37:29 +02:00
#include "Graphics/RenderTarget.h"
2024-06-09 12:20:04 +02:00
#include "RenderGraph.h"
2021-09-23 10:10:39 +02:00
using namespace Seele;
2025-01-12 11:26:52 +01:00
UIPass::UIPass(Gfx::PGraphics graphics, UI::PSystem system) : RenderPass(graphics), system(system) {
2025-01-08 19:15:12 +01:00
glyphInstanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{.name = "GlyphInstanceBuffer"});
2025-01-12 11:26:52 +01:00
elementBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{.name = "RenderStyleElements"});
2025-01-08 19:15:12 +01:00
textDescriptorLayout = graphics->createDescriptorLayout("pText");
textDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
.binding = 0,
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
});
textDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
.binding = 1,
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
});
textDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
.binding = 2,
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
.descriptorCount = 1024,
});
textPipelineLayout = graphics->createPipelineLayout("TextPipeline");
textPipelineLayout->addDescriptorLayout(viewParamsLayout);
textPipelineLayout->addDescriptorLayout(textDescriptorLayout);
2025-01-12 11:26:52 +01:00
uiDescriptorLayout = graphics->createDescriptorLayout("pParams");
uiDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
.binding = 0,
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
});
uiDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
.binding = 1,
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
});
uiDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
.binding = 2,
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
.descriptorCount = 1024,
});
2025-01-08 19:15:12 +01:00
uiPipelineLayout = graphics->createPipelineLayout("UIPipeline");
uiPipelineLayout->addDescriptorLayout(viewParamsLayout);
2025-01-12 11:26:52 +01:00
uiPipelineLayout->addDescriptorLayout(uiDescriptorLayout);
2025-01-08 19:15:12 +01:00
// todo:
}
2021-09-23 10:10:39 +02:00
2024-06-09 12:20:04 +02:00
UIPass::~UIPass() {}
2021-09-23 10:10:39 +02:00
2024-06-09 12:20:04 +02:00
void UIPass::beginFrame(const Component::Camera& cam) {
2023-11-05 10:36:01 +01:00
RenderPass::beginFrame(cam);
2025-01-08 19:15:12 +01:00
glyphs.clear();
usedTextures.clear();
2025-01-12 11:26:52 +01:00
for (const auto& render : renderElements) {
float x = render.position.x;
float y = render.position.y;
if (render.text.empty()) {
//todo: convert using actual tree depth
elements.add(RenderElementStyle{
.x = x,
.y = y,
.w = render.dimensions.x,
.h = render.dimensions.y,
.color = render.backgroundColor,
.z = render.level / 100.f,
2025-01-08 19:15:12 +01:00
});
2025-01-12 11:26:52 +01:00
} else {
y = y + render.fontSize;
for (uint32 c : render.text) {
const FontAsset::Glyph& glyph = render.font->getGlyphData(c);
Vector2 bearing = Vector2(glyph.bearing);
Vector2 size = Vector2(glyph.size);
float xpos = x + glyph.bearing.x;
float ypos = y - bearing.y;
float w = size.x;
float h = size.y;
glyphs.add(GlyphInstanceData{
.x = xpos,
.y = ypos,
.z = render.level / 100.0f,
.width = w,
.height = h,
.glyphIndex = (uint32)usedTextures.size(),
});
usedTextures.add(glyph.texture);
x += glyph.advance / 64.0f;
}
2025-01-08 19:15:12 +01:00
}
2024-09-27 15:57:37 +02:00
}
2025-01-08 19:15:12 +01:00
glyphInstanceBuffer->rotateBuffer(sizeof(GlyphInstanceData) * glyphs.size());
glyphInstanceBuffer->updateContents(0, sizeof(GlyphInstanceData) * glyphs.size(), glyphs.data());
glyphInstanceBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_VERTEX_SHADER_BIT);
2025-01-12 11:26:52 +01:00
2025-01-08 19:15:12 +01:00
textDescriptorLayout->reset();
textDescriptorSet = textDescriptorLayout->allocateDescriptorSet();
textDescriptorSet->updateBuffer(0, 0, glyphInstanceBuffer);
textDescriptorSet->updateSampler(1, 0, glyphSampler);
for (uint32 i = 0; i < usedTextures.size(); ++i) {
textDescriptorSet->updateTexture(2, i, usedTextures[i]);
}
textDescriptorSet->writeChanges();
2025-01-12 11:26:52 +01:00
elementBuffer->rotateBuffer(sizeof(RenderElementStyle) * elements.size());
elementBuffer->updateContents(0, sizeof(RenderElementStyle) * elements.size(), elements.data());
elementBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
Gfx::SE_PIPELINE_STAGE_VERTEX_SHADER_BIT);
uiDescriptorLayout->reset();
uiDescriptorSet = uiDescriptorLayout->allocateDescriptorSet();
uiDescriptorSet->updateBuffer(0, 0, elementBuffer);
uiDescriptorSet->updateSampler(1, 0, glyphSampler);
uiDescriptorSet->writeChanges();
2021-09-23 10:10:39 +02:00
}
2024-06-09 12:20:04 +02:00
void UIPass::render() {
2021-09-23 10:10:39 +02:00
graphics->beginRenderPass(renderPass);
2024-04-11 12:38:42 +02:00
Array<Gfx::ORenderCommand> commands;
2025-01-08 19:15:12 +01:00
Gfx::ORenderCommand command = graphics->createRenderCommand("TextPassCommand");
command->setViewport(viewport);
2025-01-12 11:26:52 +01:00
command->bindPipeline(uiPipeline);
command->bindDescriptor({viewParamsSet, uiDescriptorSet});
command->draw(4, elements.size(), 0, 0);
2025-01-08 19:15:12 +01:00
command->bindPipeline(textPipeline);
command->bindDescriptor({viewParamsSet, textDescriptorSet});
command->draw(4, glyphs.size(), 0, 0);
2024-04-11 12:38:42 +02:00
commands.add(std::move(command));
graphics->executeCommands(std::move(commands));
2021-09-23 10:10:39 +02:00
graphics->endRenderPass();
}
2025-01-08 19:15:12 +01:00
void UIPass::endFrame() {}
2021-09-23 10:10:39 +02:00
2025-01-08 19:15:12 +01:00
void UIPass::publishOutputs() {}
void UIPass::createRenderPass() {
2022-11-17 16:47:42 +01:00
TextureCreateInfo depthBufferInfo = {
2023-11-15 17:42:57 +01:00
.format = Gfx::SE_FORMAT_D32_SFLOAT,
2023-11-15 00:06:00 +01:00
.width = viewport->getWidth(),
.height = viewport->getHeight(),
2022-11-17 16:47:42 +01:00
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
};
2021-09-23 10:10:39 +02:00
depthBuffer = graphics->createTexture2D(depthBufferInfo);
2024-06-09 12:20:04 +02:00
depthAttachment =
Gfx::RenderTargetAttachment(depthBuffer, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
2025-01-08 19:15:12 +01:00
depthAttachment.clear.depthStencil.depth = 0;
2022-11-17 16:47:42 +01:00
2025-01-08 19:15:12 +01:00
colorAttachment = Gfx::RenderTargetAttachment(viewport, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
colorAttachment.clear.color = {{1.0f, 1.0f, 1.0f, 1.0f}};
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
.colorAttachments = {colorAttachment},
.depthAttachment = depthAttachment,
2022-11-17 16:47:42 +01:00
};
2025-01-08 19:15:12 +01:00
renderPass = graphics->createRenderPass(std::move(layout), {}, viewport, "TextPass");
2021-09-23 10:10:39 +02:00
2025-01-08 19:15:12 +01:00
graphics->beginShaderCompilation(ShaderCompilationInfo{
.name = "TextVertex",
.modules = {"TextPass"},
.entryPoints = {{"vertexMain", "TextPass"}, {"fragmentMain", "TextPass"}},
.rootSignature = textPipelineLayout,
});
textPipelineLayout->create();
textVertexShader = graphics->createVertexShader({0});
textFragmentShader = graphics->createFragmentShader({1});
glyphSampler = graphics->createSampler({
.magFilter = Gfx::SE_FILTER_LINEAR,
.minFilter = Gfx::SE_FILTER_LINEAR,
.addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
.addressModeV = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
});
2025-01-12 11:26:52 +01:00
textPipeline = graphics->createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo{
2025-01-08 19:15:12 +01:00
.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
.vertexShader = textVertexShader,
.fragmentShader = textFragmentShader,
.renderPass = renderPass,
.pipelineLayout = textPipelineLayout,
.rasterizationState =
{
.cullMode = Gfx::SE_CULL_MODE_NONE,
},
.colorBlend =
{
.attachmentCount = 1,
.blendAttachments = {{
.blendEnable = true,
.srcColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA,
.dstColorBlendFactor = Gfx::SE_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
.srcAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
.dstAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_ZERO,
.alphaBlendOp = Gfx::SE_BLEND_OP_ADD,
.colorWriteMask = Gfx::SE_COLOR_COMPONENT_R_BIT | Gfx::SE_COLOR_COMPONENT_G_BIT | Gfx::SE_COLOR_COMPONENT_B_BIT |
Gfx::SE_COLOR_COMPONENT_A_BIT,
}},
},
2025-01-12 11:26:52 +01:00
});
2025-01-08 19:15:12 +01:00
graphics->beginShaderCompilation(ShaderCompilationInfo{
2024-04-26 19:32:38 +02:00
.name = "UIVertex",
2024-07-10 21:07:10 +02:00
.modules = {"UIPass"},
2025-01-08 19:15:12 +01:00
.entryPoints = {{"vertexMain", "UIPass"}, {"fragmentMain", "UIPass"}},
.rootSignature = uiPipelineLayout,
2024-06-09 12:20:04 +02:00
});
2025-01-12 11:26:52 +01:00
uiPipelineLayout->create();
2025-01-08 19:15:12 +01:00
uiVertexShader = graphics->createVertexShader({0});
uiFragmentShader = graphics->createFragmentShader({1});
2025-01-12 11:26:52 +01:00
uiPipeline = graphics->createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo{
.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
.vertexShader = uiVertexShader,
.fragmentShader = uiFragmentShader,
.renderPass = renderPass,
.pipelineLayout = uiPipelineLayout,
.rasterizationState =
{
.cullMode = Gfx::SE_CULL_MODE_NONE,
},
.colorBlend =
{
.attachmentCount = 1,
.blendAttachments = {{
.blendEnable = true,
.srcColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA,
.dstColorBlendFactor = Gfx::SE_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
.srcAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
.dstAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_ZERO,
.alphaBlendOp = Gfx::SE_BLEND_OP_ADD,
.colorWriteMask = Gfx::SE_COLOR_COMPONENT_R_BIT | Gfx::SE_COLOR_COMPONENT_G_BIT | Gfx::SE_COLOR_COMPONENT_B_BIT |
Gfx::SE_COLOR_COMPONENT_A_BIT,
}},
},
});
system->style();
system->layout(UVector2(viewport->getWidth(), viewport->getHeight()));
renderElements = system->render();
2021-09-23 10:10:39 +02:00
}