About to relearn this version of the language.

This commit is contained in:
2024-11-25 16:09:56 -06:00
parent f8c008fd45
commit cfa9e0e99a
23 changed files with 178 additions and 60 deletions

View File

@@ -0,0 +1,12 @@
# Copyright (c) 2022 Dominic Msters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
TextureLoader.cpp
JSONLoader.cpp
TrueTypeLoader.cpp
)

View File

@@ -0,0 +1,33 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "JSONLoader.hpp"
using namespace Dawn;
JSONLoader::JSONLoader(const std::string name) :
AssetLoader(name),
loader(name),
state(JSONLoaderState::INITIAL)
{
}
void JSONLoader::updateAsync() {
if(this->state != JSONLoaderState::INITIAL) return;
this->state = JSONLoaderState::LOADING_JSON;
std::string jsonContents = loader.getEntireContentsAsString();
this->data = json::parse(jsonContents);
this->state = JSONLoaderState::DONE;
this->loaded = true;
}
void JSONLoader::updateSync() {
}
JSONLoader::~JSONLoader() {
}

View File

@@ -0,0 +1,33 @@
// Copyright (c) 2024 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 <nlohmann/json.hpp>
using json = nlohmann::json;
namespace Dawn {
enum class JSONLoaderState {
INITIAL,
LOADING_JSON,
DONE
};
class JSONLoader : public AssetLoader {
protected:
AssetDataLoader loader;
enum JSONLoaderState state;
public:
json data;
JSONLoader(const std::string name);
void updateSync() override;
void updateAsync() override;
~JSONLoader();
};
}

View File

@@ -0,0 +1,147 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "TextureLoader.hpp"
#include "assert/assert.hpp"
using namespace Dawn;
TextureLoader::TextureLoader(const std::string name) :
AssetLoader(name),
loader(name + ".texture"),
state(TextureLoaderLoadState::INITIAL)
{
sharedTexture = std::make_shared<Texture>();
weakTexture = sharedTexture;
}
void TextureLoader::updateAsync() {
if(this->state != TextureLoaderLoadState::INITIAL) return;
this->state = TextureLoaderLoadState::ASYNC_LOADING;
this->loader.open();
// Read in the header.
uint8_t buffer[TEXTURE_LOADER_HEADER_SIZE];
size_t pos = 0;
// Read Version
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
std::string version = std::string((char*)buffer);
assertTrue(version == "DT_2.00", "Invalid Texture Version!");
// Read Texture Width
this->loader.setPosition(pos);
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
width = std::stoi(std::string((char*)buffer));
assertTrue(width > 0, "Invalid Texture Width!");
// Read Texture Height
this->loader.setPosition(pos);
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
height = std::stoi(std::string((char*)buffer));
assertTrue(height > 0, "Invalid Texture Height!");
// Texture Format (RGBA, RGB, etc)
this->loader.setPosition(pos);
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
int32_t iFormat = std::stoi(std::string((char*)buffer));
switch(iFormat) {
case 1: format = TextureFormat::R; break;
case 2: format = TextureFormat::RG; break;
case 3: format = TextureFormat::RGB; break;
case 4: format = TextureFormat::RGBA; break;
default: assertUnreachable("Invalid Texture Format %i!", iFormat);
}
// Wrap X
this->loader.setPosition(pos);
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
int32_t iWrapX = std::stoi(std::string((char*)buffer));
switch(iWrapX) {
case 0: wrapX = TextureWrapMode::REPEAT; break;
case 1: wrapX = TextureWrapMode::MIRRORED_REPEAT; break;
case 2: wrapX = TextureWrapMode::CLAMP_TO_EDGE; break;
case 3: wrapX = TextureWrapMode::CLAMP_TO_BORDER; break;
default: assertUnreachable("Invalid Texture Wrap X %i!", iWrapX);
}
// Wrap Y
this->loader.setPosition(pos);
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
int32_t iWrapY = std::stoi(std::string((char*)buffer));
switch(iWrapY) {
case 0: wrapY = TextureWrapMode::REPEAT; break;
case 1: wrapY = TextureWrapMode::MIRRORED_REPEAT; break;
case 2: wrapY = TextureWrapMode::CLAMP_TO_EDGE; break;
case 3: wrapY = TextureWrapMode::CLAMP_TO_BORDER; break;
default: assertUnreachable("Invalid Texture Wrap Y %i!", iWrapY);
}
// Filter Min
this->loader.setPosition(pos);
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
int32_t iFilterMin = std::stoi(std::string((char*)buffer));
switch(iFilterMin) {
case 0: filterMin = TextureFilterMode::NEAREST; break;
case 1: filterMin = TextureFilterMode::LINEAR; break;
default: assertUnreachable("Invalid Texture Filter Min %i!", iFilterMin);
}
// Filter Mag
this->loader.setPosition(pos);
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
int32_t iFilterMag = std::stoi(std::string((char*)buffer));
switch(iFilterMag) {
case 0: filterMag = TextureFilterMode::NEAREST; break;
case 1: filterMag = TextureFilterMode::LINEAR; break;
default: assertUnreachable("Invalid Texture Filter Mag %i!", iFilterMag);
}
// Data begins here. This part is done synchronously directly to the GPU.
this->loader.setPosition(pos);
size_t bufferSize = width * height * iFormat;
data = new uint8_t[bufferSize];
assertNotNull(data, "Failed to allocate texture data!");
this->loader.read(data, bufferSize);
// Handoff to sync to buffer to GPU.
this->state = TextureLoaderLoadState::ASYNC_DONE;
}
void TextureLoader::updateSync() {
if(this->state != TextureLoaderLoadState::ASYNC_DONE) return;
this->state = TextureLoaderLoadState::SYNC_LOADING;
assertNotNull(this->sharedTexture, "Texture is null!");
assertNotNull(this->data, "Texture data is null!");
// Setup Texture
this->sharedTexture->setSize(
this->width,
this->height,
this->format,
TextureDataFormat::UNSIGNED_BYTE
);
this->sharedTexture->buffer(this->data);
// Free data buffer
delete[] this->data;
this->data = nullptr;
// Leat go of the held pointer
this->sharedTexture = nullptr;
// Hand off and call done
this->state = TextureLoaderLoadState::SYNC_DONE;
this->loaded = true;
}
TextureLoader::~TextureLoader() {
if(this->data != nullptr) {
delete[] this->data;
this->data = nullptr;
}
this->sharedTexture = nullptr;
}

View File

@@ -0,0 +1,55 @@
// Copyright (c) 2022 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/Texture.hpp"
#define TEXTURE_LOADER_HEADER_SIZE 256
namespace Dawn {
enum class TextureLoaderLoadState {
INITIAL,
ASYNC_LOADING,
ASYNC_DONE,
SYNC_LOADING,
SYNC_DONE
};
class TextureLoader : public AssetLoader {
protected:
AssetDataLoader loader;
enum TextureLoaderLoadState state;
uint8_t *data = nullptr;
int32_t width = -1, height = -1;
enum TextureFormat format;
enum TextureWrapMode wrapX;
enum TextureWrapMode wrapY;
enum TextureFilterMode filterMin;
enum TextureFilterMode filterMag;
public:
std::shared_ptr<Texture> sharedTexture;
std::weak_ptr<Texture> weakTexture;
/**
* Constructs a texture asset loader. You should instead use the parent
* asset managers' abstracted load method
*
* @param name File name asset to load, omitting the extension.
*/
TextureLoader(const std::string name);
void updateSync() override;
void updateAsync() override;
/**
* Dispose / Cleanup the texture asset. Will also dispose the underlying
* texture itself.
*/
~TextureLoader();
};
}

View File

@@ -0,0 +1,97 @@
// 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")
{
// Init the font.
auto ret = FT_Init_FreeType(&fontLibrary);
assertTrue(ret == 0, "Failed to initialize FreeType library.");
}
void TrueTypeLoader::updateSync() {
if(state != TrueTypeLoaderState::ASYNC_DONE) return;
state = TrueTypeLoaderState::SYNC_LOADING;
// Init all the textures.
auto it = textures.begin();
while(it != textures.end()) {
auto texture = it->second.lock();
if(texture) {
texture->setFace(face);
it++;
continue;
}
it = textures.erase(it);
}
// Done
state = TrueTypeLoaderState::SYNC_DONE;
this->loaded = true;
}
void TrueTypeLoader::updateAsync() {
if(state != TrueTypeLoaderState::INITIAL) return;
state = TrueTypeLoaderState::ASYNC_LOADING;
// Load the data.
this->loader.open();
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_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;
}
std::shared_ptr<TrueTypeTexture> 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<TrueTypeTexture>(fontSize);
textures[fontSize] = texture;
if(this->loaded) texture->setFace(face);
return texture;
}
TrueTypeLoader::~TrueTypeLoader() {
if(
this->state == TrueTypeLoaderState::SYNC_DONE ||
this->state == TrueTypeLoaderState::SYNC_LOADING ||
this->state == TrueTypeLoaderState::ASYNC_DONE
) {
FT_Done_Face(face);
}
FT_Done_FreeType(fontLibrary);
if(buffer != nullptr) {
delete[] buffer;
buffer = nullptr;
}
}

View File

@@ -0,0 +1,57 @@
// 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,
SYNC_LOADING,
SYNC_DONE
};
class TrueTypeLoader : public AssetLoader {
protected:
FT_Library fontLibrary;
FT_Face face;
AssetDataLoader loader;
std::unordered_map<uint32_t, std::weak_ptr<TrueTypeTexture>> 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<TrueTypeTexture> getTexture(
const uint32_t fontSize
);
/**
* Dispose / Cleanup the truetype asset. Will also dispose the underlying
* truetype itself.
*/
~TrueTypeLoader();
};
}