Added UI functionality to the Graphics System #232
|
@ -15,29 +15,25 @@
|
|||
#include <vector>
|
||||
#include <string>
|
||||
#include "msdf-atlas-gen/msdf-atlas-gen.h"
|
||||
#include "math/SHMatrix.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
struct SH_API SHFontAsset : SHAssetData
|
||||
{
|
||||
using GlyphData = std::tuple<msdfgen::unicode_t, SHMatrix>;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* MEMBER VARIABLES */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
//! Individual glyph data
|
||||
std::vector<msdf_atlas::GlyphGeometry> glyphData;
|
||||
|
||||
//! MSDF's data structure containing the raw data of the atlas
|
||||
msdfgen::Bitmap<msdfgen::byte, 3> fontBitmap;
|
||||
|
||||
//! Used for getting data of the font
|
||||
msdf_atlas::FontGeometry fontGeometry;
|
||||
|
||||
//! Handle to the font loaded. We will use this when we initialize font data.
|
||||
//! This is mainly the asset part of fonts.
|
||||
msdfgen::FontHandle* fontHandle;
|
||||
|
||||
//! Name of the shader file (without parent path)
|
||||
std::string fontName;
|
||||
//std::string fontName;
|
||||
|
||||
//! Data containing character and uv transformation data and other misc data
|
||||
std::vector<GlyphData> glyphTransformations;
|
||||
|
||||
//! The actual data of the atlas to go into the binary
|
||||
std::unique_ptr<unsigned char[]> bitmapData;
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -0,0 +1,217 @@
|
|||
#include "SHpch.h"
|
||||
#include "SHFontCompiler.h"
|
||||
#include "Graphics/MiddleEnd/TextRendering/SHFreetypeInstance.h"
|
||||
#include "Assets/Asset Types/SHFontAsset.h"
|
||||
#include "Math/Vector/SHVec2.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
\brief
|
||||
Given a valid ptr to a font asset and relevant data, initialize the data
|
||||
inside the font asset. See SHFontAsset for details.
|
||||
|
||||
\param fontAsset
|
||||
The ptr to the font asset.
|
||||
|
||||
\param glyphData
|
||||
Individual glyph data.
|
||||
|
||||
\param fontBitmap
|
||||
Actual bitmap data
|
||||
|
||||
\param fontGeometry
|
||||
Font geometry required to get advance
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
void SHFontCompiler::WriteToFontAsset(SHFontAsset* fontAsset, std::vector<msdf_atlas::GlyphGeometry> const& glyphData, msdfgen::Bitmap<msdfgen::byte, 3> const& fontBitmap, msdf_atlas::FontGeometry const& fontGeometry) noexcept
|
||||
{
|
||||
if (!fontAsset)
|
||||
return;
|
||||
|
||||
uint32_t numGlyphs = static_cast<uint32_t>(glyphData.size());
|
||||
for (uint32_t i = 0; i < numGlyphs; ++i)
|
||||
{
|
||||
// bounding box of the glyph in atlas
|
||||
double atlasL = 0.0, atlasR = 0.0, atlasT = 0.0, atlasB = 0.0;
|
||||
|
||||
// bounding box of glyph as it should be placed on the baseline
|
||||
double atlasPL = 0.0, atlasPR = 0.0, atlasPT = 0.0, atlasPB = 0.0;
|
||||
|
||||
// initialize the bounding boxes
|
||||
glyphData[i].getQuadAtlasBounds(atlasL, atlasB, atlasR, atlasT);
|
||||
glyphData[i].getQuadPlaneBounds(atlasPL, atlasPB, atlasPR, atlasPT);
|
||||
|
||||
// normalize the bounding box to (0 - 1).
|
||||
atlasL /= fontBitmap.width();
|
||||
atlasR /= fontBitmap.width();
|
||||
atlasT /= fontBitmap.height();
|
||||
atlasB /= fontBitmap.height();
|
||||
|
||||
// Normalized texture dimensions
|
||||
SHVec2 const NORMALIZED_TEX_DIMS{ static_cast<float> (atlasR - atlasL), static_cast<float> (atlasT - atlasB) };
|
||||
|
||||
// When we render the quad, it has to correctly scale depending on what letter/glyph we are rendering. This is for that scale.
|
||||
SHVec2 const QUAD_SCALE { static_cast<float> (atlasPR - atlasL), static_cast<float> (atlasT - atlasB) };
|
||||
|
||||
// initialize a matrix for uv and quad transformation data
|
||||
SHMatrix transformData
|
||||
{
|
||||
// For scaling the tex coords
|
||||
NORMALIZED_TEX_DIMS[0], 0.0f, 0.0f, 0.0f,
|
||||
0.0f, NORMALIZED_TEX_DIMS[1], 0.0f, 0.0f,
|
||||
|
||||
// For translating the tex coords
|
||||
static_cast<float>(atlasL), static_cast<float>(atlasB), 1.0f, 0.0f,
|
||||
|
||||
// Stores the transformation for a quad to correctly shape the glyph (first 2 values) and the bearing (last 2)
|
||||
QUAD_SCALE[0], QUAD_SCALE[1], static_cast<float>(atlasPL), static_cast<float>(atlasPB)
|
||||
};
|
||||
|
||||
// Initialize new data (we want the matrix transposed for shader use)
|
||||
SHFontAsset::GlyphData newData = std::make_tuple(glyphData[i].getCodepoint(), SHMatrix::Transpose(transformData));
|
||||
|
||||
// Push 1 set of data for a character/glyph into the asset.
|
||||
fontAsset->glyphTransformations.push_back(newData);
|
||||
}
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
\brief
|
||||
Loads and compiles a font to binary format. Returns a path to the binary
|
||||
data (XQ please confirm kor kor thanks <3).
|
||||
|
||||
\param path
|
||||
Path to the font file (truetype font file) to load.
|
||||
|
||||
\return
|
||||
Path to newly created binary data.
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
std::optional<AssetPath> SHFontCompiler::LoadAndCompileFont(AssetPath path) noexcept
|
||||
{
|
||||
msdfgen::FontHandle* fontHandle = nullptr;
|
||||
|
||||
// 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());
|
||||
|
||||
// Compile a font asset
|
||||
auto* fontAsset = CompileFontToMemory(fontHandle);
|
||||
|
||||
// No path to binary format
|
||||
if (!fontAsset)
|
||||
return {};
|
||||
|
||||
CompileFontToBinary(path, *fontAsset);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
\brief
|
||||
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
|
||||
asset.
|
||||
|
||||
\param fontHandle
|
||||
MSDF font handle required to initialize member variables in SHFontAsset.
|
||||
|
||||
\return
|
||||
A pointer to a brand new font asset.
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
SHADE::SHFontAsset const* SHFontCompiler::CompileFontToMemory(msdfgen::FontHandle* fontHandle) noexcept
|
||||
{
|
||||
// Individual glyph geometry
|
||||
std::vector<msdf_atlas::GlyphGeometry> glyphData;
|
||||
|
||||
// Actual bitmap data
|
||||
msdfgen::Bitmap<msdfgen::byte, 3> fontBitmap;
|
||||
|
||||
// Font geometry required to get advance
|
||||
msdf_atlas::FontGeometry fontGeometry (&glyphData);
|
||||
|
||||
// Load char set
|
||||
fontGeometry.loadCharset(fontHandle, 1.0, msdf_atlas::Charset::ASCII);
|
||||
|
||||
// Apply MSDF edge coloring
|
||||
const double maxCornerAngle = 3.0;
|
||||
for (msdf_atlas::GlyphGeometry& glyph : glyphData)
|
||||
glyph.edgeColoring(&msdfgen::edgeColoringInkTrap, maxCornerAngle, 0);
|
||||
|
||||
// configure parameters for atlas generation
|
||||
msdf_atlas::TightAtlasPacker atlasPacker;
|
||||
atlasPacker.setDimensionsConstraint(msdf_atlas::TightAtlasPacker::DimensionsConstraint::SQUARE);
|
||||
|
||||
atlasPacker.setMinimumScale(64.0);
|
||||
atlasPacker.setPixelRange(2.0);
|
||||
atlasPacker.setMiterLimit(1.0);
|
||||
atlasPacker.pack(glyphData.data(), static_cast<int>(glyphData.size()));
|
||||
|
||||
// Get the dimensions after applying parameters
|
||||
int width = 0, height = 0;
|
||||
atlasPacker.getDimensions(width, height);
|
||||
|
||||
// generate the atlas
|
||||
msdf_atlas::ImmediateAtlasGenerator<float, 3, msdf_atlas::msdfGenerator, msdf_atlas::BitmapAtlasStorage<float, 3>> generator(width, height);
|
||||
msdf_atlas::GeneratorAttributes genAttribs;
|
||||
generator.setAttributes(genAttribs);
|
||||
generator.setThreadCount(4);
|
||||
generator.generate(glyphData.data(), static_cast<int>(glyphData.size()));
|
||||
|
||||
fontBitmap = std::move(((msdfgen::Bitmap<msdfgen::byte, 3>&&)generator.atlasStorage()));
|
||||
|
||||
// at this point we have all the required data to initialize a font asset.
|
||||
|
||||
// Dynamically allocate new asset
|
||||
SHFontAsset* newAsset = new SHFontAsset();
|
||||
|
||||
// Now we populate it with data
|
||||
WriteToFontAsset(newAsset, glyphData, fontBitmap, fontGeometry);
|
||||
|
||||
return newAsset;
|
||||
}
|
||||
|
||||
std::string SHFontCompiler::CompileFontToBinary(AssetPath path, SHFontAsset const& asset) noexcept
|
||||
{
|
||||
std::string newPath{ path.string() };
|
||||
newPath = newPath.substr(0, newPath.find_last_of('.'));
|
||||
newPath += SHADER_BUILT_IN_EXTENSION.data();
|
||||
|
||||
std::ofstream file{ newPath, std::ios::binary | std::ios::out | std::ios::trunc };
|
||||
|
||||
//file.write(
|
||||
// reinterpret_cast<char const*>(&data.shaderType), sizeof(uint8_t)
|
||||
//);
|
||||
|
||||
//size_t const byteCount = sizeof(uint32_t) * data.spirvBinary.size();
|
||||
|
||||
//file.write(
|
||||
// reinterpret_cast<char const*>(&byteCount), sizeof(size_t)
|
||||
//);
|
||||
|
||||
//file.write(
|
||||
// reinterpret_cast<char const*>(data.spirvBinary.data()), byteCount
|
||||
//);
|
||||
|
||||
file.close();
|
||||
|
||||
return newPath;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#include "Assets/SHAssetMacros.h"
|
||||
#include "msdf-atlas-gen/msdf-atlas-gen.h"
|
||||
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SHFontAsset;
|
||||
|
||||
class SHFontCompiler
|
||||
{
|
||||
private:
|
||||
static void WriteToFontAsset (SHFontAsset* fontAsset, std::vector<msdf_atlas::GlyphGeometry> const& glyphData, msdfgen::Bitmap<msdfgen::byte, 3> const& fontBitmap, msdf_atlas::FontGeometry const& fontGeometry) noexcept;
|
||||
|
||||
public:
|
||||
static std::optional<AssetPath> LoadAndCompileFont (AssetPath path) noexcept;
|
||||
static SHFontAsset const* CompileFontToMemory (msdfgen::FontHandle* fontHandle) noexcept;
|
||||
static std::string CompileFontToBinary (AssetPath path, SHFontAsset const& asset) noexcept;
|
||||
|
||||
};
|
||||
}
|
|
@ -7,46 +7,18 @@ namespace SHADE
|
|||
{
|
||||
SHADE::SHAssetData* SHFontLoader::Load(AssetPath path)
|
||||
{
|
||||
//auto result = new SHFontAsset();
|
||||
|
||||
//// save the font name
|
||||
//result->fontName = path.stem().stem().string();
|
||||
|
||||
//result->fontHandle = msdfgen::loadFont(SHFreetypeInstance::GetFreetypeHandle(), path.string().c_str());
|
||||
|
||||
////result->fontGeometry = msdf_atlas::FontGeometry(&result->glyphData);
|
||||
|
||||
//result->fontGeometry.loadCharset(font, 1.0f, msdf_atlas::Charset::ASCII);
|
||||
|
||||
//// Apply MSDF edge coloring
|
||||
//const double maxCornerAngle = 3.0;
|
||||
//for (GlyphGeometry& glyph : glyphData)
|
||||
// glyph.edgeColoring(&msdfgen::edgeColoringInkTrap, maxCornerAngle, 0);
|
||||
|
||||
//TightAtlasPacker atlasPacker;
|
||||
//atlasPacker.setDimensionsConstraint(TightAtlasPacker::DimensionsConstraint::SQUARE);
|
||||
|
||||
//atlasPacker.setMinimumScale(64.0);
|
||||
//atlasPacker.setPixelRange(2.0);
|
||||
//atlasPacker.setMiterLimit(1.0);
|
||||
//atlasPacker.pack(glyphData.data(), static_cast<int>(glyphData.size()));
|
||||
|
||||
|
||||
//int width = 0, height = 0;
|
||||
//atlasPacker.getDimensions(width, height);
|
||||
|
||||
//ImmediateAtlasGenerator<float, 3, msdfGenerator, BitmapAtlasStorage<float, 3>> generator(width, height);
|
||||
//GeneratorAttributes genAttribs;
|
||||
//generator.setAttributes(genAttribs);
|
||||
//generator.setThreadCount(4);
|
||||
//generator.generate(glyphData.data(), static_cast<int>(glyphData.size()));
|
||||
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SHFontLoader::Write(SHAssetData const* data, AssetPath path)
|
||||
{
|
||||
/*
|
||||
Stuff to write to binary file :
|
||||
- Interleaved per character data
|
||||
- codepoint (actual character)
|
||||
- 4x4 Matrix data (stores UV transform + extra data)
|
||||
- Actual atlas texture
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,8 @@ constexpr std::string_view META_EXTENSION {".shmeta"};
|
|||
constexpr std::string_view AUDIO_EXTENSION {".ogg"};
|
||||
constexpr std::string_view AUDIO_WAV_EXTENSION {".wav"};
|
||||
constexpr std::string_view SHADER_EXTENSION{ ".shshader" };
|
||||
constexpr std::string_view SHADER_BUILT_IN_EXTENSION{".shshaderb"};
|
||||
constexpr std::string_view SHADER_BUILT_IN_EXTENSION{ ".shshaderb" };
|
||||
constexpr std::string_view FONT_EXTENSION{ ".shfont" };
|
||||
constexpr std::string_view SCRIPT_EXTENSION {".cs"};
|
||||
constexpr std::string_view SCENE_EXTENSION {".shade"};
|
||||
constexpr std::string_view PREFAB_EXTENSION {".shprefab"};
|
||||
|
@ -91,6 +92,7 @@ constexpr std::string_view EXTENSIONS[] = {
|
|||
AUDIO_EXTENSION,
|
||||
SHADER_EXTENSION,
|
||||
SHADER_BUILT_IN_EXTENSION,
|
||||
FONT_EXTENSION,
|
||||
MATERIAL_EXTENSION,
|
||||
TEXTURE_EXTENSION,
|
||||
MODEL_EXTENSION,
|
||||
|
|
|
@ -311,6 +311,8 @@ namespace SHADE
|
|||
|
||||
lightingSubSystem = resourceManager.Create<SHLightingSubSystem>();
|
||||
lightingSubSystem->Init(device, descPool);
|
||||
|
||||
SHFreetypeInstance::Init();
|
||||
}
|
||||
|
||||
void SHGraphicsSystem::InitBuiltInResources(void)
|
||||
|
|
Loading…
Reference in New Issue