diff --git a/.gitmodules b/.gitmodules index 3f17965d74c54abaabfb616bcad6481fc4500a6a..f3748ee10aa95ba9ef5f1c69d6bb67523667ef49 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,16 +1,16 @@ [submodule "DMath"] path = external/DMath url = https://github.com/Didgy74/DMath.git - branch = master + branch = origin/master [submodule "fx-gltf"] path = external/fx-gltf url = https://github.com/jessey-git/fx-gltf.git - branch = master + branch = origin/master [submodule "nlohmann-json"] path = external/nlohmann-json url = https://github.com/nlohmann/json.git - branch = master + branch = origin/master [submodule "ktxlib"] path = external/ktxlib url = https://github.com/KhronosGroup/KTX-Software.git - branch = master + branch = origin/master diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ac2c4c1c1ea46556a610f4df5c6617ee7cb4243..0e8ca488ae8e087ca3f7f5e9685323bfed65a61f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ if(WIN32) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build") endif() -file(GLOB_RECURSE SOURCE_FILES "${CMAKE_SOURCE_DIR}/src/*.cpp") +file(GLOB_RECURSE SOURCE_FILES "${CMAKE_SOURCE_DIR}/src/*.cpp" "${CMAKE_SOURCE_DIR}/src/*.hpp" "${CMAKE_SOURCE_DIR}/src/*.inl") add_executable(${PROJECT_NAME} ${SOURCE_FILES}) target_include_directories(${PROJECT_NAME} PRIVATE include) diff --git a/external/DMath b/external/DMath index 62afefe2fcf6db2471846d3b42800a0ae44f0f8e..a86909a7b37084c09c867efefa59faec47686128 160000 --- a/external/DMath +++ b/external/DMath @@ -1 +1 @@ -Subproject commit 62afefe2fcf6db2471846d3b42800a0ae44f0f8e +Subproject commit a86909a7b37084c09c867efefa59faec47686128 diff --git a/src/Engine/Asset.cpp b/src/Engine/Asset.cpp deleted file mode 100644 index 60331fb11e3676c751d4906b4f276bf4f4c3e527..0000000000000000000000000000000000000000 --- a/src/Engine/Asset.cpp +++ /dev/null @@ -1,242 +0,0 @@ -#define ASSET_TEXTURE_COUNT -#define ASSET_MESH_COUNT -#include "Asset.hpp" - -#include <cassert> -#include <map> -#include <type_traits> -#include <iostream> - -#include "fx/gltf.h" - -struct AssetInfo -{ - std::string_view name; - std::string_view relativePath; -}; - -static const std::map<Asset::Sprite, AssetInfo> textureInfos -{ - { Asset::Sprite::None, {"None" , ""} }, - { Asset::Sprite::Default, {"Default", "defaultTexture.png"} }, - { Asset::Sprite::Test, {"Test", "test.png"} }, - { Asset::Sprite::Circle, {"Circle", "circle.png"} }, -}; - -static const std::map<size_t, AssetInfo> meshInfos -{ - { size_t(Asset::Mesh::None), {"None", ""} }, - { size_t(Asset::Mesh::Cube), {"Cube", "Cube/Cube.gltf"} }, - { size_t(Asset::Mesh::SpritePlane), {"SpritePlane", "SpritePlane/SpritePlane.gltf"} }, - { size_t(Asset::Mesh::Helmet), {"Helmet", "Helmet/Helmet.gltf"} }, -}; - -bool Asset::CheckValid(Sprite sprite) -{ - using Type = std::underlying_type_t<Sprite>; - return (0 <= static_cast<Type>(sprite) && static_cast<Type>(sprite) < static_cast<Type>(Sprite::COUNT)) || sprite == Sprite::None; -} - -std::string Asset::GetMeshPath(size_t i) -{ - auto iterator = meshInfos.find(i); - if (iterator == meshInfos.end()) - return {}; - else - return std::string(meshFolderPath) + std::string(iterator->second.relativePath); -} - -std::optional<Asset::MeshDocument> Asset::LoadMeshDocument(std::string_view path) -{ - try - { - const auto gltfDocument = fx::gltf::LoadFromText(std::string(path)); - - auto& primitive = gltfDocument.meshes[0].primitives[0]; - - auto posAccIterator = primitive.attributes.find("POSITION"); - if (posAccIterator == primitive.attributes.end()) - { - std::cerr << "Error. Found no position attribute for mesh." << std::endl; - return {}; - } - auto& posAcc = gltfDocument.accessors[posAccIterator->second]; - bool validAccessor = posAcc.type == fx::gltf::Accessor::Type::Vec3 && posAcc.componentType == fx::gltf::Accessor::ComponentType::Float; - if (!validAccessor) - { - std::cerr << "Error. Position attribute of mesh is in wrong format." << std::endl; - return {}; - } - auto& posBufferView = gltfDocument.bufferViews[posAcc.bufferView]; - const auto posByteOffset = posAcc.byteOffset + posBufferView.byteOffset; - - - auto& uvAccessor = gltfDocument.accessors[primitive.attributes.find("TEXCOORD_0")->second]; - assert(uvAccessor.type == fx::gltf::Accessor::Type::Vec2 && uvAccessor.componentType == fx::gltf::Accessor::ComponentType::Float); - auto& uvBufferView = gltfDocument.bufferViews[uvAccessor.bufferView]; - - - - auto& normalAccessor = gltfDocument.accessors[primitive.attributes.find("NORMAL")->second]; - assert(normalAccessor.type == fx::gltf::Accessor::Type::Vec3 && normalAccessor.componentType == fx::gltf::Accessor::ComponentType::Float); - auto& normalBufferView = gltfDocument.bufferViews[normalAccessor.bufferView]; - - - assert(posAcc.count == uvAccessor.count && posAcc.count == normalAccessor.count); - - auto& indexAccessor = gltfDocument.accessors[primitive.indices]; - assert(indexAccessor.type == fx::gltf::Accessor::Type::Scalar); - assert(indexAccessor.componentType == fx::gltf::Accessor::ComponentType::UnsignedShort - || indexAccessor.componentType == fx::gltf::Accessor::ComponentType::UnsignedInt); - auto& indexBufferView = gltfDocument.bufferViews[indexAccessor.bufferView]; - - - MeshDocument::CreateInfo createInfo{}; - createInfo.byteArray = std::move(gltfDocument.buffers[posBufferView.buffer].data); - createInfo.vertexCount = posAcc.count; - createInfo.posByteOffset = posByteOffset; - createInfo.uvByteOffset = uvBufferView.byteOffset + uvAccessor.byteOffset; - createInfo.normalByteOffset = normalBufferView.byteOffset + normalAccessor.byteOffset; - createInfo.indexByteOffset = indexBufferView.byteOffset + indexAccessor.byteOffset; - createInfo.indexCount = indexAccessor.count; - createInfo.indexType = indexAccessor.componentType == fx::gltf::Accessor::ComponentType::UnsignedShort ? MeshDocument::IndexType::UInt16 : MeshDocument::IndexType::UInt32; - - return { MeshDocument(std::move(createInfo)) }; - } - catch (std::exception e) - { - std::cerr << "Asset System Error: Could not load file. Message: " << e.what() << std::endl; - return {}; - } -} - -Asset::TextureDocument Asset::LoadTextureDocument(Sprite texture) -{ - TextureDocument::CreateInfo createInfo{}; - - return TextureDocument(std::move(createInfo)); -} - -std::optional<Engine::Renderer::MeshDocument> Asset::LoadMesh(size_t i) -{ - auto path = GetMeshPath(i); - if (path == "") - return {}; - - auto assetMeshDocOpt = LoadMeshDocument(path); - if (assetMeshDocOpt.has_value() == false) - return {}; - - auto oldInfo = MeshDocument::ToCreateInfo(std::move(assetMeshDocOpt.value())); - - using namespace Engine; - Renderer::MeshDocument::CreateInfo newInfo; - newInfo.byteArray = std::move(oldInfo.byteArray); - newInfo.vertexCount = std::move(oldInfo.vertexCount); - newInfo.indexCount = std::move(oldInfo.indexCount); - newInfo.indexType = oldInfo.indexType == MeshDocument::IndexType::UInt16 ? Renderer::MeshDocument::IndexType::UInt16 : Renderer::MeshDocument::IndexType::UInt32; - - newInfo.posByteOffset = std::move(oldInfo.posByteOffset); - newInfo.uvByteOffset = std::move(oldInfo.uvByteOffset); - newInfo.normalByteOffset = std::move(oldInfo.normalByteOffset); - newInfo.tangentByteOffset = std::move(oldInfo.tangentByteOffset); - newInfo.indexByteOffset = std::move(oldInfo.indexByteOffset); - - return Renderer::MeshDocument(std::move(newInfo)); -} - -static Asset::MeshDocument::IndexType ToIndexType(fx::gltf::Accessor::ComponentType componentType) -{ - switch (componentType) - { - case fx::gltf::Accessor::ComponentType::UnsignedShort: - return Asset::MeshDocument::IndexType::UInt16; - case fx::gltf::Accessor::ComponentType::UnsignedInt: - return Asset::MeshDocument::IndexType::UInt32; - default: - return static_cast<Asset::MeshDocument::IndexType>(-1); - } -} - -Asset::MeshDocument::CreateInfo Asset::MeshDocument::ToCreateInfo(MeshDocument&& input) -{ - CreateInfo returnValue; - - returnValue.byteArray = std::move(input.byteArray); - returnValue.vertexCount = std::move(input.vertexCount); - returnValue.indexType = std::move(input.indexType); - returnValue.indexCount = std::move(input.indexCount); - - returnValue.posByteOffset = std::move(input.GetByteOffset(Attribute::Position)); - returnValue.uvByteOffset = std::move(input.GetByteOffset(Attribute::TexCoord)); - returnValue.normalByteOffset = std::move(input.GetByteOffset(Attribute::Normal)); - returnValue.tangentByteOffset = std::move(input.GetByteOffset(Attribute::Tangent)); - returnValue.indexByteOffset = std::move(input.GetByteOffset(Attribute::Index)); - - return returnValue; -} - -Asset::MeshDocument::MeshDocument(CreateInfo&& info) : - byteArray(std::move(info.byteArray)), - indexType(info.indexType), - vertexCount(info.vertexCount), - indexCount(info.indexCount) -{ - GetByteOffset(Attribute::Position) = info.posByteOffset; - GetByteOffset(Attribute::TexCoord) = info.uvByteOffset; - GetByteOffset(Attribute::Normal) = info.normalByteOffset; - GetByteOffset(Attribute::Tangent) = info.normalByteOffset; - GetByteOffset(Attribute::Index) = info.indexByteOffset; -} - -const std::vector<uint8_t>& Asset::MeshDocument::GetByteArray() const { return byteArray; } - -Asset::MeshDocument::IndexType Asset::MeshDocument::GetIndexType() const { return indexType; } - -const uint8_t* Asset::MeshDocument::GetDataPtr(Attribute type) const -{ - return byteArray.data() + byteOffsets.at(size_t(type)); -} - -size_t& Asset::MeshDocument::GetByteOffset(Attribute type) { return byteOffsets.at(size_t(type)); } - -const size_t& Asset::MeshDocument::GetByteOffset(Attribute type) const { return byteOffsets.at(size_t(type)); } - -uint8_t Asset::MeshDocument::ToByteSize(IndexType indexType) -{ - return indexType == IndexType::UInt16 ? uint8_t(2) : uint8_t(4); -} - -Asset::TextureDocument::TextureDocument(CreateInfo&& right) : - byteArray(right.byteArray), - dimensions(right.dimensions), - channelCount(right.channelCount), - owner(true) -{ -} - -Asset::TextureDocument::TextureDocument(TextureDocument&& right) : - byteArray(right.byteArray), - dimensions(right.dimensions), - channelCount(right.channelCount), - owner(true) -{ - right.owner = false; -} - -Asset::TextureDocument::~TextureDocument() -{ - if (owner) - delete[] byteArray; -} - -Utility::ImgDim Asset::TextureDocument::GetDimensions() const { return dimensions; } - -const uint8_t* Asset::TextureDocument::GetData() const { return byteArray; } - -uint8_t Asset::TextureDocument::GetChannelCount() const { return channelCount; } - -size_t Asset::TextureDocument::GetByteLength() const -{ - return dimensions.width * dimensions.height * channelCount; -} diff --git a/src/Engine/Asset.hpp b/src/Engine/Asset.hpp deleted file mode 100644 index 841eb6b34b133ff7314dcce7d94c0b1097d46fa4..0000000000000000000000000000000000000000 --- a/src/Engine/Asset.hpp +++ /dev/null @@ -1,150 +0,0 @@ -#pragma once - -#include "Utility/ImgDim.hpp" - -#include <string> -#include <string_view> -#include <cstdint> -#include <vector> -#include <array> -#include <optional> - -#include "Renderer/MeshDocument.hpp" - -namespace Asset -{ - constexpr std::string_view textureFolderPath = "Data/Textures/"; - constexpr std::string_view meshFolderPath = "Data/Meshes/"; - - class MeshDocument; - class TextureDocument; - - enum class Sprite : uint32_t; - bool CheckValid(Sprite texture); - - enum class Mesh : uint32_t; - std::string GetMeshPath(size_t i); - - MeshDocument LoadMeshDocument(Mesh mesh); - std::optional<MeshDocument> LoadMeshDocument(std::string_view path); - TextureDocument LoadTextureDocument(Sprite texture); - - std::optional<Engine::Renderer::MeshDocument> LoadMesh(size_t i); -} - -class Asset::MeshDocument -{ -public: - using PositionType = std::array<float, 3>; - using UVType = std::array<float, 2>; - using NormalType = std::array<float, 3>; - using TangentType = std::array<float, 3>; - - enum class IndexType - { - UInt16, - UInt32 - }; - - enum class Attribute - { - Position, - TexCoord, - Normal, - Tangent, - Index, - COUNT - }; - - struct CreateInfo - { - std::vector<uint8_t> byteArray; - size_t posByteOffset; - size_t uvByteOffset; - size_t normalByteOffset; - size_t tangentByteOffset; - size_t indexByteOffset; - IndexType indexType; - uint32_t vertexCount; - uint32_t indexCount; - }; - - MeshDocument(CreateInfo&& info); - MeshDocument(MeshDocument&&) = default; - MeshDocument(const MeshDocument&) = default; - - const std::vector<uint8_t>& GetByteArray() const; - const size_t& GetByteOffset(Attribute attr) const; - size_t GetByteLength(Attribute attr) const; - const uint8_t* GetDataPtr(Attribute attr) const; - - uint32_t GetVertexCount() const; - - IndexType GetIndexType() const; - uint32_t GetIndexCount() const; - - size_t GetTotalSizeRequired() const; - - static uint8_t ToByteSize(IndexType indexType); - static CreateInfo ToCreateInfo(MeshDocument&& input); - -private: - size_t& GetByteOffset(Attribute attr); - - std::vector<uint8_t> byteArray; - std::array<size_t, static_cast<size_t>(Attribute::COUNT)> byteOffsets; - uint32_t vertexCount; - IndexType indexType; - uint32_t indexCount; -}; - -class Asset::TextureDocument -{ -public: - struct CreateInfo - { - Utility::ImgDim dimensions; - uint8_t* byteArray; - uint8_t channelCount; - }; - - TextureDocument(CreateInfo&&); - TextureDocument(TextureDocument&&); - TextureDocument(const TextureDocument&) = delete; - ~TextureDocument(); - - Utility::ImgDim GetDimensions() const; - const uint8_t* GetData() const; - uint8_t GetChannelCount() const; - - size_t GetByteLength() const; - -private: - Utility::ImgDim dimensions; - bool owner; - uint8_t* byteArray; - uint8_t channelCount; -}; - -enum class Asset::Sprite : uint32_t -{ - None, - Default, - Test, - Circle, -#ifdef ASSET_TEXTURE_COUNT - COUNT -#endif -}; - -enum class Asset::Mesh : uint32_t -{ - None, - Plane, - Cube, - SpritePlane, - Helmet, -#ifdef ASSET_MESH_COUNT - COUNT -#endif -}; \ No newline at end of file diff --git a/src/Engine/AssetManager/AssetManager.cpp b/src/Engine/AssetManager/AssetManager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..74a96f37b467135f281e6b62167663fa1d37dc0d --- /dev/null +++ b/src/Engine/AssetManager/AssetManager.cpp @@ -0,0 +1,77 @@ +#include "AssetManager.hpp" +#include "MeshDocument.hpp" +#include "TextureDocument.hpp" + +#include <cassert> +#include <map> +#include <type_traits> +#include <iostream> +#include <string_view> + +struct AssetManagerInfo +{ + std::string_view name; + std::string_view relativePath; +}; + +static const std::map<Engine::AssetManager::Sprite, AssetManagerInfo> textureInfos +{ + { Engine::AssetManager::Sprite::None, {"None" , ""} }, + { Engine::AssetManager::Sprite::Default, {"Default", "defaultTexture.png"} }, + { Engine::AssetManager::Sprite::Test, {"Test", "test.png"} }, + { Engine::AssetManager::Sprite::Circle, {"Circle", "circle.png"} }, +}; + +static const std::map<size_t, AssetManagerInfo> meshInfos +{ + { size_t(Engine::AssetManager::Mesh::None), {"None", ""} }, + { size_t(Engine::AssetManager::Mesh::Cube), {"Cube", "Cube/Cube.gltf"} }, + { size_t(Engine::AssetManager::Mesh::SpritePlane), {"SpritePlane", "SpritePlane/SpritePlane.gltf"} }, + { size_t(Engine::AssetManager::Mesh::Helmet), {"Helmet", "Helmet/Helmet.gltf"} }, +}; + +namespace Engine +{ + namespace AssetManager + { + std::string GetMeshPath(size_t i) + { + auto iterator = meshInfos.find(i); + if (iterator == meshInfos.end()) + return {}; + else + return std::string(meshFolderPath) + std::string(iterator->second.relativePath); + } + + std::optional<Renderer::MeshDocument> AssetManager::LoadMesh(size_t i) + { + auto path = GetMeshPath(i); + if (path == "") + return {}; + + auto AssetManagerMeshDocOpt = LoadMeshDocument(path); + if (AssetManagerMeshDocOpt.has_value() == false) + return {}; + + auto oldInfo = MeshDocument::ToCreateInfo(std::move(AssetManagerMeshDocOpt.value())); + + Renderer::MeshDocument::CreateInfo newInfo; + newInfo.byteArray = std::move(oldInfo.byteArray); + newInfo.vertexCount = std::move(oldInfo.vertexCount); + newInfo.indexCount = std::move(oldInfo.indexCount); + newInfo.indexType = oldInfo.indexType == MeshDocument::IndexType::UInt16 ? Renderer::MeshDocument::IndexType::UInt16 : Renderer::MeshDocument::IndexType::UInt32; + + newInfo.posByteOffset = std::move(oldInfo.posByteOffset); + newInfo.uvByteOffset = std::move(oldInfo.uvByteOffset); + newInfo.normalByteOffset = std::move(oldInfo.normalByteOffset); + newInfo.tangentByteOffset = std::move(oldInfo.tangentByteOffset); + newInfo.indexByteOffset = std::move(oldInfo.indexByteOffset); + + return { Renderer::MeshDocument(std::move(newInfo)) }; + } + } + +} + +#include "MeshDocument.inl" +#include "TextureDocument.inl" \ No newline at end of file diff --git a/src/Engine/AssetManager/AssetManager.hpp b/src/Engine/AssetManager/AssetManager.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ed4ba0370cc04ec834a8ad6c41086fa1f59c73b4 --- /dev/null +++ b/src/Engine/AssetManager/AssetManager.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include "Typedefs.hpp" +#include "MeshDocument.hpp" +#include "TextureDocument.hpp" + +#include <string> +#include <string_view> +#include <optional> + +#include "../Renderer/MeshDocument.hpp" + +namespace Engine +{ + namespace AssetManager + { + constexpr std::string_view textureFolderPath = "Data/Textures/"; + constexpr std::string_view meshFolderPath = "Data/Meshes/"; + + std::string GetMeshPath(size_t i); + + std::optional<Renderer::MeshDocument> LoadMesh(size_t i); + } + + namespace AssMan = AssetManager; +} \ No newline at end of file diff --git a/src/Engine/AssetManager/MeshDocument.hpp b/src/Engine/AssetManager/MeshDocument.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f1950fe64bfbb1b1b15669fab0db40b30f8e0a97 --- /dev/null +++ b/src/Engine/AssetManager/MeshDocument.hpp @@ -0,0 +1,80 @@ +#pragma once + +#include <vector> +#include <array> +#include <string_view> +#include <optional> + +namespace Engine +{ + namespace AssetManager + { + class MeshDocument + { + public: + using PositionType = std::array<float, 3>; + using UVType = std::array<float, 2>; + using NormalType = std::array<float, 3>; + using TangentType = std::array<float, 3>; + + enum class IndexType + { + UInt16, + UInt32 + }; + + enum class Attribute + { + Position, + TexCoord, + Normal, + Tangent, + Index, + COUNT + }; + + struct CreateInfo + { + std::vector<uint8_t> byteArray; + size_t posByteOffset; + size_t uvByteOffset; + size_t normalByteOffset; + size_t tangentByteOffset; + size_t indexByteOffset; + IndexType indexType; + uint32_t vertexCount; + uint32_t indexCount; + }; + + MeshDocument(CreateInfo&& info); + MeshDocument(MeshDocument&&) = default; + MeshDocument(const MeshDocument&) = default; + + const std::vector<uint8_t>& GetByteArray() const; + const size_t& GetByteOffset(Attribute attr) const; + size_t GetByteLength(Attribute attr) const; + const uint8_t* GetDataPtr(Attribute attr) const; + + uint32_t GetVertexCount() const; + + IndexType GetIndexType() const; + uint32_t GetIndexCount() const; + + size_t GetTotalSizeRequired() const; + + static uint8_t ToByteSize(IndexType indexType); + static CreateInfo ToCreateInfo(MeshDocument&& input); + + private: + size_t& GetByteOffset(Attribute attr); + + std::vector<uint8_t> byteArray; + std::array<size_t, static_cast<size_t>(Attribute::COUNT)> byteOffsets; + uint32_t vertexCount; + IndexType indexType; + uint32_t indexCount; + }; + + std::optional<MeshDocument> LoadMeshDocument(std::string_view path); + } +} \ No newline at end of file diff --git a/src/Engine/AssetManager/MeshDocument.inl b/src/Engine/AssetManager/MeshDocument.inl new file mode 100644 index 0000000000000000000000000000000000000000..1fca96722885270217e9a0dfba44d11fe428afe8 --- /dev/null +++ b/src/Engine/AssetManager/MeshDocument.inl @@ -0,0 +1,137 @@ +#pragma once +#include "MeshDocument.hpp" + +#include "fx/gltf.h" + +namespace Engine +{ + namespace AssetManager + { + static MeshDocument::IndexType ToIndexType(fx::gltf::Accessor::ComponentType componentType) + { + switch (componentType) + { + case fx::gltf::Accessor::ComponentType::UnsignedShort: + return MeshDocument::IndexType::UInt16; + case fx::gltf::Accessor::ComponentType::UnsignedInt: + return MeshDocument::IndexType::UInt32; + default: + assert(false); + return static_cast<MeshDocument::IndexType>(-1); + } + } + + std::optional<MeshDocument> LoadMeshDocument(std::string_view path) + { + try + { + const auto gltfDocument = fx::gltf::LoadFromText(std::string(path)); + + auto& primitive = gltfDocument.meshes[0].primitives[0]; + + auto posAccIterator = primitive.attributes.find("POSITION"); + if (posAccIterator == primitive.attributes.end()) + { + std::cerr << "Error. Found no position attribute for mesh." << std::endl; + return {}; + } + auto& posAcc = gltfDocument.accessors[posAccIterator->second]; + bool validAccessor = posAcc.type == fx::gltf::Accessor::Type::Vec3 && posAcc.componentType == fx::gltf::Accessor::ComponentType::Float; + if (!validAccessor) + { + std::cerr << "Error. Position attribute of mesh is in wrong format." << std::endl; + return {}; + } + auto& posBufferView = gltfDocument.bufferViews[posAcc.bufferView]; + const auto posByteOffset = posAcc.byteOffset + posBufferView.byteOffset; + + + auto& uvAccessor = gltfDocument.accessors[primitive.attributes.find("TEXCOORD_0")->second]; + assert(uvAccessor.type == fx::gltf::Accessor::Type::Vec2 && uvAccessor.componentType == fx::gltf::Accessor::ComponentType::Float); + auto & uvBufferView = gltfDocument.bufferViews[uvAccessor.bufferView]; + + + + auto & normalAccessor = gltfDocument.accessors[primitive.attributes.find("NORMAL")->second]; + assert(normalAccessor.type == fx::gltf::Accessor::Type::Vec3 && normalAccessor.componentType == fx::gltf::Accessor::ComponentType::Float); + auto & normalBufferView = gltfDocument.bufferViews[normalAccessor.bufferView]; + + + assert(posAcc.count == uvAccessor.count && posAcc.count == normalAccessor.count); + + auto & indexAccessor = gltfDocument.accessors[primitive.indices]; + assert(indexAccessor.type == fx::gltf::Accessor::Type::Scalar); + assert(indexAccessor.componentType == fx::gltf::Accessor::ComponentType::UnsignedShort + || indexAccessor.componentType == fx::gltf::Accessor::ComponentType::UnsignedInt); + auto & indexBufferView = gltfDocument.bufferViews[indexAccessor.bufferView]; + + + MeshDocument::CreateInfo createInfo{}; + createInfo.byteArray = std::move(gltfDocument.buffers[posBufferView.buffer].data); + createInfo.vertexCount = posAcc.count; + createInfo.posByteOffset = posByteOffset; + createInfo.uvByteOffset = uvBufferView.byteOffset + uvAccessor.byteOffset; + createInfo.normalByteOffset = normalBufferView.byteOffset + normalAccessor.byteOffset; + createInfo.indexByteOffset = indexBufferView.byteOffset + indexAccessor.byteOffset; + createInfo.indexCount = indexAccessor.count; + createInfo.indexType = ToIndexType(indexAccessor.componentType); + + return { MeshDocument(std::move(createInfo)) }; + } + catch (std::exception e) + { + std::cerr << "AssetManager System Error: Could not load file. Message: " << e.what() << std::endl; + return {}; + } + } + + MeshDocument::CreateInfo AssetManager::MeshDocument::ToCreateInfo(MeshDocument&& input) + { + CreateInfo returnValue; + + returnValue.byteArray = std::move(input.byteArray); + returnValue.vertexCount = std::move(input.vertexCount); + returnValue.indexType = std::move(input.indexType); + returnValue.indexCount = std::move(input.indexCount); + + returnValue.posByteOffset = std::move(input.GetByteOffset(Attribute::Position)); + returnValue.uvByteOffset = std::move(input.GetByteOffset(Attribute::TexCoord)); + returnValue.normalByteOffset = std::move(input.GetByteOffset(Attribute::Normal)); + returnValue.tangentByteOffset = std::move(input.GetByteOffset(Attribute::Tangent)); + returnValue.indexByteOffset = std::move(input.GetByteOffset(Attribute::Index)); + + return returnValue; + } + + AssetManager::MeshDocument::MeshDocument(CreateInfo && info) : + byteArray(std::move(info.byteArray)), + indexType(info.indexType), + vertexCount(info.vertexCount), + indexCount(info.indexCount) + { + GetByteOffset(Attribute::Position) = info.posByteOffset; + GetByteOffset(Attribute::TexCoord) = info.uvByteOffset; + GetByteOffset(Attribute::Normal) = info.normalByteOffset; + GetByteOffset(Attribute::Tangent) = info.normalByteOffset; + GetByteOffset(Attribute::Index) = info.indexByteOffset; + } + + const std::vector<uint8_t>& AssetManager::MeshDocument::GetByteArray() const { return byteArray; } + + AssetManager::MeshDocument::IndexType AssetManager::MeshDocument::GetIndexType() const { return indexType; } + + const uint8_t* AssetManager::MeshDocument::GetDataPtr(Attribute type) const + { + return byteArray.data() + byteOffsets.at(size_t(type)); + } + + size_t& AssetManager::MeshDocument::GetByteOffset(Attribute type) { return byteOffsets.at(size_t(type)); } + + const size_t& AssetManager::MeshDocument::GetByteOffset(Attribute type) const { return byteOffsets.at(size_t(type)); } + + uint8_t AssetManager::MeshDocument::ToByteSize(IndexType indexType) + { + return indexType == IndexType::UInt16 ? uint8_t(2) : uint8_t(4); + } + } +} \ No newline at end of file diff --git a/src/Engine/AssetManager/TextureDocument.hpp b/src/Engine/AssetManager/TextureDocument.hpp new file mode 100644 index 0000000000000000000000000000000000000000..83403430fe7ed10f81a67dbd12573f0edb83ca49 --- /dev/null +++ b/src/Engine/AssetManager/TextureDocument.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include <array> +#include <vector> +#include <optional> + +namespace Engine +{ + namespace AssetManager + { + class TextureDocument + { + public: + enum class Format; + + private: + Format format; + std::array<uint32_t, 2> dimensions; + std::vector<uint8_t> byteArray; + }; + + enum class TextureDocument::Format + { + RGBA + }; + + std::optional<TextureDocument> LoadTextureDocument(std::string path); + } + + namespace AssMan = AssetManager; +} \ No newline at end of file diff --git a/src/Engine/AssetManager/TextureDocument.inl b/src/Engine/AssetManager/TextureDocument.inl new file mode 100644 index 0000000000000000000000000000000000000000..288748324561c24d5b99f2001a87cd17f0fdaf3f --- /dev/null +++ b/src/Engine/AssetManager/TextureDocument.inl @@ -0,0 +1,14 @@ +#pragma once + +#include "TextureDocument.hpp" + +namespace Engine +{ + namespace AssetManager + { + std::optional<TextureDocument> LoadTextureDocument(std::string path) + { + return {}; + } + } +} \ No newline at end of file diff --git a/src/Engine/AssetManager/Typedefs.hpp b/src/Engine/AssetManager/Typedefs.hpp new file mode 100644 index 0000000000000000000000000000000000000000..0e627fb85f1644802c93714bf3405898e984da27 --- /dev/null +++ b/src/Engine/AssetManager/Typedefs.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include <cstdint> + +namespace Engine +{ + namespace AssetManager + { + enum class Sprite : uint32_t; + enum class Mesh : uint32_t; + + class MeshDocument; + class TextureDocument; + } + + namespace AssMan = AssetManager; +} + +enum class Engine::AssetManager::Sprite : uint32_t +{ + None, + Default, + Test, + Circle, +#ifdef ASSETMANAGER_TEXTURE_COUNT + COUNT +#endif +}; + +enum class Engine::AssetManager::Mesh : uint32_t +{ + None, + Plane, + Cube, + SpritePlane, + Helmet, +#ifdef ASSETMANAGER_MESH_COUNT + COUNT +#endif +}; \ No newline at end of file diff --git a/src/Engine/Components/MeshRenderer.cpp b/src/Engine/Components/MeshRenderer.cpp index 627ae6a1400197690bee259dca73e00ab49f52e6..30b6cbd23cfcb00dad11ea4a5bb96a78be573ec6 100644 --- a/src/Engine/Components/MeshRenderer.cpp +++ b/src/Engine/Components/MeshRenderer.cpp @@ -17,7 +17,7 @@ namespace Engine { MeshRenderer::MeshRenderer(SceneObject& owningSceneObject) : ParentType(owningSceneObject), - mesh(Asset::Mesh::None), + mesh(AssMan::Mesh::None), positionOffset{ 0, 0, 0 }, scale{ 1, 1, 1 }, rotation() @@ -28,11 +28,11 @@ namespace Engine { } - Asset::Mesh MeshRenderer::GetMesh() const { return mesh; } + AssMan::Mesh MeshRenderer::GetMesh() const { return mesh; } - std::underlying_type_t<Asset::Mesh> MeshRenderer::GetMeshID() const { return static_cast<std::underlying_type_t<Asset::Mesh>>(GetMesh()); } + std::underlying_type_t<AssMan::Mesh> MeshRenderer::GetMeshID() const { return static_cast<std::underlying_type_t<AssMan::Mesh>>(GetMesh()); } - void MeshRenderer::SetMesh(Asset::Mesh newMesh) + void MeshRenderer::SetMesh(AssMan::Mesh newMesh) { if (GetMesh() == newMesh) return; diff --git a/src/Engine/Components/MeshRenderer.hpp b/src/Engine/Components/MeshRenderer.hpp index 18841df923246c7e83b1db353504cce7f771d74b..c920a15c92051e92c4cf8b2648242f9d0b9cff56 100644 --- a/src/Engine/Components/MeshRenderer.hpp +++ b/src/Engine/Components/MeshRenderer.hpp @@ -2,7 +2,7 @@ #include "Components.hpp" -#include "../Asset.hpp" +#include "../AssetManager/AssetManager.hpp" #include "../Enum.hpp" @@ -22,9 +22,9 @@ namespace Engine explicit MeshRenderer(SceneObject& owningObject); ~MeshRenderer(); - [[nodiscard]] Asset::Mesh GetMesh() const; - std::underlying_type_t<Asset::Mesh> GetMeshID() const; - void SetMesh(Asset::Mesh newMesh); + [[nodiscard]] AssMan::Mesh GetMesh() const; + std::underlying_type_t<AssMan::Mesh> GetMeshID() const; + void SetMesh(AssMan::Mesh newMesh); [[nodiscard]] Math::Matrix<4, 3> GetModel_Reduced(Space space) const; Math::Matrix4x4 GetModel(Space space) const; @@ -34,7 +34,7 @@ namespace Engine Math::Vector3D scale; private: - Asset::Mesh mesh; + AssMan::Mesh mesh; }; } } diff --git a/src/Engine/Components/SpriteRenderer.cpp b/src/Engine/Components/SpriteRenderer.cpp index f46ff15a45cecdebebee85b660f7ccf5277d4d24..e13eb3c6aa629a08b33cfb829c0cd3fc96f2193f 100644 --- a/src/Engine/Components/SpriteRenderer.cpp +++ b/src/Engine/Components/SpriteRenderer.cpp @@ -14,7 +14,7 @@ namespace Engine { SpriteRenderer::SpriteRenderer(SceneObject& owningObject) : ParentType(owningObject), - sprite(Asset::Sprite::None), + sprite(AssMan::Sprite::None), positionOffset{ 0, 0 }, rotation(0), scale{ 1, 1 } @@ -25,17 +25,15 @@ namespace Engine { } - void SpriteRenderer::SetSprite(Asset::Sprite newSprite) + void SpriteRenderer::SetSprite(AssMan::Sprite newSprite) { if (GetSprite() == newSprite) return; - assert(Asset::CheckValid(newSprite)); - sprite = newSprite; } - Asset::Sprite SpriteRenderer::GetSprite() const { return sprite; } + AssMan::Sprite SpriteRenderer::GetSprite() const { return sprite; } Math::Matrix<3, 2> SpriteRenderer::GetModel2D_Reduced(Space space) const { diff --git a/src/Engine/Components/SpriteRenderer.hpp b/src/Engine/Components/SpriteRenderer.hpp index 70994367f7f2f6dfea79ec033718cb5bae774190..8018258280275ccb6d300aee176324ee7c260803 100644 --- a/src/Engine/Components/SpriteRenderer.hpp +++ b/src/Engine/Components/SpriteRenderer.hpp @@ -2,7 +2,7 @@ #include "Components.hpp" -#include "../Asset.hpp" +#include "../AssetManager/AssetManager.hpp" #include "DMath/Vector/Vector.hpp" #include "DMath/Matrix/Matrix.hpp" @@ -21,8 +21,8 @@ namespace Engine explicit SpriteRenderer(SceneObject& owningObject); ~SpriteRenderer(); - void SetSprite(Asset::Sprite newTexture); - [[nodiscard]] Asset::Sprite GetSprite() const; + void SetSprite(AssMan::Sprite newTexture); + [[nodiscard]] AssMan::Sprite GetSprite() const; Math::Matrix<3, 2> GetModel2D_Reduced(Space space) const; Math::Matrix4x4 GetModel(Space space) const; @@ -32,7 +32,7 @@ namespace Engine Math::Vector2D scale; private: - Asset::Sprite sprite; + AssMan::Sprite sprite; }; } diff --git a/src/Engine/Engine.cpp b/src/Engine/Engine.cpp index 3485afaa8eaade7e4de8b876a4e5d0c3d2485006..c312ea4f654ed51ea95a4aee53b79f51bdd2d086 100644 --- a/src/Engine/Engine.cpp +++ b/src/Engine/Engine.cpp @@ -17,8 +17,6 @@ #include "Systems/RenderSystem.hpp" -#include "DMath/LinearTransform3D.hpp" - #include "Components/ScriptBase.hpp" #include <iostream> @@ -70,7 +68,7 @@ namespace Engine rendererInitInfo.surfaceDimensions = Application::GetWindowSize(); rendererInitInfo.surfaceHandle = Application::Core::GetMainWindowHandle(); - rendererInitInfo.assetLoadCreateInfo.meshLoader = &Asset::LoadMesh; + rendererInitInfo.assetLoadCreateInfo.meshLoader = &AssMan::LoadMesh; rendererInitInfo.openGLInitInfo.glSwapBuffers = &Application::Core::GL_SwapWindow; Renderer::Core::Initialize(rendererInitInfo); @@ -79,6 +77,7 @@ namespace Engine void Engine::Core::Run() { + Application::Core::Initialize(Application::API3D::OpenGL); Time::Core::Initialize(); Input::Core::Initialize(); @@ -96,14 +95,14 @@ void Engine::Core::Run() auto& sceneObject1 = scene1.NewSceneObject(); auto& mesh1 = sceneObject1.AddComponent<Components::MeshRenderer>().first.get(); - mesh1.SetMesh(Asset::Mesh::Helmet); + mesh1.SetMesh(AssMan::Mesh::Helmet); auto& meshTest = sceneObject1.AddComponent<Components::MeshRenderer>().first.get(); - meshTest.SetMesh(Asset::Mesh::Helmet); + meshTest.SetMesh(AssMan::Mesh::Helmet); meshTest.positionOffset.x = -3.f; auto& mesh2 = sceneObject1.AddComponent<Components::MeshRenderer>().first.get(); - mesh2.SetMesh(Asset::Mesh::Cube); + mesh2.SetMesh(AssMan::Mesh::Cube); mesh2.positionOffset.x = 2.f; auto& objCamera = scene1.NewSceneObject(); @@ -115,14 +114,14 @@ void Engine::Core::Run() Components::PointLight& light1 = lightObj.AddComponent<Components::PointLight>().first.get(); light1.color = { 1.f, 0.5f, 0.f }; auto& mesh3 = lightObj.AddComponent<Components::MeshRenderer>().first.get(); - mesh3.SetMesh(Asset::Mesh::Cube); + mesh3.SetMesh(AssMan::Mesh::Cube); mesh3.scale = { 0.1f, 0.1f, 0.1f }; auto& obj4 = scene1.NewSceneObject(); obj4.transform.localPosition = { 0.f, -7.5f, -10.f }; Components::PointLight& light3 = obj4.AddComponent<Components::PointLight>().first.get(); auto& mesh4 = obj4.AddComponent<Components::MeshRenderer>().first.get(); - mesh4.SetMesh(Asset::Mesh::Cube); + mesh4.SetMesh(AssMan::Mesh::Cube); mesh4.scale = { 0.1f, 0.1f, 0.1f }; diff --git a/src/Engine/Renderer/MeshDocument.hpp b/src/Engine/Renderer/MeshDocument.hpp index dc46a1db5d283748d63f4ee965f790613aaf9488..695ba4a3328bc8433dc3ad5408a9def015f21e09 100644 --- a/src/Engine/Renderer/MeshDocument.hpp +++ b/src/Engine/Renderer/MeshDocument.hpp @@ -3,6 +3,8 @@ #include <cstddef> #include <array> +#include <cassert> + namespace Engine { namespace Renderer diff --git a/src/Engine/Renderer/Renderer.hpp b/src/Engine/Renderer/Renderer.hpp index 9ccf32c6551c1038e291f9533b3725e848ad492b..2abf2052789b8a7844215cfee93d7c50ab2dab41 100644 --- a/src/Engine/Renderer/Renderer.hpp +++ b/src/Engine/Renderer/Renderer.hpp @@ -64,6 +64,8 @@ namespace Engine { using MeshLoaderPFN = std::optional<MeshDocument>(*)(size_t); MeshLoaderPFN meshLoader = nullptr; + using TextureLoaderPFN = std::optional<TextureDocument>(*)(size_t); + TextureLoaderPFN textureLoader = nullptr; }; struct Renderer::InitInfo diff --git a/src/Engine/Renderer/Typedefs.hpp b/src/Engine/Renderer/Typedefs.hpp index f2c34df31bf14a605d36ebbcc0fa9674c8dff8d0..fd71484ef7d9889a4abc5023c185edb77941b8e2 100644 --- a/src/Engine/Renderer/Typedefs.hpp +++ b/src/Engine/Renderer/Typedefs.hpp @@ -23,6 +23,7 @@ namespace Engine struct InitInfo; class MeshDocument; + class TextureDocument; enum class API;