refactor: asset loading/caching
This commit is contained in:
parent
eca1bc91e6
commit
b572b61f4b
14 changed files with 174 additions and 140 deletions
|
@ -2,20 +2,29 @@
|
|||
|
||||
#include <filesystem>
|
||||
|
||||
namespace Assets {
|
||||
|
||||
class TextAsset;
|
||||
|
||||
class TextureAsset;
|
||||
|
||||
} // namespace Assets
|
||||
|
||||
namespace Light {
|
||||
|
||||
class Shader;
|
||||
class Texture;
|
||||
|
||||
/**
|
||||
* Asset is the data on the disk.
|
||||
* Resource is the data on the gpu/cpu
|
||||
*
|
||||
* eg. TextureAsset is the file on the disk
|
||||
* eg. Texture is the representation of it in the GPU
|
||||
*/
|
||||
class AssetManager
|
||||
{
|
||||
public:
|
||||
static auto instance() -> AssetManager &
|
||||
{
|
||||
static auto instance = AssetManager {};
|
||||
return instance;
|
||||
}
|
||||
|
||||
static void load_shader(
|
||||
const std::string &name,
|
||||
const std::filesystem::path &vertex_path,
|
||||
|
@ -43,6 +52,8 @@ public:
|
|||
private:
|
||||
AssetManager() = default;
|
||||
|
||||
static auto instance() -> AssetManager &;
|
||||
|
||||
void load_shader_impl(
|
||||
const std::string &name,
|
||||
const std::filesystem::path &vertex_path,
|
||||
|
@ -51,6 +62,14 @@ private:
|
|||
|
||||
void load_texture_impl(const std::string &name, const std::filesystem::path &path);
|
||||
|
||||
auto get_or_load_text_asset(const std::filesystem::path &path) -> Ref<Assets::TextAsset>;
|
||||
|
||||
auto get_or_load_texture_asset(const std::filesystem::path &path) -> Ref<Assets::TextureAsset>;
|
||||
|
||||
std::unordered_map<std::string, Ref<Assets::TextAsset>> m_text_assets;
|
||||
|
||||
std::unordered_map<std::string, Ref<Assets::TextureAsset>> m_texture_assets;
|
||||
|
||||
std::unordered_map<std::string, Ref<Shader>> m_shaders;
|
||||
|
||||
std::unordered_map<std::string, Ref<Texture>> m_textures;
|
||||
|
|
|
@ -1,13 +1,19 @@
|
|||
#include <asset_manager/asset_manager.hpp>
|
||||
#include <asset_parser/assets/text.hpp>
|
||||
#include <asset_parser/assets/texture.hpp>
|
||||
#include <logger/logger.hpp>
|
||||
#include <renderer/graphics_context.hpp>
|
||||
#include <renderer/shader.hpp>
|
||||
#include <renderer/texture.hpp>
|
||||
#include <asset_manager/asset_manager.hpp>
|
||||
#include <logger/logger.hpp>
|
||||
|
||||
namespace Light {
|
||||
|
||||
/* static */ auto AssetManager::instance() -> AssetManager &
|
||||
{
|
||||
static auto instance = AssetManager {};
|
||||
return instance;
|
||||
}
|
||||
|
||||
void AssetManager::load_shader_impl(
|
||||
const std::string &name,
|
||||
const std::filesystem::path &vertex_path,
|
||||
|
@ -21,21 +27,9 @@ void AssetManager::load_shader_impl(
|
|||
log_trc("\tvertex path: {}", vertex_path.string());
|
||||
log_trc("\tpixel path : {}", pixel_path.string());
|
||||
|
||||
auto vertex_asset = Assets::TextAsset { vertex_path };
|
||||
auto pixel_asset = Assets::TextAsset { pixel_path };
|
||||
|
||||
auto vertex_blob_metadata = vertex_asset.get_blob_metadata(Assets::BlobMetadata::Tag::text);
|
||||
auto pixel_blob_metadata = pixel_asset.get_blob_metadata(Assets::BlobMetadata::Tag::text);
|
||||
|
||||
auto vertex_blob = Assets::Blob(vertex_blob_metadata.uncompressed_size);
|
||||
auto pixel_blob = Assets::Blob(pixel_blob_metadata.uncompressed_size);
|
||||
|
||||
vertex_asset.unpack_blob(vertex_blob_metadata.tag, vertex_blob.data(), vertex_blob.size());
|
||||
pixel_asset.unpack_blob(pixel_blob_metadata.tag, pixel_blob.data(), pixel_blob.size());
|
||||
|
||||
m_shaders[name] = Ref<Shader>(Shader::create(
|
||||
std::move(vertex_blob),
|
||||
std::move(pixel_blob),
|
||||
get_or_load_text_asset(vertex_path.string()),
|
||||
get_or_load_text_asset(pixel_path),
|
||||
GraphicsContext::get_shared_context()
|
||||
));
|
||||
}
|
||||
|
@ -57,21 +51,9 @@ void AssetManager::load_texture_impl(const std::string &name, const std::filesys
|
|||
log_trc("\tname: {}", name);
|
||||
log_trc("\tpath: {}", path.string());
|
||||
|
||||
auto asset = Assets::TextureAsset { path };
|
||||
const auto metadata = asset.get_metadata();
|
||||
const auto blob_metadata = asset.get_blob_metadata(Assets::BlobMetadata::Tag::color);
|
||||
|
||||
auto blob = std::vector<std::byte>(blob_metadata.uncompressed_size);
|
||||
asset.unpack_blob(blob_metadata.tag, blob.data(), blob.size());
|
||||
|
||||
m_textures[name] = Ref<Texture>(Texture::create(
|
||||
metadata.pixel_size[0],
|
||||
metadata.pixel_size[1],
|
||||
metadata.num_components,
|
||||
std::bit_cast<unsigned char *>(blob.data()),
|
||||
GraphicsContext::get_shared_context(),
|
||||
path
|
||||
));
|
||||
m_textures[name] = Ref<Texture>(
|
||||
Texture::create(get_or_load_texture_asset(path), GraphicsContext::get_shared_context())
|
||||
);
|
||||
}
|
||||
catch (const std::exception &exp)
|
||||
{
|
||||
|
@ -82,4 +64,29 @@ void AssetManager::load_texture_impl(const std::string &name, const std::filesys
|
|||
}
|
||||
}
|
||||
|
||||
auto AssetManager::get_or_load_text_asset(const std::filesystem::path &path)
|
||||
-> Ref<Assets::TextAsset>
|
||||
{
|
||||
const auto key = std::filesystem::canonical(path).string();
|
||||
if (!m_text_assets.contains(key))
|
||||
{
|
||||
m_text_assets.emplace(key, create_ref<Assets::TextAsset>(path));
|
||||
}
|
||||
|
||||
return m_text_assets[key];
|
||||
}
|
||||
|
||||
auto AssetManager::get_or_load_texture_asset(const std::filesystem::path &path)
|
||||
-> Ref<Assets::TextureAsset>
|
||||
{
|
||||
const auto key = std::filesystem::canonical(path).string();
|
||||
if (!m_texture_assets.contains(key))
|
||||
{
|
||||
m_texture_assets.emplace(key, create_ref<Assets::TextureAsset>(path));
|
||||
}
|
||||
|
||||
return m_texture_assets[key];
|
||||
}
|
||||
|
||||
|
||||
} // namespace Light
|
||||
|
|
|
@ -31,7 +31,8 @@ public:
|
|||
|
||||
TextAsset(const std::filesystem::path &path);
|
||||
|
||||
void unpack_blob(BlobMetadata::Tag tag, std::byte *destination, size_t destination_capacity);
|
||||
void unpack_blob(BlobMetadata::Tag tag, std::byte *destination, size_t destination_capacity)
|
||||
const;
|
||||
|
||||
[[nodiscard]] auto get_asset_metadata() const -> const Asset::Metadata &;
|
||||
|
||||
|
@ -48,7 +49,7 @@ private:
|
|||
|
||||
BlobMetadata m_text_blob_metadata {};
|
||||
|
||||
std::ifstream m_stream;
|
||||
mutable std::ifstream m_stream;
|
||||
};
|
||||
|
||||
} // namespace Assets
|
||||
|
|
|
@ -80,7 +80,7 @@ void TextAsset::unpack_blob(
|
|||
BlobMetadata::Tag tag,
|
||||
std::byte *destination,
|
||||
size_t destination_capacity
|
||||
)
|
||||
) const
|
||||
{
|
||||
if (tag != BlobMetadata::Tag::text)
|
||||
{
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include <glm/glm.hpp>
|
||||
#include <utility>
|
||||
#include <utility>
|
||||
|
||||
namespace Light {
|
||||
|
||||
|
|
|
@ -269,16 +269,17 @@ void SceneSerializer::serialize_entity(YAML::Emitter &out, Entity entity)
|
|||
|
||||
if (entity.has_component<SpriteRendererComponent>())
|
||||
{
|
||||
out << YAML::Key << "SpriteRendererComponent";
|
||||
out << YAML::BeginMap; // sprite renderer component;
|
||||
// TODO(Light): get scene serialization/de-serialization working.
|
||||
// out << YAML::Key << "SpriteRendererComponent";
|
||||
// out << YAML::BeginMap; // sprite renderer component;
|
||||
|
||||
auto &spriteRendererComponent = entity.get_component<SpriteRendererComponent>();
|
||||
// auto &spriteRendererComponent = entity.get_component<SpriteRendererComponent>();
|
||||
|
||||
out << YAML::Key << "Texture" << YAML::Value
|
||||
<< spriteRendererComponent.texture->GetFilePath();
|
||||
out << YAML::Key << "Tint" << YAML::Value << spriteRendererComponent.tint;
|
||||
// out << YAML::Key << "Texture" << YAML::Value
|
||||
// << spriteRendererComponent.texture->GetFilePath();
|
||||
// out << YAML::Key << "Tint" << YAML::Value << spriteRendererComponent.tint;
|
||||
|
||||
out << YAML::EndMap; // sprite renderer component
|
||||
// out << YAML::EndMap; // sprite renderer component
|
||||
}
|
||||
|
||||
// #todo:
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
|
||||
#include <renderer/shader.hpp>
|
||||
|
||||
namespace Light {
|
||||
|
@ -8,7 +7,7 @@ namespace Light {
|
|||
class glShader: public Shader
|
||||
{
|
||||
public:
|
||||
glShader(Assets::Blob vertex_blob, Assets::Blob pixel_blob);
|
||||
glShader(const Ref<Assets::TextAsset> &vertex_asset, const Ref<Assets::TextAsset> &pixel_asset);
|
||||
|
||||
~glShader() override;
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
|
||||
#include <renderer/texture.hpp>
|
||||
|
||||
namespace Light {
|
||||
|
@ -8,13 +7,7 @@ namespace Light {
|
|||
class glTexture: public Texture
|
||||
{
|
||||
public:
|
||||
glTexture(
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
unsigned int components,
|
||||
unsigned char *pixels,
|
||||
const std::string &filePath
|
||||
);
|
||||
glTexture(const Ref<Assets::TextureAsset> &asset);
|
||||
|
||||
~glTexture() override;
|
||||
|
||||
|
@ -23,7 +16,11 @@ public:
|
|||
auto get_texture() -> void * override;
|
||||
|
||||
private:
|
||||
unsigned int m_texture_id;
|
||||
[[nodiscard]] auto map_num_components_to_format(uint32_t num_components) const -> int;
|
||||
|
||||
[[nodiscard]] auto map_num_components_to_internal_format(uint32_t num_components) const -> int;
|
||||
|
||||
uint32_t m_texture_id {};
|
||||
};
|
||||
|
||||
} // namespace Light
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <asset_parser/assets/text.hpp>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
namespace Assets {
|
||||
|
||||
class TextAsset;
|
||||
|
||||
} // namespace Assets
|
||||
|
||||
namespace Light {
|
||||
|
||||
class SharedContext;
|
||||
|
@ -11,7 +15,7 @@ class SharedContext;
|
|||
class Shader
|
||||
{
|
||||
public:
|
||||
enum Stage
|
||||
enum Stage : uint8_t
|
||||
{
|
||||
none = 0,
|
||||
|
||||
|
@ -21,8 +25,8 @@ public:
|
|||
};
|
||||
|
||||
static auto create(
|
||||
Assets::Blob vertex_blob,
|
||||
Assets::Blob pixel_blob,
|
||||
Ref<Assets::TextAsset> vertex_asset,
|
||||
Ref<Assets::TextAsset> pixel_asset,
|
||||
const Ref<SharedContext> &shared_context
|
||||
) -> Ref<Shader>;
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
namespace Assets {
|
||||
|
||||
class TextureAsset;
|
||||
|
||||
}
|
||||
|
||||
namespace Light {
|
||||
|
||||
|
@ -10,33 +14,26 @@ class Texture
|
|||
{
|
||||
public:
|
||||
static Ref<Texture> create(
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
unsigned int components,
|
||||
unsigned char *pixels,
|
||||
const Ref<SharedContext>& sharedContext,
|
||||
const std::string &filePath
|
||||
Ref<Assets::TextureAsset> asset,
|
||||
const Ref<SharedContext> &shared_context
|
||||
);
|
||||
|
||||
virtual ~Texture() = default;
|
||||
|
||||
Texture(Texture &&) = default;
|
||||
|
||||
auto operator=(Texture &&) -> Texture & = default;
|
||||
|
||||
Texture(const Texture &) = delete;
|
||||
|
||||
auto operator=(const Texture &) -> Texture & = delete;
|
||||
|
||||
virtual ~Texture() = default;
|
||||
|
||||
virtual void bind(unsigned int slot = 0) = 0;
|
||||
|
||||
virtual auto get_texture() -> void * = 0;
|
||||
|
||||
[[nodiscard]] auto GetFilePath() const -> const std::string &
|
||||
{
|
||||
return m_file_path;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string m_file_path;
|
||||
|
||||
Texture(std::string filePath);
|
||||
Texture() = default;
|
||||
};
|
||||
|
||||
} // namespace Light
|
||||
|
|
|
@ -1,14 +1,27 @@
|
|||
#include <renderer/gl/shader.hpp>
|
||||
#include <asset_parser/assets/text.hpp>
|
||||
#include <glad/gl.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/matrix.hpp>
|
||||
#include <renderer/gl/shader.hpp>
|
||||
|
||||
namespace Light {
|
||||
|
||||
glShader::glShader(Assets::Blob vertex_blob, Assets::Blob pixel_blob)
|
||||
glShader::glShader(
|
||||
const Ref<Assets::TextAsset> &vertex_asset,
|
||||
const Ref<Assets::TextAsset> &pixel_asset
|
||||
)
|
||||
: m_shader_id(glCreateProgram())
|
||||
{
|
||||
auto vertex_blob_metadata = vertex_asset->get_blob_metadata(Assets::BlobMetadata::Tag::text);
|
||||
auto pixel_blob_metadata = pixel_asset->get_blob_metadata(Assets::BlobMetadata::Tag::text);
|
||||
|
||||
auto vertex_blob = Assets::Blob(vertex_blob_metadata.uncompressed_size);
|
||||
auto pixel_blob = Assets::Blob(pixel_blob_metadata.uncompressed_size);
|
||||
|
||||
vertex_asset->unpack_blob(vertex_blob_metadata.tag, vertex_blob.data(), vertex_blob.size());
|
||||
pixel_asset->unpack_blob(pixel_blob_metadata.tag, pixel_blob.data(), pixel_blob.size());
|
||||
|
||||
auto vertex_source = std::string {
|
||||
vertex_blob.data(),
|
||||
vertex_blob.data() + vertex_blob.size(), // NOLINT
|
||||
|
|
|
@ -1,58 +1,35 @@
|
|||
#include <glad/gl.h>
|
||||
#include <asset_parser/assets/texture.hpp>
|
||||
#include <debug/assertions.hpp>
|
||||
#include <glad/gl.h>
|
||||
#include <renderer/gl/texture.hpp>
|
||||
|
||||
namespace Light {
|
||||
|
||||
glTexture::glTexture(
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
unsigned int components,
|
||||
unsigned char *pixels,
|
||||
const std::string &filePath
|
||||
)
|
||||
: Texture(filePath)
|
||||
, m_texture_id(NULL)
|
||||
glTexture::glTexture(const Ref<Assets::TextureAsset> &asset)
|
||||
{
|
||||
// create texture
|
||||
glCreateTextures(GL_TEXTURE_2D, 1, &m_texture_id);
|
||||
const auto metadata = asset->get_metadata();
|
||||
const auto blob_metadata = asset->get_blob_metadata(Assets::BlobMetadata::Tag::color);
|
||||
|
||||
// set texture parameters
|
||||
glCreateTextures(GL_TEXTURE_2D, 1, &m_texture_id);
|
||||
glTextureParameteri(m_texture_id, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTextureParameteri(m_texture_id, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTextureParameteri(m_texture_id, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTextureParameteri(m_texture_id, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
// determine formats
|
||||
auto format = components == 4u ? GL_RGBA :
|
||||
components == 3u ? GL_RGB :
|
||||
components == 2u ? GL_RG :
|
||||
components == 1u ? GL_RED :
|
||||
NULL;
|
||||
auto blob = std::vector<std::byte>(blob_metadata.uncompressed_size);
|
||||
asset->unpack_blob(blob_metadata.tag, blob.data(), blob.size());
|
||||
|
||||
auto internalFormat = format == GL_RGBA ? GL_RGBA8 :
|
||||
format == GL_RGB ? GL_RGB8 :
|
||||
format == GL_RG ? GL_RG8 :
|
||||
format == GL_RED ? GL_R8 :
|
||||
NULL;
|
||||
|
||||
// check
|
||||
lt_assert(format, "Invalid number of components: {}", components);
|
||||
|
||||
|
||||
// #todo: isn't there something like glTextureImage2D ???
|
||||
// create texture and mipsmaps
|
||||
bind();
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
internalFormat,
|
||||
width,
|
||||
height,
|
||||
map_num_components_to_internal_format(metadata.num_components),
|
||||
static_cast<int>(metadata.pixel_size[0]),
|
||||
static_cast<int>(metadata.pixel_size[1]),
|
||||
0,
|
||||
format,
|
||||
map_num_components_to_format(metadata.num_components),
|
||||
GL_UNSIGNED_BYTE,
|
||||
pixels
|
||||
std::bit_cast<unsigned char *>(blob.data())
|
||||
);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
}
|
||||
|
@ -73,4 +50,33 @@ auto glTexture::get_texture() -> void *
|
|||
return (void *)(intptr_t)m_texture_id;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto glTexture::map_num_components_to_format(uint32_t num_components) const -> int
|
||||
{
|
||||
switch (num_components)
|
||||
{
|
||||
case 4u: return GL_RGBA;
|
||||
case 3u: return GL_RGB;
|
||||
case 2u: return GL_RG;
|
||||
case 1u: return GL_RED;
|
||||
default: lt_assert(false, "Invalid number of components: {}", num_components);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
[[nodiscard]] auto glTexture::map_num_components_to_internal_format(uint32_t num_components) const
|
||||
-> int
|
||||
{
|
||||
switch (num_components)
|
||||
{
|
||||
case 4u: return GL_RGBA8;
|
||||
case 3u: return GL_RGB8;
|
||||
case 2u: return GL_RG8;
|
||||
case 1u: return GL_R8;
|
||||
default: lt_assert(false, "Invalid number of components: {}", num_components);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace Light
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <renderer/shader.hpp>
|
||||
#include <asset_parser/assets/text.hpp>
|
||||
#include <renderer/gl/shader.hpp>
|
||||
#include <renderer/shader.hpp>
|
||||
|
||||
#ifdef LIGHT_PLATFORM_WINDOWS
|
||||
#include <renderer/dx/shader.hpp>
|
||||
|
@ -10,9 +11,9 @@
|
|||
|
||||
namespace Light {
|
||||
|
||||
auto Shader::create(
|
||||
Assets::Blob vertex_blob,
|
||||
Assets::Blob pixel_blob,
|
||||
/* static */ auto Shader::create(
|
||||
Ref<Assets::TextAsset> vertex_asset,
|
||||
Ref<Assets::TextAsset> pixel_asset,
|
||||
const Ref<SharedContext> &shared_context
|
||||
) -> Ref<Shader>
|
||||
{
|
||||
|
@ -22,12 +23,12 @@ auto Shader::create(
|
|||
switch (GraphicsContext::get_graphics_api())
|
||||
{
|
||||
case GraphicsAPI::OpenGL:
|
||||
return create_ref<glShader>(std::move(vertex_blob), std::move(pixel_blob));
|
||||
return create_ref<glShader>(std::move(vertex_asset), std::move(pixel_asset));
|
||||
|
||||
case GraphicsAPI::DirectX:
|
||||
lt_win(return create_ref<dxShader>(
|
||||
vertexFile,
|
||||
pixelFile,
|
||||
vertex_asset,
|
||||
pixel_asset,
|
||||
std::static_pointer_cast<dxSharedContext>(sharedContext)
|
||||
););
|
||||
|
||||
|
|
|
@ -8,23 +8,17 @@
|
|||
#endif
|
||||
|
||||
#include <renderer/graphics_context.hpp>
|
||||
#include <utility>
|
||||
|
||||
namespace Light {
|
||||
|
||||
auto Texture::create(
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
unsigned int components,
|
||||
unsigned char *pixels,
|
||||
const Ref<SharedContext> & /*sharedContext*/,
|
||||
const std::string &filePath
|
||||
/* static */ auto Texture::create(
|
||||
Ref<Assets::TextureAsset> asset,
|
||||
const Ref<SharedContext> &shared_context
|
||||
) -> Ref<Texture>
|
||||
{
|
||||
switch (GraphicsContext::get_graphics_api())
|
||||
{
|
||||
case GraphicsAPI::OpenGL:
|
||||
return create_ref<glTexture>(width, height, components, pixels, filePath);
|
||||
case GraphicsAPI::OpenGL: return create_ref<glTexture>(std::move(asset));
|
||||
|
||||
case GraphicsAPI::DirectX:
|
||||
lt_win(return create_ref<dxTexture>(
|
||||
|
@ -46,8 +40,4 @@ auto Texture::create(
|
|||
}
|
||||
}
|
||||
|
||||
Texture::Texture(std::string filePath): m_file_path(std::move(filePath))
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace Light
|
||||
|
|
Loading…
Add table
Reference in a new issue