Finished UI Render Context

This commit is contained in:
2023-12-13 22:55:13 -06:00
parent 952db756a0
commit d2c057cd53
12 changed files with 163 additions and 68 deletions

View File

@ -5,9 +5,8 @@
#include "UICanvas.hpp"
#include "display/pass/RenderPass.hpp"
#include "display/shader/UIShader.hpp"
#include "display/mesh/QuadMesh.hpp"
#include "ui/UIComponent.hpp"
using namespace Dawn;
@ -35,32 +34,70 @@ void UICanvas::onDispose() {
}
std::vector<std::shared_ptr<IRenderPass>> UICanvas::getPasses(
struct RenderPassContext &ctx
struct RenderPassContext &ctx
) {
std::vector<std::shared_ptr<IRenderPass>> passes;
std::unordered_map<shadertexturebinding_t, std::shared_ptr<Texture>> textures;
UIShaderData data = {
.projection = ctx.camera->getProjection(),
.view = ctx.camera->getItem()->getWorldTransform(),
.model = this->getItem()->getWorldTransform()
};
size_t quadCount = 0;
if(this->components.empty()) return {};
data.projection = ctx.camera->getProjection();
data.view = ctx.camera->getItem()->getWorldTransform();
data.model = this->getItem()->getWorldTransform();
this->passes.clear();
this->textureBindings.clear();
this->textures.clear();
quadCount = 0;
nextBinding = 0;
auto itComponents = components.begin();
auto self = std::ref(*this);
while(itComponents != components.end()) {
auto component = *itComponents;
// Get this components' quads.
auto quads = component->getQuads({ 0, 0 });
for(auto quad : quads) {
data.quads[quadCount++] = quad;
assertTrue(quadCount <= UI_SHADER_QUAD_COUNT, "Too many UI quads!");
}
component->getQuads({ 0, 0 }, self);
++itComponents;
}
flushPass();
// No render passes if no quads.
if(quadCount == 0) return passes;
return passes;
}
void UICanvas::addQuad(
const glm::vec4 quad,
const glm::vec4 uvs,
const struct Color color,
const std::shared_ptr<Texture> text
) {
float_t fTexture = -1;
if(text == nullptr) {
fTexture = -1;
} else {
shadertexturebinding_t texture;
auto bindingIt = textureBindings.find(text);
if(bindingIt == textureBindings.end()) {
if(nextBinding >= UI_SHADER_TEXTURE_COUNT) {
flushPass();
}
textureBindings[text] = nextBinding;
textures[nextBinding] = text;
data.textures[nextBinding] = nextBinding;
texture = nextBinding++;
} else {
texture = bindingIt->second;
}
fTexture = (float_t)texture;
}
data.quads[quadCount] = {
quad,
uvs,
color,
fTexture
};
quadCount++;
if(quadCount == UI_SHADER_QUAD_COUNT) flushPass();
}
void UICanvas::flushPass() {
if(quadCount == 0) return;
auto pass = createRenderPass<UIShader, UIShaderData>(
std::ref(*this),
@ -73,6 +110,8 @@ std::vector<std::shared_ptr<IRenderPass>> UICanvas::getPasses(
);
passes.push_back(pass);
return passes;
quadCount = 0;
nextBinding = 0;
textures.clear();
textureBindings.clear();
}

View File

@ -6,25 +6,47 @@
#pragma once
#include "scene/SceneItem.hpp"
#include "component/display/IRenderableComponent.hpp"
#include "ui/UIComponent.hpp"
#include "display/shader/UIShader.hpp"
namespace Dawn {
class UIComponent;
class UICanvas :
public SceneComponent,
public IRenderableComponent
{
protected:
private:
std::shared_ptr<Mesh> mesh;
UIShaderData data;
size_t quadCount = 0;
shadertexturebinding_t nextBinding = 0;
std::unordered_map<
shadertexturebinding_t, std::shared_ptr<Texture>
> textures;
std::map<
std::shared_ptr<Texture>, shadertexturebinding_t
> textureBindings;
std::vector<std::shared_ptr<IRenderPass>> passes;
protected:
virtual void onInit() override;
virtual void onDispose() override;
void flushPass();
public:
std::vector<std::shared_ptr<UIComponent>> components;
std::vector<std::shared_ptr<IRenderPass>> getPasses(
struct RenderPassContext &ctx
) override;
void addQuad(
const glm::vec4 quad,
const glm::vec4 uvs,
const struct Color color,
const std::shared_ptr<Texture> texture
);
};
}

View File

@ -11,15 +11,12 @@ std::vector<std::shared_ptr<UIComponent>> UIComponent::getChildren() {
return {};
}
std::vector<struct UIShaderQuad> UIComponent::getQuads(const glm::vec2 parent) {
void UIComponent::getQuads(const glm::vec2 parent, UICanvas &ctx) {
glm::vec2 transform = parent + position;
std::vector<struct UIShaderQuad> quads = this->getSelfQuads(transform);
this->getSelfQuads(transform, ctx);
auto children = getChildren();
for(auto &c : children) {
auto childQuads = c->getQuads(transform);
quads.insert(quads.end(), childQuads.begin(), childQuads.end());
c->getQuads(transform, ctx);
}
return quads;
}

View File

@ -6,19 +6,14 @@
#pragma once
#include "ui/UIAlign.hpp"
#include "display/shader/UIShader.hpp"
#include "component/ui/UICanvas.hpp"
namespace Dawn {
class UICanvas;
class UIComponent {
protected:
virtual std::vector<struct UIShaderQuad> getSelfQuads(
const glm::vec2 t
) = 0;
virtual void getSelfQuads(const glm::vec2 t, UICanvas &ctx) = 0;
virtual std::vector<std::shared_ptr<UIComponent>> getChildren();
std::vector<struct UIShaderQuad> getQuads(const glm::vec2 parent);
void getQuads(const glm::vec2 parent, UICanvas &ctx);
public:
glm::vec2 position;

View File

@ -7,30 +7,29 @@
using namespace Dawn;
std::vector<struct UIShaderQuad> UILabel::getSelfQuads(const glm::vec2 t) {
void UILabel::getSelfQuads(const glm::vec2 t, UICanvas &ctx) {
std::vector<struct UIShaderQuad> quads;
if(this->texture == nullptr) return quads;
if(this->texture == nullptr) return;
const std::wstring text = L"Hello World!";
const std::wstring text = L"He";
glm::vec2 position = t;
glm::vec4 quad;
for(wchar_t c : text) {
auto info = texture->getCharacterData(c);
quads.push_back({
.quad = {
ctx.addQuad(
{
position.x,
position.y,
position.x + info.size.x,
position.y + info.size.y
},
.uv = info.quad,
.color = COLOR_WHITE
});
info.quad,
COLOR_WHITE,
texture->texture
);
position += info.advance;
}
return quads;
}
void UILabel::setFont(std::shared_ptr<TrueTypeTexture> texture) {

View File

@ -13,7 +13,7 @@ namespace Dawn {
std::shared_ptr<TrueTypeTexture> texture = nullptr;
protected:
std::vector<struct UIShaderQuad> getSelfQuads(const glm::vec2 t) override;
void getSelfQuads(const glm::vec2 t, UICanvas &ctx) override;
public:
void setFont(std::shared_ptr<TrueTypeTexture> texture);

View File

@ -7,12 +7,12 @@
using namespace Dawn;
std::vector<struct UIShaderQuad> UIRectangle::getSelfQuads(const glm::vec2 t) {
void UIRectangle::getSelfQuads(const glm::vec2 t, UICanvas &ctx) {
std::vector<struct UIShaderQuad> quads;
quads.push_back({
ctx.addQuad(
glm::vec4(t, t + size),
uv,
color
});
return quads;
color,
nullptr
);
}

View File

@ -9,7 +9,7 @@
namespace Dawn {
class UIRectangle final : public UIComponent {
protected:
std::vector<struct UIShaderQuad> getSelfQuads(const glm::vec2 t) override;
void getSelfQuads(const glm::vec2 t, UICanvas &ctx) override;
public:
struct Color color = COLOR_WHITE;