From 3c9816af122dda8f06f98f5c580e5ad47aa9da9b Mon Sep 17 00:00:00 2001 From: Luke Street Date: Sun, 4 Oct 2020 02:47:43 -0400 Subject: [PATCH] Convert CTextSupportShader; CTextRenderBuffer updates --- Runtime/Graphics/CMakeLists.txt | 19 +- .../Graphics/Shaders/CTextSupportShader.cpp | 133 ++++++++++++-- .../Graphics/Shaders/CTextSupportShader.hpp | 9 +- .../Graphics/Shaders/CWorldShadowShader.cpp | 2 +- Runtime/GuiSys/CTextRenderBuffer.cpp | 166 +++++------------- Runtime/GuiSys/CTextRenderBuffer.hpp | 33 +++- 6 files changed, 203 insertions(+), 159 deletions(-) diff --git a/Runtime/Graphics/CMakeLists.txt b/Runtime/Graphics/CMakeLists.txt index 60c246253..94571eabf 100644 --- a/Runtime/Graphics/CMakeLists.txt +++ b/Runtime/Graphics/CMakeLists.txt @@ -50,20 +50,17 @@ runtime_add_list(Graphics GRAPHICS_SOURCES) runtime_add_hsh(Graphics CMoviePlayer.cpp - Shaders/CLineRendererShaders.cpp - Shaders/CColoredQuadFilter.cpp - Shaders/CTexturedQuadFilter.cpp - Shaders/CCameraBlurFilter.cpp - Shaders/CFogVolumePlaneShader.cpp Shaders/CAABoxShader.cpp + Shaders/CCameraBlurFilter.cpp + Shaders/CColoredQuadFilter.cpp Shaders/CColoredStripShader.cpp Shaders/CDecalShaders.cpp - Shaders/CEnergyBarShader.cpp - Shaders/CThermalColdFilter.cpp - Shaders/CThermalHotFilter.cpp Shaders/CElementGenShaders.cpp + Shaders/CEnergyBarShader.cpp Shaders/CEnvFxShaders.cpp Shaders/CFogVolumeFilter.cpp + Shaders/CFogVolumePlaneShader.cpp + Shaders/CLineRendererShaders.cpp Shaders/CMapSurfaceShader.cpp Shaders/CParticleSwooshShaders.cpp Shaders/CPhazonSuitFilter.cpp @@ -71,6 +68,10 @@ runtime_add_hsh(Graphics Shaders/CRandomStaticFilter.cpp Shaders/CScanLinesFilter.cpp Shaders/CSpaceWarpFilter.cpp - Shaders/CXRayBlurFilter.cpp + Shaders/CTextSupportShader.cpp + Shaders/CTexturedQuadFilter.cpp + Shaders/CThermalColdFilter.cpp + Shaders/CThermalHotFilter.cpp Shaders/CWorldShadowShader.cpp + Shaders/CXRayBlurFilter.cpp ) diff --git a/Runtime/Graphics/Shaders/CTextSupportShader.cpp b/Runtime/Graphics/Shaders/CTextSupportShader.cpp index 77e0c0a19..e39db9e60 100644 --- a/Runtime/Graphics/Shaders/CTextSupportShader.cpp +++ b/Runtime/Graphics/Shaders/CTextSupportShader.cpp @@ -1,45 +1,142 @@ #include "Runtime/Graphics/Shaders/CTextSupportShader.hpp" +#include "hsh/hsh.h" +#include "Runtime/Graphics/CGraphics.hpp" #include "Runtime/GuiSys/CFontImageDef.hpp" #include "Runtime/GuiSys/CRasterFont.hpp" +#include "Runtime/GuiSys/CTextRenderBuffer.hpp" + +#include "CTextSupportShader.cpp.hshhead" namespace urde { +using namespace hsh::pipeline; + +constexpr hsh::sampler ClampEdgeSamp(hsh::Linear, hsh::Linear, hsh::Linear, hsh::ClampToEdge, hsh::ClampToEdge, + hsh::ClampToEdge); + +template +struct DrawFlagsAttachmentExt { + using type = BlendAttachment<>; +}; +template <> +struct DrawFlagsAttachmentExt { + using type = AdditiveAttachment<>; +}; +template <> +struct DrawFlagsAttachmentExt { + using type = color_attachment; +}; +template +using DrawFlagsAttachment = typename DrawFlagsAttachmentExt::type; + +template +struct CTextSupportShaderCharacterPipeline +: pipeline, DrawFlagsAttachment, depth_write, depth_compare> { + CTextSupportShaderCharacterPipeline(hsh::vertex_buffer vbo, + hsh::uniform_buffer ubo, hsh::texture2d_array tex) { + this->position = ubo->m_mvp * hsh::float4(vbo->m_pos[this->vertex_id], 1.f); + hsh::float4 fontColor = ubo->m_uniformColor * vbo->m_fontColor; + hsh::float4 outlineColor = ubo->m_uniformColor * vbo->m_outlineColor; + hsh::float4 texel = tex.sample(vbo->m_uv[this->vertex_id]); + this->color_out[0] = (fontColor * texel.x + outlineColor * texel.y) * vbo->m_mulColor; + } +}; +template struct CTextSupportShaderCharacterPipeline; +template struct CTextSupportShaderCharacterPipeline; +template struct CTextSupportShaderCharacterPipeline; + +template +struct CTextSupportShaderImagePipeline +: pipeline, DrawFlagsAttachment, depth_write, depth_compare> { + CTextSupportShaderImagePipeline(hsh::vertex_buffer vbo, + hsh::uniform_buffer ubo, hsh::texture2d tex) { + this->position = ubo->m_mvp * hsh::float4(vbo->m_pos[this->vertex_id], 1.f); + // FIXME hsh bug: sampler appears to be completely ignored + hsh::float4 texel = tex.sample(vbo->m_uv[this->vertex_id], ClampEdgeSamp); + this->color_out[0] = ubo->m_uniformColor * vbo->m_color * texel; + } +}; +template struct CTextSupportShaderImagePipeline; +template struct CTextSupportShaderImagePipeline; +template struct CTextSupportShaderImagePipeline; void CTextSupportShader::CharacterInstance::SetMetrics(const CGlyph& glyph, const zeus::CVector2i& offset) { float layer = glyph.GetLayer(); - m_pos[0].assign(offset.x, 0.f, offset.y); - m_uv[0].assign(glyph.GetStartU(), 1.f - glyph.GetStartV(), layer); + m_pos[0] = {float(offset.x), 0.f, float(offset.y)}; + m_uv[0] = {glyph.GetStartU(), 1.f - glyph.GetStartV(), layer}; - m_pos[1].assign(offset.x + glyph.GetCellWidth(), 0.f, offset.y); - m_uv[1].assign(glyph.GetEndU(), 1.f - glyph.GetStartV(), layer); + m_pos[1] = {float(offset.x + glyph.GetCellWidth()), 0.f, float(offset.y)}; + m_uv[1] = {glyph.GetEndU(), 1.f - glyph.GetStartV(), layer}; - m_pos[2].assign(offset.x, 0.f, offset.y + glyph.GetCellHeight()); - m_uv[2].assign(glyph.GetStartU(), 1.f - glyph.GetEndV(), layer); + m_pos[2] = {float(offset.x), 0.f, float(offset.y + glyph.GetCellHeight())}; + m_uv[2] = {glyph.GetStartU(), 1.f - glyph.GetEndV(), layer}; - m_pos[3].assign(offset.x + glyph.GetCellWidth(), 0.f, offset.y + glyph.GetCellHeight()); - m_uv[3].assign(glyph.GetEndU(), 1.f - glyph.GetEndV(), layer); + m_pos[3] = {float(offset.x + glyph.GetCellWidth()), 0.f, float(offset.y + glyph.GetCellHeight())}; + m_uv[3] = {glyph.GetEndU(), 1.f - glyph.GetEndV(), layer}; } void CTextSupportShader::ImageInstance::SetMetrics(const CFontImageDef& imgDef, const zeus::CVector2i& offset) { zeus::CVector2f imgSize; - if (imgDef.x4_texs.size()) { + if (!imgDef.x4_texs.empty()) { const CTexture& tex = *imgDef.x4_texs[0].GetObj(); - imgSize.assign(tex.GetWidth() * imgDef.x14_cropFactor.x(), tex.GetHeight() * imgDef.x14_cropFactor.y()); + imgSize = {tex.GetWidth() * imgDef.x14_cropFactor.x(), tex.GetHeight() * imgDef.x14_cropFactor.y()}; } zeus::CVector2f cropPad = imgDef.x14_cropFactor * 0.5f; - m_pos[0].assign(offset.x, 0.f, offset.y); - m_uv[0].assign(0.5f - cropPad.x(), 0.5f + cropPad.y()); + m_pos[0] = {float(offset.x), 0.f, float(offset.y)}; + m_uv[0] = {0.5f - cropPad.x(), 0.5f + cropPad.y()}; - m_pos[1].assign(offset.x + imgSize.x(), 0.f, offset.y); - m_uv[1].assign(0.5f + cropPad.x(), 0.5f + cropPad.y()); + m_pos[1] = {offset.x + imgSize.x(), 0.f, float(offset.y)}; + m_uv[1] = {0.5f + cropPad.x(), 0.5f + cropPad.y()}; - m_pos[2].assign(offset.x, 0.f, offset.y + imgSize.y()); - m_uv[2].assign(0.5f - cropPad.x(), 0.5f - cropPad.y()); + m_pos[2] = {float(offset.x), 0.f, offset.y + imgSize.y()}; + m_uv[2] = {0.5f - cropPad.x(), 0.5f - cropPad.y()}; - m_pos[3].assign(offset.x + imgSize.x(), 0.f, offset.y + imgSize.y()); - m_uv[3].assign(0.5f + cropPad.x(), 0.5f - cropPad.y()); + m_pos[3] = {offset.x + imgSize.x(), 0.f, offset.y + imgSize.y()}; + m_uv[3] = {0.5f + cropPad.x(), 0.5f - cropPad.y()}; +} + +static CGuiWidget::EGuiModelDrawFlags ResolveFlags(CGuiWidget::EGuiModelDrawFlags flags) { + switch (flags) { + case CGuiWidget::EGuiModelDrawFlags::Shadeless: + case CGuiWidget::EGuiModelDrawFlags::Opaque: + case CGuiWidget::EGuiModelDrawFlags::AlphaAdditiveOverdraw: + return CGuiWidget::EGuiModelDrawFlags::Alpha; + default: + return flags; + } +} + +void CTextSupportShader::BuildCharacterShaderBinding(CTextRenderBuffer& buf, BooFontCharacters& chs, + CGuiWidget::EGuiModelDrawFlags flags) { + chs.m_instBuf = hsh::create_dynamic_vertex_buffer(chs.m_charCount); + hsh::texture2d_array tex = chs.m_font->GetTexture(); + if (flags == CGuiWidget::EGuiModelDrawFlags::AlphaAdditiveOverdraw) { + chs.m_dataBindingOverdraw.hsh_char_overdraw_bind( + CTextSupportShaderCharacterPipeline(chs.m_instBuf.get(), buf.m_uniBuf2.get(), tex)); + } + chs.m_dataBinding.hsh_char_bind( + CTextSupportShaderCharacterPipeline(chs.m_instBuf.get(), buf.m_uniBuf.get(), tex)); +} + +void CTextSupportShader::BuildImageShaderBinding(CTextRenderBuffer& buf, BooImage& img, + CGuiWidget::EGuiModelDrawFlags flags) { + img.m_instBuf = hsh::create_dynamic_vertex_buffer(1); + if (flags == CGuiWidget::EGuiModelDrawFlags::AlphaAdditiveOverdraw) { + for (TToken& token : img.m_imageDef.x4_texs) { + hsh::texture2d tex = token->GetBooTexture(); + img.m_dataBindingOverdraw.emplace_back().hsh_img_overdraw_bind( + CTextSupportShaderImagePipeline(img.m_instBuf.get(), buf.m_uniBuf2.get(), tex)); + } + } + flags = ResolveFlags(flags); + for (TToken& token : img.m_imageDef.x4_texs) { + hsh::texture2d tex = token->GetBooTexture(); + img.m_dataBinding.emplace_back().hsh_img_bind( + CTextSupportShaderImagePipeline(img.m_instBuf.get(), buf.m_uniBuf.get(), tex)); + } } } // namespace urde diff --git a/Runtime/Graphics/Shaders/CTextSupportShader.hpp b/Runtime/Graphics/Shaders/CTextSupportShader.hpp index 0083000b9..e9c3ab3b6 100644 --- a/Runtime/Graphics/Shaders/CTextSupportShader.hpp +++ b/Runtime/Graphics/Shaders/CTextSupportShader.hpp @@ -14,10 +14,13 @@ namespace urde { class CGlyph; class CFontImageDef; class CTextRenderBuffer; +struct BooFontCharacters; +struct BooImage; class CTextSupportShader { friend class CTextRenderBuffer; +public: struct Uniform { hsh::float4x4 m_mvp; hsh::float4 m_uniformColor; @@ -25,7 +28,7 @@ class CTextSupportShader { struct CharacterInstance { std::array m_pos; - std::array m_uv; + std::array m_uv; hsh::float4 m_fontColor; hsh::float4 m_outlineColor; hsh::float4 m_mulColor; @@ -38,6 +41,10 @@ class CTextSupportShader { hsh::float4 m_color; void SetMetrics(const CFontImageDef& imgDef, const zeus::CVector2i& offset); }; + + static void BuildCharacterShaderBinding(CTextRenderBuffer& buf, BooFontCharacters& chs, + CGuiWidget::EGuiModelDrawFlags flags); + static void BuildImageShaderBinding(CTextRenderBuffer& buf, BooImage& img, CGuiWidget::EGuiModelDrawFlags flags); }; } // namespace urde diff --git a/Runtime/Graphics/Shaders/CWorldShadowShader.cpp b/Runtime/Graphics/Shaders/CWorldShadowShader.cpp index 174ec73d9..8c890518b 100644 --- a/Runtime/Graphics/Shaders/CWorldShadowShader.cpp +++ b/Runtime/Graphics/Shaders/CWorldShadowShader.cpp @@ -31,7 +31,7 @@ CWorldShadowShader::CWorldShadowShader(u32 w, u32 h) : m_w(w), m_h(h) { bool depth = false; m_dataBind.hsh_bind(CWorldShadowShaderPipeline(m_vbo.get(), m_uniBuf.get())); depth = true; - m_dataBind.hsh_z_bind(CWorldShadowShaderPipeline(m_vbo.get(), m_uniBuf.get())); + m_zDataBind.hsh_z_bind(CWorldShadowShaderPipeline(m_vbo.get(), m_uniBuf.get())); } void CWorldShadowShader::bindRenderTarget() { m_tex.attach(); } diff --git a/Runtime/GuiSys/CTextRenderBuffer.cpp b/Runtime/GuiSys/CTextRenderBuffer.cpp index c389ca7fa..24be64008 100644 --- a/Runtime/GuiSys/CTextRenderBuffer.cpp +++ b/Runtime/GuiSys/CTextRenderBuffer.cpp @@ -12,31 +12,6 @@ namespace urde { -struct CTextRenderBuffer::BooFontCharacters { - TLockedToken m_font; - hecl::VertexBufferPool::Token m_instBuf; - boo::ObjToken m_dataBinding; - boo::ObjToken m_dataBinding2; - std::vector m_charData; - u32 m_charCount = 0; - bool m_dirty = true; - - BooFontCharacters(const CToken& token) : m_font(token) {} -}; - -struct CTextRenderBuffer::BooImage { - CFontImageDef m_imageDef; - hecl::VertexBufferPool::Token m_instBuf; - std::vector> m_dataBinding; - std::vector> m_dataBinding2; - CTextSupportShader::ImageInstance m_imageData; - bool m_dirty = true; - - BooImage(const CFontImageDef& imgDef, const zeus::CVector2i& offset) : m_imageDef(imgDef) { - m_imageData.SetMetrics(imgDef, offset); - } -}; - struct CTextRenderBuffer::BooPrimitiveMark { Command m_cmd; u32 m_bindIdx; @@ -47,13 +22,13 @@ struct CTextRenderBuffer::BooPrimitiveMark { case Command::CharacterRender: { BooFontCharacters& fc = rb.m_fontCharacters[m_bindIdx]; CTextSupportShader::CharacterInstance& inst = fc.m_charData[m_instIdx]; - inst.m_mulColor.a() = opacity; + inst.m_mulColor.w = opacity; fc.m_dirty = true; break; } case Command::ImageRender: { BooImage& img = rb.m_images[m_bindIdx]; - img.m_imageData.m_color.a() = opacity; + img.m_imageData.m_color.w = opacity; img.m_dirty = true; break; } @@ -72,83 +47,29 @@ CTextRenderBuffer::~CTextRenderBuffer() = default; CTextRenderBuffer& CTextRenderBuffer::operator=(CTextRenderBuffer&&) noexcept = default; void CTextRenderBuffer::CommitResources() { - if (m_committed) + if (m_committed) { return; + } m_committed = true; - /* Ensure font textures are ready outside transaction */ - for (BooFontCharacters& chs : m_fontCharacters) - chs.m_font->GetTexture(); - - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - m_uniBuf = CTextSupportShader::s_Uniforms.allocateBlock(CGraphics::g_BooFactory); - auto uBufInfo = m_uniBuf.getBufferInfo(); - decltype(uBufInfo) uBufInfo2; - if (m_drawFlags == CGuiWidget::EGuiModelDrawFlags::AlphaAdditiveOverdraw) { - m_uniBuf2 = CTextSupportShader::s_Uniforms.allocateBlock(CGraphics::g_BooFactory); - uBufInfo2 = m_uniBuf2.getBufferInfo(); - } - - for (BooFontCharacters& chs : m_fontCharacters) { - chs.m_instBuf = CTextSupportShader::s_CharInsts.allocateBlock(CGraphics::g_BooFactory, chs.m_charCount); - auto iBufInfo = chs.m_instBuf.getBufferInfo(); - - boo::ObjToken uniforms[] = {uBufInfo.first.get()}; - boo::PipelineStage unistages[] = {boo::PipelineStage::Vertex}; - size_t unioffs[] = {size_t(uBufInfo.second)}; - size_t unisizes[] = {sizeof(CTextSupportShader::Uniform)}; - boo::ObjToken texs[] = {chs.m_font->GetTexture()}; - chs.m_dataBinding = ctx.newShaderDataBinding(CTextSupportShader::SelectTextPipeline(m_drawFlags), nullptr, - iBufInfo.first.get(), nullptr, 1, uniforms, unistages, unioffs, - unisizes, 1, texs, nullptr, nullptr, 0, iBufInfo.second); - - if (m_drawFlags == CGuiWidget::EGuiModelDrawFlags::AlphaAdditiveOverdraw) { - uniforms[0] = uBufInfo2.first.get(); - unioffs[0] = size_t(uBufInfo2.second); - chs.m_dataBinding2 = ctx.newShaderDataBinding(CTextSupportShader::GetTextAdditiveOverdrawPipeline(), nullptr, - iBufInfo.first.get(), nullptr, 1, uniforms, unistages, unioffs, - unisizes, 1, texs, nullptr, nullptr, 0, iBufInfo.second); - } - } - - for (BooImage& img : m_images) { - img.m_instBuf = CTextSupportShader::s_ImgInsts.allocateBlock(CGraphics::g_BooFactory, 1); - auto iBufInfo = img.m_instBuf.getBufferInfo(); - - boo::ObjToken uniforms[] = {uBufInfo.first.get()}; - boo::PipelineStage unistages[] = {boo::PipelineStage::Vertex}; - size_t unioffs[] = {size_t(uBufInfo.second)}; - size_t unisizes[] = {sizeof(CTextSupportShader::Uniform)}; - img.m_dataBinding.reserve(img.m_imageDef.x4_texs.size()); - for (TToken& tex : img.m_imageDef.x4_texs) { - boo::ObjToken texs[] = {tex->GetBooTexture()}; - texs[0]->setClampMode(boo::TextureClampMode::ClampToEdge); - img.m_dataBinding.push_back(ctx.newShaderDataBinding( - CTextSupportShader::SelectImagePipeline(m_drawFlags), nullptr, iBufInfo.first.get(), nullptr, 1, uniforms, - unistages, unioffs, unisizes, 1, texs, nullptr, nullptr, 0, iBufInfo.second)); - } - - if (m_drawFlags == CGuiWidget::EGuiModelDrawFlags::AlphaAdditiveOverdraw) { - uniforms[0] = uBufInfo2.first.get(); - unioffs[0] = size_t(uBufInfo2.second); - img.m_dataBinding2.reserve(img.m_imageDef.x4_texs.size()); - for (TToken& tex : img.m_imageDef.x4_texs) { - boo::ObjToken texs[] = {tex->GetBooTexture()}; - img.m_dataBinding2.push_back(ctx.newShaderDataBinding( - CTextSupportShader::GetImageAdditiveOverdrawPipeline(), nullptr, iBufInfo.first.get(), nullptr, 1, - uniforms, unistages, unioffs, unisizes, 1, texs, nullptr, nullptr, 0, iBufInfo.second)); - } - } - } - return true; - } BooTrace); + m_uniBuf = hsh::create_dynamic_uniform_buffer(); + if (m_drawFlags == CGuiWidget::EGuiModelDrawFlags::AlphaAdditiveOverdraw) { + m_uniBuf2 = hsh::create_dynamic_uniform_buffer(); + } + for (BooFontCharacters& chs : m_fontCharacters) { + CTextSupportShader::BuildCharacterShaderBinding(*this, chs, m_drawFlags); + } + for (BooImage& img : m_images) { + CTextSupportShader::BuildImageShaderBinding(*this, img, m_drawFlags); + } } void CTextRenderBuffer::SetMode(EMode mode) { if (mode == EMode::BufferFill) { m_images.reserve(m_imagesCount); - for (BooFontCharacters& fc : m_fontCharacters) + for (BooFontCharacters& fc : m_fontCharacters) { fc.m_charData.reserve(fc.m_charCount); + } } m_activeFontCh = -1; x0_mode = mode; @@ -167,58 +88,55 @@ void CTextRenderBuffer::Render(const zeus::CColor& col, float time) { const zeus::CMatrix4f proj = CGraphics::GetPerspectiveProjectionMatrix(true); const zeus::CMatrix4f mat = proj * mv; - m_uniBuf.access() = CTextSupportShader::Uniform{mat, col}; + m_uniBuf.load({mat, col}); if (m_drawFlags == CGuiWidget::EGuiModelDrawFlags::AlphaAdditiveOverdraw) { zeus::CColor colPremul = col * col.a(); colPremul.a() = col.a(); - m_uniBuf2.access() = CTextSupportShader::Uniform{mat, colPremul}; + m_uniBuf2.load({mat, colPremul}); } for (BooFontCharacters& chs : m_fontCharacters) { - if (chs.m_charData.size()) { + if (!chs.m_charData.empty()) { if (chs.m_dirty) { - std::memmove(chs.m_instBuf.access(), chs.m_charData.data(), - sizeof(CTextSupportShader::CharacterInstance) * chs.m_charData.size()); + chs.m_instBuf.load(chs.m_charData); chs.m_dirty = false; } - CGraphics::SetShaderDataBinding(chs.m_dataBinding); - CGraphics::DrawInstances(0, 4, chs.m_charData.size()); + chs.m_dataBinding.draw_instanced(0, 4, chs.m_charData.size()); if (m_drawFlags == CGuiWidget::EGuiModelDrawFlags::AlphaAdditiveOverdraw) { - CGraphics::SetShaderDataBinding(chs.m_dataBinding2); - CGraphics::DrawInstances(0, 4, chs.m_charData.size()); + chs.m_dataBindingOverdraw.draw_instanced(0, 4, chs.m_charData.size()); } } } for (BooImage& img : m_images) { if (img.m_dirty) { - *img.m_instBuf.access() = img.m_imageData; + img.m_instBuf.load(img.m_imageData); img.m_dirty = false; } const int idx = int(img.m_imageDef.x0_fps * time) % img.m_dataBinding.size(); - CGraphics::SetShaderDataBinding(img.m_dataBinding[idx]); - CGraphics::DrawInstances(0, 4, 1); + img.m_dataBinding[idx].draw_instanced(0, 4, 1); if (m_drawFlags == CGuiWidget::EGuiModelDrawFlags::AlphaAdditiveOverdraw) { - CGraphics::SetShaderDataBinding(img.m_dataBinding2[idx]); - CGraphics::DrawInstances(0, 4, 1); + img.m_dataBindingOverdraw[idx].draw_instanced(0, 4, 1); } } } void CTextRenderBuffer::AddImage(const zeus::CVector2i& offset, const CFontImageDef& image) { - if (x0_mode == EMode::AllocTally) - m_primitiveMarks.push_back({Command::ImageRender, m_imagesCount++, 0}); - else + if (x0_mode == EMode::AllocTally) { + m_primitiveMarks.emplace_back({Command::ImageRender, m_imagesCount++, 0}); + } else { m_images.emplace_back(image, offset); + } } void CTextRenderBuffer::AddCharacter(const zeus::CVector2i& offset, char16_t ch, const zeus::CColor& color) { - if (m_activeFontCh == UINT32_MAX) + if (m_activeFontCh == UINT32_MAX) { return; + } BooFontCharacters& chs = m_fontCharacters[m_activeFontCh]; - if (x0_mode == EMode::AllocTally) - m_primitiveMarks.push_back({Command::CharacterRender, m_activeFontCh, chs.m_charCount++}); - else { + if (x0_mode == EMode::AllocTally) { + m_primitiveMarks.emplace_back({Command::CharacterRender, m_activeFontCh, chs.m_charCount++}); + } else { const CGlyph* glyph = chs.m_font.GetObj()->GetGlyph(ch); CTextSupportShader::CharacterInstance& inst = chs.m_charData.emplace_back(); @@ -265,18 +183,18 @@ std::pair CTextRenderBuffer::AccumulateTextBou for (const BooFontCharacters& chars : m_fontCharacters) { for (const CTextSupportShader::CharacterInstance& charInst : chars.m_charData) { - ret.first.x = std::min(ret.first.x, int(charInst.m_pos[0].x())); - ret.first.y = std::min(ret.first.y, int(charInst.m_pos[0].z())); - ret.second.x = std::max(ret.second.x, int(charInst.m_pos[3].x())); - ret.second.y = std::max(ret.second.y, int(charInst.m_pos[3].z())); + ret.first.x = std::min(ret.first.x, int(charInst.m_pos[0].x)); + ret.first.y = std::min(ret.first.y, int(charInst.m_pos[0].z)); + ret.second.x = std::max(ret.second.x, int(charInst.m_pos[3].x)); + ret.second.y = std::max(ret.second.y, int(charInst.m_pos[3].z)); } } for (const BooImage& imgs : m_images) { - ret.first.x = std::min(ret.first.x, int(imgs.m_imageData.m_pos[0].x())); - ret.first.y = std::min(ret.first.y, int(imgs.m_imageData.m_pos[0].z())); - ret.second.x = std::max(ret.second.x, int(imgs.m_imageData.m_pos[3].x())); - ret.second.y = std::max(ret.second.y, int(imgs.m_imageData.m_pos[3].z())); + ret.first.x = std::min(ret.first.x, int(imgs.m_imageData.m_pos[0].x)); + ret.first.y = std::min(ret.first.y, int(imgs.m_imageData.m_pos[0].z)); + ret.second.x = std::max(ret.second.x, int(imgs.m_imageData.m_pos[3].x)); + ret.second.y = std::max(ret.second.y, int(imgs.m_imageData.m_pos[3].z)); } return ret; diff --git a/Runtime/GuiSys/CTextRenderBuffer.hpp b/Runtime/GuiSys/CTextRenderBuffer.hpp index 2f9add5bd..a806988a1 100644 --- a/Runtime/GuiSys/CTextRenderBuffer.hpp +++ b/Runtime/GuiSys/CTextRenderBuffer.hpp @@ -22,6 +22,31 @@ class CTextExecuteBuffer; using CTextColor = zeus::CColor; +struct BooFontCharacters { + TLockedToken m_font; + hsh::dynamic_owner> m_instBuf; + hsh::binding m_dataBinding; + hsh::binding m_dataBindingOverdraw; + std::vector m_charData; + u32 m_charCount = 0; + bool m_dirty = true; + + BooFontCharacters(const CToken& token) : m_font(token) {} +}; + +struct BooImage { + CFontImageDef m_imageDef; + hsh::dynamic_owner> m_instBuf; + std::vector m_dataBinding; + std::vector m_dataBindingOverdraw; + CTextSupportShader::ImageInstance m_imageData; + bool m_dirty = true; + + BooImage(const CFontImageDef& imgDef, const zeus::CVector2i& offset) : m_imageDef(imgDef) { + m_imageData.SetMetrics(imgDef, offset); + } +}; + class CTextRenderBuffer { friend class CGuiTextSupport; friend class CTextSupportShader; @@ -42,7 +67,7 @@ public: enum class EMode { AllocTally, BufferFill }; private: - EMode x0_mode; + EMode x0_mode{}; #if 0 std::vector> x4_fonts; std::vector x14_images; @@ -58,11 +83,7 @@ private: #else /* Boo-specific text-rendering functionality */ hsh::dynamic_owner> m_uniBuf, m_uniBuf2; - - struct BooFontCharacters; std::vector m_fontCharacters; - - struct BooImage; std::vector m_images; struct BooPrimitiveMark; @@ -73,7 +94,7 @@ private: zeus::CColor m_main; zeus::CColor m_outline = zeus::skBlack; - CGuiWidget::EGuiModelDrawFlags m_drawFlags; + CGuiWidget::EGuiModelDrawFlags m_drawFlags{}; bool m_committed = false; void CommitResources();