From 5a266f43596dc181f82060175a95776e482a0ccc Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Mon, 4 Dec 2023 21:43:31 -0600 Subject: [PATCH] TTF --- src/dawn/asset/AssetManager.cpp | 26 ++++++-- src/dawn/asset/AssetManager.hpp | 19 ++++++ src/dawn/asset/loaders/CMakeLists.txt | 1 + src/dawn/asset/loaders/TrueTypeLoader.cpp | 67 ++++++++++++++++++++ src/dawn/asset/loaders/TrueTypeLoader.hpp | 55 ++++++++++++++++ src/dawn/display/font/TrueTypeTexture.cpp | 13 ++-- src/dawn/display/font/TrueTypeTexture.hpp | 9 +-- src/dawnhelloworld/scene/HelloWorldScene.cpp | 11 ++-- 8 files changed, 173 insertions(+), 28 deletions(-) create mode 100644 src/dawn/asset/loaders/TrueTypeLoader.cpp create mode 100644 src/dawn/asset/loaders/TrueTypeLoader.hpp diff --git a/src/dawn/asset/AssetManager.cpp b/src/dawn/asset/AssetManager.cpp index 922434c5..ca45a8e9 100644 --- a/src/dawn/asset/AssetManager.cpp +++ b/src/dawn/asset/AssetManager.cpp @@ -5,6 +5,7 @@ #include "AssetManager.hpp" #include "loaders/TextureLoader.hpp" +#include "loaders/TrueTypeLoader.hpp" using namespace Dawn; @@ -53,16 +54,11 @@ template<> std::shared_ptr AssetManager::get( const std::string filename ) { - auto existing = this->getExisting(filename); if(existing) { - std::cout << "Found existing texture loader for " << filename << std::endl; - // Check pointer hasn't gone stale, if it has remove it and create new. auto texture = existing->weakTexture.lock(); if(texture) return texture; - - std::cout << "Texture loader for " << filename << " has gone stale." << std::endl; this->removeExisting(filename); } @@ -73,6 +69,26 @@ std::shared_ptr AssetManager::get( return loader->sharedTexture; } +template<> +std::shared_ptr AssetManager::get( + const std::string filename, + const uint32_t fontSize +) { + auto existing = this->getExisting(filename); + if(existing) { + // Check pointer hasn't gone stale, if it has remove it and create new. + auto texture = existing->getTexture(fontSize); + if(texture) return texture; + this->removeExisting(filename); + } + + std::shared_ptr loader = std::make_shared( + filename + ); + pendingAssetLoaders.push_back(std::static_pointer_cast(loader)); + return loader->getTexture(fontSize); +} + AssetManager::~AssetManager() { } \ No newline at end of file diff --git a/src/dawn/asset/AssetManager.hpp b/src/dawn/asset/AssetManager.hpp index a71ccd00..cd6f07eb 100644 --- a/src/dawn/asset/AssetManager.hpp +++ b/src/dawn/asset/AssetManager.hpp @@ -60,9 +60,28 @@ namespace Dawn { */ void update(); + /** + * Returns the asset loader for the given asset. + * + * @param filename The filename of the asset to get. + * @return The asset loader for the given asset. + */ template std::shared_ptr get(const std::string filename); + /** + * Returns the asset loader for the given asset. + * + * @param filename The filename of the asset to get. + * @param fontSize The font size to get the truetype asset of. + * @return The asset loader for the given asset. + */ + template + std::shared_ptr get( + const std::string filename, + const uint32_t fontSize + ); + /** * Dispose the asset manager, and all attached assets. */ diff --git a/src/dawn/asset/loaders/CMakeLists.txt b/src/dawn/asset/loaders/CMakeLists.txt index b4f5f2b4..e7c90da1 100644 --- a/src/dawn/asset/loaders/CMakeLists.txt +++ b/src/dawn/asset/loaders/CMakeLists.txt @@ -7,4 +7,5 @@ target_sources(${DAWN_TARGET_NAME} PRIVATE TextureLoader.cpp + TrueTypeLoader.cpp ) \ No newline at end of file diff --git a/src/dawn/asset/loaders/TrueTypeLoader.cpp b/src/dawn/asset/loaders/TrueTypeLoader.cpp new file mode 100644 index 00000000..04c0a59e --- /dev/null +++ b/src/dawn/asset/loaders/TrueTypeLoader.cpp @@ -0,0 +1,67 @@ +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "TrueTypeLoader.hpp" +#include "assert/assert.hpp" + +using namespace Dawn; + +TrueTypeLoader::TrueTypeLoader(const std::string name) : + AssetLoader(name), + loader(name + ".ttf") +{ + +} + +void TrueTypeLoader::updateSync() { +} + +void TrueTypeLoader::updateAsync() { + if(state != TrueTypeLoaderState::INITIAL) return; + state = TrueTypeLoaderState::ASYNC_LOADING; + + // Load the data. + size_t size = loader.getSize(); + buffer = new uint8_t[size]; + + // Read the data. + size_t readSize = loader.read(buffer, size); + assertTrue(readSize == size, "Failed to read all data from TrueTypeLoader."); + + // Init the font. + auto ret = FT_Init_FreeType(&fontLibrary); + assertTrue(ret == 0, "Failed to initialize FreeType library."); + + ret = FT_New_Memory_Face(fontLibrary, buffer, size, 0, &face); + assertTrue(ret == 0, "Failed to load font face."); + + // Now close the asset loader + loader.close(); + state = TrueTypeLoaderState::ASYNC_DONE; + this->loaded = true; +} + +std::shared_ptr TrueTypeLoader::getTexture( + const uint32_t fontSize +) { + // Check if we have the texture already and it hasn't gone stale. + auto it = textures.find(fontSize); + if(it != textures.end()) { + if(!it->second.expired()) return it->second.lock(); + textures.erase(it); + } + + // Create the texture. + auto texture = std::make_shared(face, fontSize); + textures[fontSize] = texture; + return texture; +} + +TrueTypeLoader::~TrueTypeLoader() { + if(buffer != nullptr) { + delete[] buffer; + buffer = nullptr; + } +} \ No newline at end of file diff --git a/src/dawn/asset/loaders/TrueTypeLoader.hpp b/src/dawn/asset/loaders/TrueTypeLoader.hpp new file mode 100644 index 00000000..78198fce --- /dev/null +++ b/src/dawn/asset/loaders/TrueTypeLoader.hpp @@ -0,0 +1,55 @@ +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "asset/AssetLoader.hpp" +#include "asset/AssetDataLoader.hpp" +#include "display/font/TrueTypeTexture.hpp" + +namespace Dawn { + enum class TrueTypeLoaderState { + INITIAL, + ASYNC_LOADING, + ASYNC_DONE + }; + + class TrueTypeLoader : public AssetLoader { + protected: + FT_Library fontLibrary; + FT_Face face; + AssetDataLoader loader; + std::unordered_map> textures; + enum TrueTypeLoaderState state = TrueTypeLoaderState::INITIAL; + uint8_t *buffer = nullptr; + + public: + /** + * Constructs a TrueTypeLoader. You should instead use the parent + * asset managers' abstracted load method + * + * @param name File name asset to load, omitting the extension. + */ + TrueTypeLoader(const std::string name); + + void updateSync() override; + void updateAsync() override; + + /** + * Returns the texture for the given font size. + * + * @param fontSize Font size to get the texture for. + * @return Texture for the given character. + */ + std::shared_ptr getTexture( + const uint32_t fontSize + ); + + /** + * Dispose / Cleanup the truetype asset. Will also dispose the underlying + * truetype itself. + */ + ~TrueTypeLoader(); + }; +} \ No newline at end of file diff --git a/src/dawn/display/font/TrueTypeTexture.cpp b/src/dawn/display/font/TrueTypeTexture.cpp index 7e059a08..c9915634 100644 --- a/src/dawn/display/font/TrueTypeTexture.cpp +++ b/src/dawn/display/font/TrueTypeTexture.cpp @@ -9,14 +9,9 @@ using namespace Dawn; -TrueTypeTexture::TrueTypeTexture( - FT_Face face, - uint32_t fontSize, - uint8_t style -) : +TrueTypeTexture::TrueTypeTexture(FT_Face face, uint32_t fontSize) : face(face), - fontSize(fontSize), - style(style) + fontSize(fontSize) { assertTrue(fontSize < 256, "Font size cannot be greater than 256"); @@ -29,8 +24,8 @@ TrueTypeTexture::TrueTypeTexture( // Set the texture size texture->setSize( - 4096, - 4096, + fontSize * 26, + fontSize * 26, TextureFormat::R, TextureDataFormat::UNSIGNED_BYTE ); diff --git a/src/dawn/display/font/TrueTypeTexture.hpp b/src/dawn/display/font/TrueTypeTexture.hpp index a5feb92a..b95ba1be 100644 --- a/src/dawn/display/font/TrueTypeTexture.hpp +++ b/src/dawn/display/font/TrueTypeTexture.hpp @@ -15,20 +15,15 @@ namespace Dawn { FT_Face face; std::shared_ptr texture; uint32_t fontSize; - uint8_t style; std::unordered_map characterData; /** * Construct a new New True Type Face Texture object * * @param face The freetype face object. - * @param style Style that this font has, used for locking. + * @param fontSize The font size to render at. */ - TrueTypeTexture( - FT_Face face, - uint32_t fontSize, - uint8_t style - ); + TrueTypeTexture(FT_Face face, uint32_t fontSize); /** * Returns the character data for the given character. diff --git a/src/dawnhelloworld/scene/HelloWorldScene.cpp b/src/dawnhelloworld/scene/HelloWorldScene.cpp index a4b6aa7b..27a67f98 100644 --- a/src/dawnhelloworld/scene/HelloWorldScene.cpp +++ b/src/dawnhelloworld/scene/HelloWorldScene.cpp @@ -29,22 +29,19 @@ void Dawn::helloWorldScene(Scene &s) { &face ); assertTrue(ret == 0, "Failed to load font face"); - texture = std::make_shared(face, 128, 0); - - auto test = texture->getCharacterData(L'あ'); + texture = std::make_shared(face, 128); auto cameraItem = s.createSceneItem(); auto camera = cameraItem->addComponent(); - // cameraItem->lookAt({ 5, 5, 5 }, { 0, 0, 0 }, { 0, 1, 0 }); - cameraItem->lookAt({ 0, 0, 3 }, { 0, 0, 0 }, { 0, 1, 0 }); + cameraItem->lookAt({ 5, 5, 5 }, { 0, 0, 0 }, { 0, 1, 0 }); auto quad = s.createSceneItem(); auto quadMesh = std::make_shared(); quadMesh->createBuffers(QUAD_VERTICE_COUNT, QUAD_INDICE_COUNT); QuadMesh::buffer( quadMesh, - glm::vec4(0, 0, test.size.x, test.size.y) / 128.0f, - test.quad, + glm::vec4(-1, -1, 1, 1), + glm::vec4(0, 1, 1, 0), 0, 0 );