Text Rendering WIP

This commit is contained in:
Brandon Mak 2022-11-07 19:38:08 +08:00
parent 6a6785d296
commit 1165b9fa47
7 changed files with 235 additions and 19 deletions

View File

@ -35,6 +35,7 @@ namespace SHADE
//! The actual data of the atlas to go into the binary //! The actual data of the atlas to go into the binary
std::unique_ptr<unsigned char[]> bitmapData; std::unique_ptr<unsigned char[]> bitmapData;
//! size of the bitmap
uint32_t bitmapSize;
}; };
} }

View File

@ -81,8 +81,12 @@ namespace SHADE
fontAsset->glyphTransformations.push_back(newData); fontAsset->glyphTransformations.push_back(newData);
} }
uint32_t bytesRequired = fontBitmap.width() * fontBitmap.height() * 3 * sizeof(float);
// copy data from bitmap to asset. Each channel is a 32 bit float and there are 3 channels. // copy data from bitmap to asset. Each channel is a 32 bit float and there are 3 channels.
fontAsset->bitmapData = std::make_unique<unsigned char[]>(fontBitmap.width() * fontBitmap.height() * 3 * sizeof (float)); fontAsset->bitmapData = std::make_unique<unsigned char[]>(bytesRequired);
fontAsset->bitmapSize = bytesRequired;
} }
/***************************************************************************/ /***************************************************************************/
@ -107,14 +111,19 @@ namespace SHADE
// XQ I need your help for path manipulation to actually load the msdfgen::FontHandle here. Am I doing this correctly? // XQ I need your help for path manipulation to actually load the msdfgen::FontHandle here. Am I doing this correctly?
fontHandle = msdfgen::loadFont(SHFreetypeInstance::GetFreetypeHandle(), path.string().c_str()); fontHandle = msdfgen::loadFont(SHFreetypeInstance::GetFreetypeHandle(), path.string().c_str());
// Compile a font asset if (fontHandle)
auto* fontAsset = CompileFontToMemory(fontHandle); {
// Compile a font asset
auto* fontAsset = CompileFontToMemory(fontHandle);
// No path to binary format // No path to binary format
if (!fontAsset) if (!fontAsset)
return {}; return {};
CompileFontToBinary(path, *fontAsset); return CompileFontToBinary(path, *fontAsset);
}
SHLOG_ERROR("Unable to open font file: {}", path.string());
return {}; return {};
} }
@ -124,7 +133,7 @@ namespace SHADE
\brief \brief
This function takes in a font handle and generates a font asset from it. This function takes in a font handle and generates a font asset from it.
It first geneates an atlas and all relevant data before creating the It first generates an atlas and all relevant data before creating the
asset. asset.
\param fontHandle \param fontHandle
@ -187,6 +196,24 @@ namespace SHADE
return newAsset; return newAsset;
} }
/***************************************************************************/
/*!
\brief
After generating the asset we call this function to serialize the font
data into binary data.
\param path
path to font file (?).
\param asset
Asset to write.
\return
Path the asset.
*/
/***************************************************************************/
std::string SHFontCompiler::CompileFontToBinary(AssetPath path, SHFontAsset const& asset) noexcept std::string SHFontCompiler::CompileFontToBinary(AssetPath path, SHFontAsset const& asset) noexcept
{ {
std::string newPath{ path.string() }; std::string newPath{ path.string() };
@ -195,19 +222,28 @@ namespace SHADE
std::ofstream file{ newPath, std::ios::binary | std::ios::out | std::ios::trunc }; std::ofstream file{ newPath, std::ios::binary | std::ios::out | std::ios::trunc };
//file.write( uint32_t numGlyphs = asset.glyphTransformations.size();
// reinterpret_cast<char const*>(&data.shaderType), sizeof(uint8_t)
//);
//size_t const byteCount = sizeof(uint32_t) * data.spirvBinary.size(); // Write number of glyphs first
file.write(reinterpret_cast<char const*>(&numGlyphs), sizeof (uint32_t));
//file.write( for (uint32_t i = 0; i < numGlyphs; ++i)
// reinterpret_cast<char const*>(&byteCount), sizeof(size_t) {
//); auto const& [glyph, data] = asset.glyphTransformations[i];
// write the glyph first
file.write (reinterpret_cast<char const*>(&glyph), sizeof (msdfgen::unicode_t));
// then write the data next to it
file.write (reinterpret_cast<char const*>(&data), sizeof (SHMatrix));
}
// Write bytes required for bitmap
file.write(reinterpret_cast<char const*>(asset.bitmapSize), sizeof (uint32_t));
// now we write the actual bitmap
file.write (reinterpret_cast<char const*>(asset.bitmapData.get()), asset.bitmapSize);
//file.write(
// reinterpret_cast<char const*>(data.spirvBinary.data()), byteCount
//);
file.close(); file.close();

View File

@ -2,11 +2,50 @@
#include "SHFontLoader.h" #include "SHFontLoader.h"
#include "Assets/Asset Types/SHFontAsset.h" #include "Assets/Asset Types/SHFontAsset.h"
#include "Graphics/MiddleEnd/TextRendering/SHFreetypeInstance.h" #include "Graphics/MiddleEnd/TextRendering/SHFreetypeInstance.h"
#include "msdf-atlas-gen/msdf-atlas-gen.h"
#include <fstream>
#include <sstream>
#include <string>
#include <algorithm>
namespace SHADE namespace SHADE
{ {
SHADE::SHAssetData* SHFontLoader::Load(AssetPath path) SHADE::SHAssetData* SHFontLoader::Load(AssetPath path)
{ {
auto newFontAsset = new SHFontAsset();
std::ifstream file{ path.string(), std::ios::in | std::ios::binary };
if (!file.is_open())
{
SHLOG_ERROR("Unable to open compiled font file: {}", path.string());
return nullptr;
}
uint32_t numGlyphs = 0;
// read how many glyphs we have
file.read (reinterpret_cast<char*>(&numGlyphs), sizeof (uint32_t));
newFontAsset->glyphTransformations.resize(numGlyphs);
for (uint32_t i = 0; i < numGlyphs; ++i)
{
// read the glyph
file.read(reinterpret_cast<char*>(&std::get<0>(newFontAsset->glyphTransformations[i])), sizeof(msdfgen::unicode_t));
// Read the data for the glyph
file.read(reinterpret_cast<char*>(&std::get<1>(newFontAsset->glyphTransformations[i])), sizeof(SHMatrix));
}
// Read bytes required for the bitmap
file.read(reinterpret_cast<char*>(&newFontAsset->bitmapSize), sizeof(uint32_t));
// Read the bitmap
newFontAsset->bitmapData = std::make_unique<unsigned char[]>(newFontAsset->bitmapSize);
file.read (reinterpret_cast<char*>(newFontAsset->bitmapData.get()), newFontAsset->bitmapSize);
file.close();
return nullptr; return nullptr;
} }

View File

@ -0,0 +1,69 @@
#include "SHpch.h"
#include "SHTextRendererComponent.h"
namespace SHADE
{
void SHTextRendererComponent::MakeDirty(void) noexcept
{
requiresRecompute = true;
}
void SHTextRendererComponent::Clean(void) noexcept
{
requiresRecompute = false;
}
/***************************************************************************/
/*!
\brief
On create the text has nothing.
*/
/***************************************************************************/
void SHTextRendererComponent::OnCreate(void)
{
text = "";
requiresRecompute = true;
// Default white color.
color = SHColour::WHITE;
}
/***************************************************************************/
/*!
\brief
Sets the text to be rendered.
\param newText
\return
*/
/***************************************************************************/
void SHTextRendererComponent::SetText(std::string_view newText) noexcept
{
text = newText;
MakeDirty();
}
/***************************************************************************/
/*!
\brief
Getter for the text required to render.
\return
*/
/***************************************************************************/
std::string const& SHTextRendererComponent::GetText(void) const noexcept
{
return text;
}
}

View File

@ -0,0 +1,37 @@
#pragma once
#include <string>
#include <string_view>
#include "ECS_Base/Components/SHComponent.h"
#include "Math/SHColour.h"
namespace SHADE
{
class SHTextRendererComponent final : public SHComponent
{
private:
//! Text required to be rendered
std::string text;
//! Color of the text
SHColour color;
//! Requires to recompute the positions of each glyph/character
bool requiresRecompute;
void MakeDirty (void) noexcept;
void Clean (void) noexcept;
public:
void OnCreate(void) override final;
/*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/
void SetText (std::string_view newText) noexcept;
std::string const& GetText (void) const noexcept;
};
}

View File

@ -0,0 +1,7 @@
#include "SHpch.h"
#include "SHTextRenderingSubSystem.h"
namespace SHADE
{
}

View File

@ -0,0 +1,27 @@
#pragma once
#include "Resource/SHHandle.h"
namespace SHADE
{
class SHVkLogicalDevice;
class SHVkDescriptorPool;
class SHVkDescriptorSetGroup;
class SHVkDescriptorSetLayout;
class SHVkBuffer;
class SHLightComponent;
class SHVkCommandBuffer;
class SHTextRenderingSubSystem
{
private:
public:
void Init(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool) noexcept;
void Run(uint32_t frameIndex) noexcept;
void Exit(void) noexcept;
};
}