Compare commits
No commits in common. "fc2fe2616056a3f0f4716e896b20e47e15ab8efa" and "38997b3908c96bf3adfde191069dcd14a4cb58ea" have entirely different histories.
fc2fe26160
...
38997b3908
34 changed files with 533 additions and 635 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -19,3 +19,4 @@ void main()
|
||||||
vso_Tint = a_Tint;
|
vso_Tint = a_Tint;
|
||||||
vso_TexCoord = a_TexCoord;
|
vso_TexCoord = a_TexCoord;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,6 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <asset_parser/assets/text.hpp>
|
|
||||||
#include <asset_parser/assets/texture.hpp>
|
#include <asset_parser/assets/texture.hpp>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <logger/logger.hpp>
|
#include <logger/logger.hpp>
|
||||||
|
@ -118,66 +117,4 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class TextLoader: Loader
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
[[nodiscard]] static auto get_supported_extensions() -> std::unordered_set<std::string_view>
|
|
||||||
{
|
|
||||||
return { ".glsl", ".txt", ".hlsl" };
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_name() const -> std::string_view override
|
|
||||||
{
|
|
||||||
return "TextLoader";
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto load(std::filesystem::path file_path) const -> Assets::TextAsset::PackageData
|
|
||||||
{
|
|
||||||
auto stream = std::ifstream { file_path, std::ios::binary };
|
|
||||||
if (!stream.good())
|
|
||||||
{
|
|
||||||
throw std::runtime_error {
|
|
||||||
std::format(
|
|
||||||
"Failed to open ifstream for text loading of file: {}",
|
|
||||||
file_path.string()
|
|
||||||
),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto file_size = std::filesystem::file_size(file_path);
|
|
||||||
|
|
||||||
auto text_blob = Assets::Blob(file_size);
|
|
||||||
|
|
||||||
stream.read((char *)(text_blob.data()), static_cast<long>(file_size)); // NOLINT
|
|
||||||
|
|
||||||
const auto metadata = Assets::Asset::Metadata {
|
|
||||||
.type = Assets::Asset::Type::Text,
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto text_metadata = Assets::TextAsset::Metadata {
|
|
||||||
.lines = {},
|
|
||||||
};
|
|
||||||
|
|
||||||
return Assets::TextAsset::PackageData {
|
|
||||||
.metadata = metadata,
|
|
||||||
.text_metadata = {},
|
|
||||||
.text_blob = std::move(text_blob),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class TextLoaderFactory
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static auto create(std::string_view file_extension) -> std::unique_ptr<TextLoader>
|
|
||||||
{
|
|
||||||
if (TextLoader::get_supported_extensions().contains(file_extension))
|
|
||||||
{
|
|
||||||
return std::make_unique<TextLoader>();
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace lt
|
} // namespace lt
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#include <asset_baker/bakers.hpp>
|
#include <asset_baker/bakers.hpp>
|
||||||
#include <asset_parser/assets/text.hpp>
|
|
||||||
#include <asset_parser/assets/texture.hpp>
|
#include <asset_parser/assets/texture.hpp>
|
||||||
#include <asset_parser/parser.hpp>
|
#include <asset_parser/parser.hpp>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
@ -21,14 +20,14 @@ void try_packing_texture(
|
||||||
{
|
{
|
||||||
Assets::TextureAsset::pack(texture_loader->load(in_path), out_path);
|
Assets::TextureAsset::pack(texture_loader->load(in_path), out_path);
|
||||||
|
|
||||||
log_inf("Packed a texture asset:");
|
log_inf("Packed a texture:");
|
||||||
log_inf("\tloader : {}", texture_loader->get_name());
|
log_inf("\tloader : {}", texture_loader->get_name());
|
||||||
log_inf("\tin path: {}", in_path.string());
|
log_inf("\tin path: {}", in_path.string());
|
||||||
log_inf("\tout path: {}", out_path.string());
|
log_inf("\tout path: {}", out_path.string());
|
||||||
}
|
}
|
||||||
catch (const std::exception &exp)
|
catch (const std::exception &exp)
|
||||||
{
|
{
|
||||||
log_err("Failed to pack texture asset:");
|
log_err("Failed to pack texture:");
|
||||||
log_err("\tloader : {}", texture_loader->get_name());
|
log_err("\tloader : {}", texture_loader->get_name());
|
||||||
log_err("\tin path : {}", in_path.string());
|
log_err("\tin path : {}", in_path.string());
|
||||||
log_err("\tout path: {}", out_path.string());
|
log_err("\tout path: {}", out_path.string());
|
||||||
|
@ -36,34 +35,6 @@ void try_packing_texture(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void try_packing_text(const std::filesystem::path &in_path, const std::filesystem::path &out_path)
|
|
||||||
{
|
|
||||||
auto text_loader = lt::TextLoaderFactory::create(in_path.extension().string());
|
|
||||||
if (!text_loader)
|
|
||||||
{
|
|
||||||
// Don't log anything; this is expected.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Assets::TextAsset::pack(text_loader->load(in_path), out_path);
|
|
||||||
|
|
||||||
log_inf("Packed a text asset:");
|
|
||||||
log_inf("\tloader : {}", text_loader->get_name());
|
|
||||||
log_inf("\tin path: {}", in_path.string());
|
|
||||||
log_inf("\tout path: {}", out_path.string());
|
|
||||||
}
|
|
||||||
catch (const std::exception &exp)
|
|
||||||
{
|
|
||||||
log_err("Failed to pack a text asset:");
|
|
||||||
log_err("\tloader : {}", text_loader->get_name());
|
|
||||||
log_err("\tin path : {}", in_path.string());
|
|
||||||
log_err("\tout path: {}", out_path.string());
|
|
||||||
log_err("\texp.what: {}", exp.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto main(int argc, char *argv[]) -> int32_t
|
auto main(int argc, char *argv[]) -> int32_t
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -86,7 +57,6 @@ try
|
||||||
out_path.replace_extension(".asset");
|
out_path.replace_extension(".asset");
|
||||||
|
|
||||||
try_packing_texture(in_path, out_path);
|
try_packing_texture(in_path, out_path);
|
||||||
try_packing_text(in_path, out_path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
add_library_module(asset_parser
|
add_library_module(asset_parser
|
||||||
parser.cpp
|
parser.cpp
|
||||||
assets/texture.cpp
|
assets/texture.cpp
|
||||||
assets/text.cpp
|
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <asset_parser/parser.hpp>
|
|
||||||
#include <compressors/compressors.hpp>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <filesystem>
|
|
||||||
#include <fstream>
|
|
||||||
#include <logger/logger.hpp>
|
|
||||||
|
|
||||||
namespace Assets {
|
|
||||||
|
|
||||||
class TextAsset: public Asset
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
struct Metadata
|
|
||||||
{
|
|
||||||
uint32_t lines {};
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Data required to pack a text asset */
|
|
||||||
struct PackageData
|
|
||||||
{
|
|
||||||
Asset::Metadata metadata;
|
|
||||||
|
|
||||||
Metadata text_metadata;
|
|
||||||
|
|
||||||
Blob text_blob;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void pack(const PackageData &data, const std::filesystem::path &out_path);
|
|
||||||
|
|
||||||
TextAsset(const std::filesystem::path &path);
|
|
||||||
|
|
||||||
void unpack_blob(BlobMetadata::Tag tag, std::byte *destination, size_t destination_capacity);
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_asset_metadata() const -> const Asset::Metadata &;
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_metadata() const -> const Metadata &;
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_blob_metadata(BlobMetadata::Tag tag) const -> const BlobMetadata &;
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint32_t version {};
|
|
||||||
|
|
||||||
Asset::Metadata m_asset_metadata {};
|
|
||||||
|
|
||||||
Metadata m_metadata {};
|
|
||||||
|
|
||||||
BlobMetadata m_text_blob_metadata {};
|
|
||||||
|
|
||||||
std::ifstream m_stream;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Assets
|
|
|
@ -1,64 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <asset_parser/parser.hpp>
|
|
||||||
#include <compressors/compressors.hpp>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <filesystem>
|
|
||||||
#include <fstream>
|
|
||||||
#include <logger/logger.hpp>
|
|
||||||
|
|
||||||
namespace Assets {
|
|
||||||
|
|
||||||
class TextureAsset: public Asset
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum class Format : uint32_t // NOLINT(performance-enum-size)
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
RGBA8,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Metadata
|
|
||||||
{
|
|
||||||
Format format;
|
|
||||||
|
|
||||||
uint32_t num_components;
|
|
||||||
|
|
||||||
std::array<uint32_t, 3> pixel_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Data required to pack a texture asset */
|
|
||||||
struct PackageData
|
|
||||||
{
|
|
||||||
Asset::Metadata metadata;
|
|
||||||
|
|
||||||
Metadata texture_metadata;
|
|
||||||
|
|
||||||
Blob pixels;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void pack(const PackageData &data, const std::filesystem::path &out_path);
|
|
||||||
|
|
||||||
TextureAsset(const std::filesystem::path &path);
|
|
||||||
|
|
||||||
void unpack_blob(BlobMetadata::Tag tag, std::byte *destination, size_t destination_capacity);
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_asset_metadata() const -> const Asset::Metadata &;
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_metadata() const -> const Metadata &;
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_blob_metadata(BlobMetadata::Tag tag) const -> const BlobMetadata &;
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint32_t version {};
|
|
||||||
|
|
||||||
Asset::Metadata m_asset_metadata {};
|
|
||||||
|
|
||||||
Metadata m_metadata {};
|
|
||||||
|
|
||||||
BlobMetadata m_pixel_blob_metadata {};
|
|
||||||
|
|
||||||
std::ifstream m_stream;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Assets
|
|
|
@ -16,7 +16,6 @@ struct BlobMetadata
|
||||||
{
|
{
|
||||||
enum class Tag : uint8_t
|
enum class Tag : uint8_t
|
||||||
{
|
{
|
||||||
text,
|
|
||||||
color,
|
color,
|
||||||
depth,
|
depth,
|
||||||
vertices,
|
vertices,
|
||||||
|
@ -42,9 +41,7 @@ class Asset
|
||||||
public:
|
public:
|
||||||
enum class Type : uint32_t // NOLINT(performance-enum-size)
|
enum class Type : uint32_t // NOLINT(performance-enum-size)
|
||||||
{
|
{
|
||||||
None,
|
|
||||||
Texture,
|
Texture,
|
||||||
Text,
|
|
||||||
Mesh,
|
Mesh,
|
||||||
Material,
|
Material,
|
||||||
};
|
};
|
||||||
|
@ -56,13 +53,224 @@ public:
|
||||||
|
|
||||||
Asset() = default;
|
Asset() = default;
|
||||||
|
|
||||||
|
Asset(Metadata metadata, std::filesystem::path path, std::ifstream stream)
|
||||||
|
: m_metadata(metadata)
|
||||||
|
, m_file_path(std::move(path))
|
||||||
|
, m_stream(std::move(stream))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/** Directly unpacks from disk to the destination.
|
/** Directly unpacks from disk to the destination.
|
||||||
*
|
*
|
||||||
* @note The destination MUST have at least blob_metadata.unpacked_size bytes available for
|
* @note The destination MUST have at least blob_metadata.unpacked_size bytes available for
|
||||||
* writing, otherwise segfault could occur!
|
* writing, otherwise segfault could occur!
|
||||||
*/
|
*/
|
||||||
void unpack_blob(BlobMetadata::Tag blob_tag, std::byte *destination);
|
void unpack_blob(BlobMetadata::Tag blob_tag, std::byte *destination);
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_metadata() const -> const Metadata &
|
||||||
|
{
|
||||||
|
return m_metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_file_path() const -> std::filesystem::path
|
||||||
|
{
|
||||||
|
return m_file_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Metadata m_metadata;
|
||||||
|
|
||||||
|
std::filesystem::path m_file_path;
|
||||||
|
|
||||||
|
std::ifstream m_stream;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TextureAsset: public Asset
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class Format : uint32_t // NOLINT(performance-enum-size)
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
RGBA8,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Metadata
|
||||||
|
{
|
||||||
|
Format format;
|
||||||
|
|
||||||
|
uint32_t num_components;
|
||||||
|
|
||||||
|
std::array<uint32_t, 3> pixel_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Data required to pack a texture */
|
||||||
|
struct PackageData
|
||||||
|
{
|
||||||
|
Asset::Metadata metadata;
|
||||||
|
|
||||||
|
Metadata texture_metadata;
|
||||||
|
|
||||||
|
Blob pixels;
|
||||||
|
};
|
||||||
|
|
||||||
|
TextureAsset(const std::filesystem::path &path)
|
||||||
|
{
|
||||||
|
m_stream = std::ifstream { path, std::ios::binary };
|
||||||
|
if (!m_stream.is_open())
|
||||||
|
{
|
||||||
|
throw std::runtime_error { std::format(
|
||||||
|
"Failed to open ifm_stream for loading texture asset at: {}",
|
||||||
|
path.string()
|
||||||
|
) };
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast)
|
||||||
|
m_stream.read((char *)&version, sizeof(version));
|
||||||
|
m_stream.read((char *)&m_asset_metadata, sizeof(m_asset_metadata));
|
||||||
|
m_stream.read((char *)&m_metadata, sizeof(m_metadata));
|
||||||
|
|
||||||
|
auto num_blobs = uint32_t {};
|
||||||
|
m_stream.read((char *)&num_blobs, sizeof(num_blobs));
|
||||||
|
if (num_blobs != 1)
|
||||||
|
{
|
||||||
|
throw std::runtime_error {
|
||||||
|
std::format("Failed to load texture asset: invalid number of blobs: {}", num_blobs)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
m_stream.read((char *)&m_pixel_blob_metadata, sizeof(m_pixel_blob_metadata));
|
||||||
|
if (m_pixel_blob_metadata.tag != BlobMetadata::Tag::color)
|
||||||
|
{
|
||||||
|
throw std::runtime_error {
|
||||||
|
std::format(
|
||||||
|
"Failed to load texture asset: invalid blob tag, expected {}, got {}",
|
||||||
|
std::to_underlying(BlobMetadata::Tag::color),
|
||||||
|
std::to_underlying(m_pixel_blob_metadata.tag)
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast)
|
||||||
|
}
|
||||||
|
|
||||||
|
void unpack_blob(BlobMetadata::Tag tag, std::byte *destination, size_t destination_capacity)
|
||||||
|
{
|
||||||
|
if (tag != BlobMetadata::Tag::color)
|
||||||
|
{
|
||||||
|
throw std::runtime_error { std::format(
|
||||||
|
"Invalid tag for unpack_blob of TextureAsset: {}",
|
||||||
|
std::to_underlying(tag)
|
||||||
|
) };
|
||||||
|
}
|
||||||
|
|
||||||
|
m_stream.seekg(static_cast<long>(m_pixel_blob_metadata.offset));
|
||||||
|
switch (m_pixel_blob_metadata.compression_type)
|
||||||
|
{
|
||||||
|
case Assets::CompressionType::None:
|
||||||
|
if (m_pixel_blob_metadata.uncompressed_size != m_pixel_blob_metadata.compressed_size)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to unpack blob from TextureAsset: "
|
||||||
|
"compressed/uncompressed size mismatch for no compression "
|
||||||
|
"type");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_pixel_blob_metadata.uncompressed_size > destination_capacity)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to unpack blob from TextureAsset: "
|
||||||
|
"uncompressed_size > destination_capacity, unpacking "
|
||||||
|
"would result in segfault");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_stream.is_open())
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to unpack blob from TextureAsset: ifstream is "
|
||||||
|
"closed");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_stream.read(
|
||||||
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
|
||||||
|
(char *)destination,
|
||||||
|
static_cast<long>(m_pixel_blob_metadata.uncompressed_size)
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw std::runtime_error(std::format(
|
||||||
|
"Failed to unpack blob from TextureAsset: unsupported "
|
||||||
|
"compression type: {}",
|
||||||
|
std::to_underlying(m_pixel_blob_metadata.compression_type)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pack(const PackageData &data, const std::filesystem::path &out_path)
|
||||||
|
{
|
||||||
|
const auto &[metadata, texture_metadata, pixels] = data;
|
||||||
|
|
||||||
|
auto stream = std::ofstream { out_path, std::ios::binary | std::ios::trunc };
|
||||||
|
if (!stream.is_open())
|
||||||
|
{
|
||||||
|
throw std::runtime_error {
|
||||||
|
std::format("Failed to open ofstream for packing texture at: {}", out_path.string())
|
||||||
|
};
|
||||||
|
}
|
||||||
|
stream.seekp(0);
|
||||||
|
|
||||||
|
// NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast)
|
||||||
|
stream.write((char *)¤t_version, sizeof(current_version));
|
||||||
|
|
||||||
|
stream.write((char *)&metadata, sizeof(metadata));
|
||||||
|
stream.write((char *)&texture_metadata, sizeof(texture_metadata));
|
||||||
|
|
||||||
|
constexpr auto number_of_blobs = uint32_t { 1 };
|
||||||
|
stream.write((char *)&number_of_blobs, sizeof(number_of_blobs));
|
||||||
|
|
||||||
|
auto pixels_metadata = BlobMetadata {
|
||||||
|
.tag = BlobMetadata::Tag::color,
|
||||||
|
.offset = static_cast<size_t>(stream.tellp()),
|
||||||
|
.compression_type = CompressionType::None,
|
||||||
|
.compressed_size = pixels.size(),
|
||||||
|
.uncompressed_size = pixels.size(),
|
||||||
|
};
|
||||||
|
|
||||||
|
stream.write((char *)&pixels_metadata, sizeof(pixels_metadata));
|
||||||
|
stream.write((char *)&pixels[0], static_cast<long>(pixels.size()));
|
||||||
|
// NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast)
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_asset_metadata() const -> const Asset::Metadata &
|
||||||
|
{
|
||||||
|
return m_asset_metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_metadata() const -> const Metadata &
|
||||||
|
{
|
||||||
|
return m_metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_blob_metadata(BlobMetadata::Tag tag) const -> const BlobMetadata &
|
||||||
|
{
|
||||||
|
if (tag != BlobMetadata::Tag::color)
|
||||||
|
{
|
||||||
|
throw std::runtime_error { std::format(
|
||||||
|
"Invalid tag for get_blob_metadata of TextureAsset: {}",
|
||||||
|
std::to_underlying(tag)
|
||||||
|
) };
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_pixel_blob_metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Asset::Metadata m_asset_metadata {};
|
||||||
|
|
||||||
|
Metadata m_metadata {};
|
||||||
|
|
||||||
|
BlobMetadata m_pixel_blob_metadata {};
|
||||||
|
|
||||||
|
uint32_t version {};
|
||||||
|
|
||||||
|
std::ifstream m_stream;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Assets
|
} // namespace Assets
|
||||||
|
|
|
@ -1,156 +0,0 @@
|
||||||
#include <asset_parser/assets/text.hpp>
|
|
||||||
#include <lz4.h>
|
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
|
|
||||||
namespace Assets {
|
|
||||||
|
|
||||||
/* static */ void TextAsset::pack(const PackageData &data, const std::filesystem::path &out_path)
|
|
||||||
{
|
|
||||||
const auto &[metadata, text_metadata, text] = data;
|
|
||||||
|
|
||||||
auto stream = std::ofstream { out_path, std::ios::binary | std::ios::trunc };
|
|
||||||
if (!stream.is_open())
|
|
||||||
{
|
|
||||||
throw std::runtime_error {
|
|
||||||
std::format("Failed to open ofstream for packing Text at: {}", out_path.string())
|
|
||||||
};
|
|
||||||
}
|
|
||||||
stream.seekp(0);
|
|
||||||
|
|
||||||
// NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast)
|
|
||||||
stream.write((char *)¤t_version, sizeof(current_version));
|
|
||||||
stream.write((char *)&metadata, sizeof(metadata));
|
|
||||||
stream.write((char *)&text_metadata, sizeof(text_metadata));
|
|
||||||
|
|
||||||
constexpr auto number_of_blobs = uint32_t { 1 };
|
|
||||||
stream.write((char *)&number_of_blobs, sizeof(number_of_blobs));
|
|
||||||
|
|
||||||
auto textblob_metadata = BlobMetadata {
|
|
||||||
.tag = BlobMetadata::Tag::text,
|
|
||||||
.offset = static_cast<size_t>(stream.tellp()) + sizeof(BlobMetadata),
|
|
||||||
.compression_type = CompressionType::None,
|
|
||||||
.compressed_size = text.size(),
|
|
||||||
.uncompressed_size = text.size(),
|
|
||||||
};
|
|
||||||
|
|
||||||
stream.write((char *)&textblob_metadata, sizeof(textblob_metadata));
|
|
||||||
stream.write((char *)text.data(), static_cast<long>(text.size()));
|
|
||||||
// NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast)
|
|
||||||
}
|
|
||||||
|
|
||||||
TextAsset::TextAsset(const std::filesystem::path &path)
|
|
||||||
{
|
|
||||||
m_stream = std::ifstream { path, std::ios::binary };
|
|
||||||
if (!m_stream.is_open())
|
|
||||||
{
|
|
||||||
throw std::runtime_error {
|
|
||||||
std::format("Failed to open ifstream for loading Text asset at: {}", path.string())
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast)
|
|
||||||
m_stream.read((char *)&version, sizeof(version));
|
|
||||||
m_stream.read((char *)&m_asset_metadata, sizeof(m_asset_metadata));
|
|
||||||
m_stream.read((char *)&m_metadata, sizeof(m_metadata));
|
|
||||||
|
|
||||||
auto num_blobs = uint32_t {};
|
|
||||||
m_stream.read((char *)&num_blobs, sizeof(num_blobs));
|
|
||||||
if (num_blobs != 1)
|
|
||||||
{
|
|
||||||
throw std::runtime_error {
|
|
||||||
std::format("Failed to load Text asset: invalid number of blobs: {}", num_blobs)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
m_stream.read((char *)&m_text_blob_metadata, sizeof(m_text_blob_metadata));
|
|
||||||
if (m_text_blob_metadata.tag != BlobMetadata::Tag::text)
|
|
||||||
{
|
|
||||||
throw std::runtime_error {
|
|
||||||
std::format(
|
|
||||||
"Failed to load Text asset: invalid blob tag, expected {}, got {}",
|
|
||||||
std::to_underlying(BlobMetadata::Tag::text),
|
|
||||||
std::to_underlying(m_text_blob_metadata.tag)
|
|
||||||
),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast)
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextAsset::unpack_blob(
|
|
||||||
BlobMetadata::Tag tag,
|
|
||||||
std::byte *destination,
|
|
||||||
size_t destination_capacity
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (tag != BlobMetadata::Tag::text)
|
|
||||||
{
|
|
||||||
throw std::runtime_error {
|
|
||||||
std::format("Invalid tag for unpack_blob of TextAsset: {}", std::to_underlying(tag))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
m_stream.seekg(static_cast<long>(m_text_blob_metadata.offset));
|
|
||||||
switch (m_text_blob_metadata.compression_type)
|
|
||||||
{
|
|
||||||
case Assets::CompressionType::None:
|
|
||||||
if (m_text_blob_metadata.uncompressed_size != m_text_blob_metadata.compressed_size)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Failed to unpack blob from TextAsset: "
|
|
||||||
"compressed/uncompressed size mismatch for no compression "
|
|
||||||
"type");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_text_blob_metadata.uncompressed_size > destination_capacity)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Failed to unpack blob from TextAsset: "
|
|
||||||
"uncompressed_size > destination_capacity, unpacking "
|
|
||||||
"would result in segfault");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_stream.is_open())
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Failed to unpack blob from TextAsset: ifstream is "
|
|
||||||
"closed");
|
|
||||||
}
|
|
||||||
|
|
||||||
m_stream.read(
|
|
||||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
|
|
||||||
(char *)destination,
|
|
||||||
static_cast<long>(m_text_blob_metadata.uncompressed_size)
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw std::runtime_error(std::format(
|
|
||||||
"Failed to unpack blob from TextAsset: unsupported "
|
|
||||||
"compression type: {}",
|
|
||||||
std::to_underlying(m_text_blob_metadata.compression_type)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto TextAsset::get_asset_metadata() const -> const Asset::Metadata &
|
|
||||||
{
|
|
||||||
return m_asset_metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto TextAsset::get_metadata() const -> const Metadata &
|
|
||||||
{
|
|
||||||
return m_metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto TextAsset::get_blob_metadata(BlobMetadata::Tag tag) const -> const BlobMetadata &
|
|
||||||
{
|
|
||||||
if (tag != BlobMetadata::Tag::text)
|
|
||||||
{
|
|
||||||
throw std::runtime_error { std::format(
|
|
||||||
"Invalid tag for get_blob_metadata of TextAsset: {}",
|
|
||||||
std::to_underlying(tag)
|
|
||||||
) };
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_text_blob_metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Assets
|
|
|
@ -2,157 +2,11 @@
|
||||||
#include <lz4.h>
|
#include <lz4.h>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
// [version], [type] --
|
||||||
|
// [asset_metadata], [blob_metadata] --
|
||||||
|
// [blob] --
|
||||||
|
|
||||||
namespace Assets {
|
namespace Assets {
|
||||||
|
|
||||||
/* static */ void TextureAsset::pack(const PackageData &data, const std::filesystem::path &out_path)
|
|
||||||
{
|
|
||||||
const auto &[metadata, texture_metadata, pixels] = data;
|
|
||||||
|
|
||||||
auto stream = std::ofstream { out_path, std::ios::binary | std::ios::trunc };
|
|
||||||
if (!stream.is_open())
|
|
||||||
{
|
|
||||||
throw std::runtime_error {
|
|
||||||
std::format("Failed to open ofstream for packing texture at: {}", out_path.string())
|
|
||||||
};
|
|
||||||
}
|
|
||||||
stream.seekp(0);
|
|
||||||
|
|
||||||
// NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast)
|
|
||||||
stream.write((char *)¤t_version, sizeof(current_version));
|
|
||||||
|
|
||||||
stream.write((char *)&metadata, sizeof(metadata));
|
|
||||||
stream.write((char *)&texture_metadata, sizeof(texture_metadata));
|
|
||||||
|
|
||||||
constexpr auto number_of_blobs = uint32_t { 1 };
|
|
||||||
stream.write((char *)&number_of_blobs, sizeof(number_of_blobs));
|
|
||||||
|
|
||||||
auto pixels_metadata = BlobMetadata {
|
|
||||||
.tag = BlobMetadata::Tag::color,
|
|
||||||
.offset = static_cast<size_t>(stream.tellp()) + sizeof(BlobMetadata),
|
|
||||||
.compression_type = CompressionType::None,
|
|
||||||
.compressed_size = pixels.size(),
|
|
||||||
.uncompressed_size = pixels.size(),
|
|
||||||
};
|
|
||||||
|
|
||||||
stream.write((char *)&pixels_metadata, sizeof(pixels_metadata));
|
|
||||||
stream.write((char *)&pixels[0], static_cast<long>(pixels.size()));
|
|
||||||
// NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast)
|
|
||||||
}
|
|
||||||
|
|
||||||
TextureAsset::TextureAsset(const std::filesystem::path &path)
|
|
||||||
{
|
|
||||||
m_stream = std::ifstream { path, std::ios::binary };
|
|
||||||
if (!m_stream.is_open())
|
|
||||||
{
|
|
||||||
throw std::runtime_error {
|
|
||||||
std::format("Failed to open ifstream for loading texture asset at: {}", path.string())
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast)
|
|
||||||
m_stream.read((char *)&version, sizeof(version));
|
|
||||||
m_stream.read((char *)&m_asset_metadata, sizeof(m_asset_metadata));
|
|
||||||
m_stream.read((char *)&m_metadata, sizeof(m_metadata));
|
|
||||||
|
|
||||||
auto num_blobs = uint32_t {};
|
|
||||||
m_stream.read((char *)&num_blobs, sizeof(num_blobs));
|
|
||||||
if (num_blobs != 1)
|
|
||||||
{
|
|
||||||
throw std::runtime_error {
|
|
||||||
std::format("Failed to load texture asset: invalid number of blobs: {}", num_blobs)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
m_stream.read((char *)&m_pixel_blob_metadata, sizeof(m_pixel_blob_metadata));
|
|
||||||
if (m_pixel_blob_metadata.tag != BlobMetadata::Tag::color)
|
|
||||||
{
|
|
||||||
throw std::runtime_error {
|
|
||||||
std::format(
|
|
||||||
"Failed to load texture asset: invalid blob tag, expected {}, got {}",
|
|
||||||
std::to_underlying(BlobMetadata::Tag::color),
|
|
||||||
std::to_underlying(m_pixel_blob_metadata.tag)
|
|
||||||
),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast)
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextureAsset::unpack_blob(
|
|
||||||
BlobMetadata::Tag tag,
|
|
||||||
std::byte *destination,
|
|
||||||
size_t destination_capacity
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (tag != BlobMetadata::Tag::color)
|
|
||||||
{
|
|
||||||
throw std::runtime_error {
|
|
||||||
std::format("Invalid tag for unpack_blob of TextureAsset: {}", std::to_underlying(tag))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
m_stream.seekg(static_cast<long>(m_pixel_blob_metadata.offset));
|
|
||||||
switch (m_pixel_blob_metadata.compression_type)
|
|
||||||
{
|
|
||||||
case Assets::CompressionType::None:
|
|
||||||
if (m_pixel_blob_metadata.uncompressed_size != m_pixel_blob_metadata.compressed_size)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Failed to unpack blob from TextureAsset: "
|
|
||||||
"compressed/uncompressed size mismatch for no compression "
|
|
||||||
"type");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_pixel_blob_metadata.uncompressed_size > destination_capacity)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Failed to unpack blob from TextureAsset: "
|
|
||||||
"uncompressed_size > destination_capacity, unpacking "
|
|
||||||
"would result in segfault");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_stream.is_open())
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Failed to unpack blob from TextureAsset: ifstream is "
|
|
||||||
"closed");
|
|
||||||
}
|
|
||||||
|
|
||||||
m_stream.read(
|
|
||||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
|
|
||||||
(char *)destination,
|
|
||||||
static_cast<long>(m_pixel_blob_metadata.uncompressed_size)
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw std::runtime_error(std::format(
|
|
||||||
"Failed to unpack blob from TextureAsset: unsupported "
|
|
||||||
"compression type: {}",
|
|
||||||
std::to_underlying(m_pixel_blob_metadata.compression_type)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto TextureAsset::get_asset_metadata() const -> const Asset::Metadata &
|
|
||||||
{
|
|
||||||
return m_asset_metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto TextureAsset::get_metadata() const -> const Metadata &
|
|
||||||
{
|
|
||||||
return m_metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto TextureAsset::get_blob_metadata(BlobMetadata::Tag tag) const
|
|
||||||
-> const BlobMetadata &
|
|
||||||
{
|
|
||||||
if (tag != BlobMetadata::Tag::color)
|
|
||||||
{
|
|
||||||
throw std::runtime_error { std::format(
|
|
||||||
"Invalid tag for get_blob_metadata of TextureAsset: {}",
|
|
||||||
std::to_underlying(tag)
|
|
||||||
) };
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_pixel_blob_metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Assets
|
} // namespace Assets
|
||||||
|
|
|
@ -38,6 +38,7 @@ if(NOT WIN32)
|
||||||
scene/scene.cpp
|
scene/scene.cpp
|
||||||
time/timer.cpp
|
time/timer.cpp
|
||||||
user_interface/user_interface.cpp
|
user_interface/user_interface.cpp
|
||||||
|
utils/file_manager.cpp
|
||||||
utils/resource_manager.cpp
|
utils/resource_manager.cpp
|
||||||
utils/serializer.cpp
|
utils/serializer.cpp
|
||||||
utils/stringifier.cpp
|
utils/stringifier.cpp
|
||||||
|
@ -89,6 +90,7 @@ else()
|
||||||
scene/scene.cpp
|
scene/scene.cpp
|
||||||
time/timer.cpp
|
time/timer.cpp
|
||||||
user_interface/user_interface.cpp
|
user_interface/user_interface.cpp
|
||||||
|
utils/file_manager.cpp
|
||||||
utils/resource_manager.cpp
|
utils/resource_manager.cpp
|
||||||
utils/serializer.cpp
|
utils/serializer.cpp
|
||||||
utils/stringifier.cpp
|
utils/stringifier.cpp
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <asset_parser/assets/text.hpp>
|
|
||||||
#include <engine/base/base.hpp>
|
#include <engine/base/base.hpp>
|
||||||
|
#include <engine/utils/file_manager.hpp>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
namespace Light {
|
namespace Light {
|
||||||
|
@ -13,17 +13,16 @@ class Shader
|
||||||
public:
|
public:
|
||||||
enum Stage
|
enum Stage
|
||||||
{
|
{
|
||||||
none = 0,
|
NONE = 0,
|
||||||
|
VERTEX = 1,
|
||||||
vertex,
|
PIXEL = 2,
|
||||||
pixel,
|
GEOMETRY = 3
|
||||||
geometry,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static auto create(
|
static auto create(
|
||||||
Assets::Blob vertex_blob,
|
const BasicFileHandle& vertexFile,
|
||||||
Assets::Blob pixel_blob,
|
const BasicFileHandle& pixelFile,
|
||||||
const Ref<SharedContext> &shared_context
|
const Ref<SharedContext>& sharedContext
|
||||||
) -> Ref<Shader>;
|
) -> Ref<Shader>;
|
||||||
|
|
||||||
virtual ~Shader() = default;
|
virtual ~Shader() = default;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <d3d11.h>
|
#include <d3d11.h>
|
||||||
#include <engine/base/base.hpp>
|
#include <engine/base/base.hpp>
|
||||||
#include <engine/graphics/shader.hpp>
|
#include <engine/graphics/shader.hpp>
|
||||||
|
#include <engine/utils/file_manager.hpp>
|
||||||
#include <wrl.h>
|
#include <wrl.h>
|
||||||
|
|
||||||
namespace Light {
|
namespace Light {
|
||||||
|
|
|
@ -2,13 +2,14 @@
|
||||||
|
|
||||||
#include <engine/base/base.hpp>
|
#include <engine/base/base.hpp>
|
||||||
#include <engine/graphics/shader.hpp>
|
#include <engine/graphics/shader.hpp>
|
||||||
|
#include <engine/utils/file_manager.hpp>
|
||||||
|
|
||||||
namespace Light {
|
namespace Light {
|
||||||
|
|
||||||
class glShader: public Shader
|
class glShader: public Shader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
glShader(Assets::Blob vertex_blob, Assets::Blob pixel_blob);
|
glShader(BasicFileHandle vertexFile, BasicFileHandle pixelFile);
|
||||||
|
|
||||||
~glShader() override;
|
~glShader() override;
|
||||||
|
|
||||||
|
@ -17,9 +18,9 @@ public:
|
||||||
void un_bind() override;
|
void un_bind() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int compile_shader(const std::string &source, Shader::Stage stage);
|
unsigned int compile_shader(const std::string& source, Shader::Stage stage);
|
||||||
|
|
||||||
unsigned int m_shader_id { 0u };
|
unsigned int m_shader_id{0u};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Light
|
} // namespace Light
|
||||||
|
|
80
modules/engine/include/engine/utils/file_manager.hpp
Normal file
80
modules/engine/include/engine/utils/file_manager.hpp
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <engine/base/base.hpp>
|
||||||
|
|
||||||
|
namespace Light {
|
||||||
|
|
||||||
|
class BasicFileHandle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~BasicFileHandle() = default;
|
||||||
|
BasicFileHandle(
|
||||||
|
uint8_t *data = nullptr,
|
||||||
|
uint32_t size = 0ull,
|
||||||
|
std::string path = "",
|
||||||
|
std::string name = "",
|
||||||
|
std::string extension = ""
|
||||||
|
);
|
||||||
|
|
||||||
|
virtual void release();
|
||||||
|
|
||||||
|
auto get_data() -> uint8_t *
|
||||||
|
{
|
||||||
|
return m_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto get_size() const -> uint32_t
|
||||||
|
{
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto get_path() -> const std::string &
|
||||||
|
{
|
||||||
|
return m_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto get_name() -> const std::string &
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto get_extension() -> const std::string &
|
||||||
|
{
|
||||||
|
return m_extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto get_name_with_extention() -> const std::string &
|
||||||
|
{
|
||||||
|
return m_name + '.' + m_extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto is_valid() const -> bool
|
||||||
|
{
|
||||||
|
return !!m_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator bool() const
|
||||||
|
{
|
||||||
|
return is_valid();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// made protected for custom free():
|
||||||
|
uint8_t *m_data;
|
||||||
|
|
||||||
|
uint32_t m_size;
|
||||||
|
|
||||||
|
const std::string m_path;
|
||||||
|
|
||||||
|
const std::string m_name;
|
||||||
|
|
||||||
|
const std::string m_extension;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FileManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static auto read_text_file(const std::string &path) -> BasicFileHandle;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Light
|
|
@ -20,18 +20,23 @@ public:
|
||||||
|
|
||||||
static void load_shader(
|
static void load_shader(
|
||||||
const std::string &name,
|
const std::string &name,
|
||||||
const std::filesystem::path &vertex_path,
|
const std::string &vertexPath,
|
||||||
const std::filesystem::path &pixel_path
|
const std::string &pixelPath
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
instance().load_shader_impl(name, vertex_path, pixel_path);
|
instance().load_shader_impl(name, vertexPath, pixelPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_texture(const std::string &name, const std::filesystem::path &path)
|
static void load_texture(const std::string &name, const std::string &path)
|
||||||
{
|
{
|
||||||
instance().load_texture_impl(name, path);
|
instance().load_texture_impl(name, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void release_texture(const std::string &name)
|
||||||
|
{
|
||||||
|
instance().release_texture_impl(name);
|
||||||
|
}
|
||||||
|
|
||||||
static auto get_shader(const std::string &name) -> Ref<Shader>
|
static auto get_shader(const std::string &name) -> Ref<Shader>
|
||||||
{
|
{
|
||||||
return instance().m_shaders[name];
|
return instance().m_shaders[name];
|
||||||
|
@ -47,12 +52,14 @@ private:
|
||||||
|
|
||||||
void load_shader_impl(
|
void load_shader_impl(
|
||||||
const std::string &name,
|
const std::string &name,
|
||||||
const std::filesystem::path &vertex_path,
|
const std::string &vertexPath,
|
||||||
const std::filesystem::path &pixel_path
|
const std::string &pixelPath
|
||||||
);
|
);
|
||||||
|
|
||||||
void load_texture_impl(const std::string &name, const std::filesystem::path &path);
|
void load_texture_impl(const std::string &name, const std::filesystem::path &path);
|
||||||
|
|
||||||
|
void release_texture_impl(const std::string &name);
|
||||||
|
|
||||||
std::unordered_map<std::string, Ref<Shader>> m_shaders;
|
std::unordered_map<std::string, Ref<Shader>> m_shaders;
|
||||||
|
|
||||||
std::unordered_map<std::string, Ref<Texture>> m_textures;
|
std::unordered_map<std::string, Ref<Texture>> m_textures;
|
||||||
|
|
|
@ -19,8 +19,8 @@ QuadRendererProgram::QuadRendererProgram(
|
||||||
// #todo: don't use relative path
|
// #todo: don't use relative path
|
||||||
ResourceManager::load_shader(
|
ResourceManager::load_shader(
|
||||||
"LT_ENGINE_RESOURCES_QUAD_SHADER",
|
"LT_ENGINE_RESOURCES_QUAD_SHADER",
|
||||||
"data/assets/shaders/quads/vs.asset",
|
"data/assets/shaders/quads/vs.glsl",
|
||||||
"data/assets/shaders/quads/ps.asset"
|
"data/assets/shaders/quads/ps.glsl"
|
||||||
);
|
);
|
||||||
|
|
||||||
m_shader = ResourceManager::get_shader("LT_ENGINE_RESOURCES_QUAD_SHADER");
|
m_shader = ResourceManager::get_shader("LT_ENGINE_RESOURCES_QUAD_SHADER");
|
||||||
|
|
|
@ -19,8 +19,8 @@ TextureRendererProgram::TextureRendererProgram(
|
||||||
// #todo: don't use relative path
|
// #todo: don't use relative path
|
||||||
ResourceManager::load_shader(
|
ResourceManager::load_shader(
|
||||||
"LT_ENGINE_RESOURCES_TEXTURE_SHADER",
|
"LT_ENGINE_RESOURCES_TEXTURE_SHADER",
|
||||||
"data/assets/shaders/texture/vs.asset",
|
"data/assets/shaders/texture/vs.glsl",
|
||||||
"data/assets/shaders/texture/ps.asset"
|
"data/assets/shaders/texture/ps.glsl"
|
||||||
);
|
);
|
||||||
|
|
||||||
m_shader = ResourceManager::get_shader("LT_ENGINE_RESOURCES_TEXTURE_SHADER");
|
m_shader = ResourceManager::get_shader("LT_ENGINE_RESOURCES_TEXTURE_SHADER");
|
||||||
|
|
|
@ -19,8 +19,8 @@ TintedTextureRendererProgram::TintedTextureRendererProgram(
|
||||||
// #todo: don't use relative path
|
// #todo: don't use relative path
|
||||||
ResourceManager::load_shader(
|
ResourceManager::load_shader(
|
||||||
"LT_ENGINE_RESOURCES_TINTED_TEXTURE_SHADER",
|
"LT_ENGINE_RESOURCES_TINTED_TEXTURE_SHADER",
|
||||||
"data/assets/shaders/tinted_texture/vs.asset",
|
"data/assets/shaders/tinted_texture/vs.glsl",
|
||||||
"data/assets/shaders/tinted_texture/ps.asset"
|
"data/assets/shaders/tinted_texture/ps.glsl"
|
||||||
);
|
);
|
||||||
|
|
||||||
m_shader = ResourceManager::get_shader("LT_ENGINE_RESOURCES_TINTED_TEXTURE_SHADER");
|
m_shader = ResourceManager::get_shader("LT_ENGINE_RESOURCES_TINTED_TEXTURE_SHADER");
|
||||||
|
|
|
@ -11,18 +11,15 @@
|
||||||
namespace Light {
|
namespace Light {
|
||||||
|
|
||||||
auto Shader::create(
|
auto Shader::create(
|
||||||
Assets::Blob vertex_blob,
|
const BasicFileHandle& vertexFile,
|
||||||
Assets::Blob pixel_blob,
|
const BasicFileHandle& pixelFile,
|
||||||
const Ref<SharedContext> &shared_context
|
const Ref<SharedContext>& /*sharedContext*/
|
||||||
) -> Ref<Shader>
|
) -> Ref<Shader>
|
||||||
{
|
{
|
||||||
std::ignore = shared_context;
|
|
||||||
|
|
||||||
// load shader source
|
// load shader source
|
||||||
switch (GraphicsContext::get_graphics_api())
|
switch (GraphicsContext::get_graphics_api())
|
||||||
{
|
{
|
||||||
case GraphicsAPI::OpenGL:
|
case GraphicsAPI::OpenGL: return create_ref<glShader>(vertexFile, pixelFile);
|
||||||
return create_ref<glShader>(std::move(vertex_blob), std::move(pixel_blob));
|
|
||||||
|
|
||||||
case GraphicsAPI::DirectX:
|
case GraphicsAPI::DirectX:
|
||||||
lt_win(return create_ref<dxShader>(
|
lt_win(return create_ref<dxShader>(
|
||||||
|
|
|
@ -6,29 +6,27 @@
|
||||||
|
|
||||||
namespace Light {
|
namespace Light {
|
||||||
|
|
||||||
glShader::glShader(Assets::Blob vertex_blob, Assets::Blob pixel_blob)
|
glShader::glShader(BasicFileHandle vertexFile, BasicFileHandle pixelFile)
|
||||||
: m_shader_id(glCreateProgram())
|
|
||||||
{
|
{
|
||||||
auto vertex_source = std::string {
|
// create
|
||||||
vertex_blob.data(),
|
m_shader_id = glCreateProgram();
|
||||||
vertex_blob.data() + vertex_blob.size(), // NOLINT
|
|
||||||
};
|
|
||||||
|
|
||||||
auto pixel_source = std::string {
|
std::string const vertexSource(vertexFile.get_data(), vertexFile.get_data() + vertexFile.get_size());
|
||||||
pixel_blob.data(),
|
std::string const pixelSource(pixelFile.get_data(), pixelFile.get_data() + pixelFile.get_size());
|
||||||
pixel_blob.data() + pixel_blob.size(), // NOLINT
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto vertex_shader = compile_shader(vertex_source, Shader::Stage::vertex);
|
unsigned int const vertexShader = compile_shader(vertexSource, Shader::Stage::VERTEX);
|
||||||
const auto pixel_shader = compile_shader(pixel_source, Shader::Stage::pixel);
|
unsigned int const pixelShader = compile_shader(pixelSource, Shader::Stage::PIXEL);
|
||||||
|
|
||||||
glAttachShader(m_shader_id, vertex_shader);
|
// attach shaders
|
||||||
glAttachShader(m_shader_id, pixel_shader);
|
glAttachShader(m_shader_id, vertexShader);
|
||||||
|
glAttachShader(m_shader_id, pixelShader);
|
||||||
|
|
||||||
|
// link shader program
|
||||||
glLinkProgram(m_shader_id);
|
glLinkProgram(m_shader_id);
|
||||||
|
|
||||||
glDeleteShader(vertex_shader);
|
// delete shaders (free memory)
|
||||||
glDeleteShader(pixel_shader);
|
glDeleteShader(vertexShader);
|
||||||
|
glDeleteShader(pixelShader);
|
||||||
}
|
}
|
||||||
|
|
||||||
glShader::~glShader()
|
glShader::~glShader()
|
||||||
|
@ -46,14 +44,38 @@ void glShader::un_bind()
|
||||||
glUseProgram(NULL);
|
glUseProgram(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto glShader::compile_shader(const std::string &source, Shader::Stage stage) -> unsigned int
|
// shaderc::SpvCompilationResult glShader::compile_glsl(basic_file_handle file, Shader::Stage stage)
|
||||||
|
// {
|
||||||
|
// // compile options
|
||||||
|
// shaderc::CompileOptions options;
|
||||||
|
// options.SetTargetEnvironment(shaderc_target_env_opengl, shaderc_env_version_opengl_4_5);
|
||||||
|
// options.SetOptimizationLevel(shaderc_optimization_level_performance);
|
||||||
|
//
|
||||||
|
// // compile
|
||||||
|
// shaderc::Compiler compiler;
|
||||||
|
// shaderc::SpvCompilationResult result = compiler.CompileGlslToSpv(reinterpret_cast<const
|
||||||
|
// char*>(file.GetData()), stage == Shader::Stage::VERTEX ?
|
||||||
|
// shaderc_shader_kind::shaderc_vertex_shader : shaderc_shader_kind::shaderc_fragment_shader,
|
||||||
|
// file.GetName().c_str(), options);
|
||||||
|
//
|
||||||
|
// // log error
|
||||||
|
// if (result.GetCompilationStatus() != shaderc_compilation_status_success)
|
||||||
|
// {
|
||||||
|
// log_err("Failed to compile {} shader at {}...", stage == Shader::Stage::VERTEX ?
|
||||||
|
// "vertex" : "pixel", file.GetPath()); log_err(" {}", result.GetErrorMessage());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
auto glShader::compile_shader(const std::string& source, Shader::Stage stage) -> unsigned int
|
||||||
{
|
{
|
||||||
// &(address of) needs an lvalue
|
// &(address of) needs an lvalue
|
||||||
const auto *lvalue_source = source.c_str();
|
const auto *lvalue_source = source.c_str();
|
||||||
auto shader = glCreateShader(
|
auto shader = glCreateShader(
|
||||||
stage == Shader::Stage::vertex ? GL_VERTEX_SHADER :
|
stage == Shader::Stage::VERTEX ? GL_VERTEX_SHADER :
|
||||||
stage == Shader::Stage::pixel ? GL_FRAGMENT_SHADER :
|
stage == Shader::Stage::PIXEL ? GL_FRAGMENT_SHADER :
|
||||||
stage == Shader::Stage::geometry ? GL_GEOMETRY_SHADER :
|
stage == Shader::Stage::GEOMETRY ? GL_GEOMETRY_SHADER :
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -74,7 +96,7 @@ auto glShader::compile_shader(const std::string &source, Shader::Stage stage) ->
|
||||||
|
|
||||||
log_err(
|
log_err(
|
||||||
"glShader::glShader: failed to compile {} shader:\n {}",
|
"glShader::glShader: failed to compile {} shader:\n {}",
|
||||||
stage == Shader::Stage::vertex ? "Vertex" : "Pixel",
|
stage == Shader::Stage::VERTEX ? "Vertex" : "Pixel",
|
||||||
errorLog
|
errorLog
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
111
modules/engine/src/utils/file_manager.cpp
Normal file
111
modules/engine/src/utils/file_manager.cpp
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
#include <engine/utils/file_manager.hpp>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace Light {
|
||||||
|
|
||||||
|
BasicFileHandle::BasicFileHandle(
|
||||||
|
uint8_t *data,
|
||||||
|
uint32_t size,
|
||||||
|
std::string path,
|
||||||
|
std::string name,
|
||||||
|
std::string extension
|
||||||
|
)
|
||||||
|
: m_data(data)
|
||||||
|
, m_size(size)
|
||||||
|
, m_path(std::move(path))
|
||||||
|
, m_name(std::move(name))
|
||||||
|
, m_extension(std::move(extension))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void BasicFileHandle::release()
|
||||||
|
{
|
||||||
|
delete m_data;
|
||||||
|
m_data = nullptr;
|
||||||
|
m_size = 0ull;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto FileManager::read_text_file(const std::string &path) -> BasicFileHandle
|
||||||
|
{
|
||||||
|
// parse path info
|
||||||
|
auto name = path.substr(0, path.find('.') + -1);
|
||||||
|
auto extension = path.substr(path.find('.') + 1);
|
||||||
|
|
||||||
|
// open file
|
||||||
|
auto file = std::ifstream { path.c_str(), std::ios_base::in | std::ios_base::binary };
|
||||||
|
|
||||||
|
// check
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
log_wrn("Failed to load text file: {}", path);
|
||||||
|
file.close();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetch file size
|
||||||
|
file.seekg(0, std::ios::end);
|
||||||
|
auto size = file.tellg();
|
||||||
|
file.seekg(0, std::ios::beg);
|
||||||
|
|
||||||
|
if (!size)
|
||||||
|
{
|
||||||
|
log_wrn("Empty text file: {}", path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// read file
|
||||||
|
auto *data = new uint8_t[size];
|
||||||
|
file.read(reinterpret_cast<char *>(data), size);
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
return { data, static_cast<unsigned int>(size), path, name, extension };
|
||||||
|
}
|
||||||
|
|
||||||
|
// auto FileManager::read_image_file(const std::string &path, int32_t desiredComponents)
|
||||||
|
// -> ImageFileHandle
|
||||||
|
// {
|
||||||
|
// // parse path info
|
||||||
|
// auto name = path.substr(0, path.find('.') + -1);
|
||||||
|
// auto extension = path.substr(path.find('.') + 1);
|
||||||
|
//
|
||||||
|
// // load image
|
||||||
|
// auto width = 0;
|
||||||
|
// auto height = 0;
|
||||||
|
// auto fetchedComponents = 0;
|
||||||
|
// auto *pixels = stbi_load(path.c_str(), &width, &height, &fetchedComponents, desiredComponents);
|
||||||
|
//
|
||||||
|
// // check
|
||||||
|
// if (!pixels)
|
||||||
|
// {
|
||||||
|
// log_wrn("Failed to load image file: <{}>", path);
|
||||||
|
// }
|
||||||
|
// else if (fetchedComponents != desiredComponents)
|
||||||
|
// {
|
||||||
|
// log_wrn(
|
||||||
|
// "Mismatch of fetched/desired components: <{}> ({}/{})",
|
||||||
|
// name + '.' + extension,
|
||||||
|
// fetchedComponents,
|
||||||
|
// desiredComponents
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return ImageFileHandle(
|
||||||
|
// pixels,
|
||||||
|
// width * height,
|
||||||
|
// path,
|
||||||
|
// name,
|
||||||
|
// extension,
|
||||||
|
// width,
|
||||||
|
// height,
|
||||||
|
// fetchedComponents,
|
||||||
|
// desiredComponents
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void ImageFileHandle::release()
|
||||||
|
// {
|
||||||
|
// stbi_image_free(reinterpret_cast<void *>(m_data));
|
||||||
|
// m_data = nullptr;
|
||||||
|
// m_size = 0ull;
|
||||||
|
// }
|
||||||
|
|
||||||
|
} // namespace Light
|
|
@ -1,58 +1,38 @@
|
||||||
#include <asset_parser/assets/text.hpp>
|
|
||||||
#include <asset_parser/assets/texture.hpp>
|
#include <asset_parser/assets/texture.hpp>
|
||||||
|
#include <asset_parser/parser.hpp>
|
||||||
#include <engine/graphics/graphics_context.hpp>
|
#include <engine/graphics/graphics_context.hpp>
|
||||||
#include <engine/graphics/shader.hpp>
|
#include <engine/graphics/shader.hpp>
|
||||||
#include <engine/graphics/texture.hpp>
|
#include <engine/graphics/texture.hpp>
|
||||||
|
#include <engine/utils/file_manager.hpp>
|
||||||
#include <engine/utils/resource_manager.hpp>
|
#include <engine/utils/resource_manager.hpp>
|
||||||
#include <logger/logger.hpp>
|
|
||||||
|
|
||||||
namespace Light {
|
namespace Light {
|
||||||
|
|
||||||
void ResourceManager::load_shader_impl(
|
void ResourceManager::load_shader_impl(
|
||||||
const std::string &name,
|
const std::string &name,
|
||||||
const std::filesystem::path &vertex_path,
|
const std::string &vertexPath,
|
||||||
const std::filesystem::path &pixel_path
|
const std::string &pixelPath
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
try
|
lt_assert(!vertexPath.empty(), "Empty 'vertexPath'");
|
||||||
{
|
lt_assert(!pixelPath.empty(), "Empty 'pixelPath'");
|
||||||
log_trc("Loading shader:");
|
|
||||||
log_trc("\tname : {}", name);
|
|
||||||
log_trc("\tvertex path: {}", vertex_path.string());
|
|
||||||
log_trc("\tpixel path : {}", pixel_path.string());
|
|
||||||
|
|
||||||
auto vertex_asset = Assets::TextAsset { vertex_path };
|
auto vertexFile = FileManager::read_text_file(vertexPath);
|
||||||
auto pixel_asset = Assets::TextAsset { pixel_path };
|
auto pixelFile = FileManager::read_text_file(pixelPath);
|
||||||
|
|
||||||
auto vertex_blob_metadata = vertex_asset.get_blob_metadata(Assets::BlobMetadata::Tag::text);
|
lt_assert(vertexFile.is_valid(), "Failed to read vertex file: {}", vertexPath);
|
||||||
auto pixel_blob_metadata = pixel_asset.get_blob_metadata(Assets::BlobMetadata::Tag::text);
|
lt_assert(pixelFile.is_valid(), "Failed to read vertex file: {}", pixelPath);
|
||||||
|
|
||||||
auto vertex_blob = Assets::Blob(vertex_blob_metadata.uncompressed_size);
|
m_shaders[name] = Ref<Shader>(
|
||||||
auto pixel_blob = Assets::Blob(pixel_blob_metadata.uncompressed_size);
|
Shader::create(vertexFile, pixelFile, GraphicsContext::get_shared_context())
|
||||||
|
);
|
||||||
|
|
||||||
vertex_asset.unpack_blob(vertex_blob_metadata.tag, vertex_blob.data(), vertex_blob.size());
|
vertexFile.release();
|
||||||
pixel_asset.unpack_blob(pixel_blob_metadata.tag, pixel_blob.data(), pixel_blob.size());
|
pixelFile.release();
|
||||||
|
|
||||||
m_shaders[name] = Ref<Shader>(Shader::create(
|
|
||||||
std::move(vertex_blob),
|
|
||||||
std::move(pixel_blob),
|
|
||||||
GraphicsContext::get_shared_context()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
catch (const std::exception &exp)
|
|
||||||
{
|
|
||||||
log_err("Failed to load shader:");
|
|
||||||
log_err("\tname : {}", name);
|
|
||||||
log_err("\tvertex path: {}", vertex_path.string());
|
|
||||||
log_err("\tpixel path : {}", pixel_path.string());
|
|
||||||
log_err("\texception : {}", exp.what());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceManager::load_texture_impl(const std::string &name, const std::filesystem::path &path)
|
void ResourceManager::load_texture_impl(const std::string &name, const std::filesystem::path &path)
|
||||||
{
|
{
|
||||||
try
|
|
||||||
{
|
|
||||||
log_trc("Loading texture:");
|
log_trc("Loading texture:");
|
||||||
log_trc("\tname: {}", name);
|
log_trc("\tname: {}", name);
|
||||||
log_trc("\tpath: {}", path.string());
|
log_trc("\tpath: {}", path.string());
|
||||||
|
@ -72,14 +52,17 @@ void ResourceManager::load_texture_impl(const std::string &name, const std::file
|
||||||
GraphicsContext::get_shared_context(),
|
GraphicsContext::get_shared_context(),
|
||||||
path
|
path
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
catch (const std::exception &exp)
|
|
||||||
|
void ResourceManager::release_texture_impl(const std::string &name)
|
||||||
|
{
|
||||||
|
if (!m_textures[name])
|
||||||
{
|
{
|
||||||
log_err("Failed to load texture:");
|
log_wrn("Failed to find texture named: {}", name);
|
||||||
log_err("\tname : {}", name);
|
return;
|
||||||
log_err("\tpath : {}", path.string());
|
|
||||||
log_err("\texception: {}", exp.what());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_textures[name] = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Light
|
} // namespace Light
|
||||||
|
|
Loading…
Add table
Reference in a new issue