diff --git a/src/Engine/Asset.cpp b/src/Engine/Asset.cpp index 71458652f5638e4f1aa2430e2e5ac02310b42769..a7eae7646efc45e623d607bea21b3470986689ce 100644 --- a/src/Engine/Asset.cpp +++ b/src/Engine/Asset.cpp @@ -5,6 +5,7 @@ #include <cassert> #include <map> #include <type_traits> +#include <iostream> #include "fx/gltf.h" @@ -15,8 +16,8 @@ struct AssetInfo { - std::string name; - std::string relativePath; + std::string_view name; + std::string_view relativePath; }; static const std::map<Asset::Sprite, AssetInfo> textureInfos @@ -27,12 +28,12 @@ static const std::map<Asset::Sprite, AssetInfo> textureInfos { Asset::Sprite::Circle, {"Circle", "circle.png"} }, }; -static const std::map<Asset::Mesh, AssetInfo> meshInfos +static const std::map<size_t, AssetInfo> meshInfos { - { Asset::Mesh::None, {"None", ""} }, - { Asset::Mesh::Cube, {"Cube", "Cube/Cube.gltf"} }, - { Asset::Mesh::SpritePlane, {"SpritePlane", "SpritePlane/SpritePlane.gltf"} }, - { Asset::Mesh::Helmet, {"Helmet", "Helmet/Helmet.gltf"} }, + { 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) @@ -41,118 +42,112 @@ bool Asset::CheckValid(Sprite sprite) return (0 <= static_cast<Type>(sprite) && static_cast<Type>(sprite) < static_cast<Type>(Sprite::COUNT)) || sprite == Sprite::None; } -std::string Asset::GetPath(Sprite texture) +std::string Asset::GetMeshPath(size_t i) { - assert(CheckValid(texture)); - auto iterator = textureInfos.find(texture); - assert(iterator != textureInfos.end()); - return static_cast<std::string>(textureFolderPath) + iterator->second.relativePath; + auto iterator = meshInfos.find(i); + if (iterator == meshInfos.end()) + return {}; + else + return std::string(meshFolderPath) + std::string(iterator->second.relativePath); } -std::string Asset::GetName(Sprite texture) +std::optional<Asset::MeshDocument> Asset::LoadMeshDocument(std::string_view path) { - assert(CheckValid(texture)); - auto iterator = textureInfos.find(texture); - assert(iterator != textureInfos.end()); - return iterator->second.name; -} - -bool Asset::CheckValid(Mesh mesh) -{ - using Type = std::underlying_type_t<Mesh>; - return (0 <= static_cast<Type>(mesh) && static_cast<Type>(mesh) < static_cast<Type>(Mesh::COUNT)) || mesh == Mesh::None; -} - -std::string Asset::GetPath(Mesh mesh) -{ - assert(CheckValid(mesh)); - auto iterator = meshInfos.find(mesh); - assert(iterator != meshInfos.end()); - return static_cast<std::string>(meshFolderPath) + iterator->second.relativePath; -} - -std::string Asset::GetName(Mesh mesh) -{ - assert(CheckValid(mesh)); - auto iterator = meshInfos.find(mesh); - assert(iterator != meshInfos.end()); - return iterator->second.name; -} - -Asset::MeshDocument Asset::LoadMeshDocument(Mesh mesh) -{ - const auto& path = GetPath(mesh); - return LoadMeshDocument(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::MeshDocument Asset::LoadMeshDocument(const std::string &path) +Asset::TextureDocument Asset::LoadTextureDocument(Sprite texture) { - MeshDocument::CreateInfo createInfo{}; - - const auto gltfDocument = fx::gltf::LoadFromText(path); - auto& primitive = gltfDocument.meshes[0].primitives[0]; - - auto& posAccessor = gltfDocument.accessors[primitive.attributes.find("POSITION")->second]; - assert(posAccessor.type == fx::gltf::Accessor::Type::Vec3 && posAccessor.componentType == fx::gltf::Accessor::ComponentType::Float); - auto& posBufferView = gltfDocument.bufferViews[posAccessor.bufferView]; - createInfo.posData.byteOffset = posBufferView.byteOffset + posAccessor.byteOffset; - createInfo.posData.byteLength = posAccessor.count * (sizeof(float) * 3); - - 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]; - createInfo.uvData.byteOffset = uvBufferView.byteOffset + uvAccessor.byteOffset; - createInfo.uvData.byteLength = uvAccessor.count * (sizeof(float) * 2); - - 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]; - createInfo.normalData.byteOffset = normalBufferView.byteOffset + normalAccessor.byteOffset; - createInfo.normalData.byteLength = normalAccessor.count * (sizeof(float) * 3); - - assert(posAccessor.count == uvAccessor.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]; - createInfo.indexData.byteOffset = indexBufferView.byteOffset + indexAccessor.byteOffset; - createInfo.indexData.byteLength = indexBufferView.byteLength; - createInfo.indexType = indexAccessor.componentType == fx::gltf::Accessor::ComponentType::UnsignedShort ? MeshDocument::IndexType::Uint16 : MeshDocument::IndexType::Uint32; - - createInfo.byteArray = std::move(gltfDocument.buffers[posBufferView.buffer].data); + TextureDocument::CreateInfo createInfo{}; - return MeshDocument(std::move(createInfo)); + return TextureDocument(std::move(createInfo)); } -Asset::TextureDocument Asset::LoadTextureDocument(Sprite texture) +std::optional<Engine::Renderer::MeshDocument> Asset::LoadMesh(size_t i) { - TextureDocument::CreateInfo createInfo{}; + auto path = GetMeshPath(i); + if (path == "") + return {}; - // Grab pixels as char array from image. - int32_t x = 0; - int32_t y = 0; - int32_t channelCount = 0; - constexpr int32_t desiredChannelCount = 4; - auto pixels = stbi_load(Asset::GetPath(texture).c_str(), &x, &y, &channelCount, desiredChannelCount); - assert(pixels); - // Weird STBI API stuff - if constexpr (desiredChannelCount != 0) - channelCount = desiredChannelCount; + auto assetMeshDocOpt = LoadMeshDocument(path); + if (assetMeshDocOpt.has_value() == false) + return {}; - createInfo.byteArray = pixels; - createInfo.channelCount = static_cast<uint8_t>(channelCount); + auto oldInfo = MeshDocument::ToCreateInfo(std::move(assetMeshDocOpt.value())); - using ValueType = decltype(createInfo.dimensions)::ValueType; - createInfo.dimensions = { static_cast<ValueType>(x), static_cast<ValueType>(y) }; + 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; - return TextureDocument(std::move(createInfo)); -} + 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); -Engine::Renderer::MeshDocument Asset::LoadMesh(size_t i) -{ - return Engine::Renderer::MeshDocument(); + return Renderer::MeshDocument(std::move(newInfo)); } static Asset::MeshDocument::IndexType ToIndexType(fx::gltf::Accessor::ComponentType componentType) @@ -160,56 +155,61 @@ static Asset::MeshDocument::IndexType ToIndexType(fx::gltf::Accessor::ComponentT switch (componentType) { case fx::gltf::Accessor::ComponentType::UnsignedShort: - return Asset::MeshDocument::IndexType::Uint16; + return Asset::MeshDocument::IndexType::UInt16; case fx::gltf::Accessor::ComponentType::UnsignedInt: - return Asset::MeshDocument::IndexType::Uint32; + return Asset::MeshDocument::IndexType::UInt32; default: return static_cast<Asset::MeshDocument::IndexType>(-1); } } -Asset::MeshDocument::MeshDocument(CreateInfo&& info) : - byteArray(std::move(info.byteArray)) +Asset::MeshDocument::CreateInfo Asset::MeshDocument::ToCreateInfo(MeshDocument&& input) { - data[static_cast<size_t>(Attribute::Position)] = info.posData; - data[static_cast<size_t>(Attribute::TexCoord)] = info.uvData; - data[static_cast<size_t>(Attribute::Normal)] = info.normalData; - data[static_cast<size_t>(Attribute::Index)] = info.indexData; - indexType = info.indexType; -} - -const std::vector<uint8_t>& Asset::MeshDocument::GetByteArray() const { return byteArray; } + CreateInfo returnValue; -size_t Asset::MeshDocument::GetTotalByteLength() const -{ - size_t totalLength = 0; - for (const auto& item : data) - totalLength += item.byteLength; - return totalLength; -} + returnValue.byteArray = std::move(input.byteArray); + returnValue.vertexCount = std::move(input.vertexCount); + returnValue.indexType = std::move(input.indexType); + returnValue.indexCount = std::move(input.indexCount); -Asset::MeshDocument::IndexType Asset::MeshDocument::GetIndexType() const { return indexType; } + 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)); -uint32_t Asset::MeshDocument::GetIndexCount() const -{ - return static_cast<uint32_t>(data[static_cast<size_t>(Attribute::Index)].byteLength / IndexTypeToByteSize(indexType)); + return returnValue; } -uint32_t Asset::MeshDocument::GetVertexCount() const +Asset::MeshDocument::MeshDocument(CreateInfo&& info) : + byteArray(std::move(info.byteArray)), + indexType(info.indexType), + vertexCount(info.vertexCount), + indexCount(info.indexCount) { - return static_cast<uint32_t>(data[static_cast<size_t>(Attribute::Position)].byteLength / sizeof(PositionType)); + 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() + data[static_cast<size_t>(type)].byteOffset; + return byteArray.data() + byteOffsets.at(size_t(type)); } -Asset::MeshDocument::Data Asset::MeshDocument::GetData(Attribute type) const { return data[static_cast<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::IndexTypeToByteSize(IndexType indexType) +uint8_t Asset::MeshDocument::ToByteSize(IndexType indexType) { - return indexType == IndexType::Uint16 ? uint8_t(2) : uint8_t(4); + return indexType == IndexType::UInt16 ? uint8_t(2) : uint8_t(4); } Asset::TextureDocument::TextureDocument(CreateInfo&& right) : diff --git a/src/Engine/Asset.hpp b/src/Engine/Asset.hpp index b350dbb76028bba95a15e19ac752864a316f052f..841eb6b34b133ff7314dcce7d94c0b1097d46fa4 100644 --- a/src/Engine/Asset.hpp +++ b/src/Engine/Asset.hpp @@ -7,6 +7,7 @@ #include <cstdint> #include <vector> #include <array> +#include <optional> #include "Renderer/MeshDocument.hpp" @@ -20,28 +21,29 @@ namespace Asset enum class Sprite : uint32_t; bool CheckValid(Sprite texture); - std::string GetPath(Sprite texture); - std::string GetName(Sprite texture); enum class Mesh : uint32_t; - bool CheckValid(Mesh mesh); - std::string GetPath(Mesh mesh); - std::string GetName(Mesh mesh); + std::string GetMeshPath(size_t i); MeshDocument LoadMeshDocument(Mesh mesh); - MeshDocument LoadMeshDocument(const std::string& path); + std::optional<MeshDocument> LoadMeshDocument(std::string_view path); TextureDocument LoadTextureDocument(Sprite texture); - Engine::Renderer::MeshDocument LoadMesh(size_t i); + 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 + UInt16, + UInt32 }; enum class Attribute @@ -49,46 +51,51 @@ public: Position, TexCoord, Normal, + Tangent, Index, COUNT }; - struct Data - { - size_t byteOffset; - size_t byteLength; - }; - struct CreateInfo { std::vector<uint8_t> byteArray; - Data posData; - Data uvData; - Data normalData; - Data indexData; + size_t posByteOffset; + size_t uvByteOffset; + size_t normalByteOffset; + size_t tangentByteOffset; + size_t indexByteOffset; IndexType indexType; + uint32_t vertexCount; + uint32_t indexCount; }; - using PositionType = std::array<float, 3>; - using UVType = std::array<float, 2>; - using NormalType = std::array<float, 3>; - MeshDocument(CreateInfo&& info); - MeshDocument(const MeshDocument&) = delete; + MeshDocument(MeshDocument&&) = default; + MeshDocument(const MeshDocument&) = default; const std::vector<uint8_t>& GetByteArray() const; - size_t GetTotalByteLength() 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; - uint32_t GetVertexCount() const; - const uint8_t* GetDataPtr(Attribute type) const; - Data GetData(Attribute type) 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<Data, static_cast<size_t>(Attribute::COUNT)> data; + std::array<size_t, static_cast<size_t>(Attribute::COUNT)> byteOffsets; + uint32_t vertexCount; IndexType indexType; - - static uint8_t IndexTypeToByteSize(IndexType indexType); + uint32_t indexCount; }; class Asset::TextureDocument @@ -102,7 +109,7 @@ public: }; TextureDocument(CreateInfo&&); - TextureDocument(TextureDocument&& right); + TextureDocument(TextureDocument&&); TextureDocument(const TextureDocument&) = delete; ~TextureDocument(); diff --git a/src/Engine/Components/MeshRenderer.cpp b/src/Engine/Components/MeshRenderer.cpp index f1136dc0c7ef2c918d9e05cb693c3f1b1eeacce7..627ae6a1400197690bee259dca73e00ab49f52e6 100644 --- a/src/Engine/Components/MeshRenderer.cpp +++ b/src/Engine/Components/MeshRenderer.cpp @@ -37,8 +37,6 @@ namespace Engine if (GetMesh() == newMesh) return; - assert(Asset::CheckValid(newMesh)); - mesh = newMesh; } diff --git a/src/Engine/Renderer/MeshDocument.hpp b/src/Engine/Renderer/MeshDocument.hpp index 501fd3e5eca3b2755afd778dde962356e229b40c..70e954d1901cb63eb0e3cd205407c0bbe972f7c6 100644 --- a/src/Engine/Renderer/MeshDocument.hpp +++ b/src/Engine/Renderer/MeshDocument.hpp @@ -21,14 +21,6 @@ namespace Engine UInt32 }; - static uint8_t ToByteSize(IndexType type); - - struct DataInfo - { - size_t byteOffset; - size_t byteLength; - }; - enum class Attribute { Position, @@ -42,38 +34,96 @@ namespace Engine struct CreateInfo { std::vector<uint8_t> byteArray; - DataInfo posData; - DataInfo uvData; - DataInfo normalData; - DataInfo tangentData; - DataInfo indexData; + uint32_t vertexCount; + size_t posByteOffset; + size_t uvByteOffset; + size_t normalByteOffset; + size_t tangentByteOffset; + size_t indexByteOffset; IndexType indexType; + uint32_t indexCount; }; MeshDocument(CreateInfo&& createInfo); - MeshDocument() = default; + MeshDocument(MeshDocument&&) = default; + MeshDocument(const MeshDocument&) = default; - DataInfo GetData(Attribute attr) const; + 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 GetTotalByteLength() const; + size_t GetTotalSizeRequired() const; + + static uint8_t ToByteSize(IndexType type); + static CreateInfo ToCreateInfo(MeshDocument&& input); + + private: + size_t& GetByteOffset(Attribute attr); IndexType indexType; + uint32_t indexCount; + uint32_t vertexCount; std::vector<uint8_t> byteArray; - std::array<DataInfo, static_cast<size_t>(Attribute::COUNT)> data; + std::array<size_t, static_cast<size_t>(Attribute::COUNT)> data; }; - inline MeshDocument::DataInfo MeshDocument::GetData(Attribute attr) const + inline MeshDocument::MeshDocument(CreateInfo&& createInfo) : + byteArray(std::move(createInfo.byteArray)), + indexType(std::move(createInfo.indexType)), + indexCount(std::move(createInfo.indexCount)), + vertexCount(std::move(createInfo.vertexCount)) + { + GetByteOffset(Attribute::Position) = std::move(createInfo.posByteOffset); + GetByteOffset(Attribute::TexCoord) = std::move(createInfo.uvByteOffset); + GetByteOffset(Attribute::Normal) = std::move(createInfo.normalByteOffset); + GetByteOffset(Attribute::Tangent) = std::move(createInfo.tangentByteOffset); + GetByteOffset(Attribute::Index) = std::move(createInfo.indexByteOffset); + } + + inline const size_t& MeshDocument::GetByteOffset(Attribute attr) const + { + return data.at(size_t(attr)); + } + + inline size_t MeshDocument::GetByteLength(Attribute attr) const + { + switch (attr) + { + case Attribute::Position: + return GetVertexCount() * sizeof(PositionType); + case Attribute::TexCoord: + return GetVertexCount() * sizeof(UVType); + case Attribute::Normal: + return GetVertexCount() * sizeof(NormalType); + case Attribute::Tangent: + return GetVertexCount() * sizeof(TangentType); + case Attribute::Index: + return GetIndexCount() * ToByteSize(GetIndexType()); + default: + assert(false); + return 0; + } + } + + inline size_t& MeshDocument::GetByteOffset(Attribute attr) { return data.at(static_cast<size_t>(attr)); } inline const uint8_t* MeshDocument::GetDataPtr(Attribute attr) const { - return byteArray.data() + GetData(attr).byteOffset; + return byteArray.data() + GetByteOffset(attr); + } + + inline uint32_t MeshDocument::GetVertexCount() const + { + return vertexCount; } inline MeshDocument::IndexType MeshDocument::GetIndexType() const @@ -83,10 +133,10 @@ namespace Engine inline uint32_t MeshDocument::GetIndexCount() const { - return uint32_t( GetData( Attribute::Index).byteLength / ToByteSize(GetIndexType() ) ); + return indexCount; } - inline size_t MeshDocument::GetTotalByteLength() const + inline size_t MeshDocument::GetTotalSizeRequired() const { return data.size(); } @@ -95,5 +145,21 @@ namespace Engine { return type == IndexType::UInt16 ? uint8_t(2) : uint8_t(4); } + + inline MeshDocument::CreateInfo 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)); + } } } \ No newline at end of file diff --git a/src/Engine/Renderer/OpenGL.cpp b/src/Engine/Renderer/OpenGL.cpp index 9459f736a7b7985b01fa466f11a4f9d76aa81830..a6a7d0e81cce6eacd9b2e1b262f056a68a241364 100644 --- a/src/Engine/Renderer/OpenGL.cpp +++ b/src/Engine/Renderer/OpenGL.cpp @@ -513,7 +513,11 @@ namespace Engine std::optional<Renderer::OpenGL::VBO> Renderer::OpenGL::VBOFromPath(size_t id) { - const auto meshDocument = Core::GetData().assetLoadData.meshLoader(id); + const auto meshDocumentOpt = Core::GetData().assetLoadData.meshLoader(id); + + assert(meshDocumentOpt.has_value()); + + const auto& meshDocument = meshDocumentOpt.value(); VBO vbo; @@ -523,25 +527,25 @@ namespace Engine glGenVertexArrays(1, &vbo.vertexArrayObject); glBindVertexArray(vbo.vertexArrayObject); - glGenBuffers(static_cast<GLint>(vbo.attributeBuffers.size()), vbo.attributeBuffers.data()); + glGenBuffers(GLint(vbo.attributeBuffers.size()), vbo.attributeBuffers.data()); - glBindBuffer(GL_ARRAY_BUFFER, vbo.attributeBuffers[static_cast<size_t>(VBO::Attribute::Position)]); - glBufferData(GL_ARRAY_BUFFER, meshDocument.GetData(MeshDocument::Attribute::Position).byteLength, meshDocument.GetDataPtr(MeshDocument::Attribute::Position), GL_STATIC_DRAW); - glEnableVertexAttribArray(static_cast<size_t>(VBO::Attribute::Position)); + glBindBuffer(GL_ARRAY_BUFFER, vbo.attributeBuffers[size_t(VBO::Attribute::Position)]); + glBufferData(GL_ARRAY_BUFFER, meshDocument.GetByteLength(MeshDocument::Attribute::Position), meshDocument.GetDataPtr(MeshDocument::Attribute::Position), GL_STATIC_DRAW); + glEnableVertexAttribArray(size_t(VBO::Attribute::Position)); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); - glBindBuffer(GL_ARRAY_BUFFER, vbo.attributeBuffers[static_cast<size_t>(VBO::Attribute::TexCoord)]); - glBufferData(GL_ARRAY_BUFFER, meshDocument.GetData(MeshDocument::Attribute::TexCoord).byteLength, meshDocument.GetDataPtr(MeshDocument::Attribute::TexCoord), GL_STATIC_DRAW); - glEnableVertexAttribArray(static_cast<size_t>(VBO::Attribute::TexCoord)); + glBindBuffer(GL_ARRAY_BUFFER, vbo.attributeBuffers[size_t(VBO::Attribute::TexCoord)]); + glBufferData(GL_ARRAY_BUFFER, meshDocument.GetByteLength(MeshDocument::Attribute::TexCoord), meshDocument.GetDataPtr(MeshDocument::Attribute::TexCoord), GL_STATIC_DRAW); + glEnableVertexAttribArray(size_t(VBO::Attribute::TexCoord)); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0); - glBindBuffer(GL_ARRAY_BUFFER, vbo.attributeBuffers[static_cast<size_t>(VBO::Attribute::Normal)]); - glBufferData(GL_ARRAY_BUFFER, meshDocument.GetData(MeshDocument::Attribute::Normal).byteLength, meshDocument.GetDataPtr(MeshDocument::Attribute::Normal), GL_STATIC_DRAW); - glEnableVertexAttribArray(static_cast<size_t>(VBO::Attribute::Normal)); + glBindBuffer(GL_ARRAY_BUFFER, vbo.attributeBuffers[size_t(VBO::Attribute::Normal)]); + glBufferData(GL_ARRAY_BUFFER, meshDocument.GetByteLength(MeshDocument::Attribute::Normal), meshDocument.GetDataPtr(MeshDocument::Attribute::Normal), GL_STATIC_DRAW); + glEnableVertexAttribArray(size_t(VBO::Attribute::Normal)); glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.attributeBuffers[static_cast<size_t>(VBO::Attribute::Index)]); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, meshDocument.GetData(MeshDocument::Attribute::Index).byteLength, meshDocument.GetDataPtr(MeshDocument::Attribute::Index), GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.attributeBuffers[size_t(VBO::Attribute::Index)]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, meshDocument.GetByteLength(MeshDocument::Attribute::Index), meshDocument.GetDataPtr(MeshDocument::Attribute::Index), GL_STATIC_DRAW); return vbo; } diff --git a/src/Engine/Renderer/Renderer.hpp b/src/Engine/Renderer/Renderer.hpp index a7242b18ca8b3c5c6f8bbbc03d3d4803a8999d4b..9ccf32c6551c1038e291f9533b3725e848ad492b 100644 --- a/src/Engine/Renderer/Renderer.hpp +++ b/src/Engine/Renderer/Renderer.hpp @@ -62,7 +62,7 @@ namespace Engine struct Renderer::AssetLoadCreateInfo { - using MeshLoaderPFN = MeshDocument(*)(size_t); + using MeshLoaderPFN = std::optional<MeshDocument>(*)(size_t); MeshLoaderPFN meshLoader = nullptr; }; diff --git a/src/Engine/Renderer/TextureDocument.hpp b/src/Engine/Renderer/TextureDocument.hpp new file mode 100644 index 0000000000000000000000000000000000000000..fce68b392c6d828a5cf9cce8edb7f190287d1f8c --- /dev/null +++ b/src/Engine/Renderer/TextureDocument.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include <array> +#include <vector> +#include <cstddef> + +namespace Engine +{ + namespace Renderer + { + class TextureDocument + { + public: + enum class Format; + + private: + Format format; + std::array<uint32_t, 2> dimensions; + std::array<uint8_t> byteArray; + }; + + enum class TextureDocument::Format + { + RGBA + }; + } +} \ No newline at end of file