diff --git a/.gitmodules b/.gitmodules index d33a2d4..288b2cf 100644 --- a/.gitmodules +++ b/.gitmodules @@ -20,4 +20,7 @@ path = external/ktx url = https://github.com/KhronosGroup/KTX-Software [submodule "external/stb"] - url = https://github.com/nothings/stb \ No newline at end of file + url = https://github.com/nothings/stb +[submodule "external/slang"] + path = external/slang + url = https://github.com/shader-slang/slang.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 543c5a0..ae5da99 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,7 @@ find_package(JSON REQUIRED) find_package(GLFW REQUIRED) find_package(GLM REQUIRED) find_package(KTX REQUIRED) +find_package(STB REQUIRED) find_package(SLANG REQUIRED) find_package(Aftermath REQUIRED) @@ -80,8 +81,8 @@ target_link_libraries(SeeleEngine ${Boost_LIBRARIES}) target_link_libraries(SeeleEngine ${GLFW_LIBRARIES}) target_link_libraries(SeeleEngine ${SLANG_LIBRARIES}) target_link_libraries(SeeleEngine ${ASSIMP_LIBRARIES}) -target_link_libraries(SeeleEngine ${JSON_LIBRARY}) target_link_libraries(SeeleEngine ${NSAM_LIBRARIES}) +target_link_libraries(SeeleEngine ${KTX_LIBRARIES}) #target_link_libraries(SeeleEngine ${SPIRV_LIBRARIES}) target_precompile_headers(SeeleEngine diff --git a/cmake/SuperBuild.cmake b/cmake/SuperBuild.cmake index 032d9d5..9c7d1e4 100644 --- a/cmake/SuperBuild.cmake +++ b/cmake/SuperBuild.cmake @@ -68,7 +68,7 @@ ExternalProject_Add(slang SOURCE_DIR ${SLANG_ROOT} BINARY_DIR ${SLANG_ROOT} CONFIGURE_COMMAND "" - BUILD_COMMAND msbuild slang.sln + BUILD_COMMAND msbuild slang.sln -p:Configuration=Release -p:Platform=${CMAKE_PLATFORM} INSTALL_COMMAND "") set(SLANG_LIB_PATH ${SLANG_ROOT}/${SLANG_LIB_PATH}) diff --git a/external/slang b/external/slang new file mode 160000 index 0000000..858c7c5 --- /dev/null +++ b/external/slang @@ -0,0 +1 @@ +Subproject commit 858c7c57b125afed9b5b2329d6b02477284e4803 diff --git a/res/textures/ktxd.dll b/res/textures/ktxd.dll new file mode 100644 index 0000000..f4b22fd Binary files /dev/null and b/res/textures/ktxd.dll differ diff --git a/res/textures/placeholder.ktx b/res/textures/placeholder.ktx new file mode 100644 index 0000000..dae7ccc Binary files /dev/null and b/res/textures/placeholder.ktx differ diff --git a/res/textures/toktx.exe b/res/textures/toktx.exe new file mode 100644 index 0000000..3e63987 Binary files /dev/null and b/res/textures/toktx.exe differ diff --git a/src/Engine/Asset/TextureAsset.cpp b/src/Engine/Asset/TextureAsset.cpp index 5cf1a2d..4cda278 100644 --- a/src/Engine/Asset/TextureAsset.cpp +++ b/src/Engine/Asset/TextureAsset.cpp @@ -2,9 +2,7 @@ #include "Graphics/GraphicsResources.h" #include "Graphics/Graphics.h" #include "Window/WindowManager.h" -#include -#include - +#include "Graphics/Vulkan/VulkanGraphicsEnums.h" using namespace Seele; @@ -34,19 +32,23 @@ void TextureAsset::save() void TextureAsset::load() { setStatus(Status::Loading); - int x, y, n; - unsigned char* data = stbi_load(getFullPath().c_str(), &x, &y, &n, 4); + ktxTexture2* kTexture; + KTX_error_code result = ktxTexture2_CreateFromNamedFile(getFullPath().c_str(), + KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, + &kTexture); TextureCreateInfo createInfo; - - //TODO: support other formats - createInfo.format = Gfx::SE_FORMAT_R8G8B8A8_UINT; - createInfo.resourceData.data = data; - createInfo.resourceData.size = x * y * 4 * sizeof(unsigned char); + createInfo.width = kTexture->baseWidth; + createInfo.height = kTexture->baseHeight; + createInfo.depth = kTexture->baseDepth; + createInfo.bArray = kTexture->isArray; + createInfo.arrayLayers = kTexture->numLayers; + createInfo.format = Vulkan::cast((VkFormat)kTexture->vkFormat); + createInfo.mipLevels = kTexture->numLevels; + createInfo.usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT; + createInfo.resourceData.data = ktxTexture_GetData(ktxTexture(kTexture)); + createInfo.resourceData.size = (uint32)ktxTexture_GetDataSize(ktxTexture(kTexture)); createInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER; - createInfo.width = x; - createInfo.height = y; Gfx::PTexture2D texture = WindowManager::getGraphics()->createTexture2D(createInfo); - stbi_image_free(data); texture->transferOwnership(Gfx::QueueType::GRAPHICS); setTexture(texture); setStatus(Asset::Status::Ready); diff --git a/src/Engine/Asset/TextureLoader.cpp b/src/Engine/Asset/TextureLoader.cpp index 73a3027..8cc4ccd 100644 --- a/src/Engine/Asset/TextureLoader.cpp +++ b/src/Engine/Asset/TextureLoader.cpp @@ -2,6 +2,7 @@ #include "TextureAsset.h" #include "Graphics/Graphics.h" #include "AssetRegistry.h" +#include "Graphics/Vulkan/VulkanGraphicsEnums.h" #define STB_IMAGE_IMPLEMENTATION #include #define STB_IMAGE_WRITE_IMPLEMENTATION @@ -12,10 +13,8 @@ using namespace Seele; TextureLoader::TextureLoader(Gfx::PGraphics graphics) : graphics(graphics) { - placeholderAsset = new TextureAsset(); - placeholderTexture = import("./textures/placeholder.png"); - placeholderAsset->setTexture(placeholderTexture); - placeholderAsset->setStatus(Asset::Status::Ready); + placeholderAsset = new TextureAsset(std::filesystem::absolute("./textures/placeholder.ktx")); + placeholderAsset->load(); AssetRegistry::get().textures[""] = placeholderAsset; } @@ -28,13 +27,13 @@ void TextureLoader::importAsset(const std::filesystem::path& filePath) auto assetFileName = filePath; PTextureAsset asset = new TextureAsset(assetFileName.replace_extension("asset").filename().generic_string()); asset->setStatus(Asset::Status::Loading); - asset->setTexture(placeholderTexture); + asset->setTexture(placeholderAsset->getTexture()); AssetRegistry::get().textures[asset->getFileName()] = asset; futures.add(std::async(std::launch::async, [this, filePath, asset] () mutable { using namespace std::chrono_literals; //std::this_thread::sleep_for(5s); - Gfx::PTexture2D texture = import(filePath); - asset->setTexture(texture); + import(filePath, asset); + asset->load(); asset->setStatus(Asset::Status::Ready); })); } @@ -44,20 +43,34 @@ PTextureAsset TextureLoader::getPlaceholderTexture() return placeholderAsset; } -Gfx::PTexture2D TextureLoader::import(const std::filesystem::path& path) +void TextureLoader::import(const std::filesystem::path& path, PTextureAsset textureAsset) { int x, y, n; unsigned char* data = stbi_load(path.string().c_str(), &x, &y, &n, 4); - - TextureCreateInfo createInfo; - createInfo.format = Gfx::SE_FORMAT_R8G8B8A8_SRGB; - createInfo.resourceData.data = data; - createInfo.resourceData.size = x * y * 4 * sizeof(unsigned char); - createInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER; - createInfo.width = x; - createInfo.height = y; - Gfx::PTexture2D texture = graphics->createTexture2D(createInfo); + ktxTexture2* kTexture; + ktxTextureCreateInfo createInfo; + KTX_error_code result; + + createInfo.vkFormat = VK_FORMAT_R8G8B8A8_SRGB; + createInfo.baseWidth = x; + createInfo.baseHeight = y; + createInfo.baseDepth = 1; + createInfo.numDimensions = 1 + (y > 1); + createInfo.numLevels = 1; + createInfo.numLayers = 1; + createInfo.numFaces = 1; + createInfo.isArray = false; + createInfo.generateMipmaps = true; + + result = ktxTexture2_Create(&createInfo, + KTX_TEXTURE_CREATE_ALLOC_STORAGE, + &kTexture); + + result = ktxTexture_SetImageFromMemory(ktxTexture(kTexture), + 0, 0, 0, data, x * y * 4 * sizeof(unsigned char)); + stbi_image_free(data); - texture->transferOwnership(Gfx::QueueType::GRAPHICS); - return texture; + + result = ktxTexture_WriteToNamedFile(ktxTexture(kTexture), textureAsset->getFullPath().c_str()); + ktxTexture_Destroy(ktxTexture(kTexture)); } \ No newline at end of file diff --git a/src/Engine/Asset/TextureLoader.h b/src/Engine/Asset/TextureLoader.h index b2f73f4..addf294 100644 --- a/src/Engine/Asset/TextureLoader.h +++ b/src/Engine/Asset/TextureLoader.h @@ -18,10 +18,9 @@ public: void importAsset(const std::filesystem::path& filePath); PTextureAsset getPlaceholderTexture(); private: - Gfx::PTexture2D import(const std::filesystem::path& path); + void import(const std::filesystem::path& path, PTextureAsset asset); Gfx::PGraphics graphics; List> futures; - Gfx::PTexture2D placeholderTexture; PTextureAsset placeholderAsset; }; DEFINE_REF(TextureLoader) diff --git a/src/Engine/Graphics/Graphics.h b/src/Engine/Graphics/Graphics.h index 0879294..900623d 100644 --- a/src/Engine/Graphics/Graphics.h +++ b/src/Engine/Graphics/Graphics.h @@ -4,6 +4,7 @@ #include "Containers/Array.h" #include "VertexShaderInput.h" #include "ShaderCompiler.h" +#include "ktx.h" namespace Seele { diff --git a/src/Engine/Graphics/GraphicsResources.h b/src/Engine/Graphics/GraphicsResources.h index b6199e9..3d0f5c9 100644 --- a/src/Engine/Graphics/GraphicsResources.h +++ b/src/Engine/Graphics/GraphicsResources.h @@ -500,7 +500,9 @@ public: virtual SeFormat getFormat() const = 0; virtual uint32 getSizeX() const = 0; virtual uint32 getSizeY() const = 0; + virtual uint32 getSizeZ() const = 0; virtual SeSampleCountFlags getNumSamples() const = 0; + virtual uint32 getMipLevels() const = 0; virtual void changeLayout(SeImageLayout newLayout) = 0; virtual class Texture2D* getTexture2D() { return nullptr; } virtual void* getNativeHandle() { return nullptr; } @@ -520,7 +522,9 @@ public: virtual SeFormat getFormat() const = 0; virtual uint32 getSizeX() const = 0; virtual uint32 getSizeY() const = 0; + virtual uint32 getSizeZ() const = 0; virtual SeSampleCountFlags getNumSamples() const = 0; + virtual uint32 getMipLevels() const = 0; virtual void changeLayout(SeImageLayout newLayout) = 0; virtual class Texture2D* getTexture2D() { return this; } protected: diff --git a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.h b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.h index 2940d3d..249f5e3 100644 --- a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.h +++ b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.h @@ -144,6 +144,10 @@ public: PCmdBuffer getCommands(); PRenderCommand createRenderCommand(const std::string& name); PComputeCommand createComputeCommand(const std::string& name); + VkCommandPool getPoolHandle() const + { + return commandPool; + } void submitCommands(PSemaphore signalSemaphore = nullptr); private: diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp b/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp index 41ceb60..073d600 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp @@ -360,6 +360,7 @@ PStagingManager Graphics::getStagingManager() return stagingManager; } + Array Graphics::getRequiredExtensions() { Array extensions; diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h b/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h index 02d4148..63bb7f6 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h +++ b/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h @@ -249,6 +249,10 @@ public: { return samples; } + inline uint32 getMipLevels() const + { + return mipLevels; + } inline bool isDepthStencil() const { return aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); @@ -303,6 +307,10 @@ public: { return textureHandle->sizeY; } + virtual uint32 getSizeZ() const override + { + return textureHandle->sizeZ; + } virtual Gfx::SeFormat getFormat() const override { return textureHandle->format; @@ -311,6 +319,10 @@ public: { return textureHandle->getNumSamples(); } + virtual uint32 getMipLevels() const override + { + return textureHandle->getMipLevels(); + } virtual void changeLayout(Gfx::SeImageLayout newLayout) override; virtual void* getNativeHandle() override { diff --git a/src/Engine/main.cpp b/src/Engine/main.cpp index def4164..96c590b 100644 --- a/src/Engine/main.cpp +++ b/src/Engine/main.cpp @@ -29,7 +29,7 @@ int main() AssetRegistry::init("D:\\Private\\Programming\\C++\\TestSeeleProject\\"); AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Ely\\Ely.fbx"); AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Cube\\cube.obj"); - AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Plane\\plane.obj"); + AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Plane\\plane.fbx"); PPrimitiveComponent plane = new PrimitiveComponent(AssetRegistry::findMesh("plane")); plane->setWorldScale(Vector(100, 100, 100)); PPrimitiveComponent arissa = new PrimitiveComponent(AssetRegistry::findMesh("Ely"));