More text changes
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include "MaterialAsset.h"
|
||||
#include "MaterialInstanceAsset.h"
|
||||
#include "MeshAsset.h"
|
||||
#include "SVGAsset.h"
|
||||
#include "TextureAsset.h"
|
||||
#include "Window/WindowManager.h"
|
||||
#include <fstream>
|
||||
@@ -46,6 +47,15 @@ PFontAsset AssetRegistry::findFont(std::string_view folderPath, std::string_view
|
||||
return folder->fonts.at(std::string(filePath));
|
||||
}
|
||||
|
||||
PSVGAsset AssetRegistry::findSVG(std::string_view folderPath, std::string_view filePath) {
|
||||
std::unique_lock l(get().assetLock);
|
||||
AssetFolder* folder = get().assetRoot;
|
||||
if (!folderPath.empty()) {
|
||||
folder = get().getOrCreateFolder(folderPath);
|
||||
}
|
||||
return folder->svgs.at(std::string(filePath));
|
||||
}
|
||||
|
||||
PMaterialAsset AssetRegistry::findMaterial(std::string_view folderPath, std::string_view filePath) {
|
||||
std::unique_lock l(get().assetLock);
|
||||
AssetFolder* folder = get().assetRoot;
|
||||
@@ -79,6 +89,11 @@ void AssetRegistry::registerFont(OFontAsset font) {
|
||||
get().registerFontInternal(std::move(font));
|
||||
}
|
||||
|
||||
void AssetRegistry::registerSVG(OSVGAsset svg) {
|
||||
std::unique_lock l(get().assetLock);
|
||||
get().registerSVGInternal(std::move(svg));
|
||||
}
|
||||
|
||||
void AssetRegistry::registerMaterial(OMaterialAsset material) {
|
||||
std::unique_lock l(get().assetLock);
|
||||
get().registerMaterialInternal(std::move(material));
|
||||
@@ -128,6 +143,9 @@ void AssetRegistry::loadAsset(ArchiveBuffer& buffer) {
|
||||
case FontAsset::IDENTIFIER:
|
||||
asset = PFontAsset(folder->fonts.at(name));
|
||||
break;
|
||||
case SVGAsset::IDENTIFIER:
|
||||
asset = PSVGAsset(folder->svgs.at(name));
|
||||
break;
|
||||
default:
|
||||
throw new std::logic_error("Unknown Identifier");
|
||||
}
|
||||
@@ -273,6 +291,10 @@ Pair<PAsset, ArchiveBuffer> AssetRegistry::peekAsset(ArchiveBuffer& buffer) {
|
||||
folder->fonts[name] = new FontAsset(folderPath, name);
|
||||
asset = PFontAsset(folder->fonts[name]);
|
||||
break;
|
||||
case SVGAsset::IDENTIFIER:
|
||||
folder->svgs[name] = new SVGAsset(folderPath, name);
|
||||
asset = PSVGAsset(folder->svgs[name]);
|
||||
break;
|
||||
default:
|
||||
throw new std::logic_error("Unknown Identifier");
|
||||
}
|
||||
@@ -299,6 +321,9 @@ void AssetRegistry::saveFolder(const std::filesystem::path& folderPath, AssetFol
|
||||
for (const auto& [name, font] : folder->fonts) {
|
||||
saveAsset(PFontAsset(font), FontAsset::IDENTIFIER, folderPath, name);
|
||||
}
|
||||
for (const auto& [name, svg] : folder->svgs) {
|
||||
saveAsset(PSVGAsset(svg), SVGAsset::IDENTIFIER, folderPath, name);
|
||||
}
|
||||
for (auto& [name, child] : folder->children) {
|
||||
saveFolder(folderPath / name, child);
|
||||
}
|
||||
@@ -321,6 +346,11 @@ void AssetRegistry::registerFontInternal(OFontAsset font) {
|
||||
folder->fonts[font->getName()] = std::move(font);
|
||||
}
|
||||
|
||||
void AssetRegistry::registerSVGInternal(OSVGAsset svg) {
|
||||
AssetFolder* folder = getOrCreateFolder(svg->getFolderPath());
|
||||
folder->svgs[svg->getName()] = std::move(svg);
|
||||
}
|
||||
|
||||
void AssetRegistry::registerMaterialInternal(OMaterialAsset material) {
|
||||
AssetFolder* folder = getOrCreateFolder(material->getFolderPath());
|
||||
folder->materials[material->getName()] = std::move(material);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
namespace Seele {
|
||||
DECLARE_REF(TextureAsset)
|
||||
DECLARE_REF(FontAsset)
|
||||
DECLARE_REF(SVGAsset)
|
||||
DECLARE_REF(MeshAsset)
|
||||
DECLARE_REF(MaterialAsset)
|
||||
DECLARE_REF(MaterialInstanceAsset)
|
||||
@@ -24,12 +25,14 @@ class AssetRegistry {
|
||||
static PMeshAsset findMesh(std::string_view folderPath, std::string_view filePath);
|
||||
static PTextureAsset findTexture(std::string_view folderPath, std::string_view filePath);
|
||||
static PFontAsset findFont(std::string_view folderPath, std::string_view name);
|
||||
static PSVGAsset findSVG(std::string_view folderPath, std::string_view name);
|
||||
static PMaterialAsset findMaterial(std::string_view folderPath, std::string_view filePath);
|
||||
static PMaterialInstanceAsset findMaterialInstance(std::string_view folderPath, std::string_view filePath);
|
||||
|
||||
static void registerMesh(OMeshAsset mesh);
|
||||
static void registerTexture(OTextureAsset texture);
|
||||
static void registerFont(OFontAsset font);
|
||||
static void registerSVG(OSVGAsset svg);
|
||||
static void registerMaterial(OMaterialAsset material);
|
||||
static void registerMaterialInstance(OMaterialInstanceAsset instance);
|
||||
|
||||
@@ -48,6 +51,7 @@ class AssetRegistry {
|
||||
Map<std::string, AssetFolder*> children;
|
||||
Map<std::string, OTextureAsset> textures;
|
||||
Map<std::string, OFontAsset> fonts;
|
||||
Map<std::string, OSVGAsset> svgs;
|
||||
Map<std::string, OMeshAsset> meshes;
|
||||
Map<std::string, OMaterialAsset> materials;
|
||||
Map<std::string, OMaterialInstanceAsset> instances;
|
||||
@@ -70,6 +74,7 @@ class AssetRegistry {
|
||||
void registerMeshInternal(OMeshAsset mesh);
|
||||
void registerTextureInternal(OTextureAsset texture);
|
||||
void registerFontInternal(OFontAsset font);
|
||||
void registerSVGInternal(OSVGAsset svg);
|
||||
void registerMaterialInternal(OMaterialAsset material);
|
||||
void registerMaterialInstanceInternal(OMaterialInstanceAsset instance);
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@ target_sources(Engine
|
||||
MaterialInstanceAsset.cpp
|
||||
MeshAsset.h
|
||||
MeshAsset.cpp
|
||||
SVGAsset.h
|
||||
SVGAsset.cpp
|
||||
TextureAsset.h
|
||||
TextureAsset.cpp)
|
||||
|
||||
|
||||
@@ -6,35 +6,61 @@ using namespace Seele;
|
||||
|
||||
FontAsset::FontAsset() {}
|
||||
|
||||
FontAsset::FontAsset(std::string_view folderPath, std::string_view name) : Asset(folderPath, name) {}
|
||||
|
||||
FontAsset::~FontAsset() {}
|
||||
|
||||
void FontAsset::save(ArchiveBuffer& buffer) const { Serialization::save(buffer, glyphs); }
|
||||
|
||||
void FontAsset::load(ArchiveBuffer& buffer) { Serialization::load(buffer, glyphs); }
|
||||
|
||||
void FontAsset::Glyph::save(ArchiveBuffer& buffer) const {
|
||||
Serialization::save(buffer, size);
|
||||
Serialization::save(buffer, bearing);
|
||||
Serialization::save(buffer, advance);
|
||||
Serialization::save(buffer, textureData);
|
||||
FontAsset::FontAsset(std::string_view folderPath, std::string_view name) : Asset(folderPath, name) {
|
||||
FT_Error error = FT_Init_FreeType(&ft);
|
||||
assert(!error);
|
||||
}
|
||||
|
||||
void FontAsset::Glyph::load(ArchiveBuffer& buffer) {
|
||||
Serialization::load(buffer, size);
|
||||
Serialization::load(buffer, bearing);
|
||||
Serialization::load(buffer, advance);
|
||||
Serialization::load(buffer, textureData);
|
||||
texture = buffer.getGraphics()->createTexture2D(TextureCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = textureData.size(),
|
||||
.data = textureData.data(),
|
||||
},
|
||||
.format = Gfx::SE_FORMAT_R8_UNORM,
|
||||
.width = size.x,
|
||||
.height = size.y,
|
||||
.name = "FontGlyph",
|
||||
});
|
||||
FontAsset::~FontAsset() {
|
||||
FT_Done_Face(face);
|
||||
FT_Done_FreeType(ft);
|
||||
}
|
||||
|
||||
void FontAsset::save(ArchiveBuffer& buffer) const { Serialization::save(buffer, ttfFile); }
|
||||
|
||||
void FontAsset::load(ArchiveBuffer& buffer) {
|
||||
Serialization::load(buffer, ttfFile);
|
||||
graphics = buffer.getGraphics();
|
||||
loadFace();
|
||||
}
|
||||
|
||||
void FontAsset::loadFace() {
|
||||
FT_Error error = FT_New_Memory_Face(ft, ttfFile.data(), ttfFile.size(), 0, &face);
|
||||
assert(!error);
|
||||
}
|
||||
|
||||
void FontAsset::loadFontSize(uint32 fontSize) {
|
||||
FT_Set_Pixel_Sizes(face, 0, fontSize);
|
||||
fontSizes[fontSize].ascent = face->ascender;
|
||||
fontSizes[fontSize].descent = face->descender;
|
||||
fontSizes[fontSize].linegap = 0;
|
||||
for (uint32 c = 0; c < 256; ++c) {
|
||||
if (FT_Load_Char(face, c, FT_LOAD_RENDER | FT_LOAD_COLOR)) {
|
||||
continue;
|
||||
}
|
||||
FontAsset::Glyph& glyph = fontSizes[fontSize].glyphs[c];
|
||||
glyph.size = IVector2(face->glyph->bitmap.width, face->glyph->bitmap.rows);
|
||||
glyph.bearing = IVector2(face->glyph->bitmap_left, face->glyph->bitmap_top);
|
||||
glyph.advance = face->glyph->advance.x;
|
||||
glyph.textureData.resize(glyph.size.x * glyph.size.y);
|
||||
if (glyph.textureData.size() == 0) {
|
||||
glyph.size.x = 1;
|
||||
glyph.size.y = 1;
|
||||
glyph.textureData.add(0);
|
||||
// load a single transparent pixel, so that we dont have to handle empty textures later
|
||||
} else {
|
||||
std::memcpy(glyph.textureData.data(), face->glyph->bitmap.buffer, glyph.textureData.size());
|
||||
}
|
||||
glyph.texture = graphics->createTexture2D(TextureCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = glyph.textureData.size(),
|
||||
.data = glyph.textureData.data(),
|
||||
},
|
||||
.format = Gfx::SE_FORMAT_R8_UNORM,
|
||||
.width = glyph.size.x,
|
||||
.height = glyph.size.y,
|
||||
.name = "FontGlyph",
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
#pragma once
|
||||
#include "Asset.h"
|
||||
#include "Containers/Map.h"
|
||||
#include "Graphics/Texture.h"
|
||||
#include "Math/Math.h"
|
||||
#include <freetype/freetype.h>
|
||||
|
||||
namespace Seele {
|
||||
DECLARE_NAME_REF(Gfx, Texture2D)
|
||||
class FontAsset : public Asset {
|
||||
public:
|
||||
static constexpr uint64 IDENTIFIER = 0x10;
|
||||
@@ -24,10 +24,27 @@ class FontAsset : public Asset {
|
||||
void save(ArchiveBuffer& buffer) const;
|
||||
void load(ArchiveBuffer& buffer);
|
||||
};
|
||||
const Glyph& getGlyphData(char c) const { return glyphs[c]; }
|
||||
struct FontData {
|
||||
int32 ascent;
|
||||
int32 descent;
|
||||
int32 linegap;
|
||||
Map<uint32, Glyph> glyphs;
|
||||
};
|
||||
const Glyph& getGlyphData(char c, uint32 fontSize) {
|
||||
if (!fontSizes.contains(fontSize))
|
||||
loadFontSize(fontSize);
|
||||
return fontSizes[fontSize].glyphs[c];
|
||||
}
|
||||
const FontData& getFontData(uint32 fontSize) { return fontSizes[fontSize]; }
|
||||
void loadFace();
|
||||
|
||||
private:
|
||||
Map<uint32, Glyph> glyphs;
|
||||
void loadFontSize(uint32 fontSize);
|
||||
Gfx::PGraphics graphics;
|
||||
FT_Library ft;
|
||||
FT_Face face;
|
||||
Array<uint8> ttfFile;
|
||||
Map<uint32, FontData> fontSizes;
|
||||
friend class FontLoader;
|
||||
};
|
||||
DECLARE_REF(FontAsset)
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
#include "SVGAsset.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
SVGAsset::SVGAsset() {}
|
||||
|
||||
SVGAsset::SVGAsset(std::string_view folderPath, std::string_view name) : Asset(folderPath, name) {}
|
||||
|
||||
SVGAsset::~SVGAsset() {}
|
||||
|
||||
void SVGAsset::save(ArchiveBuffer& buffer) const { Serialization::save(buffer, data); }
|
||||
|
||||
void SVGAsset::load(ArchiveBuffer& buffer) {
|
||||
Serialization::load(buffer, data);
|
||||
document = lunasvg::Document::loadFromData(data.data());
|
||||
}
|
||||
|
||||
Gfx::PTexture2D SVGAsset::getTexture(UVector2 dimensions) {
|
||||
auto viewbox = ViewBox{
|
||||
.width = dimensions.x,
|
||||
.height = dimensions.y,
|
||||
};
|
||||
if (!cachedTextures.contains(viewbox)) {
|
||||
auto bitmap = document->renderToBitmap(viewbox.width, viewbox.height);
|
||||
bitmap.convertToRGBA();
|
||||
cachedTextures[viewbox] = graphics->createTexture2D(TextureCreateInfo{
|
||||
.format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.width = viewbox.width,
|
||||
.height = viewbox.height,
|
||||
.name = "SVGTexture",
|
||||
});
|
||||
}
|
||||
return cachedTextures[viewbox];
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include "Asset.h"
|
||||
#include "Containers/Map.h"
|
||||
#include "Graphics/Texture.h"
|
||||
#include "Math/Math.h"
|
||||
#include <lunasvg.h>
|
||||
|
||||
namespace Seele {
|
||||
class SVGAsset : public Asset {
|
||||
public:
|
||||
static constexpr uint64 IDENTIFIER = 0x20;
|
||||
SVGAsset();
|
||||
SVGAsset(std::string_view folderPath, std::string_view name);
|
||||
virtual ~SVGAsset();
|
||||
virtual void save(ArchiveBuffer& buffer) const override;
|
||||
virtual void load(ArchiveBuffer& buffer) override;
|
||||
|
||||
Gfx::PTexture2D getTexture(UVector2 viewbox);
|
||||
|
||||
private:
|
||||
// workaround to make vector a map key, could be solved by either implementing
|
||||
// comparison operators for vectors, or implementing a hash map
|
||||
struct ViewBox {
|
||||
uint32 width;
|
||||
uint32 height;
|
||||
constexpr std::strong_ordering operator<=>(const ViewBox& other) const = default;
|
||||
};
|
||||
Array<char> data;
|
||||
Gfx::PGraphics graphics;
|
||||
std::unique_ptr<lunasvg::Document> document;
|
||||
Map<ViewBox, Gfx::OTexture2D> cachedTextures;
|
||||
friend class SVGLoader;
|
||||
};
|
||||
} // namespace Seele
|
||||
Reference in New Issue
Block a user