diff --git a/openVulkanoCpp/ExampleApps/CubesExampleApp.cpp b/openVulkanoCpp/ExampleApps/CubesExampleApp.cpp index c3f169a..68faa63 100644 --- a/openVulkanoCpp/ExampleApps/CubesExampleApp.cpp +++ b/openVulkanoCpp/ExampleApps/CubesExampleApp.cpp @@ -7,6 +7,7 @@ #include "CubesExampleApp.hpp" #include "Scene/Scene.hpp" #include "Scene/Shader.hpp" +#include "Scene/Vertex.hpp" #include "Input/InputManager.hpp" #include "Host/GraphicsAppManager.hpp" #include "Math/Math.hpp" @@ -130,4 +131,4 @@ std::unique_ptr CubesExampleApp::Create() } #pragma clang diagnostic pop -#pragma clang diagnostic pop \ No newline at end of file +#pragma clang diagnostic pop diff --git a/openVulkanoCpp/Scene/Geometry.cpp b/openVulkanoCpp/Scene/Geometry.cpp new file mode 100644 index 0000000..df35eb6 --- /dev/null +++ b/openVulkanoCpp/Scene/Geometry.cpp @@ -0,0 +1,177 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include "Geometry.hpp" +#include "Vertex.hpp" +#include "Base/Utils.hpp" +#include "Base/Logger.hpp" +#if __has_include("assimp/Importer.hpp") +#include +#include +#include +#include +#define ASSIMP_AVAILABLE +#endif +#include + +namespace openVulkanoCpp::Scene +{ + void Geometry::Init(uint32_t vertexCount, uint32_t indexCount) + { + if (this->vertexCount || this->indexCount) throw std::runtime_error("Geometry is already initialized."); + this->vertexCount = vertexCount; + this->indexCount = indexCount; + indexType = (vertexCount > UINT16_MAX) ? VertexIndexType::UINT32 : VertexIndexType::UINT16; + vertices = new Vertex[vertexCount]; + indices = malloc(static_cast(Utils::EnumAsInt(indexType)) * indexCount); + renderGeo = nullptr; + } + + void Geometry::InitFromFile(const std::string& file) + { +#ifdef ASSIMP_AVAILABLE + Assimp::Importer importer; + + const uint32_t flags = aiProcess_CalcTangentSpace | aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_GenNormals | + aiProcess_ImproveCacheLocality | aiProcess_RemoveRedundantMaterials | aiProcess_GenUVCoords | aiProcess_TransformUVCoords | + aiProcess_ConvertToLeftHanded | aiProcess_PreTransformVertices | aiProcess_OptimizeGraph; + + const aiScene* scene = importer.ReadFile(file, flags); + if (!scene) throw std::runtime_error("Failed to load file \"" + file + "\" Error: " + importer.GetErrorString()); + if (!scene->HasMeshes()) throw std::runtime_error("File \"" + file + "\" does not have any meshes"); + if (scene->mNumMeshes > 1) Logger::DATA->warn("File {0} contains more than one mesh. Only first one will be loaded", file); + Init(scene->mMeshes[0]); + importer.FreeScene(); +#else + throw std::runtime_error("ASSIMP not available!"); +#endif + } + + void Geometry::Init(aiMesh* mesh) + { +#ifdef ASSIMP_AVAILABLE + aabb.Init(); + Init(mesh->mNumVertices, mesh->mNumFaces * 3); // Reserve the space for the data + for (unsigned int i = 0; i < mesh->mNumVertices; i++) + { + vertices[i].Set(mesh->mVertices[i]); + if (mesh->HasNormals()) vertices[i].SetNormal(mesh->mNormals[i]); + if (mesh->HasTangentsAndBitangents()) + { + vertices[i].SetTangentAndBiTangent(mesh->mTangents[i], mesh->mBitangents[i]); + } + if (mesh->HasTextureCoords(0)) vertices[i].SetTextureCoordinates(mesh->mTextureCoords[0][i]); + if (mesh->HasVertexColors(0)) vertices[i].SetColor(mesh->mColors[0][i]); + aabb.Grow(vertices[i].position); + } + + for (unsigned int i = 0; i < mesh->mNumFaces; i++) + { + const aiFace face = mesh->mFaces[i]; + if (face.mNumIndices != 3) throw std::runtime_error("Mesh is not a triangle mesh!"); + for (unsigned int j = 0; j < face.mNumIndices; j++) + { + if (indexType == VertexIndexType::UINT16) + { + static_cast(indices)[i * face.mNumIndices + j] = static_cast(face.mIndices[j]); + } + else + { + static_cast(indices)[i * face.mNumIndices + j] = face.mIndices[j]; + } + } + } + + //TODO load bones + //TODO load materials +#else + throw std::runtime_error("ASSIMP not available!"); +#endif + } + + void Geometry::InitCube(float x, float y, float z, const Math::Vector4f& color) + { + Init(24, 36); + SetIndices(new uint32_t[indexCount]{ + 0, 1, 2, 0, 2, 3, // front face index data + 4, 5, 6, 4, 6, 7, // back face index data + 8, 9, 10, 8, 10, 11, // top face index data + 12, 13, 14, 12, 14, 15, // bottom face index data + 16, 17, 18, 16, 18, 19, // left face index data + 20, 21, 22, 20, 22, 23 // right face index data + }, indexCount); + x *= 0.5f; y *= 0.5f; z *= 0.5f; + uint32_t i = 0; + // front face vertex data + vertices[i++].Set(-x, +y, -z, +0, +0, -1, +0, +0); + vertices[i++].Set(-x, -y, -z, +0, +0, -1, +0, +1); + vertices[i++].Set(+x, -y, -z, +0, +0, -1, +1, +1); + vertices[i++].Set(+x, +y, -z, +0, +0, -1, +1, +0); + // back face vertex data + vertices[i++].Set(-x, +y, +z, +0, +0, +1, +1, +0); + vertices[i++].Set(+x, +y, +z, +0, +0, +1, +0, +0); + vertices[i++].Set(+x, -y, +z, +0, +0, +1, +0, +1); + vertices[i++].Set(-x, -y, +z, +0, +0, +1, +1, +1); + // top face vertex data + vertices[i++].Set(-x, -y, -z, +0, +1, +0, +0, +0); + vertices[i++].Set(-x, -y, +z, +0, +1, +0, +0, +1); + vertices[i++].Set(+x, -y, +z, +0, +1, +0, +1, +1); + vertices[i++].Set(+x, -y, -z, +0, +1, +0, +1, +0); + // bottom face vertex data + vertices[i++].Set(-x, +y, -z, +0, -1, +0, +1, +0); + vertices[i++].Set(+x, +y, -z, +0, -1, +0, +0, +0); + vertices[i++].Set(+x, +y, +z, +0, -1, +0, +0, +1); + vertices[i++].Set(-x, +y, +z, +0, -1, +0, +1, +1); + // Fill in the left face vertex data + vertices[i++].Set(-x, +y, +z, -1, +0, +0, +0, +0); + vertices[i++].Set(-x, -y, +z, -1, +0, +0, +0, +1); + vertices[i++].Set(-x, -y, -z, -1, +0, +0, +1, +1); + vertices[i++].Set(-x, +y, -z, -1, +0, +0, +1, +0); + // Fill in the right face vertex data + vertices[i++].Set(+x, +y, -z, +1, +0, +0, +0, +0); + vertices[i++].Set(+x, -y, -z, +1, +0, +0, +0, +1); + vertices[i++].Set(+x, -y, +z, +1, +0, +0, +1, +1); + vertices[i].Set(+x, +y, +z, +1, +0, +0, +1, +0); + + for(i = 0; i < vertexCount; i++) + { + vertices[i].color = color; + } + } + + void Geometry::SetIndices(const uint32_t* data, uint32_t size, uint32_t offset) const + { + size += offset; + for(; offset < size; offset++) + { + if (indexType == VertexIndexType::UINT16) + { + static_cast(indices)[offset] = static_cast(data[offset]); + } + else + { + static_cast(indices)[offset] = data[offset]; + } + } + } + + void Geometry::Close() + { + vertexCount = 0; + indexCount = 0; + Free(); + renderGeo->Close(); + renderGeo = nullptr; + } + + void Geometry::Free() + { + delete[] vertices; + free(indices); + vertices = nullptr; + indices = nullptr; + } +} diff --git a/openVulkanoCpp/Scene/Geometry.hpp b/openVulkanoCpp/Scene/Geometry.hpp index cb44411..b1ed01f 100644 --- a/openVulkanoCpp/Scene/Geometry.hpp +++ b/openVulkanoCpp/Scene/Geometry.hpp @@ -1,17 +1,21 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + #pragma once -#include -#include -#include -#include -#include -#include "Vertex.hpp" -#include "Base/Logger.hpp" -#include "Base/Utils.hpp" + #include "Base/ICloseable.hpp" #include "AABB.hpp" +#include + +class aiMesh; namespace openVulkanoCpp { + struct Vertex; + namespace Scene { enum class VertexIndexType @@ -35,7 +39,7 @@ namespace openVulkanoCpp uint32_t GetIndexCount() const { return indexCount; } uint32_t GetVertexCount() const { return vertexCount; } - static Geometry* LoadFromFile(const std::string file) + static Geometry* LoadFromFile(const std::string& file) { Geometry* mesh = new Geometry(); mesh->InitFromFile(file); @@ -49,158 +53,24 @@ namespace openVulkanoCpp if (vertices) Geometry::Close(); } - void InitFromFile(const std::string file) - { - Assimp::Importer importer; - - const uint32_t flags = aiProcess_CalcTangentSpace | aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_GenNormals | - aiProcess_ImproveCacheLocality | aiProcess_RemoveRedundantMaterials | aiProcess_GenUVCoords | aiProcess_TransformUVCoords | - aiProcess_ConvertToLeftHanded | aiProcess_PreTransformVertices | aiProcess_OptimizeGraph; - - const aiScene* scene = importer.ReadFile(file, flags); - if (!scene) throw std::runtime_error("Failed to load file \"" + file + "\" Error: " + importer.GetErrorString()); - if (!scene->HasMeshes()) throw std::runtime_error("File \"" + file + "\" does not have any meshes"); - if (scene->mNumMeshes > 1) Logger::DATA->warn("File {0} contains more than one mesh. Only first one will be loaded", file); - Init(scene->mMeshes[0]); - importer.FreeScene(); - } + void InitFromFile(const std::string& file); /** * \brief Creates the arrays for the vertices and indices. They will not be filled! * \param vertexCount The amount of vertices that will be used * \param indexCount The amount of indices that will be used */ - void Init(uint32_t vertexCount, uint32_t indexCount) - { - if (this->vertexCount || this->indexCount) throw std::runtime_error("Geometry is already initialized."); - this->vertexCount = vertexCount; - this->indexCount = indexCount; - indexType = (vertexCount > UINT16_MAX) ? VertexIndexType::UINT32 : VertexIndexType::UINT16; - vertices = new Vertex[vertexCount]; - indices = malloc(static_cast(Utils::EnumAsInt(indexType)) * indexCount); - renderGeo = nullptr; - } + void Init(uint32_t vertexCount, uint32_t indexCount); - void Init(aiMesh* mesh) - { - aabb.Init(); - Init(mesh->mNumVertices, mesh->mNumFaces * 3); // Reserve the space for the data - for (unsigned int i = 0; i < mesh->mNumVertices; i++) - { - vertices[i].Set(mesh->mVertices[i]); - if (mesh->HasNormals()) vertices[i].SetNormal(mesh->mNormals[i]); - if (mesh->HasTangentsAndBitangents()) - { - vertices[i].SetTangentAndBiTangent(mesh->mTangents[i], mesh->mBitangents[i]); - } - if (mesh->HasTextureCoords(0)) vertices[i].SetTextureCoordinates(mesh->mTextureCoords[0][i]); - if (mesh->HasVertexColors(0)) vertices[i].SetColor(mesh->mColors[0][i]); - aabb.Grow(vertices[i].position); - } - - for (unsigned int i = 0; i < mesh->mNumFaces; i++) - { - const aiFace face = mesh->mFaces[i]; - if (face.mNumIndices != 3) throw std::runtime_error("Mesh is not a triangle mesh!"); - for (unsigned int j = 0; j < face.mNumIndices; j++) - { - if (indexType == VertexIndexType::UINT16) - { - static_cast(indices)[i * face.mNumIndices + j] = static_cast(face.mIndices[j]); - } - else - { - static_cast(indices)[i * face.mNumIndices + j] = face.mIndices[j]; - } - } - } + void Init(aiMesh* mesh); - //TODO load bones - //TODO load materials - } + void InitCube(float x = 1, float y = 1, float z = 1, const Math::Vector4f& color = Math::Vector4f(1)); - void InitCube(float x = 1, float y = 1, float z = 1, Math::Vector4f color = Math::Vector4f(1)) - { - Init(24, 36); - SetIndices(new uint32_t[indexCount]{ - 0, 1, 2, 0, 2, 3, // front face index data - 4, 5, 6, 4, 6, 7, // back face index data - 8, 9, 10, 8, 10, 11, // top face index data - 12, 13, 14, 12, 14, 15, // bottom face index data - 16, 17, 18, 16, 18, 19, // left face index data - 20, 21, 22, 20, 22, 23 // right face index data - }, indexCount); - x *= 0.5f; y *= 0.5f; z *= 0.5f; - uint32_t i = 0; - // front face vertex data - vertices[i++].Set(-x, +y, -z, +0, +0, -1, +0, +0); - vertices[i++].Set(-x, -y, -z, +0, +0, -1, +0, +1); - vertices[i++].Set(+x, -y, -z, +0, +0, -1, +1, +1); - vertices[i++].Set(+x, +y, -z, +0, +0, -1, +1, +0); - // back face vertex data - vertices[i++].Set(-x, +y, +z, +0, +0, +1, +1, +0); - vertices[i++].Set(+x, +y, +z, +0, +0, +1, +0, +0); - vertices[i++].Set(+x, -y, +z, +0, +0, +1, +0, +1); - vertices[i++].Set(-x, -y, +z, +0, +0, +1, +1, +1); - // top face vertex data - vertices[i++].Set(-x, -y, -z, +0, +1, +0, +0, +0); - vertices[i++].Set(-x, -y, +z, +0, +1, +0, +0, +1); - vertices[i++].Set(+x, -y, +z, +0, +1, +0, +1, +1); - vertices[i++].Set(+x, -y, -z, +0, +1, +0, +1, +0); - // bottom face vertex data - vertices[i++].Set(-x, +y, -z, +0, -1, +0, +1, +0); - vertices[i++].Set(+x, +y, -z, +0, -1, +0, +0, +0); - vertices[i++].Set(+x, +y, +z, +0, -1, +0, +0, +1); - vertices[i++].Set(-x, +y, +z, +0, -1, +0, +1, +1); - // Fill in the left face vertex data - vertices[i++].Set(-x, +y, +z, -1, +0, +0, +0, +0); - vertices[i++].Set(-x, -y, +z, -1, +0, +0, +0, +1); - vertices[i++].Set(-x, -y, -z, -1, +0, +0, +1, +1); - vertices[i++].Set(-x, +y, -z, -1, +0, +0, +1, +0); - // Fill in the right face vertex data - vertices[i++].Set(+x, +y, -z, +1, +0, +0, +0, +0); - vertices[i++].Set(+x, -y, -z, +1, +0, +0, +0, +1); - vertices[i++].Set(+x, -y, +z, +1, +0, +0, +1, +1); - vertices[i].Set(+x, +y, +z, +1, +0, +0, +1, +0); + void SetIndices(const uint32_t* data, uint32_t size, uint32_t offset = 0) const; - for(i = 0; i < vertexCount; i++) - { - vertices[i].color = color; - } - } + void Close() override; - void SetIndices(const uint32_t* data, uint32_t size, uint32_t offset = 0) const - { - size += offset; - for(; offset < size; offset++) - { - if (indexType == VertexIndexType::UINT16) - { - static_cast(indices)[offset] = static_cast(data[offset]); - } - else - { - static_cast(indices)[offset] = data[offset]; - } - } - } - - void Close() override - { - vertexCount = 0; - indexCount = 0; - Free(); - renderGeo->Close(); - renderGeo = nullptr; - } - - void Free() - { - delete[] vertices; - free(indices); - vertices = nullptr; - indices = nullptr; - } + void Free(); }; } } diff --git a/openVulkanoCpp/Scene/Node.cpp b/openVulkanoCpp/Scene/Node.cpp index d879bca..5a4d122 100644 --- a/openVulkanoCpp/Scene/Node.cpp +++ b/openVulkanoCpp/Scene/Node.cpp @@ -6,6 +6,7 @@ #include "Node.hpp" #include "Base/Utils.hpp" +#include "Base/Logger.hpp" #include namespace openVulkanoCpp::Scene @@ -121,4 +122,4 @@ namespace openVulkanoCpp::Scene drawable->SetScene(scene); } } -} \ No newline at end of file +} diff --git a/openVulkanoCpp/Scene/Scene.hpp b/openVulkanoCpp/Scene/Scene.hpp index 7674345..db0dd5b 100644 --- a/openVulkanoCpp/Scene/Scene.hpp +++ b/openVulkanoCpp/Scene/Scene.hpp @@ -1,6 +1,14 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + #pragma once + #include "Node.hpp" #include "Camera.hpp" +#include "Base/Logger.hpp" namespace openVulkanoCpp { diff --git a/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp b/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp index ad82608..009c9a2 100644 --- a/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp +++ b/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp @@ -5,6 +5,7 @@ */ #include "ResourceManager.hpp" +#include "Scene/Vertex.hpp" #include "Vulkan/Context.hpp" #include "Vulkan/Scene/VulkanShader.hpp" #include "Vulkan/Scene/VulkanGeometry.hpp" @@ -239,4 +240,4 @@ namespace openVulkanoCpp::Vulkan shaders.push_back(vkShader); return vkShader; } -} \ No newline at end of file +}