From b1d8ef41206b3071d722b6869f1fe871257e2c1c Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Fri, 15 Oct 2021 23:12:29 +0200 Subject: [PATCH] Preparing for Writeup --- .vscode/launch.json | 20 +++ .vscode/settings.json | 9 +- CMakeLists.txt | 2 +- WRITEUP.md | 125 +++++++++++++++++- cmake/FindAssimp.cmake | 16 +-- cmake/FindGLFW.cmake | 20 +-- cmake/FindSLANG.cmake | 41 +----- cmake/SuperBuild.cmake | 6 +- res/shaders/Placeholder.asset | 77 +++-------- src/Engine/Asset/AssetRegistry.cpp | 5 + src/Engine/Asset/MeshLoader.cpp | 8 +- src/Engine/Asset/TextureAsset.cpp | 3 +- src/Engine/Asset/TextureLoader.cpp | 10 +- src/Engine/Containers/Array.h | 4 +- src/Engine/Containers/Map.h | 4 +- src/Engine/Graphics/GraphicsEnums.h | 2 +- src/Engine/Graphics/GraphicsResources.cpp | 2 + .../Graphics/RenderPass/DepthPrepass.cpp | 4 +- .../Graphics/RenderPass/LightCullingPass.cpp | 2 +- .../Graphics/Vulkan/VulkanCommandBuffer.cpp | 2 +- .../Graphics/Vulkan/VulkanDescriptorSets.cpp | 2 +- .../Graphics/Vulkan/VulkanDescriptorSets.h | 2 +- src/Engine/Graphics/Vulkan/VulkanGraphics.cpp | 3 + .../Graphics/Vulkan/VulkanInitializer.cpp | 4 +- src/Engine/Graphics/Vulkan/VulkanShader.cpp | 4 +- src/Engine/Graphics/Vulkan/VulkanViewport.cpp | 2 +- src/Engine/Material/Material.cpp | 5 +- src/Engine/Material/ShaderExpression.cpp | 2 +- src/Engine/MinimalEngine.h | 4 +- .../Scene/Components/CameraComponent.cpp | 4 +- src/Engine/Scene/Components/Component.cpp | 2 +- src/Engine/UI/Elements/Element.cpp | 5 + src/Engine/Window/InspectorView.cpp | 6 +- src/Engine/Window/InspectorView.h | 6 +- src/Engine/Window/SceneView.cpp | 39 +++++- src/Engine/Window/SceneView.h | 4 +- src/Engine/Window/View.cpp | 2 +- src/Engine/Window/View.h | 4 +- src/Engine/Window/Window.cpp | 4 +- src/Engine/main.cpp | 10 +- 40 files changed, 284 insertions(+), 192 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 67360e2..fd0efbb 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,6 +4,26 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + { + "name": "Engine Debug (Linux)", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceRoot}/bin/Debug/SeeleEngine", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceRoot}/bin/Debug", + "console": "internalConsole", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable break on all exceptions", + "text": "catch throw", + "ignoreFailures": true + } + ] + }, { "name": "Engine Debug", "type": "cppvsdbg", diff --git a/.vscode/settings.json b/.vscode/settings.json index 5db8820..a5f0af8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -112,14 +112,19 @@ "span": "cpp", "charconv": "cpp", "format": "cpp", - "semaphore": "cpp" + "semaphore": "cpp", + "netfwd": "cpp", + "string_view": "cpp", + "rope": "cpp", + "slist": "cpp", + "numbers": "cpp" }, "cmake.skipConfigureIfCachePresent": false, "cmake.configureArgs": [ "-Wno-dev" ], "C_Cpp.default.cppStandard": "c++20", - "C_Cpp.default.intelliSenseMode": "msvc-x64", + "C_Cpp.default.intelliSenseMode": "gcc-x64", "files.watcherExclude": { "**/target": true }, diff --git a/CMakeLists.txt b/CMakeLists.txt index b3da341..f39c987 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -120,4 +120,4 @@ add_custom_target(copy-runtime-files ALL COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GLFW_BINARY} $ COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ASSIMP_BINARY} $ COMMAND ${CMAKE_COMMAND} -E copy_if_different ${NSAM_BINARIES} $ - DEPENDS SeeleEngine) \ No newline at end of file + DEPENDS SeeleEngine) diff --git a/WRITEUP.md b/WRITEUP.md index 81ef4f2..91f1094 100644 --- a/WRITEUP.md +++ b/WRITEUP.md @@ -1,7 +1,7 @@ # Seele Engine -Seele is a Proof-of-Concept 3D render engine using Vulkan as it's primary graphics API, but other APIs could also be implemented. -The focus of the project is to make the renderer use as many of the system resources as efficiently as possible to maximize the framerate +Seele is a Proof-of-Concept 3D render engine using Vulkan as it's primary graphics API, but other APIs could also be implemented. Due to this, a lot of terminology will be Vulkan-related, but it can be translated to other APIs. +The focus of the project is to make the renderer use as many of the system resources as efficiently as possible to maximize the framerate while minimizing resource usage. It does this by being designed to support multithreading for more recent APIs, like DX12 or Vulkan, while still providing an interface that could be implemented by an API that doesn't support it, like OpenGL. These APIs would suffer a significant performance loss, but would still work correctly. @@ -23,3 +23,124 @@ performance optimizations, like serialization for example. Due to them occuring - `PHelloWorld`, the same as `RefPtr` - `UPHelloWorld`, the same as `UniquePtr` +## Basic Architecture + +The first piece to the puzzle is the `WindowManager`, a container that manages a `Graphics` object, which is the interface for the graphics API, as well as all `Window`s that are active. Each `Window` represents, well, a window, and contains several `View`s. A `View` represents a viewport in the window. For an analogy to Unity, a `View` would be the Inspector, the Asset Browser or the Hierarchy. + +Since all viewports in a window are backed by the same image and can only be presented together, the rendering for all viewports is synchronized, while the logic for each `View` runs in a separate thread. + +The interactions between logic and rendering are modelled through two parts of the interface: `beginUpdate()`, `update()` and `commitUpdate()` for the logic side, and `prepareRender()` and `render()` for the rendering side. The views use a set of concrete `RenderPass` objects to render a new frame, depending on what kind of content should be displayed. In order to draw a frame, a `RenderPass` needs an "update packet" in form of a struct, but the contents of that packet is dependent on the render pass itself. A depth prepass for example might only need a mesh list, while a light culling pass needs the dynamic lights or a base pass might need both. + +In order to avoid inheritance and casting for these update packets, each `RenderPass` needs to be updated individually by the view that uses it, so the thread interactions are not enforced in the `View` base class, instead `commitUpdate()` is called from a locked context from the logic thread, so that the view can copy the packet to a shared storage, while `prepareRender()` is locked and called from the render thread, so that it can be passed to the render passes. + +## RenderPass + +To better illustrate how render passes work, here is part of the `RenderPass` base class: + +```cpp +template +class RenderPass +{ +public: + RenderPass(Gfx::PGraphics graphics, Gfx::PViewport viewport) + : graphics(graphics) + , viewport(viewport) + {} + virtual ~RenderPass() + {} + void updateViewFrame(RenderPassDataType viewFrame) { + passData = std::move(viewFrame); + } + virtual void beginFrame() = 0; + virtual void render() = 0; + virtual void endFrame() = 0; + virtual void publishOutputs() = 0; + virtual void createRenderPass() = 0; + //.... +private: + PRenderGraphResources resources; + RenderPassDataType passData; + Gfx::PGraphics graphics; + //.... +}; +``` + +All render passes in a `View` share a `RenderGraphResources` object, which is used to share outputs between the different passes. During initialization, every render pass "publishes" any outputs that it produces in `publishOutputs()`, so that they can be consumed by other render passes. For example the output of a depth prepass is the depth buffer, for a light culling pass it is the culled light indices. Next the render passes get any resources that they require and have been registered by other passes to create the render pass in `createRenderPass()`. This is split into two parts, so that the order of initialization of different renderpasses doesn't matter, as all outputs are available before any are requested. + +## Materials + +The material system fully embraced a Vulkan-style descriptor system, abstracted by the `Graphics` API. A material is a file stored on disk in form of a JSON document, here is an example: + +```json +{ + "name": "Placeholder", + "profile": "BlinnPhong", + "params": { + "diffuseTexture": { + "type": "Texture2D" + }, + "specularTexture": { + "type": "Texture2D" + }, + "normalTexture": { + "type": "Texture2D" + }, + "uvScale": { + "type": "float", + "default": "0.0f" + }, + "metallic": { + "type": "float", + "default": "0.0f" + }, + "roughness": { + "type": "float", + "default": "0.5f" + }, + "sheen": { + "type": "float", + "default": "0.0f" + }, + "worldOffset": { + "type": "float3", + "default": "float3(0, 0, 0)" + }, + "textureSampler": { + "type": "SamplerState" + } + }, + "code": { + "baseColor": [ + "return diffuseTexture.Sample(textureSampler, input.texCoords[0] * uvScale).xyz;" + ], + "metallic": [ + "return metallic;" + ], + "normal": [ + "return normalTexture.Sample(textureSampler, input.texCoords[0] * uvScale).xyz;" + ], + "specular": [ + "return specularTexture.Sample(textureSampler, input.texCoords[0] * uvScale).x;" + ], + "roughness": [ + "return roughness;" + ], + "sheen": [ + "return sheen;" + ], + "worldOffset": [ + "return worldOffset;" + ] + } +} +``` + +The document starts with the asset `name`, followed by the `profile`, which tells the engine which BRDF function it uses, and thus what outputs it can expect from the material. Next are the parameters, which are the inputs that need to get passed to the shader later. The `type` field must be a valid HLSL datatype and `default` a valid value for that datatype. In the `code` section, there must be an entry for every output required by the `profile`, each of which is a string array for each line of shader code to compute that value and ends by `return`ing that value. + +### MaterialAsset + +The `MaterialAsset` class represents such a JSON document on disk, and is the base class for `Material` and `MaterialInstance`. It stores the layout of the parameters as well as their values, but does not store, parse or generate any shader code. + +### Material + +The `Material` class inherits from `MaterialAsset` and represents a base material, diff --git a/cmake/FindAssimp.cmake b/cmake/FindAssimp.cmake index ea544d5..e84f515 100644 --- a/cmake/FindAssimp.cmake +++ b/cmake/FindAssimp.cmake @@ -55,7 +55,7 @@ else() # Find library files find_library( ASSIMP_LIBRARY - NAMES libassimp${CMAKE_DEBUG_POSTFIX}.a + NAMES libassimp${CMAKE_DEBUG_POSTFIX}.so PATHS /usr/lib64 /usr/lib @@ -66,22 +66,10 @@ else() ${ASSIMP_ROOT}/code DOC "Assimp library file") - find_file( - ASSIMP_BINARY - NAMES libassimp${CMAKE_DEBUG_POSTFIX}.so - PATHS - /usr/lib64 - /usr/lib - /usr/local/lib64 - /usr/local/lib - /sw/lib - /opt/local/lib - ${ASSIMP_ROOT}/code - DOC "The Assimp library") endif() # Handle REQUIRD argument, define *_FOUND variable -find_package_handle_standard_args(assimp DEFAULT_MSG ASSIMP_INCLUDE_DIR ASSIMP_BINARY) +find_package_handle_standard_args(assimp DEFAULT_MSG ASSIMP_INCLUDE_DIR ASSIMP_LIBRARY) # Define GLFW_LIBRARIES and GLFW_INCLUDE_DIRS if (ASSIMP_FOUND) diff --git a/cmake/FindGLFW.cmake b/cmake/FindGLFW.cmake index c7a44d6..beef978 100644 --- a/cmake/FindGLFW.cmake +++ b/cmake/FindGLFW.cmake @@ -68,23 +68,9 @@ else() /opt/local/include DOC "The directory where GL/glfw.h resides") - # Find library files - # Try to use static libraries - find_library( - GLFW_LIBRARY - NAMES libglfw3${CMAKE_DEBUG_POSTFIX}.a - PATHS - /usr/lib64 - /usr/lib - /usr/local/lib64 - /usr/local/lib - /sw/lib - /opt/local/lib - ${GLFW_ROOT}/src - DOC "The GLFW library") - + # Find library files find_file( - GLFW_BINARY + GLFW_LIBRARY NAMES libglfw${CMAKE_DEBUG_POSTFIX}.so PATHS /usr/lib64 @@ -98,7 +84,7 @@ else() endif() # Handle REQUIRD argument, define *_FOUND variable -find_package_handle_standard_args(GLFW DEFAULT_MSG GLFW_INCLUDE_DIR GLFW_LIBRARY GLFW_BINARY) +find_package_handle_standard_args(GLFW DEFAULT_MSG GLFW_INCLUDE_DIR GLFW_LIBRARY) # Define GLFW_LIBRARIES and GLFW_INCLUDE_DIRS if (GLFW_FOUND) diff --git a/cmake/FindSLANG.cmake b/cmake/FindSLANG.cmake index f4bd60e..63200b2 100644 --- a/cmake/FindSLANG.cmake +++ b/cmake/FindSLANG.cmake @@ -49,63 +49,32 @@ if (WIN32) PATHS ${SLANG_BINARY_PATH}) else() - set(SLANG_BINARY_PATH ${SLANG_ROOT}/bin/linux-${CMAKE_PLATFORM}/debug/) + set(SLANG_BINARY_PATH ${SLANG_ROOT}/bin/linux-${CMAKE_PLATFORM}/release/) # Find include files find_path( SLANG_INCLUDE_DIR NAMES slang.h PATHS - /usr/include - /usr/local/include - /sw/include - /opt/local/include ${SLANG_ROOT} DOC "The directory where GL/glfw.h resides") - - find_library( - SLANG_LIBRARY - NAMES libcore.a - PATHS - /usr/include - /usr/local/include - /sw/include - /opt/local/include - ${SLANG_BINARY_PATH} - DOC "The directory where GL/glfw.h resides") - - find_library( - SLANG_COMPILER - NAMES libcompiler-core.a - PATHS - /usr/include - /usr/local/include - /sw/include - /opt/local/include - ${SLANG_BINARY_PATH} - DOC "The directory where GL/glfw.h resides") # Find library files find_library( - SLANG_BINARY + SLANG_LIBRARY NAMES libslang.so PATHS - /usr/lib64 - /usr/lib - /usr/local/lib64 - /usr/local/lib - /sw/lib - /opt/local/lib ${SLANG_BINARY_PATH} + NO_DEFAULT_PATH DOC "The SLANG library") endif() # Handle REQUIRD argument, define *_FOUND variable -find_package_handle_standard_args(SLANG DEFAULT_MSG SLANG_INCLUDE_DIR SLANG_LIBRARY SLANG_BINARY) +find_package_handle_standard_args(SLANG DEFAULT_MSG SLANG_INCLUDE_DIR SLANG_LIBRARY) # Define SLANG_LIBRARIES and SLANG_INCLUDE_DIRS if (SLANG_FOUND) set(SLANG_BINARIES ${SLANG_BINARY} ${SLANG_GLSLANG}) - set(SLANG_LIBRARIES ${SLANG_LIBRARY} ${SLANG_COMPILER}) + set(SLANG_LIBRARIES ${SLANG_LIBRARY}) set(SLANG_INCLUDE_DIRS ${SLANG_INCLUDE_DIR}) endif() diff --git a/cmake/SuperBuild.cmake b/cmake/SuperBuild.cmake index d899fc2..ee6e687 100644 --- a/cmake/SuperBuild.cmake +++ b/cmake/SuperBuild.cmake @@ -10,7 +10,7 @@ set(ASSIMP_BUILD_OVERALLS OFF CACHE INTERNAL "") set(ASSIMP_BUILD_ASSIMP_TOOLS OFF CACHE INTERNAL "") set(ASSIMP_INSTALL OFF CACHE INTERNAL "") set(ASSIMP_BUILD_ZLIB OFF CACHE INTERNAL "") -set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "") +set(BUILD_SHARED_LIBS ON CACHE INTERNAL "") add_subdirectory(${ASSIMP_ROOT} ${ASSIMP_ROOT}) target_compile_definitions(assimp PRIVATE _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING) @@ -59,13 +59,13 @@ set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "GLFW lib only" ) set(GLFW_BUILD_TESTS OFF CACHE BOOL "GLFW lib only" ) set(GLFW_BUILD_DOCS OFF CACHE BOOL "GLFW lib only" ) set(GLFW_BUILD_INSTALL OFF CACHE BOOL "GLFW lib only" ) -set(GLFW_VULKAN_STATIC ON CACHE BOOL "GLFW vulkan static") +set(GLFW_VULKAN_STATIC OFF CACHE BOOL "GLFW vulkan static") add_subdirectory(${GLFW_ROOT} ${GLFW_ROOT}) #--------------SLang------------------------------ list(APPEND DEPENDENCIES slang) -string(TOLOWER debug_${CMAKE_PLATFORM} SLANG_CONFIG) +string(TOLOWER release_${CMAKE_PLATFORM} SLANG_CONFIG) if(WIN32) ExternalProject_Add(slang SOURCE_DIR ${SLANG_ROOT} diff --git a/res/shaders/Placeholder.asset b/res/shaders/Placeholder.asset index 8fbe65b..3e9eb74 100644 --- a/res/shaders/Placeholder.asset +++ b/res/shaders/Placeholder.asset @@ -5,10 +5,10 @@ "diffuseTexture": { "type": "Texture2D" }, - "specularTexture": { + "specularTexture": { "type": "Texture2D" }, - "normalTexture": { + "normalTexture": { "type": "Texture2D" }, "uvScale": { @@ -19,82 +19,43 @@ "type": "float", "default": "0.0f" }, - "subsurface": { - "type": "float", - "default": "0.0f" - }, "roughness": { "type": "float", "default": "0.5f" }, - "specularTint": { - "type": "float", - "default": "0.0f" - }, - "anisotropic": { - "type": "float", - "default": "0.0f" - }, "sheen": { "type": "float", "default": "0.0f" }, - "sheenTint": { - "type": "float", - "default": "0.5f" - }, - "clearCoat": { - "type": "float", - "default": "0.0f" - }, - "clearCoatGloss": { - "type": "float", - "default": "1.0f" - }, - "worldOffset": { - "type": "float3", - "default": "float3(0, 0, 0)" + "worldOffset": { + "type": "float3", + "default": "float3(0, 0, 0)" }, "textureSampler": { "type": "SamplerState" } }, "code": { - "baseColor": [ - "return diffuseTexture.Sample(textureSampler, input.texCoords[0] * uvScale).xyz;" + "baseColor": [ + "return diffuseTexture.Sample(textureSampler, input.texCoords[0] * uvScale).xyz;" ], - "metallic": [ - "return 0;" + "metallic": [ + "return metallic;" ], - "normal": [ - "return normalTexture.Sample(textureSampler, input.texCoords[0] * uvScale).xyz;" + "normal": [ + "return normalTexture.Sample(textureSampler, input.texCoords[0] * uvScale).xyz;" ], - "specular": [ - "return specularTexture.Sample(textureSampler, input.texCoords[0] * uvScale).x;" + "specular": [ + "return specularTexture.Sample(textureSampler, input.texCoords[0] * uvScale).x;" ], - "roughness": [ - "return roughness;" + "roughness": [ + "return roughness;" ], - "specularTint": [ - "return specularTint;" + "sheen": [ + "return sheen;" ], - "anisotropic": [ - "return anisotropic;" - ], - "sheen": [ - "return sheen;" - ], - "sheenTint": [ - "return sheenTint;" - ], - "clearCoat": [ - "return clearCoat;" - ], - "clearCoatGloss": [ - "return clearCoatGloss;" - ], - "worldOffset": [ - "return worldOffset;" + "worldOffset": [ + "return worldOffset;" ] } } \ No newline at end of file diff --git a/src/Engine/Asset/AssetRegistry.cpp b/src/Engine/Asset/AssetRegistry.cpp index e5862ef..c6fbf5f 100644 --- a/src/Engine/Asset/AssetRegistry.cpp +++ b/src/Engine/Asset/AssetRegistry.cpp @@ -124,6 +124,11 @@ void AssetRegistry::registerMesh(PMeshAsset mesh) } } +void AssetRegistry::registerTexture(PTextureAsset texture) +{ + textures[texture->getFileName()] = texture; +} + void AssetRegistry::registerMaterial(PMaterialAsset material) { materials[material->getFileName()] = material; diff --git a/src/Engine/Asset/MeshLoader.cpp b/src/Engine/Asset/MeshLoader.cpp index e13ad3e..9f86f3f 100644 --- a/src/Engine/Asset/MeshLoader.cpp +++ b/src/Engine/Asset/MeshLoader.cpp @@ -86,8 +86,8 @@ void MeshLoader::loadMaterials(const aiScene* scene, Array& glob outMatFile << std::setw(4) << matCode; outMatFile.flush(); outMatFile.close(); - //TODO: let the material loader handle this instead - //std::cout << matCode << std::endl; + + std::cout << "writing json to " << outMatFilename << std::endl; PMaterial result = new Material(outMatFilename); result->compile(); graphics->getShaderCompiler()->registerMaterial(result); @@ -225,12 +225,13 @@ void MeshLoader::loadTextures(const aiScene* scene, const std::filesystem::path& stbi_write_png(texPngPath.string().c_str(), tex->mWidth, tex->mHeight, 4, tex->pcData, tex->mWidth * 32); delete texData; } - + std::cout << "Loading model texture " << texPngPath.string() << std::endl; AssetRegistry::importFile(texPngPath.string()); } } void MeshLoader::import(PMeshAsset meshAsset, const std::filesystem::path &path) { + std::cout << "Starting to import "<setStatus(Asset::Status::Loading); Assimp::Importer importer; importer.ReadFile(path.string().c_str(), @@ -262,4 +263,5 @@ void MeshLoader::import(PMeshAsset meshAsset, const std::filesystem::path &path) } meshAsset->setStatus(Asset::Status::Ready); meshAsset->save(); + std::cout << "Finished loading " << path << std::endl; } diff --git a/src/Engine/Asset/TextureAsset.cpp b/src/Engine/Asset/TextureAsset.cpp index 4cda278..cb804cd 100644 --- a/src/Engine/Asset/TextureAsset.cpp +++ b/src/Engine/Asset/TextureAsset.cpp @@ -33,7 +33,8 @@ void TextureAsset::load() { setStatus(Status::Loading); ktxTexture2* kTexture; - KTX_error_code result = ktxTexture2_CreateFromNamedFile(getFullPath().c_str(), + // TODO: consider return + ktxTexture2_CreateFromNamedFile(getFullPath().c_str(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, &kTexture); TextureCreateInfo createInfo; diff --git a/src/Engine/Asset/TextureLoader.cpp b/src/Engine/Asset/TextureLoader.cpp index 8cc4ccd..ef2b624 100644 --- a/src/Engine/Asset/TextureLoader.cpp +++ b/src/Engine/Asset/TextureLoader.cpp @@ -28,7 +28,8 @@ void TextureLoader::importAsset(const std::filesystem::path& filePath) PTextureAsset asset = new TextureAsset(assetFileName.replace_extension("asset").filename().generic_string()); asset->setStatus(Asset::Status::Loading); asset->setTexture(placeholderAsset->getTexture()); - AssetRegistry::get().textures[asset->getFileName()] = asset; + std::cout << "Loading texture " << asset->getFileName() << std::endl; + AssetRegistry::get().registerTexture(asset); futures.add(std::async(std::launch::async, [this, filePath, asset] () mutable { using namespace std::chrono_literals; //std::this_thread::sleep_for(5s); @@ -49,7 +50,6 @@ void TextureLoader::import(const std::filesystem::path& path, PTextureAsset text unsigned char* data = stbi_load(path.string().c_str(), &x, &y, &n, 4); ktxTexture2* kTexture; ktxTextureCreateInfo createInfo; - KTX_error_code result; createInfo.vkFormat = VK_FORMAT_R8G8B8A8_SRGB; createInfo.baseWidth = x; @@ -62,15 +62,15 @@ void TextureLoader::import(const std::filesystem::path& path, PTextureAsset text createInfo.isArray = false; createInfo.generateMipmaps = true; - result = ktxTexture2_Create(&createInfo, + ktxTexture2_Create(&createInfo, KTX_TEXTURE_CREATE_ALLOC_STORAGE, &kTexture); - result = ktxTexture_SetImageFromMemory(ktxTexture(kTexture), + ktxTexture_SetImageFromMemory(ktxTexture(kTexture), 0, 0, 0, data, x * y * 4 * sizeof(unsigned char)); stbi_image_free(data); - result = ktxTexture_WriteToNamedFile(ktxTexture(kTexture), textureAsset->getFullPath().c_str()); + ktxTexture_WriteToNamedFile(ktxTexture(kTexture), textureAsset->getFullPath().c_str()); ktxTexture_Destroy(ktxTexture(kTexture)); } \ No newline at end of file diff --git a/src/Engine/Containers/Array.h b/src/Engine/Containers/Array.h index 481958b..4ddb32c 100644 --- a/src/Engine/Containers/Array.h +++ b/src/Engine/Containers/Array.h @@ -32,9 +32,9 @@ namespace Seele Array(Init_t) : arraySize(0) , allocated(0) - , _data(nullptr) , beginIt(Iterator(nullptr)) , endIt(Iterator(nullptr)) + , _data(nullptr) { } Array(size_t size, T value = T()) @@ -420,7 +420,7 @@ namespace Seele } friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int version) + void serialize(Archive& ar, const unsigned int) { ar & arraySize; resize(arraySize); diff --git a/src/Engine/Containers/Map.h b/src/Engine/Containers/Map.h index b103010..9578fa5 100644 --- a/src/Engine/Containers/Map.h +++ b/src/Engine/Containers/Map.h @@ -111,10 +111,10 @@ private: public: Map() : root(nullptr) - , _size(0) - , iteratorsDirty(false) , beginIt(nullptr) , endIt(nullptr) + , iteratorsDirty(false) + , _size(0) { } Map(const Map& other) diff --git a/src/Engine/Graphics/GraphicsEnums.h b/src/Engine/Graphics/GraphicsEnums.h index 096f48a..592f004 100644 --- a/src/Engine/Graphics/GraphicsEnums.h +++ b/src/Engine/Graphics/GraphicsEnums.h @@ -162,7 +162,7 @@ typedef uint32 KeyModifierFlags; namespace Gfx { static constexpr bool useAsyncCompute = true; -static constexpr bool waitIdleOnSubmit = true; +static constexpr bool waitIdleOnSubmit = false; static constexpr uint32 numFramesBuffered = 8; extern uint32 currentFrameIndex; extern double currentFrameDelta; diff --git a/src/Engine/Graphics/GraphicsResources.cpp b/src/Engine/Graphics/GraphicsResources.cpp index c03eaac..6e99fad 100644 --- a/src/Engine/Graphics/GraphicsResources.cpp +++ b/src/Engine/Graphics/GraphicsResources.cpp @@ -26,8 +26,10 @@ void modifyRenderPassMacros(Gfx::RenderPassType type, MapgetTexture()->transferOwnership(Gfx::QueueType::GRAPHICS); graphics->beginRenderPass(renderPass); - /*for (auto &&meshBatch : scene->getStaticMeshes()) + for (auto &&meshBatch : passData.staticDrawList) { processor->addMeshBatch(meshBatch, renderPass, depthPrepassLayout, primitiveLayout, descriptorSets); - }*/ + } graphics->executeCommands(processor->getRenderCommands()); graphics->endRenderPass(); } diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp index 64e7b99..191e34a 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp @@ -232,7 +232,7 @@ void LightCullingPass::createRenderPass() depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH")->getTexture(); } -void LightCullingPass::modifyRenderPassMacros(Map& defines) +void LightCullingPass::modifyRenderPassMacros(Map&) { } diff --git a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp index a515018..1b96cc1 100644 --- a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp @@ -304,7 +304,7 @@ ComputeCommand::~ComputeCommand() { } -void ComputeCommand::begin(PCmdBuffer parent) +void ComputeCommand::begin(PCmdBuffer) { ready = false; VkCommandBufferBeginInfo beginInfo = diff --git a/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp b/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp index bb88fda..26cc076 100644 --- a/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp @@ -117,7 +117,7 @@ DescriptorSet::~DescriptorSet() void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) { PUniformBuffer vulkanBuffer = uniformBuffer.cast(); - UniformBuffer* cachedBuffer = reinterpret_cast(cachedData[binding]); + //UniformBuffer* cachedBuffer = reinterpret_cast(cachedData[binding]); /*if(vulkanBuffer->isDataEquals(cachedBuffer)) { std::cout << "uniform data equal, skip" << std::endl; diff --git a/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.h b/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.h index b88ab1d..884291f 100644 --- a/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.h +++ b/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.h @@ -63,8 +63,8 @@ public: : setHandle(VK_NULL_HANDLE) , graphics(graphics) , owner(owner) - , currentlyInUse(false) , currentlyBound(false) + , currentlyInUse(false) { } virtual ~DescriptorSet(); diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp b/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp index 6d7e259..61b700b 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp @@ -432,16 +432,19 @@ void Graphics::pickPhysicalDevice() vkGetPhysicalDeviceFeatures(dev, &features); if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) { + std::cout << "found dedicated gpu " << props.deviceName << std::endl; currentRating += 100; } else if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) { + std::cout << "found integrated gpu " << props.deviceName << std::endl; currentRating += 10; } if (currentRating > deviceRating) { deviceRating = currentRating; bestDevice = dev; + std::cout << "bestDevice: " << props.deviceName << std::endl; } } physicalDevice = bestDevice; diff --git a/src/Engine/Graphics/Vulkan/VulkanInitializer.cpp b/src/Engine/Graphics/Vulkan/VulkanInitializer.cpp index 53c5f91..30f00f6 100644 --- a/src/Engine/Graphics/Vulkan/VulkanInitializer.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanInitializer.cpp @@ -765,8 +765,7 @@ VkPipelineShaderStageCreateInfo init::PipelineShaderStageCreateInfo(VkShaderStag return info; } -#pragma warning(disable : 4100) -VkBool32 Seele::Vulkan::debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code, const char *layerPrefix, const char *msg, void *userDataManager) +VkBool32 Seele::Vulkan::debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT, uint64_t, size_t, int32_t, const char *layerPrefix, const char *msg, void *) { if(flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) { @@ -778,7 +777,6 @@ VkBool32 Seele::Vulkan::debugCallback(VkDebugReportFlagsEXT flags, VkDebugReport return VK_FALSE; } } -#pragma warning(default : 4100) VkResult Seele::Vulkan::CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pCallback) { diff --git a/src/Engine/Graphics/Vulkan/VulkanShader.cpp b/src/Engine/Graphics/Vulkan/VulkanShader.cpp index b2f0b29..bb2d9b0 100644 --- a/src/Engine/Graphics/Vulkan/VulkanShader.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanShader.cpp @@ -2,7 +2,7 @@ #include "VulkanGraphics.h" #include "VulkanDescriptorSets.h" #include "slang.h" -//#include "spirv_cross/spirv_reflect.hpp" +#include "stdlib.h" using namespace slang; using namespace Seele; @@ -55,7 +55,7 @@ static SlangStage getStageFromShaderType(ShaderType type) void Shader::create(const ShaderCreateInfo& createInfo) { entryPointName = createInfo.entryPoint; - static SlangSession* session = spCreateSession(NULL); + static SlangSession* session = spCreateSession(nullptr); SlangCompileRequest* request = spCreateCompileRequest(session); int targetIndex = spAddCodeGenTarget(request, SLANG_SPIRV); diff --git a/src/Engine/Graphics/Vulkan/VulkanViewport.cpp b/src/Engine/Graphics/Vulkan/VulkanViewport.cpp index 9fae121..caa107a 100644 --- a/src/Engine/Graphics/Vulkan/VulkanViewport.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanViewport.cpp @@ -162,9 +162,9 @@ void Window::advanceBackBuffer() imageAcquiredSemaphore = imageAcquired[semaphoreIndex]; currentImageIndex = imageIndex; - PCmdBuffer cmdBuffer = graphics->getGraphicsCommands()->getCommands(); backBufferImages[currentImageIndex]->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); VkClearColorValue clearColor = {0.0f, 0.0f, 0.0f, 0.0f}; + PCmdBuffer cmdBuffer = graphics->getGraphicsCommands()->getCommands(); VkImageSubresourceRange range = init::ImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT); vkCmdClearColorImage( cmdBuffer->getHandle(), diff --git a/src/Engine/Material/Material.cpp b/src/Engine/Material/Material.cpp index 1be78d6..69bd693 100644 --- a/src/Engine/Material/Material.cpp +++ b/src/Engine/Material/Material.cpp @@ -54,7 +54,6 @@ void Material::compile() std::string profile = j["profile"].get(); codeStream << "import VERTEX_INPUT_IMPORT;" << std::endl; - codeStream << "import LightEnv;" << std::endl; codeStream << "import Material;" << std::endl; codeStream << "import BRDF;" << std::endl; codeStream << "import MaterialParameter;" << std::endl; @@ -105,7 +104,9 @@ void Material::compile() layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE); if(defaultValue != param.value().end()) { - p->data = AssetRegistry::findTexture(defaultValue.value().get()); + std::string defaultString = defaultValue.value().get(); + std::cout << "Texture parameter " << defaultString << std::endl; + p->data = AssetRegistry::findTexture(defaultString); } else { diff --git a/src/Engine/Material/ShaderExpression.cpp b/src/Engine/Material/ShaderExpression.cpp index 78ed264..435eced 100644 --- a/src/Engine/Material/ShaderExpression.cpp +++ b/src/Engine/Material/ShaderExpression.cpp @@ -82,7 +82,7 @@ CombinedTextureParameter::~CombinedTextureParameter() } -void CombinedTextureParameter::updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) +void CombinedTextureParameter::updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8*) { descriptorSet->updateTexture(binding, data->getTexture(), sampler); } \ No newline at end of file diff --git a/src/Engine/MinimalEngine.h b/src/Engine/MinimalEngine.h index 82f6ae9..5be9c51 100644 --- a/src/Engine/MinimalEngine.h +++ b/src/Engine/MinimalEngine.h @@ -53,9 +53,9 @@ public: std::scoped_lock lock(registeredObjectsLock); registeredObjects.erase(handle); } - #pragma warning( disable: 4150) +// #pragma warning( disable: 4150) delete handle; - #pragma warning( default: 4150) +// #pragma warning( default: 4150) } RefObject &operator=(const RefObject &rhs) { diff --git a/src/Engine/Scene/Components/CameraComponent.cpp b/src/Engine/Scene/Components/CameraComponent.cpp index 3c29868..bf49b1a 100644 --- a/src/Engine/Scene/Components/CameraComponent.cpp +++ b/src/Engine/Scene/Components/CameraComponent.cpp @@ -6,8 +6,8 @@ using namespace Seele; CameraComponent::CameraComponent() - : bNeedsProjectionBuild(true) - , bNeedsViewBuild(true) + : bNeedsViewBuild(true) + , bNeedsProjectionBuild(true) , originPoint(0, 0, 0) , cameraPosition(0, 0, 0) { diff --git a/src/Engine/Scene/Components/Component.cpp b/src/Engine/Scene/Components/Component.cpp index 11f0f13..f27bcdd 100644 --- a/src/Engine/Scene/Components/Component.cpp +++ b/src/Engine/Scene/Components/Component.cpp @@ -13,7 +13,7 @@ Component::Component() Component::~Component() { } -void Component::tick(float deltaTime) +void Component::tick(float) { } PComponent Component::getParent() diff --git a/src/Engine/UI/Elements/Element.cpp b/src/Engine/UI/Elements/Element.cpp index 4efd4c3..8fe0a5a 100644 --- a/src/Engine/UI/Elements/Element.cpp +++ b/src/Engine/UI/Elements/Element.cpp @@ -11,6 +11,11 @@ Element::~Element() { } +PElement Element::getParent() const +{ + return parent; +} + void Element::addChild(PElement element) { children.add(element); diff --git a/src/Engine/Window/InspectorView.cpp b/src/Engine/Window/InspectorView.cpp index 9959db0..7c0d1c6 100644 --- a/src/Engine/Window/InspectorView.cpp +++ b/src/Engine/Window/InspectorView.cpp @@ -5,7 +5,7 @@ using namespace Seele; InspectorView::InspectorView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &createInfo) : View(graphics, window, createInfo) - , renderGraph(UIPass(graphics, viewport, new Gfx::SwapchainAttachment(window->getGfxHandle()))) + , uiPass(UIPass(graphics, viewport, new Gfx::SwapchainAttachment(window->getGfxHandle()))) { } @@ -13,7 +13,7 @@ InspectorView::~InspectorView() { } -void InspectorView::beginFrame() +void InspectorView::beginUpdate() { } @@ -22,7 +22,7 @@ void InspectorView::update() } -void InspectorView::endFrame() +void InspectorView::commitUpdate() { } diff --git a/src/Engine/Window/InspectorView.h b/src/Engine/Window/InspectorView.h index 56e89f5..d9fd8b5 100644 --- a/src/Engine/Window/InspectorView.h +++ b/src/Engine/Window/InspectorView.h @@ -13,15 +13,15 @@ public: InspectorView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &createInfo); virtual ~InspectorView(); - virtual void beginFrame() override; + virtual void beginUpdate() override; virtual void update() override; - virtual void endFrame() override; + virtual void commitUpdate() override; virtual void prepareRender() override; virtual void render() override; void selectActor(); protected: - UIPass renderGraph; + UIPass uiPass; UIPassData uiPassData; diff --git a/src/Engine/Window/SceneView.cpp b/src/Engine/Window/SceneView.cpp index 68a37ce..12ab04a 100644 --- a/src/Engine/Window/SceneView.cpp +++ b/src/Engine/Window/SceneView.cpp @@ -1,6 +1,7 @@ #include "SceneView.h" #include "Scene/Scene.h" #include "Window.h" +#include "Asset/AssetRegistry.h" #include "Scene/Actor/CameraActor.h" #include "Scene/Components/CameraComponent.h" @@ -15,15 +16,39 @@ Seele::SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const Viewpo { scene = new Scene(graphics); scene->addActor(activeCamera); + AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Body_Diffuse.png"); + AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Body_Lightmap.png"); + AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Face_Diffuse.png"); + AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Hair_Diffuse.png"); + AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Hair_Lightmap.png"); + AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Tex_FaceLightmap.png"); + AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Ayaka.fbx"); + PPrimitiveComponent ayaka = new PrimitiveComponent(AssetRegistry::findMesh("Ayaka")); + ayaka->addWorldTranslation(Vector(0, 0, 100)); + ayaka->setWorldScale(Vector(0.1f, 0.1f, 0.1f)); + scene->addPrimitiveComponent(ayaka); + + PRenderGraphResources resources = new RenderGraphResources(); + depthPrepass.setResources(resources); + lightCullingPass.setResources(resources); + basePass.setResources(resources); + + depthPrepass.publishOutputs(); + lightCullingPass.publishOutputs(); + basePass.publishOutputs(); + + depthPrepass.createRenderPass(); + lightCullingPass.createRenderPass(); + basePass.createRenderPass(); } Seele::SceneView::~SceneView() { } -void SceneView::beginFrame() +void SceneView::beginUpdate() { - View::beginFrame(); + View::beginUpdate(); scene->tick(Gfx::currentFrameDelta); } @@ -31,7 +56,7 @@ void SceneView::update() { } -void SceneView::endFrame() +void SceneView::commitUpdate() { depthPrepassData.staticDrawList = scene->getStaticMeshes(); lightCullingPassData.lightEnv = scene->getLightBuffer(); @@ -47,9 +72,17 @@ void SceneView::prepareRender() void SceneView::render() { + depthPrepass.beginFrame(); + lightCullingPass.beginFrame(); + basePass.beginFrame(); + depthPrepass.render(); lightCullingPass.render(); basePass.render(); + + depthPrepass.endFrame(); + lightCullingPass.endFrame(); + basePass.endFrame(); } void SceneView::keyCallback(KeyCode code, InputAction action, KeyModifier) diff --git a/src/Engine/Window/SceneView.h b/src/Engine/Window/SceneView.h index 3625750..7e28e59 100644 --- a/src/Engine/Window/SceneView.h +++ b/src/Engine/Window/SceneView.h @@ -13,9 +13,9 @@ class SceneView : public View public: SceneView(Gfx::PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo); ~SceneView(); - virtual void beginFrame() override; + virtual void beginUpdate() override; virtual void update() override; - virtual void endFrame() override; + virtual void commitUpdate() override; virtual void prepareRender() override; virtual void render() override; diff --git a/src/Engine/Window/View.cpp b/src/Engine/Window/View.cpp index 5baa8b2..cda1898 100644 --- a/src/Engine/Window/View.cpp +++ b/src/Engine/Window/View.cpp @@ -14,7 +14,7 @@ View::~View() { } -void View::applyArea(URect area) +void View::applyArea(URect) { } diff --git a/src/Engine/Window/View.h b/src/Engine/Window/View.h index a5d1150..551b17a 100644 --- a/src/Engine/Window/View.h +++ b/src/Engine/Window/View.h @@ -12,10 +12,10 @@ public: virtual ~View(); // These are called from the view thread, and handle updating game data - virtual void beginFrame() {} + virtual void beginUpdate() {} virtual void update() {} // End frame is called with a lock, so it is safe to write to shared memory - virtual void endFrame() {} + virtual void commitUpdate() {} // These are called from the render thread // prepare render is also locked, so reading from shared memory is also safe diff --git a/src/Engine/Window/Window.cpp b/src/Engine/Window/Window.cpp index 3acdc17..51cacdb 100644 --- a/src/Engine/Window/Window.cpp +++ b/src/Engine/Window/Window.cpp @@ -58,9 +58,9 @@ void Window::viewWorker(WindowView* windowView) { while(true) { - windowView->view->beginFrame(); + windowView->view->beginUpdate(); windowView->view->update(); std::lock_guard lock(windowView->workerMutex); - windowView->view->endFrame(); + windowView->view->commitUpdate(); } } diff --git a/src/Engine/main.cpp b/src/Engine/main.cpp index 3948725..d9aafd3 100644 --- a/src/Engine/main.cpp +++ b/src/Engine/main.cpp @@ -9,6 +9,7 @@ using namespace Seele; int main() { PWindowManager windowManager = new WindowManager(); + AssetRegistry::init("/home/dynamitos/TestSeeleProject"); WindowCreateInfo mainWindowInfo; mainWindowInfo.title = "SeeleEngine"; mainWindowInfo.width = 1280; @@ -33,15 +34,6 @@ int main() PInspectorView inspectorView = new InspectorView(windowManager->getGraphics(), window, inspectorViewInfo); window->addView(inspectorView); sceneView->setFocused(); - 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.fbx"); - PPrimitiveComponent plane = new PrimitiveComponent(AssetRegistry::findMesh("plane")); - plane->setWorldScale(Vector(100, 100, 100)); - PPrimitiveComponent arissa = new PrimitiveComponent(AssetRegistry::findMesh("Ely")); - arissa->addWorldTranslation(Vector(0, 0, 100)); - arissa->setWorldScale(Vector(0.1f, 0.1f, 0.1f)); while (windowManager->isActive()) { windowManager->render();