From f635ee21008dc80bf89678f8d6882096a5590ba8 Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Tue, 15 Nov 2022 12:19:11 +0100 Subject: [PATCH] Implementing ECS SystemBase and updating slang --- .gitmodules | 3 + CMakeLists.txt | 25 +- cmake/SuperBuild.cmake | 5 + external/slang | 2 +- external/thread-pool | 1 + res/shaders/DepthPrepass.slang | 3 +- res/shaders/ForwardPlus.slang | 6 +- res/shaders/LightCulling.slang | 2 +- res/shaders/Mat.slang | 7 + res/shaders/Simple.slang | 10 + res/shaders/lib/Material.slang | 3 +- res/shaders/lib/StaticMeshVertexInput.slang | 4 +- res/shaders/shaders.slang | 487 +----------------- src/Editor/main.cpp | 1 - src/Engine/Asset/Asset.h | 4 +- src/Engine/Asset/AssetRegistry.cpp | 4 +- src/Engine/Asset/AssetRegistry.h | 1 + src/Engine/Asset/FontAsset.cpp | 4 +- src/Engine/Asset/FontAsset.h | 4 +- src/Engine/Asset/MeshLoader.cpp | 28 +- src/Engine/Asset/MeshLoader.h | 4 +- src/Engine/Asset/TextureAsset.cpp | 8 +- src/Engine/Asset/TextureAsset.h | 4 +- src/Engine/Containers/Array.h | 10 + src/Engine/Containers/Map.h | 36 +- src/Engine/Graphics/Graphics.cpp | 6 +- src/Engine/Graphics/GraphicsInitializer.h | 6 +- src/Engine/Graphics/GraphicsResources.cpp | 136 ++++- src/Engine/Graphics/GraphicsResources.h | 40 +- src/Engine/Graphics/MeshBatch.h | 4 +- src/Engine/Graphics/RenderPass/BasePass.cpp | 13 +- src/Engine/Graphics/RenderPass/BasePass.h | 5 +- .../Graphics/RenderPass/DepthPrepass.cpp | 13 +- src/Engine/Graphics/RenderPass/DepthPrepass.h | 5 +- .../Graphics/RenderPass/LightCullingPass.cpp | 36 +- .../Graphics/RenderPass/LightCullingPass.h | 5 +- src/Engine/Graphics/RenderPass/RenderPass.h | 13 +- src/Engine/Graphics/RenderPass/TextPass.cpp | 38 +- src/Engine/Graphics/RenderPass/TextPass.h | 14 +- src/Engine/Graphics/RenderPass/UIPass.cpp | 16 +- src/Engine/Graphics/StaticMeshVertexInput.cpp | 6 +- src/Engine/Graphics/VertexShaderInput.cpp | 16 +- src/Engine/Graphics/VertexShaderInput.h | 2 +- .../Graphics/Vulkan/VulkanAllocator.cpp | 6 +- src/Engine/Graphics/Vulkan/VulkanAllocator.h | 6 +- src/Engine/Graphics/Vulkan/VulkanBuffer.cpp | 26 +- .../Graphics/Vulkan/VulkanCommandBuffer.cpp | 2 +- src/Engine/Graphics/Vulkan/VulkanGraphics.h | 1 + .../Graphics/Vulkan/VulkanGraphicsEnums.cpp | 4 +- .../Graphics/Vulkan/VulkanGraphicsResources.h | 9 +- src/Engine/Graphics/Vulkan/VulkanShader.cpp | 161 +++--- src/Engine/Material/MaterialAsset.cpp | 5 +- src/Engine/Material/MaterialAsset.h | 2 + src/Engine/Material/ShaderExpression.cpp | 2 +- src/Engine/Material/ShaderExpression.h | 2 +- src/Engine/Math/CMakeLists.txt | 6 +- src/Engine/Math/Math.h | 3 + src/Engine/Math/Matrix.h | 3 + src/Engine/Math/Transform.cpp | 27 +- src/Engine/Math/Transform.h | 9 +- src/Engine/Math/Vector.cpp | 10 +- src/Engine/Math/Vector.h | 6 + src/Engine/Scene/Actor/Actor.cpp | 131 +---- src/Engine/Scene/Actor/Actor.h | 47 +- src/Engine/Scene/Actor/CMakeLists.txt | 4 +- src/Engine/Scene/Actor/CameraActor.cpp | 26 +- src/Engine/Scene/Actor/CameraActor.h | 12 +- src/Engine/Scene/Actor/Entity.cpp | 15 + src/Engine/Scene/Actor/Entity.h | 25 + src/Engine/Scene/CMakeLists.txt | 3 +- src/Engine/Scene/Component/CMakeLists.txt | 8 + .../Camera.cpp} | 37 +- .../CameraComponent.h => Component/Camera.h} | 38 +- src/Engine/Scene/Component/Component.h | 47 ++ src/Engine/Scene/Component/StaticMesh.h | 15 + src/Engine/Scene/Component/Transform.cpp | 34 ++ src/Engine/Scene/Component/Transform.h | 52 ++ src/Engine/Scene/Components/CMakeLists.txt | 12 - src/Engine/Scene/Components/Component.cpp | 201 -------- src/Engine/Scene/Components/Component.h | 77 --- src/Engine/Scene/Components/MyComponent.cpp | 30 -- src/Engine/Scene/Components/MyComponent.h | 20 - .../Scene/Components/MyOtherComponent.cpp | 15 - .../Scene/Components/MyOtherComponent.h | 15 - .../Scene/Components/PrimitiveComponent.cpp | 54 -- .../Scene/Components/PrimitiveComponent.h | 36 -- src/Engine/Scene/Scene.cpp | 116 +++-- src/Engine/Scene/Scene.h | 48 +- src/Engine/Scene/SceneUpdater.cpp | 75 --- src/Engine/Scene/SceneUpdater.h | 31 -- src/Engine/Scene/System/CMakeLists.txt | 7 + src/Engine/Scene/System/CameraSystem.cpp | 11 + src/Engine/Scene/System/CameraSystem.h | 18 + src/Engine/Scene/System/Executor.cpp | 4 + src/Engine/Scene/System/Executor.h | 19 + src/Engine/Scene/System/SystemBase.h | 47 ++ src/Engine/UI/Elements/Element.cpp | 4 +- src/Engine/UI/Elements/Element.h | 6 +- src/Engine/UI/HorizontalLayout.cpp | 4 +- src/Engine/UI/RenderHierarchy.h | 8 +- src/Engine/UI/System.cpp | 10 +- src/Engine/UI/VerticalLayout.cpp | 4 +- src/Engine/Window/SceneView.cpp | 53 +- src/Engine/Window/SceneView.h | 5 + src/Engine/Window/View.cpp | 2 +- src/Engine/Window/View.h | 2 +- 106 files changed, 1083 insertions(+), 1675 deletions(-) create mode 160000 external/thread-pool create mode 100644 res/shaders/Mat.slang create mode 100644 res/shaders/Simple.slang create mode 100644 src/Engine/Scene/Actor/Entity.cpp create mode 100644 src/Engine/Scene/Actor/Entity.h create mode 100644 src/Engine/Scene/Component/CMakeLists.txt rename src/Engine/Scene/{Components/CameraComponent.cpp => Component/Camera.cpp} (63%) rename src/Engine/Scene/{Components/CameraComponent.h => Component/Camera.h} (62%) create mode 100644 src/Engine/Scene/Component/Component.h create mode 100644 src/Engine/Scene/Component/StaticMesh.h create mode 100644 src/Engine/Scene/Component/Transform.cpp create mode 100644 src/Engine/Scene/Component/Transform.h delete mode 100644 src/Engine/Scene/Components/CMakeLists.txt delete mode 100644 src/Engine/Scene/Components/Component.cpp delete mode 100644 src/Engine/Scene/Components/Component.h delete mode 100644 src/Engine/Scene/Components/MyComponent.cpp delete mode 100644 src/Engine/Scene/Components/MyComponent.h delete mode 100644 src/Engine/Scene/Components/MyOtherComponent.cpp delete mode 100644 src/Engine/Scene/Components/MyOtherComponent.h delete mode 100644 src/Engine/Scene/Components/PrimitiveComponent.cpp delete mode 100644 src/Engine/Scene/Components/PrimitiveComponent.h delete mode 100644 src/Engine/Scene/SceneUpdater.cpp delete mode 100644 src/Engine/Scene/SceneUpdater.h create mode 100644 src/Engine/Scene/System/CMakeLists.txt create mode 100644 src/Engine/Scene/System/CameraSystem.cpp create mode 100644 src/Engine/Scene/System/CameraSystem.h create mode 100644 src/Engine/Scene/System/Executor.cpp create mode 100644 src/Engine/Scene/System/Executor.h create mode 100644 src/Engine/Scene/System/SystemBase.h diff --git a/.gitmodules b/.gitmodules index dff0602..ad3f32a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -34,3 +34,6 @@ [submodule "external/entt"] path = external/entt url = git@github.com:skypjack/entt.git +[submodule "external/thread-pool"] + path = external/thread-pool + url = https://github.com/DeveloperPaul123/thread-pool.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e0b936..41dcc93 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,7 @@ set(CMAKE_CXX_STANDARD 20) option (USE_SUPERBUILD "Whether or not a superbuild should be invoked" ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +set(CMAKE_COMPILE_WARNING_AS_ERROR OFF) set(ENGINE_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/src/Engine) set(EXTERNAL_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/external) @@ -25,6 +26,7 @@ set(FREETYPE_ROOT ${EXTERNAL_ROOT}/freetype) set(SPIRV_ROOT ${EXTERNAL_ROOT}/SPIRV-Cross) set(ENTT_ROOT ${EXTERNAL_ROOT}/entt) set(NSAM_ROOT ${EXTERNAL_ROOT}/aftermath) +set(THREADPOOL_ROOT ${EXTERNAL_ROOT}/thread-pool) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/) set(Boost_NO_WARN_NEW_VERSIONS 1) @@ -53,7 +55,8 @@ if(CMAKE_DEBUG_POSTFIX) add_compile_definitions(ENABLE_VALIDATION) add_compile_definitions(SEELE_DEBUG) endif() -add_library(Engine "") + +add_library(Engine SHARED "") add_executable(Editor "") target_compile_definitions(Engine PUBLIC GLFW_WINDOWS) target_include_directories(Engine PUBLIC src/Engine) @@ -70,9 +73,10 @@ target_link_libraries(Engine PUBLIC nsam) target_link_libraries(Engine PUBLIC ktx) target_link_libraries(Engine PUBLIC stb) target_link_libraries(Engine PUBLIC nlohmann_json::nlohmann_json) +target_link_libraries(Engine PUBLIC dp::thread-pool) if(UNIX) -target_link_libraries(Engine Threads::Threads) -target_link_libraries(Engine dl) + target_link_libraries(Engine Threads::Threads) + target_link_libraries(Engine dl) endif() target_precompile_headers(Engine PUBLIC @@ -89,20 +93,19 @@ target_precompile_headers(Engine - - ) - -target_link_libraries(Editor PRIVATE Engine) - -add_subdirectory(src/) - + ) + if(MSVC) set(_CRT_SECURE_NO_WARNINGS) - target_compile_options(Engine PUBLIC -Zi -MP -DEBUG) + target_compile_options(Engine PUBLIC /Zi /MP /W4 /DEBUG "/WX-") else() target_compile_options(Engine PUBLIC -g -Wall -Wextra -Wno-delete-incomplete -pedantic -fcoroutines) endif() +target_link_libraries(Editor PUBLIC Engine) + +add_subdirectory(src/) + add_executable(Seele_unit_tests "") add_subdirectory(test/) diff --git a/cmake/SuperBuild.cmake b/cmake/SuperBuild.cmake index 6c95591..b3e102a 100644 --- a/cmake/SuperBuild.cmake +++ b/cmake/SuperBuild.cmake @@ -31,6 +31,7 @@ add_subdirectory(${JSON_ROOT}) #--------------GLM------------------------------ add_subdirectory(${GLM_ROOT}) +target_compile_options(glm_shared INTERFACE /W0) #--------------GLFW------------------------------ set(ENKITS_BUILD_EXAMPLES OFF CACHE BOOL "Build basic example applications" ) @@ -61,6 +62,10 @@ target_link_libraries(nsam INTERFACE ${NSAM_ROOT}/lib/${CMAKE_PLATFORM}/*.lib) set_target_properties(nsam PROPERTIES NSAM_BINARY ${NSAM_ROOT}/lib/${CMAKE_PLATFORM}/GFSDK_Aftermath_Lib.${CMAKE_PLATFORM}.dll) set_target_properties(nsam PROPERTIES LLVM_BINARY ${NSAM_ROOT}/lib/${CMAKE_PLATFORM}/llvm_7_0_1.dll) +#--------------thread-pool------------------------------ +add_subdirectory(${THREADPOOL_ROOT}) + +target_compile_options(ThreadPool INTERFACE "/WX-") #--------------SLang------------------------------ string(TOLOWER release_${CMAKE_PLATFORM} SLANG_CONFIG) diff --git a/external/slang b/external/slang index ec530b3..cedd936 160000 --- a/external/slang +++ b/external/slang @@ -1 +1 @@ -Subproject commit ec530b300524635dfe0fd86949b0a4fc5c19a984 +Subproject commit cedd93690c63188cf98e452c9d104cf51aad6c4e diff --git a/external/thread-pool b/external/thread-pool new file mode 160000 index 0000000..dad69c1 --- /dev/null +++ b/external/thread-pool @@ -0,0 +1 @@ +Subproject commit dad69c1661983379af6cecbf5e33e83f764cd61d diff --git a/res/shaders/DepthPrepass.slang b/res/shaders/DepthPrepass.slang index bb2d47b..602d90a 100644 --- a/res/shaders/DepthPrepass.slang +++ b/res/shaders/DepthPrepass.slang @@ -1,8 +1,7 @@ import Common; import Material; -import VERTEX_INPUT_IMPORT; -import MATERIAL_IMPORT; import PrimitiveSceneData; +import StaticMeshVertexInput; struct VertexStageOutput diff --git a/res/shaders/ForwardPlus.slang b/res/shaders/ForwardPlus.slang index 359cc23..33f0d3c 100644 --- a/res/shaders/ForwardPlus.slang +++ b/res/shaders/ForwardPlus.slang @@ -2,9 +2,8 @@ import Common; import LightEnv; import BRDF; import Material; +import StaticMeshVertexInput; -import VERTEX_INPUT_IMPORT; -import MATERIAL_IMPORT; import PrimitiveSceneData; import MaterialParameter; @@ -13,7 +12,6 @@ StructuredBuffer lightIndexList; layout(set = INDEX_LIGHT_ENV, binding = 5) RWTexture2D lightGrid; - struct VertexStageOutput { ShaderAttributeInterpolation shaderAttributeInterpolation : Interpolation; @@ -50,7 +48,7 @@ float4 fragmentMain( ) : SV_Target { MaterialFragmentParameter materialParams = input.getMaterialParameter(position); - TMaterial.BRDF brdf = gMaterial.prepare(materialParams); + let brdf = gMaterial.prepare(materialParams); float3 viewDir = normalize(materialParams.viewDir); diff --git a/res/shaders/LightCulling.slang b/res/shaders/LightCulling.slang index 93af0e6..f63c116 100644 --- a/res/shaders/LightCulling.slang +++ b/res/shaders/LightCulling.slang @@ -82,7 +82,7 @@ void tAppendLight(uint lightIndex) [shader("compute")] void cullLights(ComputeShaderInput in) { - int2 texCoord = in.dispatchThreadID.xy; + int2 texCoord = int2(in.dispatchThreadID.xy); float fDepth = depthTextureVS.Load(int3(texCoord, 0)).r; uint uDepth = asuint(fDepth); diff --git a/res/shaders/Mat.slang b/res/shaders/Mat.slang new file mode 100644 index 0000000..60c6738 --- /dev/null +++ b/res/shaders/Mat.slang @@ -0,0 +1,7 @@ +interface IMaterial +{ + float4 sample(float2 texCoord); +} + +type_param TMaterial : IMaterial; +ParameterBlock gMaterial; \ No newline at end of file diff --git a/res/shaders/Simple.slang b/res/shaders/Simple.slang new file mode 100644 index 0000000..a5fde30 --- /dev/null +++ b/res/shaders/Simple.slang @@ -0,0 +1,10 @@ +import Mat; + + +struct SimpleMaterial : IMaterial +{ + float4 sample(float2 texCoord) + { + return float4(1, 0, 1, 1); + } +} diff --git a/res/shaders/lib/Material.slang b/res/shaders/lib/Material.slang index cfd2f47..52e82ea 100644 --- a/res/shaders/lib/Material.slang +++ b/res/shaders/lib/Material.slang @@ -17,6 +17,5 @@ interface IMaterial float getSheen(MaterialFragmentParameter input); }; -type_param TMaterial : IMaterial; layout(set = INDEX_MATERIAL, binding = 0, std430) -ParameterBlock gMaterial; +ParameterBlock gMaterial; diff --git a/res/shaders/lib/StaticMeshVertexInput.slang b/res/shaders/lib/StaticMeshVertexInput.slang index ed37a38..f04a21a 100644 --- a/res/shaders/lib/StaticMeshVertexInput.slang +++ b/res/shaders/lib/StaticMeshVertexInput.slang @@ -63,7 +63,7 @@ struct ShaderAttributeInterpolation #if NUM_MATERIAL_TEXCOORDS for(int i = 0; i < NUM_MATERIAL_TEXCOORDS; ++i) { - if(i % 2) + if(i % 2 == 1) { result.texCoords[i] = packedTexCoords[i / 2].zw; } @@ -191,7 +191,7 @@ struct VertexShaderInput result.viewPosition = vertexParams.viewPosition; for(int i = 0; i < NUM_MATERIAL_TEXCOORDS; ++i) { - if(i % 2) + if(i % 2 == 1) { result.packedTexCoords[i / 2].zw = vertexParams.texCoords[i]; } diff --git a/res/shaders/shaders.slang b/res/shaders/shaders.slang index 15ce012..691205d 100644 --- a/res/shaders/shaders.slang +++ b/res/shaders/shaders.slang @@ -1,485 +1,8 @@ -// shaders.slang +import Mat; +import Simple; -// -// This example builds on the simplistic shaders presented in the -// "Hello, World" example by adding support for (intentionally -// simplistic) surface materil and light shading. -// -// The code here is not meant to exemplify state-of-the-art material -// and lighting techniques, but rather to show how a shader -// library can be developed in a modular fashion without reliance -// on the C preprocessor manual parameter-binding decorations. -// - -// We are going to define a simple model for surface material shading. -// -// The first building block in our model will be the representation of -// the geometry attributes of a surface as fed into the material. -// -struct SurfaceGeometry -{ - float3 position; - float3 normal; - - // TODO: tangent vectors would be the natural next thing to add here, - // and would be required for anisotropic materials. However, the - // simplistic model loading code we are currently using doesn't - // produce tangents... - // - // float3 tangentU; - // float3 tangentV; - - // We store a single UV parameterization in these geometry attributes. - // A more complex renderer might need support for multiple UV sets, - // and indeed it might choose to use interfaces and generics to capture - // the different requirements that different materials impose on - // the available surface attributes. We won't go to that kind of - // trouble for such a simple example. - // - float2 uv; -}; -// -// Next, we want to define the fundamental concept of a refletance -// function, so that we can use it as a building block for other -// parts of the system. This is a case where we are trying to -// show how a proper physically-based renderer (PBR) might -// decompose the problem using Slang, even though our simple -// example is *not* physically based. -// -interface IBRDF -{ - // Technically, a BRDF is only a function of the incident - // (`wi`) and exitant (`wo`) directions, but for simplicity - // we are passing in the surface normal (`N`) as well. - // - float3 evaluate(float3 wo, float3 wi, float3 N); -}; -// -// We can now define various implemntations of the `IBRDF` interface -// that represent different reflectance functions we want to support. -// For now we keep things simple by defining about the simplest -// reflectance function we can think of: the Blinn-Phong reflectance -// model: -// -struct BlinnPhong : IBRDF -{ - // Blinn-Phong needs diffuse and specular reflectances, plus - // a specular exponent value (which relates to "roughness" - // in more modern physically-based models). - // - float3 kd; - float3 ks; - float specularity; - - // Here we implement the one requirement of the `IBRDF` interface - // for our concrete implementation, using a textbook definition - // of Blinng-Phong shading. - // - // Note: our "BRDF" definition here folds the N-dot-L term into - // the evlauation of the reflectance function in case there are - // useful algebraic simplifications this enables. - // - float3 evaluate(float3 V, float3 L, float3 N) - { - float nDotL = saturate(dot(N, L)); - float3 H = normalize(L + V); - float nDotH = saturate(dot(N, H)); - - return kd*nDotL + ks*pow(nDotH, specularity); - } -}; -// -// It is important to note that a reflectance function is *not* -// a "material." In most cases, a material will have spatially-varying -// properties so that it cannot be summarized as a single `IBRDF` -// instance. -// -// Thus a "material" is a value that can produce a BRDF for any point -// on a surface (e.g., by sampling texture maps, etc.). -// -interface IMaterial -{ - // Different concrete material implementations might yield BRDF - // values with different types. E.g., one material might yield - // reflectance functions using `BlinnPhong` while another uses - // a much more complicated/accurate representation. - // - // We encapsulate the choice of BRDF parameters/evaluation in - // our material interface with an "associated type." In the - // simplest terms, think of this as an interface requirement - // that is a type, instead of a method. - // - // (If you are C++-minded, you might think of this as akin to - // how every container provided an `iterator` type, but different - // containers may have different types of iterators) - // - associatedtype BRDF : IBRDF; - - // For our simple example program, it is enough for a material to - // be able to return a BRDF given a point on the surface. - // - // A more complex implementation of material shading might also - // have the material return updated surface geometry to reflect - // the result of normal mapping, occlusion mapping, etc. or - // return an opacity/coverage value for partially transparent - // surfaces. - // - BRDF prepare(SurfaceGeometry geometry); -}; - -// We will now define a trivial first implementation of the material -// interface, which uses our Blinn-Phong BRDF with uniform values -// for its parameters. -// -// Note that this implemetnation is being provided *after* the -// shader parameter `gMaterial` is declared, so that there is no -// assumption in the shader code that `gMaterial` will be plugged -// in using an instance of `SimpleMaterial` -// -// -struct SimpleMaterial : IMaterial -{ - // We declare the properties we need as fields of the material type. - // When `SimpleMaterial` is used for `TMaterial` above, then - // `gMaterial` will be a `ParameterBlock`, and these - // parameters will be allocated to a constant buffer that is part of - // that parameter block. - // - // TODO: A future version of this example will include texture parameters - // here to show that they are declared just like simple uniforms. - // - float3 diffuseColor; - float3 specularColor; - float specularity; - - // To satisfy the requirements of the `IMaterial` interface, our - // material type needs to provide a suitable `BRDF` type. We - // do this by using a simple `typedef`, although a nested - // `struct` type can also satisfy an associated type requirement. - // - // A future version of the Slang compiler may allow the "right" - // associated type definition to be inferred from the signature - // of the `prepare()` method below. - // - typedef BlinnPhong BRDF; - - BlinnPhong prepare(SurfaceGeometry geometry) - { - BlinnPhong brdf; - brdf.kd = diffuseColor; - brdf.ks = specularColor; - brdf.specularity = specularity; - return brdf; - } -}; -// -// Note that no other code in this file statically -// references the `SimpleMaterial` type, and instead -// it is up to the application to "plug in" this type, -// or another `IMaterial` implementation for the -// `TMaterial` parameter. -// - -// A light, or an entire lighting *environment* is an object -// that can illuminate a surface using some BRDF implemented -// with our abstractions above. -// -interface ILightEnv -{ - // The `illuminate` method is intended to integrate incoming - // illumination from this light (environment) incident at the - // surface point given by `g` (which has the reflectance function - // `brdf`) and reflected into the outgoing direction `wo`. - // - float3 illuminate(SurfaceGeometry g, B brdf, float3 wo); - // - // Note that the `illuminate()` method is allowed as an interface - // requirement in Slang even though it is a generic. Constract that - // with C++ where a `template` method cannot be `virtual`. -}; - -// Given the `ILightEnv` interface, we can write up almost textbook -// definition of directional and point lights. - -struct DirectionalLight : ILightEnv -{ - float3 direction; - float3 intensity; - - float3 illuminate(SurfaceGeometry g, B brdf, float3 wo) - { - return intensity * brdf.evaluate(wo, direction, g.normal); - } -}; -struct PointLight : ILightEnv -{ - float3 position; - float3 intensity; - - float3 illuminate(SurfaceGeometry g, B brdf, float3 wo) - { - float3 delta = position - g.position; - float d = length(delta); - float3 direction = normalize(delta); - float3 illuminance = intensity / (d*d); - return illuminance * brdf.evaluate(wo, direction, g.normal); - } -}; - -// In most cases, a shader entry point will only be specialized for a single -// material, but interesting rendering almost always needs multiple lights. -// For that reason we will next define types to represent *composite* lighting -// environment with multiple lights. -// -// A naive approach might be to have a single undifferntiated list of lights -// where any type of light may appear at any index, but this would lose all -// of the benefits of static specialization: we would have to perform dynamic -// branching to determine what kind of light is stored at each index. -// -// Instead, we will start with a type for *homogeneous* arrays of lights: -// -struct LightArray : ILightEnv -{ - // The `LightArray` type has two generic parameters: - // - // - `L` is a type parameter, representing the type of lights that will be in our array - // - `N` is a generic *value* parameter, representing the maximum number of lights allowed - // - // Slang's support for generic value parameters is currently experimental, - // and the syntax might change. - - int count; - L lights[N]; - - float3 illuminate(SurfaceGeometry g, B brdf, float3 wo) - { - // Our light array integrates illumination by naively summing - // contributions from all the lights in the array (up to `count`). - // - // A more advanced renderer might try apply sampling techniques - // to pick a subset of lights to sample. - // - float3 sum = 0; - for( int ii = 0; ii < count; ++ii ) - { - sum += lights[ii].illuminate(g, brdf, wo); - } - return sum; - } -}; - -// `LightArray` can handle multiple lights as long as they have the -// same type, but we need a way to have a scene with multiple lights -// of different types *without* losing static specialization. -// -// The `LightPair` type supports this in about the simplest way -// possible, by aggregating a light (environment) of type `T` and -// one of type `U`. Those light environments might themselves be -// `LightArray`s or `LightPair`s, so that arbitrarily complex -// environments can be created from just these two composite types. -// -// This is probably a good place to insert a reminder the Slang's -// generics are *not* C++ templates, so that the error messages -// produced when working with these types are in general reasonable, -// and this is *not* any form of "template metaprogramming." -// -// That said, we expect that future versions of Slang will make -// defining composite types light this a bit less cumbersome. -// -struct LightPair : ILightEnv -{ - T first; - U second; - - float3 illuminate(SurfaceGeometry g, B brdf, float3 wo) - { - return first.illuminate(g, brdf, wo) - + second.illuminate(g, brdf, wo); - } -}; - -// As a final (degenerate) case, we will define a light -// environment with *no* lights, which contributes no illumination. -// -struct EmptyLightEnv : ILightEnv -{ - float3 illuminate(SurfaceGeometry g, B brdf, float3 wo) - { - return 0; - } -}; - -// The code above constitutes the "shader library" for our -// application, while the code below this point is the -// implementation of a simple forward rendering pass -// using that library. -// -// While the shader library has used many of Slang's advanced -// mechanisms, the vertex and fragment shaders will be -// much more modest, and hopefully easier to follow. - - -// We will start with a `struct` for per-view parameters that -// will be allocated into a `ParameterBlock`. -// -// As written, this isn't very different from using an HLSL -// `cbuffer` declaration, but importantly this code will -// continue to work if we add one or more resources (e.g., -// an enironment map texture) to the `PerView` type. -// -struct PerView -{ - float4x4 viewProjection; - float3 eyePosition; -}; -ParameterBlock gViewParams; - -// Declaring a block for per-model parameter data is -// similarly simple. -// -struct PerModel -{ - float4x4 modelTransform; - float4x4 inverseTransposeModelTransform; -}; -ParameterBlock gModelParams; - -// We want our shader to work with any kind of lighting environment -// - that is, and type that implements `ILightEnv`. Furthermore, -// we want the parameters of that lighting environment to be passed -// as parameter block - `ParameterBlock` for some type `L`. -// -// We handle this by defining a global generic type parameter for -// our shader, and constrainting it to implement `ILightEnv`... -// -type_param TLightEnv : ILightEnv; -// -// ... and then defining a parameter block that uses that type -// parameter as the "element type" of the block: -// -ParameterBlock gLightEnv; - -// Our handling of the material parameter for our shader -// is quite similar to the case for the lighting environment: -// -type_param TMaterial : IMaterial; -ParameterBlock gMaterial; - -// Our vertex shader entry point is only marginally more -// complicated than the Hello World example. We will -// start by declaring the various "connector" `struct`s. -// -struct AssembledVertex -{ - float3 position : POSITION; - float3 normal : NORMAL; - float2 uv : UV; -}; -struct CoarseVertex -{ - float3 worldPosition; - float3 worldNormal; - float2 uv; -}; -struct VertexStageOutput -{ - CoarseVertex coarseVertex : CoarseVertex; - float4 sv_position : SV_Position; -}; - -// Perhaps most interesting new feature of the entry -// point decalrations is that we use a `[shader(...)]` -// attribute (as introduced in HLSL Shader Model 6.x) -// in order to tag our entry points. -// -// This attribute informs the Slang compiler which -// functions are intended to be compiled as shader -// entry points (and what stage they target), so that -// the programmer no longer needs to specify the -// entry point name/stage through the API (or on -// the command line when using `slangc`). -// -// While HLSL added this feature only in newer versions, -// the Slang compiler supports this attribute across -// *all* targets, so that it is okay to use whether you -// want DXBC, DXIL, or SPIR-V output. -// -[shader("vertex")] -VertexStageOutput vertexMain( - AssembledVertex assembledVertex) -{ - VertexStageOutput output; - - float3 position = assembledVertex.position; - float3 normal = assembledVertex.normal; - float2 uv = assembledVertex.uv; - - float3 worldPosition = mul(gModelParams.modelTransform, float4(position, 1.0)).xyz; - float3 worldNormal = mul(gModelParams.inverseTransposeModelTransform, float4(normal, 0.0)).xyz; - - output.coarseVertex.worldPosition = worldPosition; - output.coarseVertex.worldNormal = worldNormal; - output.coarseVertex.uv = uv; - - output.sv_position = mul(gViewParams.viewProjection, float4(worldPosition, 1.0)); - - return output; -} - -// Our fragment shader is almost trivial, with the most interesting -// thing being how it uses the `TMaterial` type parameter (through the -// value stored in the `gMaterial` parameter block) to dispatch to -// the correct implementation of the `getDiffuseColor()` method -// in the `IMaterial` interface. -// -// The `gMaterial` parameter block declaration thus serves not only -// to group certain shader parameters for efficient CPU-to-GPU -// communication, but also to select the code that will execute -// in specialized versions of the `fragmentMain` entry point. -// [shader("fragment")] -float4 fragmentMain( - CoarseVertex coarseVertex : CoarseVertex) : SV_Target +float4 fragmentMain(float2 texCoord) { - // We start by using our interpolated vertex attributes - // to construct the local surface geometry that we will - // use for material evaluation. - // - SurfaceGeometry g; - g.position = coarseVertex.worldPosition; - g.normal = normalize(coarseVertex.worldNormal); - g.uv = coarseVertex.uv; - - float3 V = normalize(gViewParams.eyePosition - g.position); - - // Next we prepare the material, which involves running - // any "pattern generation" logic of the material (e.g., - // sampling and blending texture layers), to produce - // a BRDF suitable for evaluating under illumination - // from different light sources. - // - // Note that the return type here is `TMaterial.BRDF`, - // which is the `BRDF` type *associated* with the (unknown) - // `TMaterial` type. When `TMaterial` gets substituted for - // a concrete type later (e.g., `SimpleMaterial`) this - // will resolve to a concrete type too (e.g., `SimpleMaterial.BRDF` - // which is an alias for `BlinnPhong`). - // - TMaterial.BRDF brdf = gMaterial.prepare(g); - - // Now that we've done the first step of material evaluation - // and sampled texture maps, etc., it is time to start - // integrating incident light at our surface point. - // - // Because we've wrapped up the lighting environment as - // a single (composite) object, this is as simple as calling - // its `illuminate()` method. Our particular fragment shader - // is thus abstracted from how the renderer chooses to structure - // this integration step, somewhat similar to how an - // `illuminance` loop in RenderMan Shading Language works. - // - - float3 color = gLightEnv.illuminate(g, brdf, V); - - return float4(color, 1); -} + return gMaterial.sample(texCoord); +} \ No newline at end of file diff --git a/src/Editor/main.cpp b/src/Editor/main.cpp index 5d9b92d..089732e 100644 --- a/src/Editor/main.cpp +++ b/src/Editor/main.cpp @@ -1,5 +1,4 @@ #include "Window/WindowManager.h" -#include "Scene/Components/PrimitiveComponent.h" #include "Window/SceneView.h" #include "Window/InspectorView.h" #include "Asset/AssetRegistry.h" diff --git a/src/Engine/Asset/Asset.h b/src/Engine/Asset/Asset.h index fc0f9e5..413f4ea 100644 --- a/src/Engine/Asset/Asset.h +++ b/src/Engine/Asset/Asset.h @@ -31,10 +31,10 @@ public: std::scoped_lock lck(lock); return status; } - inline void setStatus(Status status) + inline void setStatus(Status _status) { std::scoped_lock lck(lock); - this->status = status; + status = _status; } protected: std::mutex lock; diff --git a/src/Engine/Asset/AssetRegistry.cpp b/src/Engine/Asset/AssetRegistry.cpp index 7a532f3..c9c3a43 100644 --- a/src/Engine/Asset/AssetRegistry.cpp +++ b/src/Engine/Asset/AssetRegistry.cpp @@ -91,10 +91,10 @@ AssetRegistry::AssetRegistry() { } -void AssetRegistry::init(const std::filesystem::path &rootFolder, Gfx::PGraphics graphics) +void AssetRegistry::init(const std::filesystem::path &_rootFolder, Gfx::PGraphics graphics) { AssetRegistry ® = get(); - reg.rootFolder = rootFolder; + reg.rootFolder = _rootFolder; reg.fontLoader = new FontLoader(graphics); reg.meshLoader = new MeshLoader(graphics); reg.textureLoader = new TextureLoader(graphics); diff --git a/src/Engine/Asset/AssetRegistry.h b/src/Engine/Asset/AssetRegistry.h index c0b785c..313a9f1 100644 --- a/src/Engine/Asset/AssetRegistry.h +++ b/src/Engine/Asset/AssetRegistry.h @@ -1,6 +1,7 @@ #pragma once #include "MinimalEngine.h" #include "Asset.h" +#include "Material/MaterialAsset.h" #include #include diff --git a/src/Engine/Asset/FontAsset.cpp b/src/Engine/Asset/FontAsset.cpp index a17bdb2..f483be6 100644 --- a/src/Engine/Asset/FontAsset.cpp +++ b/src/Engine/Asset/FontAsset.cpp @@ -52,8 +52,8 @@ void FontAsset::load() continue; } Glyph& glyph = glyphs[c]; - glyph.size = IVector2(face->glyph->bitmap.width, face->glyph->bitmap.rows); - glyph.bearing = IVector2(face->glyph->bitmap_left, face->glyph->bitmap_top); + glyph.size = Math::IVector2(face->glyph->bitmap.width, face->glyph->bitmap.rows); + glyph.bearing = Math::IVector2(face->glyph->bitmap_left, face->glyph->bitmap_top); glyph.advance = face->glyph->advance.x; TextureCreateInfo imageData; imageData.format = Gfx::SE_FORMAT_R8_UINT; diff --git a/src/Engine/Asset/FontAsset.h b/src/Engine/Asset/FontAsset.h index 7a50390..600d274 100644 --- a/src/Engine/Asset/FontAsset.h +++ b/src/Engine/Asset/FontAsset.h @@ -17,8 +17,8 @@ public: struct Glyph { Gfx::PTexture2D texture; - IVector2 size; - IVector2 bearing; + Math::IVector2 size; + Math::IVector2 bearing; uint32 advance; }; const std::map getGlyphData() const { return glyphs; } diff --git a/src/Engine/Asset/MeshLoader.cpp b/src/Engine/Asset/MeshLoader.cpp index 4718027..48fd5c4 100644 --- a/src/Engine/Asset/MeshLoader.cpp +++ b/src/Engine/Asset/MeshLoader.cpp @@ -36,7 +36,7 @@ void MeshLoader::importAsset(const std::filesystem::path &path) import(path, asset); } -void MeshLoader::loadMaterials(const aiScene* scene, Array& globalMaterials, Gfx::PGraphics graphics) +void MeshLoader::loadMaterials(const aiScene* scene, Array& globalMaterials) { using json = nlohmann::json; for(uint32 i = 0; i < scene->mNumMaterials; ++i) @@ -111,44 +111,44 @@ void findMeshRoots(aiNode *node, List &meshNodes) } VertexStreamComponent createVertexStream(uint32 size, aiVector3D* sourceData, Gfx::PGraphics graphics) { - Array buffer(size); + Array buffer(size); for(uint32 i = 0; i < size; ++i) { - buffer[i] = Vector(sourceData[i].x, sourceData[i].y, sourceData[i].z); + buffer[i] = Math::Vector(sourceData[i].x, sourceData[i].y, sourceData[i].z); } VertexBufferCreateInfo vbInfo; vbInfo.numVertices = size; - vbInfo.vertexSize = sizeof(Vector); + vbInfo.vertexSize = sizeof(Math::Vector); vbInfo.resourceData.data = (uint8 *)buffer.data(); vbInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER; - vbInfo.resourceData.size = sizeof(Vector) * (uint32)buffer.size(); + vbInfo.resourceData.size = sizeof(Math::Vector) * buffer.size(); Gfx::PVertexBuffer vertexBuffer = graphics->createVertexBuffer(vbInfo); vertexBuffer->transferOwnership(Gfx::QueueType::GRAPHICS); return VertexStreamComponent(vertexBuffer, 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32B32_SFLOAT); } VertexStreamComponent createVertexStream(uint32 size, aiVector2D* sourceData, Gfx::PGraphics graphics) { - Array buffer(size); + Array buffer(size); for(uint32 i = 0; i < size; ++i) { - buffer[i] = Vector2(sourceData[i].x, sourceData[i].y); + buffer[i] = Math::Vector2(sourceData[i].x, sourceData[i].y); } VertexBufferCreateInfo vbInfo; vbInfo.numVertices = size; - vbInfo.vertexSize = sizeof(Vector2); + vbInfo.vertexSize = sizeof(Math::Vector2); vbInfo.resourceData.data = (uint8 *)buffer.data(); vbInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER; - vbInfo.resourceData.size = sizeof(Vector2) * (uint32)buffer.size(); + vbInfo.resourceData.size = sizeof(Math::Vector2) * buffer.size(); Gfx::PVertexBuffer vertexBuffer = graphics->createVertexBuffer(vbInfo); vertexBuffer->transferOwnership(Gfx::QueueType::GRAPHICS); return VertexStreamComponent(vertexBuffer, 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32_SFLOAT); } -void MeshLoader::loadGlobalMeshes(const aiScene* scene, Array& globalMeshes, const Array& materials, Gfx::PGraphics graphics) +void MeshLoader::loadGlobalMeshes(const aiScene* scene, Array& globalMeshes, const Array& materials) { for (uint32 meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex) { aiMesh *mesh = scene->mMeshes[meshIndex]; - + PMaterialAsset material = materials[mesh->mMaterialIndex]; PStaticMeshVertexInput vertexShaderInput = new StaticMeshVertexInput(std::string(mesh->mName.C_Str())); StaticMeshDataType data; data.positionStream = createVertexStream(mesh->mNumVertices, mesh->mVertices, graphics); @@ -188,7 +188,7 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, Array& globalMesh idxInfo.indexType = Gfx::SE_INDEX_TYPE_UINT32; idxInfo.resourceData.data = (uint8 *)indices.data(); idxInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER; - idxInfo.resourceData.size = sizeof(uint32) * (uint32)indices.size(); + idxInfo.resourceData.size = sizeof(uint32) * indices.size(); Gfx::PIndexBuffer indexBuffer = graphics->createIndexBuffer(idxInfo); indexBuffer->transferOwnership(Gfx::QueueType::GRAPHICS); @@ -249,10 +249,10 @@ void MeshLoader::import(std::filesystem::path path, PMeshAsset meshAsset) Array globalMaterials(scene->mNumMaterials); loadTextures(scene, path.parent_path()); - loadMaterials(scene, globalMaterials, graphics); + loadMaterials(scene, globalMaterials); Array globalMeshes(scene->mNumMeshes); - loadGlobalMeshes(scene, globalMeshes, globalMaterials, graphics); + loadGlobalMeshes(scene, globalMeshes, globalMaterials); List meshNodes; diff --git a/src/Engine/Asset/MeshLoader.h b/src/Engine/Asset/MeshLoader.h index c929ba2..7de51c8 100644 --- a/src/Engine/Asset/MeshLoader.h +++ b/src/Engine/Asset/MeshLoader.h @@ -18,9 +18,9 @@ public: ~MeshLoader(); void importAsset(const std::filesystem::path& filePath); private: - void loadMaterials(const aiScene* scene, Array& globalMaterials, Gfx::PGraphics graphics); + void loadMaterials(const aiScene* scene, Array& globalMaterials); void loadTextures(const aiScene* scene, const std::filesystem::path& meshPath); - void loadGlobalMeshes(const aiScene* scene, Array& globalMeshes, const Array& materials, Gfx::PGraphics graphics); + void loadGlobalMeshes(const aiScene* scene, Array& globalMeshes, const Array& materials); void convertAssimpARGB(unsigned char* dst, aiTexel* src, uint32 numPixels); void import(std::filesystem::path path, PMeshAsset meshAsset); diff --git a/src/Engine/Asset/TextureAsset.cpp b/src/Engine/Asset/TextureAsset.cpp index afb2fd5..f881da2 100644 --- a/src/Engine/Asset/TextureAsset.cpp +++ b/src/Engine/Asset/TextureAsset.cpp @@ -50,10 +50,10 @@ void TextureAsset::load() 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.size = ktxTexture_GetDataSize(ktxTexture(kTexture)); createInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER; - Gfx::PTexture2D texture = WindowManager::getGraphics()->createTexture2D(createInfo); - texture->transferOwnership(Gfx::QueueType::GRAPHICS); - setTexture(texture); + Gfx::PTexture2D tex = WindowManager::getGraphics()->createTexture2D(createInfo); + tex->transferOwnership(Gfx::QueueType::GRAPHICS); + setTexture(tex); setStatus(Asset::Status::Ready); } \ No newline at end of file diff --git a/src/Engine/Asset/TextureAsset.h b/src/Engine/Asset/TextureAsset.h index 7e1a0b2..bd845da 100644 --- a/src/Engine/Asset/TextureAsset.h +++ b/src/Engine/Asset/TextureAsset.h @@ -12,10 +12,10 @@ public: virtual ~TextureAsset(); virtual void save() override; virtual void load() override; - void setTexture(Gfx::PTexture texture) + void setTexture(Gfx::PTexture _texture) { std::scoped_lock lck(lock); - this->texture = texture; + texture = _texture; } Gfx::PTexture getTexture() { diff --git a/src/Engine/Containers/Array.h b/src/Engine/Containers/Array.h index 9bccde0..38488b5 100644 --- a/src/Engine/Containers/Array.h +++ b/src/Engine/Containers/Array.h @@ -679,6 +679,16 @@ public: beginIt = iterator(_data); endIt = iterator(_data + N); } + StaticArray(std::initializer_list init) + { + assert(init.size() == N); + auto beg = init.begin(); + for (int i = 0; i < N; ++i) + { + _data[i] = *beg; + beg++; + } + } ~StaticArray() { } diff --git a/src/Engine/Containers/Map.h b/src/Engine/Containers/Map.h index 98a7038..b696e3a 100644 --- a/src/Engine/Containers/Map.h +++ b/src/Engine/Containers/Map.h @@ -40,8 +40,8 @@ private: size_t rightChild; Pair pair; Node() - : leftChild(-1) - , rightChild(-1) + : leftChild(SIZE_MAX) + , rightChild(SIZE_MAX) , pair() { } @@ -50,8 +50,8 @@ private: Node& operator=(const Node& other) = default; Node& operator=(Node&& other) = default; Node(K key) - : leftChild(-1) - , rightChild(-1) + : leftChild(SIZE_MAX) + , rightChild(SIZE_MAX) , pair(std::move(key)) { } @@ -71,7 +71,7 @@ public: using reference = PairType&; using pointer = PairType*; - IteratorBase(size_t x = -1) + IteratorBase(size_t x = SIZE_MAX) : node(x) { } @@ -199,9 +199,9 @@ public: using const_reverse_iterator = std::reverse_iterator; constexpr Map() noexcept - : root(-1) - , beginIt(-1) - , endIt(-1) + : root(SIZE_MAX) + , beginIt(SIZE_MAX) + , endIt(SIZE_MAX) , iteratorsDirty(true) , _size(0) , comp(Compare()) @@ -209,9 +209,9 @@ public: } constexpr explicit Map(const Compare& comp, const Allocator& alloc = Allocator()) noexcept(noexcept(Allocator())) : nodeContainer(alloc) - , root(-1) - , beginIt(-1) - , endIt(-1) + , root(SIZE_MAX) + , beginIt(SIZE_MAX) + , endIt(SIZE_MAX) , iteratorsDirty(true) , _size(0) , comp(comp) @@ -219,9 +219,9 @@ public: } constexpr explicit Map(const Allocator& alloc) noexcept(noexcept(Compare)) : nodeContainer(alloc) - , root(-1) - , beginIt(-1) - , endIt(-1) + , root(SIZE_MAX) + , beginIt(SIZE_MAX) + , endIt(SIZE_MAX) , iteratorsDirty(true) , _size(0) , comp(Compare()) @@ -335,7 +335,7 @@ public: constexpr void clear() { nodeContainer.clear(); - root = -1; + root = SIZE_MAX; _size = 0; markIteratorsDirty(); } @@ -510,13 +510,13 @@ private: { newNode->rightChild = r; newNode->leftChild = node->leftChild; - node->leftChild = -1; + node->leftChild = SIZE_MAX; } else { newNode->leftChild = r; newNode->rightChild = node->rightChild; - node->rightChild = -1; + node->rightChild = SIZE_MAX; } return nodeContainer.size() - 1; } @@ -525,7 +525,7 @@ private: { size_t temp; if (!isValid(r)) - return -1; + return SIZE_MAX; r = splay(r, key); Node* node = getNode(r); diff --git a/src/Engine/Graphics/Graphics.cpp b/src/Engine/Graphics/Graphics.cpp index 9b55e72..5e59c6e 100644 --- a/src/Engine/Graphics/Graphics.cpp +++ b/src/Engine/Graphics/Graphics.cpp @@ -18,10 +18,10 @@ PVertexBuffer Graphics::getNullVertexBuffer() { VertexBufferCreateInfo createInfo; createInfo.numVertices = 1; - createInfo.vertexSize = sizeof(Vector4); - Vector4 data = Vector4(1, 1, 1, 1); + createInfo.vertexSize = sizeof(Math::Vector4); + Math::Vector4 data = Math::Vector4(1, 1, 1, 1); createInfo.resourceData.data = reinterpret_cast(&data); - createInfo.resourceData.size = sizeof(Vector4); + createInfo.resourceData.size = sizeof(Math::Vector4); nullVertexBuffer = createVertexBuffer(createInfo); } return nullVertexBuffer; diff --git a/src/Engine/Graphics/GraphicsInitializer.h b/src/Engine/Graphics/GraphicsInitializer.h index bf77843..859fab7 100644 --- a/src/Engine/Graphics/GraphicsInitializer.h +++ b/src/Engine/Graphics/GraphicsInitializer.h @@ -50,7 +50,8 @@ struct ViewportCreateInfo // doesnt own the data, only proxy it struct BulkResourceData { - uint32 size = 0; + uint64 size = 0; + uint64 offset = 0; uint8 *data = nullptr; Gfx::QueueType owner = Gfx::QueueType::GRAPHICS; }; @@ -111,8 +112,9 @@ struct StructuredBufferCreateInfo }; struct ShaderCreateInfo { + std::string mainModule; //It's possible to input multiple source files for materials or vertexFactories - Array shaderCode; + Array additionalModules; std::string name; // Debug info std::string entryPoint; Array typeParameter; diff --git a/src/Engine/Graphics/GraphicsResources.cpp b/src/Engine/Graphics/GraphicsResources.cpp index 03c140e..e63a7c0 100644 --- a/src/Engine/Graphics/GraphicsResources.cpp +++ b/src/Engine/Graphics/GraphicsResources.cpp @@ -2,6 +2,7 @@ #include "Graphics.h" #include "RenderPass/DepthPrepass.h" #include "RenderPass/BasePass.h" +#include "Material/MaterialAsset.h" using namespace Seele; using namespace Seele::Gfx; @@ -11,9 +12,9 @@ std::string getShaderNameFromRenderPassType(Gfx::RenderPassType type) switch (type) { case Gfx::RenderPassType::DepthPrepass: - return "DepthPrepass.slang"; + return "DepthPrepass"; case Gfx::RenderPassType::BasePass: - return "ForwardPlus.slang"; + return "ForwardPlus"; default: return ""; } @@ -64,8 +65,6 @@ ShaderCollection& ShaderMap::createShaders( ShaderCreateInfo createInfo; createInfo.entryPoint = "vertexMain"; createInfo.typeParameter = {material->getName().c_str()}; - createInfo.defines["VERTEX_INPUT_IMPORT"] = vertexInput->getShaderFilename(); - createInfo.defines["MATERIAL_IMPORT"] = material->getName().c_str(); createInfo.defines["NUM_MATERIAL_TEXCOORDS"] = "1"; createInfo.defines["USE_INSTANCING"] = "0"; modifyRenderPassMacros(renderPass, createInfo.defines); @@ -73,7 +72,9 @@ ShaderCollection& ShaderMap::createShaders( std::ifstream codeStream("./shaders/" + getShaderNameFromRenderPassType(renderPass)); - createInfo.shaderCode.add(std::string(std::istreambuf_iterator{codeStream}, {})); + createInfo.mainModule = getShaderNameFromRenderPassType(renderPass); + createInfo.additionalModules.add(vertexInput->getShaderFilename()); + createInfo.additionalModules.add(material->getName()); collection.vertexShader = graphics->createVertexShader(createInfo); @@ -227,7 +228,7 @@ VertexBuffer::VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint3 VertexBuffer::~VertexBuffer() { } -IndexBuffer::IndexBuffer(QueueFamilyMapping mapping, uint32 size, Gfx::SeIndexType indexType, QueueType startQueueType) +IndexBuffer::IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexType indexType, QueueType startQueueType) : Buffer(mapping, startQueueType) , indexType(indexType) { @@ -264,6 +265,129 @@ const Array VertexStream::getVertexDescriptions() const { return vertexDescription; } + +VertexDataManager::VertexDataManager(PGraphics graphics) + : currentSize(8 * 1024 * 1024) + , inUse(0) + , graphics(graphics) +{ + VertexBufferCreateInfo defaultInfo = { + .resourceData = { + .size = currentSize, + .data = nullptr, + } + }; + buffer = graphics->createVertexBuffer(defaultInfo); +} + +VertexDataManager::~VertexDataManager() +{ + +} + +VertexDataAllocation VertexDataManager::createVertexBuffer(const VertexBufferCreateInfo& vbInfo) +{ + VertexDataAllocation data = allocateData(vbInfo.resourceData.size); + + buffer->updateRegion(BulkResourceData{ + .size = data.size, + .offset = data.offset, + .data = vbInfo.resourceData.data + }); + + activeAllocations[data.offset] = data; + + return data; +} + +void VertexDataManager::freeAllocation(VertexDataAllocation alloc) +{ + uint64 lowerBound = alloc.offset; + uint64 upperBound = alloc.offset + alloc.size; + bool joinedLower = false; + uint64 lowerOffset = 0; + + //Join lower bound + for (auto& [offset, freeAlloc] : freeRanges) + { + if (freeAlloc.offset <= lowerBound + && freeAlloc.offset + freeAlloc.size >= upperBound) + { + // allocation is already in a free region + return; + } + if (freeAlloc.offset + freeAlloc.size == lowerBound) + { + //extend freeAlloc by the allocatedSize + freeAlloc.size += alloc.size; + joinedLower = true; + lowerOffset = freeAlloc.offset; + break; + } + } + //Join upper bound + auto foundAlloc = freeRanges.find(upperBound); + if (foundAlloc != freeRanges.end()) + { + // There is a free allocation ending where the new free one ends + if (joinedLower) + { + // extend allocHandle by another foundAlloc->allocatedSize bytes + freeRanges[lowerOffset].size += foundAlloc->value.size; + freeRanges.erase(upperBound); + } + else + { + // set foundAlloc back by size amount + freeRanges[upperBound].offset -= alloc.size; + freeRanges[upperBound].size += alloc.size; + // place back at correct offset + freeRanges[freeRanges[upperBound].offset] = freeRanges[upperBound]; + // remove from offset map since key changes + freeRanges.erase(upperBound); + } + } + else + { + // No matching upper bound found + if(!joinedLower) + { + // Lower bound also not joined, create new range + freeRanges[alloc.offset] = alloc; + } + } + activeAllocations.erase(alloc.offset); + inUse -= alloc.size; +} + + +VertexDataAllocation VertexDataManager::allocateData(uint64 size) +{ + for (auto& [offset, freeAllocation] : freeRanges) + { + assert(offset == freeAllocation.offset); + if (freeAllocation.size == size) + { + activeAllocations[offset] = freeAllocation; + freeRanges.erase(offset); + inUse += size; + return freeAllocation; + } + else if (size < freeAllocation.size) + { + freeAllocation.size -= size; + freeAllocation.offset += size; + VertexDataAllocation subAlloc = VertexDataAllocation(size, offset); + activeAllocations[offset] = subAlloc; + freeRanges[freeAllocation.offset] = freeAllocation; + freeRanges.erase(offset); + inUse += size; + return subAlloc; + } + } + throw std::logic_error("TODO: expand buffer"); +} + VertexDeclaration::VertexDeclaration() { } diff --git a/src/Engine/Graphics/GraphicsResources.h b/src/Engine/Graphics/GraphicsResources.h index f0c47c8..46b2449 100644 --- a/src/Engine/Graphics/GraphicsResources.h +++ b/src/Engine/Graphics/GraphicsResources.h @@ -3,7 +3,10 @@ #include "Containers/Array.h" #include "Containers/List.h" #include "GraphicsInitializer.h" +#pragma warning(push) +#pragma warning(disable: 4701) #include +#pragma warning(pop) #include @@ -372,6 +375,8 @@ public: return vertexSize; } + virtual void updateRegion(BulkResourceData update) = 0; + protected: // Inherited via QueueOwnedResource virtual void executeOwnershipBarrier(QueueType newOwner) = 0; @@ -385,9 +390,9 @@ DEFINE_REF(VertexBuffer) class IndexBuffer : public Buffer { public: - IndexBuffer(QueueFamilyMapping mapping, uint32 size, Gfx::SeIndexType index, QueueType startQueueType); + IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexType index, QueueType startQueueType); virtual ~IndexBuffer(); - constexpr uint32 getNumIndices() const + constexpr uint64 getNumIndices() const { return numIndices; } @@ -402,7 +407,7 @@ protected: virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; Gfx::SeIndexType indexType; - uint32 numIndices; + uint64 numIndices; }; DEFINE_REF(IndexBuffer) @@ -442,7 +447,6 @@ protected: uint32 stride; }; DEFINE_REF(StructuredBuffer) - class VertexStream { public: @@ -459,6 +463,34 @@ public: uint8 instanced; }; DEFINE_REF(VertexStream) + +struct VertexDataAllocation +{ + uint64 size; + uint64 offset; +}; + +class VertexDataManager +{ +public: + VertexDataManager(PGraphics graphics); + virtual ~VertexDataManager(); + + VertexDataAllocation createVertexBuffer(const VertexBufferCreateInfo& vbInfo); + void freeAllocation(VertexDataAllocation alloc); + + PVertexBuffer getVertexBuffer() const { return buffer; } +private: + VertexDataAllocation allocateData(uint64 size); + Map freeRanges; + Map activeAllocations; + uint64 currentSize; + uint64 inUse; + PVertexBuffer buffer; + PGraphics graphics; +}; +DEFINE_REF(VertexDataManager) + class VertexDeclaration { public: diff --git a/src/Engine/Graphics/MeshBatch.h b/src/Engine/Graphics/MeshBatch.h index 656e04e..9024bfa 100644 --- a/src/Engine/Graphics/MeshBatch.h +++ b/src/Engine/Graphics/MeshBatch.h @@ -34,7 +34,7 @@ public: }; struct MeshBatch { - std::vector elements; + Array elements; uint8 useReverseCulling : 1; uint8 isBackfaceCullingDisabled : 1; @@ -73,10 +73,8 @@ struct MeshBatch MeshBatch& operator=(const MeshBatch& other) = default; MeshBatch& operator=(MeshBatch&& other) = default; }; -DECLARE_REF(PrimitiveComponent) struct StaticMeshBatch : public MeshBatch { uint32 index; - PPrimitiveComponent primitiveComponent; }; } // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index 0b69011..3d5b5c4 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -1,10 +1,11 @@ #include "BasePass.h" #include "Graphics/Graphics.h" #include "Window/Window.h" -#include "Scene/Components/CameraComponent.h" +#include "Scene/Component/Camera.h" #include "Scene/Actor/CameraActor.h" #include "Math/Vector.h" #include "RenderGraph.h" +#include "Material/MaterialAsset.h" using namespace Seele; @@ -73,7 +74,7 @@ BasePass::BasePass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActo : RenderPass(graphics, viewport) , processor(new BasePassMeshProcessor(viewport, graphics, false)) , descriptorSets(4) - , source(source->getCameraComponent()) + , source(source) { UniformBufferCreateInfo uniformInitializer; basePassLayout = graphics->createPipelineLayout(); @@ -120,11 +121,11 @@ void BasePass::beginFrame() primitiveLayout->reset(); BulkResourceData uniformUpdate; - viewParams.viewMatrix = source->getViewMatrix(); - viewParams.projectionMatrix = source->getProjectionMatrix(); - viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0); + viewParams.viewMatrix = source->getCameraComponent().getViewMatrix(); + viewParams.projectionMatrix = source->getCameraComponent().getProjectionMatrix(); + viewParams.cameraPosition = Math::Vector4(source->getCameraComponent().getCameraPosition(), 0); viewParams.inverseProjectionMatrix = glm::inverse(viewParams.projectionMatrix); - viewParams.screenDimensions = Vector2(static_cast(viewport->getSizeX()), static_cast(viewport->getSizeY())); + viewParams.screenDimensions = Math::Vector2(static_cast(viewport->getSizeX()), static_cast(viewport->getSizeY())); uniformUpdate.size = sizeof(ViewParameter); uniformUpdate.data = (uint8*)&viewParams; viewParamBuffer->updateContents(uniformUpdate); diff --git a/src/Engine/Graphics/RenderPass/BasePass.h b/src/Engine/Graphics/RenderPass/BasePass.h index e62eb24..bd185c5 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.h +++ b/src/Engine/Graphics/RenderPass/BasePass.h @@ -27,10 +27,9 @@ private: }; DEFINE_REF(BasePassMeshProcessor) DECLARE_REF(CameraActor) -DECLARE_REF(CameraComponent) struct BasePassData { - std::vector staticDrawList; + Array staticDrawList; }; class BasePass : public RenderPass { @@ -49,7 +48,7 @@ private: UPBasePassMeshProcessor processor; Array descriptorSets; - PCameraComponent source; + PCameraActor source; Gfx::PPipelineLayout basePassLayout; // Set 0: Light environment static constexpr uint32 INDEX_LIGHT_ENV = 0; diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp index 2326a12..c8a42fb 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp @@ -1,10 +1,11 @@ #include "DepthPrepass.h" #include "Graphics/Graphics.h" #include "Window/Window.h" -#include "Scene/Components/CameraComponent.h" +#include "Scene/Component/Camera.h" #include "Scene/Actor/CameraActor.h" #include "Math/Vector.h" #include "RenderGraph.h" +#include "Material/MaterialAsset.h" using namespace Seele; @@ -72,7 +73,7 @@ DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCa : RenderPass(graphics, viewport) , processor(new DepthPrepassMeshProcessor(viewport, graphics)) , descriptorSets(3) - , source(source->getCameraComponent()) + , source(source) { UniformBufferCreateInfo uniformInitializer; @@ -103,11 +104,11 @@ void DepthPrepass::beginFrame() primitiveLayout->reset(); BulkResourceData uniformUpdate; - viewParams.viewMatrix = source->getViewMatrix(); - viewParams.projectionMatrix = source->getProjectionMatrix(); - viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0); + viewParams.viewMatrix = source->getCameraComponent().getViewMatrix(); + viewParams.projectionMatrix = source->getCameraComponent().getProjectionMatrix(); + viewParams.cameraPosition = Math::Vector4(source->getCameraComponent().getCameraPosition(), 0); viewParams.inverseProjectionMatrix = glm::inverse(viewParams.projectionMatrix); - viewParams.screenDimensions = Vector2(static_cast(viewport->getSizeX()), static_cast(viewport->getSizeY())); + viewParams.screenDimensions = Math::Vector2(static_cast(viewport->getSizeX()), static_cast(viewport->getSizeY())); uniformUpdate.size = sizeof(ViewParameter); uniformUpdate.data = (uint8*)&viewParams; viewParamBuffer->updateContents(uniformUpdate); diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.h b/src/Engine/Graphics/RenderPass/DepthPrepass.h index db00cbc..76b9a7f 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.h +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.h @@ -24,10 +24,9 @@ private: }; DEFINE_REF(DepthPrepassMeshProcessor) DECLARE_REF(CameraActor) -DECLARE_REF(CameraComponent) struct DepthPrepassData { - std::vector staticDrawList; + Array staticDrawList; }; class DepthPrepass : public RenderPass { @@ -46,7 +45,7 @@ private: UPDepthPrepassMeshProcessor processor; Array descriptorSets; - PCameraComponent source; + PCameraActor source; Gfx::PPipelineLayout depthPrepassLayout; // Set 0: viewParameter static constexpr uint32 INDEX_VIEW_PARAMS = 0; diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp index f6c2069..510418f 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp @@ -2,14 +2,14 @@ #include "Graphics/Graphics.h" #include "Scene/Scene.h" #include "Scene/Actor/CameraActor.h" -#include "Scene/Components/CameraComponent.h" +#include "Scene/Component/Camera.h" #include "RenderGraph.h" using namespace Seele; LightCullingPass::LightCullingPass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor camera) : RenderPass(graphics, viewport) - , source(camera->getCameraComponent()) + , source(camera) { } @@ -24,11 +24,11 @@ void LightCullingPass::beginFrame() uint32_t viewportHeight = viewport->getSizeY(); BulkResourceData uniformUpdate; - viewParams.viewMatrix = source->getViewMatrix(); - viewParams.projectionMatrix = source->getProjectionMatrix(); - viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0); + viewParams.viewMatrix = source->getCameraComponent().getViewMatrix(); + viewParams.projectionMatrix = source->getCameraComponent().getProjectionMatrix(); + viewParams.cameraPosition = Math::Vector4(source->getCameraComponent().getCameraPosition(), 0); viewParams.inverseProjectionMatrix = glm::inverse(viewParams.projectionMatrix); - viewParams.screenDimensions = Vector2(static_cast(viewportWidth), static_cast(viewportHeight)); + viewParams.screenDimensions = Math::Vector2(static_cast(viewportWidth), static_cast(viewportHeight)); uniformUpdate.size = sizeof(ViewParameter); uniformUpdate.data = (uint8*)&viewParams; viewParamsBuffer->updateContents(uniformUpdate); @@ -162,13 +162,7 @@ void LightCullingPass::publishOutputs() ShaderCreateInfo createInfo; createInfo.name = "Culling"; - std::ifstream codeStream("./shaders/LightCulling.slang", std::ios::ate); - auto fileSize = codeStream.tellg(); - codeStream.seekg(0); - Array buffer(static_cast(fileSize)); - codeStream.read(buffer.data(), fileSize); - - createInfo.shaderCode.add(std::string(buffer.data())); + createInfo.mainModule = "LightCulling"; createInfo.entryPoint = "cullLights"; createInfo.defines["INDEX_VIEW_PARAMS"] = "0"; createInfo.defines["INDEX_LIGHT_ENV"] = "1"; @@ -269,10 +263,10 @@ void LightCullingPass::setupFrustums() glm::uvec3 numThreadGroups = glm::ceil(glm::vec3(numThreads.x / (float)BLOCK_SIZE, numThreads.y / (float)BLOCK_SIZE, 1)); viewParams = { - .viewMatrix = source->getViewMatrix(), - .projectionMatrix = source->getProjectionMatrix(), - .inverseProjectionMatrix = glm::inverse(source->getProjectionMatrix()), - .cameraPosition = Vector4(source->getCameraPosition(), 0), + .viewMatrix = source->getCameraComponent().getViewMatrix(), + .projectionMatrix = source->getCameraComponent().getProjectionMatrix(), + .inverseProjectionMatrix = glm::inverse(source->getCameraComponent().getProjectionMatrix()), + .cameraPosition = Math::Vector4(source->getTransform().getPosition(), 0), .screenDimensions = glm::vec2(viewportWidth, viewportHeight), }; dispatchParams.numThreads = numThreads; @@ -288,13 +282,7 @@ void LightCullingPass::setupFrustums() ShaderCreateInfo createInfo; createInfo.name = "Frustum"; - std::ifstream codeStream("./shaders/ComputeFrustums.slang", std::ios::ate); - auto fileSize = codeStream.tellg(); - codeStream.seekg(0); - Array buffer(static_cast(fileSize)); - codeStream.read(buffer.data(), fileSize); - - createInfo.shaderCode.add(std::string(buffer.data())); + createInfo.mainModule = "ComputeFrustums"; createInfo.entryPoint = "computeFrustums"; createInfo.defines["INDEX_VIEW_PARAMS"] = "0"; frustumShader = graphics->createComputeShader(createInfo); diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.h b/src/Engine/Graphics/RenderPass/LightCullingPass.h index a83e0e8..0295f9b 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.h +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.h @@ -6,7 +6,6 @@ namespace Seele { DECLARE_REF(CameraActor) -DECLARE_REF(CameraComponent) DECLARE_REF(Scene) DECLARE_REF(Viewport) struct LightCullingPassData @@ -37,7 +36,7 @@ private: } dispatchParams; struct Plane { - Vector n; + Math::Vector n; float d; }; struct Frustum @@ -72,7 +71,7 @@ private: Gfx::PComputeShader cullingShader; Gfx::PPipelineLayout cullingLayout; Gfx::PComputePipeline cullingPipeline; - PCameraComponent source; + PCameraActor source; }; DEFINE_REF(LightCullingPass) } // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/RenderPass.h b/src/Engine/Graphics/RenderPass/RenderPass.h index 4d17db3..8b45134 100644 --- a/src/Engine/Graphics/RenderPass/RenderPass.h +++ b/src/Engine/Graphics/RenderPass/RenderPass.h @@ -26,15 +26,16 @@ public: virtual void endFrame() = 0; virtual void publishOutputs() = 0; virtual void createRenderPass() = 0; - void setResources(PRenderGraphResources resources) { this->resources = resources; } + void setResources(PRenderGraphResources _resources) { resources = _resources; } protected: struct ViewParameter { - Matrix4 viewMatrix; - Matrix4 projectionMatrix; - Matrix4 inverseProjectionMatrix; - Vector4 cameraPosition; - Vector2 screenDimensions; + Math::Matrix4 viewMatrix; + Math::Matrix4 projectionMatrix; + Math::Matrix4 inverseProjectionMatrix; + Math::Vector4 cameraPosition; + Math::Vector2 screenDimensions; + Math::Vector2 pad0; } viewParams; PRenderGraphResources resources; RenderPassDataType passData; diff --git a/src/Engine/Graphics/RenderPass/TextPass.cpp b/src/Engine/Graphics/RenderPass/TextPass.cpp index 50f53cd..7d83d8f 100644 --- a/src/Engine/Graphics/RenderPass/TextPass.cpp +++ b/src/Engine/Graphics/RenderPass/TextPass.cpp @@ -20,16 +20,16 @@ void TextPass::beginFrame() { for(TextRender& render : passData.texts) { - FontData& fontData = getFontData(render.font); - TextResources& resources = textResources[render.font].add(); + FontData& fd = getFontData(render.font); + TextResources& res = textResources[render.font].add(); Array instanceData; float x = render.position.x; float y = render.position.y; for(uint32 c : render.text) { - const GlyphData& glyph = fontData.glyphDataSet[fontData.characterToGlyphIndex[c]]; - Vector2 bearing = glyph.bearing; - Vector2 size = glyph.size; + const GlyphData& glyph = fd.glyphDataSet[fd.characterToGlyphIndex[c]]; + Math::Vector2 bearing = glyph.bearing; + Math::Vector2 size = glyph.size; float xpos = x + bearing.x * render.scale; float ypos = y - (size.y - bearing.y) * render.scale; @@ -37,9 +37,9 @@ void TextPass::beginFrame() float h = size.y * render.scale; instanceData.add(GlyphInstanceData{ - .position = Vector2(xpos, ypos), - .widthHeight = Vector2(w, h), - .glyphIndex = fontData.characterToGlyphIndex[c], + .position = Math::Vector2(xpos, ypos), + .widthHeight = Math::Vector2(w, h), + .glyphIndex = fd.characterToGlyphIndex[c], }); x += (glyph.advance >> 6) * render.scale; } @@ -51,11 +51,11 @@ void TextPass::beginFrame() .vertexSize = sizeof(GlyphInstanceData), .numVertices = static_cast(instanceData.size()), }; - resources.vertexBuffer = graphics->createVertexBuffer(vbInfo); + res.vertexBuffer = graphics->createVertexBuffer(vbInfo); - resources.textureArraySet = fontData.textureArraySet; + res.textureArraySet = fd.textureArraySet; - resources.textData = { + res.textData = { .textColor = render.textColor, .scale = render.scale, }; @@ -67,12 +67,12 @@ void TextPass::render() { graphics->beginRenderPass(renderPass); Array commands; - for(const auto& [fontAsset, resources] : textResources) + for(const auto& [fontAsset, res] : textResources) { Gfx::PRenderCommand command = graphics->createRenderCommand("TextPassCommand"); command->setViewport(viewport); command->bindPipeline(pipeline); - for(const auto& resource : resources) + for(const auto& resource : res) { command->bindDescriptor({generalSet, resource.textureArraySet}); command->bindVertexBuffer({VertexInputStream(0, 0, resource.vertexBuffer)}); @@ -100,14 +100,8 @@ void TextPass::publishOutputs() void TextPass::createRenderPass() { depthAttachment = resources->requestRenderTarget("UIPASS_DEPTH"); - std::ifstream codeStream("./shaders/TextPass.slang", std::ios::ate); - auto fileSize = codeStream.tellg(); - codeStream.seekg(0); - Array buffer(static_cast(fileSize)); - codeStream.read(buffer.data(), fileSize); - ShaderCreateInfo createInfo; - createInfo.shaderCode.add(std::string(buffer.data())); + createInfo.mainModule = "TextPass"; createInfo.defines["INDEX_VIEW_PARAMS"] = "0"; createInfo.name = "TextVertex"; createInfo.entryPoint = "vertexMain"; @@ -152,10 +146,10 @@ void TextPass::createRenderPass() textureArrayLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 256, Gfx::SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT); textureArrayLayout->create(); - Matrix4 projectionMatrix = glm::ortho(0.f, (float)viewport->getSizeX(), 0.f, (float)viewport->getSizeY()); + Math::Matrix4 projectionMatrix = glm::ortho(0.f, (float)viewport->getSizeX(), 0.f, (float)viewport->getSizeY()); projectionBuffer = graphics->createUniformBuffer({ .resourceData = { - .size = sizeof(Matrix4), + .size = sizeof(Math::Matrix4), .data = (uint8*)&projectionMatrix, }, .bDynamic = false, diff --git a/src/Engine/Graphics/RenderPass/TextPass.h b/src/Engine/Graphics/RenderPass/TextPass.h index 0912929..25460b8 100644 --- a/src/Engine/Graphics/RenderPass/TextPass.h +++ b/src/Engine/Graphics/RenderPass/TextPass.h @@ -13,8 +13,8 @@ struct TextRender { std::string text; PFontAsset font; - Vector4 textColor; - Vector2 position; + Math::Vector4 textColor; + Math::Vector2 position; float scale; }; struct TextPassData @@ -35,19 +35,19 @@ public: private: struct GlyphData { - Vector2 bearing; - Vector2 size; + Math::Vector2 bearing; + Math::Vector2 size; uint32 advance; }; struct GlyphInstanceData { - Vector2 position; - Vector2 widthHeight; + Math::Vector2 position; + Math::Vector2 widthHeight; uint32 glyphIndex; }; struct TextData { - Vector4 textColor; + Math::Vector4 textColor; float scale; }; struct FontData diff --git a/src/Engine/Graphics/RenderPass/UIPass.cpp b/src/Engine/Graphics/RenderPass/UIPass.cpp index 59246fa..3fa0914 100644 --- a/src/Engine/Graphics/RenderPass/UIPass.cpp +++ b/src/Engine/Graphics/RenderPass/UIPass.cpp @@ -26,7 +26,7 @@ void UIPass::beginFrame() .numVertices = (uint32)passData.renderElements.size(), }; elementBuffer = graphics->createVertexBuffer(info); - uint32 numTextures = passData.usedTextures.size(); + uint32 numTextures = static_cast(passData.usedTextures.size()); numTexturesBuffer->updateContents({ .size = sizeof(uint32), .data = (uint8*)&numTextures, @@ -45,7 +45,7 @@ void UIPass::render() command->bindPipeline(pipeline); command->bindVertexBuffer({VertexInputStream(0, 0, elementBuffer)}); command->bindDescriptor(descriptorSet); - command->draw(4, passData.renderElements.size(), 0, 0); + command->draw(4, static_cast(passData.renderElements.size()), 0, 0); graphics->executeCommands(Array({command})); graphics->endRenderPass(); //co_return; @@ -76,14 +76,8 @@ void UIPass::publishOutputs() void UIPass::createRenderPass() { - std::ifstream codeStream("./shaders/UIPass.slang", std::ios::ate); - auto fileSize = codeStream.tellg(); - codeStream.seekg(0); - Array buffer(static_cast(fileSize)); - codeStream.read(buffer.data(), fileSize); - ShaderCreateInfo createInfo; - createInfo.shaderCode.add(std::string(buffer.data())); + createInfo.mainModule = "UIPass"; createInfo.name = "UIVertex"; createInfo.entryPoint = "vertexMain"; vertexShader = graphics->createVertexShader(createInfo); @@ -141,10 +135,10 @@ void UIPass::createRenderPass() descriptorLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 256, Gfx::SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT | Gfx::SE_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT); descriptorLayout->create(); - Matrix4 projectionMatrix = glm::ortho(0, 1, 1, 0); + Math::Matrix4 projectionMatrix = glm::ortho(0, 1, 1, 0); UniformBufferCreateInfo info = { .resourceData = { - .size = sizeof(Matrix4), + .size = sizeof(Math::Matrix4), .data = (uint8*)&projectionMatrix, }, .bDynamic = false, diff --git a/src/Engine/Graphics/StaticMeshVertexInput.cpp b/src/Engine/Graphics/StaticMeshVertexInput.cpp index 4958c9b..1115b63 100644 --- a/src/Engine/Graphics/StaticMeshVertexInput.cpp +++ b/src/Engine/Graphics/StaticMeshVertexInput.cpp @@ -54,16 +54,16 @@ void StaticMeshVertexInput::init(Gfx::PGraphics graphics) { elements.add(accessStreamComponent( data.textureCoordinates[coordinateIndex], - baseTexCoordAttribute + coordinateIndex + static_cast(baseTexCoordAttribute + coordinateIndex) )); } } initDeclaration(graphics, elements); } -void StaticMeshVertexInput::setData(StaticMeshDataType&& data) +void StaticMeshVertexInput::setData(StaticMeshDataType&& _data) { - this->data = std::move(data); + data = std::move(_data); } IMPLEMENT_VERTEX_INPUT_TYPE(StaticMeshVertexInput, "StaticMeshVertexInput") \ No newline at end of file diff --git a/src/Engine/Graphics/VertexShaderInput.cpp b/src/Engine/Graphics/VertexShaderInput.cpp index 61550a8..f2cc2c3 100644 --- a/src/Engine/Graphics/VertexShaderInput.cpp +++ b/src/Engine/Graphics/VertexShaderInput.cpp @@ -43,7 +43,7 @@ const char* VertexInputType::getName() return name; } -const char* VertexInputType::getShaderFilename() +std::string VertexInputType::getShaderFilename() { return shaderFilename; } @@ -90,20 +90,22 @@ Gfx::VertexElement VertexShaderInput::accessStreamComponent(const VertexStreamCo { VertexStream vertexStream; vertexStream.vertexBuffer = component.vertexBuffer; - vertexStream.stride = component.stride; - vertexStream.offset = component.offset; + assert(component.stride < UINT8_MAX && component.offset < UINT8_MAX && component.offset < UINT8_MAX); + vertexStream.stride = static_cast(component.stride); + vertexStream.offset = static_cast(component.offset); - return Gfx::VertexElement((uint8)streams.indexOf(streams.addUnique(vertexStream)), component.offset, component.type, attributeIndex, vertexStream.stride); + return Gfx::VertexElement((uint8)streams.indexOf(streams.addUnique(vertexStream)), static_cast(component.offset), component.type, attributeIndex, vertexStream.stride); } Gfx::VertexElement VertexShaderInput::accessPositionStreamComponent(const VertexStreamComponent& component, uint8 attributeIndex) { VertexStream vertexStream; vertexStream.vertexBuffer = component.vertexBuffer; - vertexStream.stride = component.stride; - vertexStream.offset = component.offset; + assert(component.stride < UINT8_MAX && component.offset < UINT8_MAX && component.offset < UINT8_MAX); + vertexStream.stride = static_cast(component.stride); + vertexStream.offset = static_cast(component.offset); - return Gfx::VertexElement((uint8)positionStreams.indexOf(positionStreams.addUnique(vertexStream)), component.offset, component.type, attributeIndex, vertexStream.stride); + return Gfx::VertexElement((uint8)positionStreams.indexOf(positionStreams.addUnique(vertexStream)), static_cast(component.offset), component.type, attributeIndex, vertexStream.stride); } void VertexShaderInput::initDeclaration(Gfx::PGraphics graphics, Array& elements) diff --git a/src/Engine/Graphics/VertexShaderInput.h b/src/Engine/Graphics/VertexShaderInput.h index 1fd725a..cee2345 100644 --- a/src/Engine/Graphics/VertexShaderInput.h +++ b/src/Engine/Graphics/VertexShaderInput.h @@ -91,7 +91,7 @@ public: virtual ~VertexInputType(); const char* getName(); - const char* getShaderFilename(); + std::string getShaderFilename(); private: const char* name; const char* shaderFilename; diff --git a/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp b/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp index b0a9ee9..8903e44 100644 --- a/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp @@ -95,7 +95,7 @@ PSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDevice VkDeviceSize allocatedOffset = it.first; PSubAllocation freeAllocation = it.second; assert(allocatedOffset == freeAllocation->allocatedOffset); - VkDeviceSize alignedOffset = align(allocatedOffset, alignment); + VkDeviceSize alignedOffset = Math::align(allocatedOffset, alignment); VkDeviceSize alignmentAdjustment = alignedOffset - allocatedOffset; VkDeviceSize size = alignmentAdjustment + requestedSize; if (freeAllocation->size == size) @@ -171,6 +171,8 @@ void Allocation::markFree(SubAllocation *allocation) allocHandle = foundAlloc->second; allocHandle->allocatedOffset -= allocation->allocatedSize; allocHandle->alignedOffset -= allocation->allocatedSize; + allocHandle->size += allocation->allocatedSize; + allocHandle->allocatedSize += allocation->allocatedSize; // place back at correct offset freeRanges[allocHandle->allocatedOffset] = allocHandle; // remove from offset map since key changes @@ -310,7 +312,7 @@ void StagingManager::clearPending() { } -PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageFlags usage, bool bCPURead) +PStagingBuffer StagingManager::allocateStagingBuffer(uint64 size, VkBufferUsageFlags usage, bool bCPURead) { std::scoped_lock l(lock); for (auto it = freeBuffers.begin(); it != freeBuffers.end(); ++it) diff --git a/src/Engine/Graphics/Vulkan/VulkanAllocator.h b/src/Engine/Graphics/Vulkan/VulkanAllocator.h index f098b44..6d3ff73 100644 --- a/src/Engine/Graphics/Vulkan/VulkanAllocator.h +++ b/src/Engine/Graphics/Vulkan/VulkanAllocator.h @@ -191,7 +191,7 @@ public: { return allocation->getOffset(); } - uint32 getSize() const + uint64 getSize() const { return size; } @@ -203,7 +203,7 @@ public: private: PSubAllocation allocation; VkBuffer buffer; - uint32 size; + uint64 size; VkBufferUsageFlags usage; uint8 bReadable; friend class StagingManager; @@ -215,7 +215,7 @@ class StagingManager public: StagingManager(PGraphics graphics, PAllocator allocator); ~StagingManager(); - PStagingBuffer allocateStagingBuffer(uint32 size, VkBufferUsageFlags usageFlags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, bool bCPURead = false); + PStagingBuffer allocateStagingBuffer(uint64 size, VkBufferUsageFlags usageFlags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, bool bCPURead = false); void releaseStagingBuffer(PStagingBuffer buffer); void clearPending(); diff --git a/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp b/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp index ab3c61c..642fee3 100644 --- a/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp @@ -9,6 +9,8 @@ using namespace Seele::Vulkan; struct PendingBuffer { + uint64 offset; + uint64 size; PStagingBuffer stagingBuffer; Gfx::QueueType prevQueue; bool bWriteOnly; @@ -16,7 +18,7 @@ struct PendingBuffer static std::map pendingBuffers; -ShaderBuffer::ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic) +ShaderBuffer::ShaderBuffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic) : graphics(graphics) , currentBuffer(0) , size(size) @@ -63,7 +65,7 @@ ShaderBuffer::~ShaderBuffer() { PCmdBuffer cmdBuffer = graphics->getQueueCommands(owner)->getCommands(); VkDevice device = graphics->getDevice(); - auto deletionLambda = [cmdBuffer, device](VkBuffer buffer) -> void + auto deletionLambda = [cmdBuffer, device](VkBuffer) -> void { //co_await cmdBuffer->asyncWait(); //vkDestroyBuffer(device, buffer, nullptr); @@ -169,6 +171,11 @@ void ShaderBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineSta } void *ShaderBuffer::lock(bool bWriteOnly) +{ + return lockRegion(0, size, bWriteOnly); +} + +void *ShaderBuffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnly) { void *data = nullptr; @@ -189,10 +196,12 @@ void *ShaderBuffer::lock(bool bWriteOnly) PendingBuffer pending; pending.bWriteOnly = bWriteOnly; pending.prevQueue = owner; + pending.offset = regionOffset; + pending.size = regionSize; if (bWriteOnly) { //requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER); - PStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); + PStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(regionSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); data = stagingBuffer->getMappedPointer(); pending.stagingBuffer = stagingBuffer; } @@ -255,7 +264,8 @@ void ShaderBuffer::unlock() VkBufferCopy region; std::memset(®ion, 0, sizeof(VkBufferCopy)); - region.size = size; + region.size = pending.size; + region.dstOffset = pending.offset; vkCmdCopyBuffer(cmdHandle, stagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, ®ion); graphics->getQueueCommands(owner)->submitCommands(); } @@ -448,6 +458,14 @@ VertexBuffer::~VertexBuffer() { } +void VertexBuffer::updateRegion(BulkResourceData update) +{ + void* data = lockRegion(update.offset, update.size); + std::memcpy(data, update.data, update.size); + unlock(); +} + + void VertexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) { Gfx::QueueOwnedResource::transferOwnership(newOwner); diff --git a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp index 8724a4a..f9dd1b1 100644 --- a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp @@ -302,7 +302,7 @@ void RenderCommand::pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStag void RenderCommand::draw(const MeshBatchElement& data) { assert(threadId == std::this_thread::get_id()); - vkCmdDrawIndexed(handle, data.indexBuffer->getNumIndices(), data.numInstances, data.minVertexIndex, data.baseVertexIndex, 0); + vkCmdDrawIndexed(handle, static_cast(data.indexBuffer->getNumIndices()), data.numInstances, data.minVertexIndex, data.baseVertexIndex, 0); } void RenderCommand::draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphics.h b/src/Engine/Graphics/Vulkan/VulkanGraphics.h index 5a57c34..aa0651c 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphics.h +++ b/src/Engine/Graphics/Vulkan/VulkanGraphics.h @@ -67,6 +67,7 @@ public: virtual Gfx::PPipelineLayout createPipelineLayout(Gfx::PPipelineLayout baseLayout = nullptr) override; virtual void copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) override; + protected: Array getRequiredExtensions(); void initInstance(GraphicsInitializer initInfo); diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphicsEnums.cpp b/src/Engine/Graphics/Vulkan/VulkanGraphicsEnums.cpp index cd2b220..8da81e4 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphicsEnums.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanGraphicsEnums.cpp @@ -1390,7 +1390,7 @@ Gfx::SeCompareOp Seele::Vulkan::cast(const VkCompareOp &op) VkClearValue Seele::Vulkan::cast(const Gfx::SeClearValue& clear) { VkClearValue result; - if(sizeof(clear) == sizeof(Gfx::SeClearColorValue)) + if constexpr (sizeof(clear) == sizeof(Gfx::SeClearColorValue)) { result.color.float32[0] = clear.color.float32[0]; result.color.float32[1] = clear.color.float32[1]; @@ -1408,7 +1408,7 @@ VkClearValue Seele::Vulkan::cast(const Gfx::SeClearValue& clear) Gfx::SeClearValue Seele::Vulkan::cast(const VkClearValue& clear) { Gfx::SeClearValue result; - if(sizeof(clear) == sizeof(VkClearColorValue)) + if constexpr (sizeof(clear) == sizeof(VkClearColorValue)) { result.color.float32[0] = clear.color.float32[0]; result.color.float32[1] = clear.color.float32[1]; diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h b/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h index 97f861e..60b63e7 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h +++ b/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h @@ -72,13 +72,13 @@ DEFINE_REF(VertexDeclaration) class ShaderBuffer { public: - ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic = false); + ShaderBuffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic = false); virtual ~ShaderBuffer(); VkBuffer getHandle() const { return buffers[currentBuffer].buffer; } - uint32 getSize() const + uint64 getSize() const { return size; } @@ -88,6 +88,7 @@ public: currentBuffer = (currentBuffer + 1) % numBuffers; } virtual void *lock(bool bWriteOnly = true); + virtual void *lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnly = true); virtual void unlock(); protected: @@ -98,7 +99,7 @@ protected: }; PGraphics graphics; uint32 currentBuffer; - uint32 size; + uint64 size; Gfx::QueueType& owner; BufferAllocation buffers[Gfx::numFramesBuffered]; uint32 numBuffers; @@ -168,6 +169,8 @@ public: VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData); virtual ~VertexBuffer(); + virtual void updateRegion(BulkResourceData update) override; + protected: // Inherited via Vulkan::Buffer virtual VkAccessFlags getSourceAccessMask(); diff --git a/src/Engine/Graphics/Vulkan/VulkanShader.cpp b/src/Engine/Graphics/Vulkan/VulkanShader.cpp index 0d20ac5..6a8696d 100644 --- a/src/Engine/Graphics/Vulkan/VulkanShader.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanShader.cpp @@ -2,9 +2,9 @@ #include "VulkanGraphics.h" #include "VulkanDescriptorSets.h" #include "slang.h" +#include "slang-com-ptr.h" #include "stdlib.h" -using namespace slang; using namespace Seele; using namespace Seele::Vulkan; @@ -33,85 +33,130 @@ uint32 Seele::Vulkan::Shader::getShaderHash() const return hash; } -static SlangStage getStageFromShaderType(ShaderType type) -{ - switch (type) - { - case ShaderType::VERTEX: - return SLANG_STAGE_VERTEX; - case ShaderType::CONTROL: - return SLANG_STAGE_HULL; - case ShaderType::EVALUATION: - return SLANG_STAGE_DOMAIN; - case ShaderType::GEOMETRY: - return SLANG_STAGE_GEOMETRY; - case ShaderType::FRAGMENT: - return SLANG_STAGE_PIXEL; - default: - return SLANG_STAGE_NONE; - } -} - void Shader::create(const ShaderCreateInfo& createInfo) { entryPointName = createInfo.entryPoint; - static SlangSession* session = spCreateSession(nullptr); - - SlangCompileRequest* request = spCreateCompileRequest(session); - int targetIndex = spAddCodeGenTarget(request, SLANG_SPIRV); - spSetTargetProfile(request, targetIndex, spFindProfile(session, "glsl_vk")); - spSetDumpIntermediates(request, true); - int translationUnitIndex = spAddTranslationUnit(request, SLANG_SOURCE_LANGUAGE_SLANG, ""); - - for(auto code : createInfo.shaderCode) + thread_local Slang::ComPtr globalSession; + if(!globalSession) { - spAddTranslationUnitSourceString( - request, - translationUnitIndex, - entryPointName.c_str(), - code.data() - ); + slang::createGlobalSession(globalSession.writeRef()); } + slang::SessionDesc sessionDesc; + sessionDesc.flags = 0; + sessionDesc.defaultMatrixLayoutMode = SLANG_MATRIX_LAYOUT_COLUMN_MAJOR; + Array macros; for(auto define : createInfo.defines) { - spAddPreprocessorDefine(request, define.key, define.value); + macros.add(slang::PreprocessorMacroDesc{ + .name = define.key, + .value = define.value + }); } - spAddSearchPath(request, "shaders/lib/"); - spAddSearchPath(request, "shaders/generated/"); + sessionDesc.preprocessorMacroCount = macros.size(); + sessionDesc.preprocessorMacros = macros.data(); + slang::TargetDesc vulkan; + vulkan.profile = globalSession->findProfile("glsl_vk"); + vulkan.format = SLANG_SPIRV; + sessionDesc.targetCount = 1; + sessionDesc.targets = &vulkan; + StaticArray searchPaths = {"shaders/", "shaders/lib/", "shaders/generated/"}; + sessionDesc.searchPaths = searchPaths.data(); + sessionDesc.searchPathCount = searchPaths.size(); - spSetGlobalGenericArgs(request, (int)createInfo.typeParameter.size(), createInfo.typeParameter.data()); + Slang::ComPtr session; + globalSession->createSession(sessionDesc, session.writeRef()); + + Slang::ComPtr diagnostics; + Array modules; + Slang::ComPtr entrypoint; - int entryPointIndex = spAddEntryPoint(request, translationUnitIndex, entryPointName.c_str(), getStageFromShaderType(type)); - if(spCompile(request)) + for (auto moduleName : createInfo.additionalModules) { - char const* diagnostics = spGetDiagnosticOutput(request); - std::cout << "Compile error for shader " << createInfo.name << std::endl; - std::cout << diagnostics << std::endl; - std::cout << "Defines: " << std::endl; - for(auto define : createInfo.defines) + modules.add(session->loadModule(moduleName.c_str(), diagnostics.writeRef())); + if(diagnostics) { - std::cout << define.key << ": " << define.value << std::endl; + std::cout << (const char*)diagnostics->getBufferPointer() << std::endl; } - std::cout << "For shader code: " << std::endl; - for(auto code : createInfo.shaderCode) - { - std::cout << code << std::endl; - } - return; } - size_t dataSize = 0; - const uint32* data = reinterpret_cast(spGetEntryPointCode(request, entryPointIndex, &dataSize)); + slang::IModule* mainModule = session->loadModule(createInfo.mainModule.c_str(), diagnostics.writeRef()); + modules.add(mainModule); + + if(diagnostics) + { + std::cout << (const char*)diagnostics->getBufferPointer() << std::endl; + } + + mainModule->findEntryPointByName(createInfo.entryPoint.c_str(), entrypoint.writeRef()); + modules.add(entrypoint); + + slang::IComponentType* moduleComposition; + session->createCompositeComponentType(modules.data(), modules.size(), &moduleComposition, diagnostics.writeRef()); + + if(diagnostics) + { + std::cout << (const char*)diagnostics->getBufferPointer() << std::endl; + } + + /*for(auto typeParam : createInfo.typeParameter) + { + Slang::ComPtr typeConformance; + session->createTypeConformanceComponentType(moduleComposition->getLayout()->findTypeByName(typeParam), moduleComposition->getLayout()->findTypeByName("IMaterial"), typeConformance.writeRef(), -1, diagnostics.writeRef()); + modules.add(typeConformance); + if(diagnostics) + { + std::cout << (const char*)diagnostics->getBufferPointer() << std::endl; + } + } + + Slang::ComPtr conformingModule; + session->createCompositeComponentType(modules.data(), modules.size(), conformingModule.writeRef(), diagnostics.writeRef()); +*/ + Slang::ComPtr linkedProgram; + moduleComposition->link(linkedProgram.writeRef(), diagnostics.writeRef()); + if(diagnostics) + { + std::cout << (const char*)diagnostics->getBufferPointer() << std::endl; + } + + slang::ProgramLayout* reflection = linkedProgram->getLayout(0, diagnostics.writeRef()); + if(diagnostics) + { + std::cout << (const char*)diagnostics->getBufferPointer() << std::endl; + } + + Array specialization; + for(auto typeArg : createInfo.typeParameter) + { + specialization.add(slang::SpecializationArg::fromType(reflection->findTypeByName(typeArg))); + } + Slang::ComPtr specializedComponent; + linkedProgram->specialize(specialization.data(), specialization.size(), specializedComponent.writeRef(), diagnostics.writeRef()); + if(diagnostics) + { + std::cout << (const char*)diagnostics->getBufferPointer() << std::endl; + } + Slang::ComPtr kernelBlob; + specializedComponent->getEntryPointCode( + 0, + 0, + kernelBlob.writeRef(), + diagnostics.writeRef() + ); + if(diagnostics) + { + std::cout << (const char*)diagnostics->getBufferPointer() << std::endl; + } VkShaderModuleCreateInfo moduleInfo; moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; moduleInfo.pNext = nullptr; moduleInfo.flags = 0; - moduleInfo.codeSize = dataSize; - moduleInfo.pCode = data; + moduleInfo.codeSize = kernelBlob->getBufferSize(); + moduleInfo.pCode = (uint32_t*)kernelBlob->getBufferPointer(); VK_CHECK(vkCreateShaderModule(graphics->getDevice(), &moduleInfo, nullptr, &module)); boost::crc_32_type result; result.process_bytes(entryPointName.data(), entryPointName.size()); - result.process_bytes(data, dataSize); + result.process_bytes(kernelBlob->getBufferPointer(), kernelBlob->getBufferSize()); hash = result.checksum(); } \ No newline at end of file diff --git a/src/Engine/Material/MaterialAsset.cpp b/src/Engine/Material/MaterialAsset.cpp index dc52e3c..770edd3 100644 --- a/src/Engine/Material/MaterialAsset.cpp +++ b/src/Engine/Material/MaterialAsset.cpp @@ -53,7 +53,6 @@ void MaterialAsset::load() std::ofstream codeStream("./shaders/generated/"+materialName+".slang"); std::string profile = j["profile"].get(); - codeStream << "import VERTEX_INPUT_IMPORT;" << std::endl; codeStream << "import Material;" << std::endl; codeStream << "import BRDF;" << std::endl; codeStream << "import MaterialParameter;" << std::endl << std::endl; @@ -94,7 +93,7 @@ void MaterialAsset::load() uniformBufferOffset += 12; if(defaultValue != param.value().end()) { - p->data = parseVector(defaultValue.value().get().c_str()); + p->data = Math::parseVector(defaultValue.value().get().c_str()); } parameters.add(p); } @@ -184,6 +183,6 @@ const Gfx::ShaderCollection* MaterialAsset::getShaders(Gfx::RenderPassType rende Gfx::ShaderCollection& MaterialAsset::createShaders(Gfx::PGraphics graphics, Gfx::RenderPassType renderPass, VertexInputType* vertexInput) { - std::scoped_lock lock(shaderMapLock); + std::scoped_lock l(shaderMapLock); return shaderMap.createShaders(graphics, renderPass, this, vertexInput, false); } diff --git a/src/Engine/Material/MaterialAsset.h b/src/Engine/Material/MaterialAsset.h index fb823b2..1f7ca19 100644 --- a/src/Engine/Material/MaterialAsset.h +++ b/src/Engine/Material/MaterialAsset.h @@ -40,6 +40,8 @@ private: uint8* uniformData; int32 uniformBinding; std::string materialName; + // With draw-indirect, we batch vertex data into big vertex buffers + // Gfx::PVertexDataManager vertexData; }; DEFINE_REF(MaterialAsset) } // namespace Seele diff --git a/src/Engine/Material/ShaderExpression.cpp b/src/Engine/Material/ShaderExpression.cpp index 435eced..8eb7aa5 100644 --- a/src/Engine/Material/ShaderExpression.cpp +++ b/src/Engine/Material/ShaderExpression.cpp @@ -40,7 +40,7 @@ VectorParameter::~VectorParameter() void VectorParameter::updateDescriptorSet(Gfx::PDescriptorSet, uint8* dst) { - std::memcpy(dst + byteOffset, &data, sizeof(Vector)); + std::memcpy(dst + byteOffset, &data, sizeof(Math::Vector)); } TextureParameter::TextureParameter(std::string name, uint32 byteOffset, uint32 binding) diff --git a/src/Engine/Material/ShaderExpression.h b/src/Engine/Material/ShaderExpression.h index 3a5fdb2..c9fc972 100644 --- a/src/Engine/Material/ShaderExpression.h +++ b/src/Engine/Material/ShaderExpression.h @@ -36,7 +36,7 @@ struct FloatParameter : public ShaderParameter DEFINE_REF(FloatParameter) struct VectorParameter : public ShaderParameter { - Vector data; + Math::Vector data; VectorParameter(std::string name, uint32 byteOffset, uint32 binding); virtual ~VectorParameter(); virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) override; diff --git a/src/Engine/Math/CMakeLists.txt b/src/Engine/Math/CMakeLists.txt index 2e79fb5..eb76468 100644 --- a/src/Engine/Math/CMakeLists.txt +++ b/src/Engine/Math/CMakeLists.txt @@ -2,7 +2,7 @@ target_sources(Engine PUBLIC Math.h Matrix.h - Vector.h - Vector.cpp Transform.h - Transform.cpp) \ No newline at end of file + Transform.cpp + Vector.h + Vector.cpp) \ No newline at end of file diff --git a/src/Engine/Math/Math.h b/src/Engine/Math/Math.h index 9a18713..34743b3 100644 --- a/src/Engine/Math/Math.h +++ b/src/Engine/Math/Math.h @@ -5,6 +5,8 @@ namespace Seele { +namespace Math +{ struct Rect { Rect() @@ -58,4 +60,5 @@ inline constexpr T align(const T ptr, int64_t alignment) { return (T)(((uint64_t)ptr + alignment - 1) & ~(alignment - 1)); } +} // namespace Math } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Math/Matrix.h b/src/Engine/Math/Matrix.h index b1f68bb..837e2ad 100644 --- a/src/Engine/Math/Matrix.h +++ b/src/Engine/Math/Matrix.h @@ -5,7 +5,10 @@ #include namespace Seele { +namespace Math +{ typedef glm::mat2 Matrix2; typedef glm::mat3 Matrix3; typedef glm::mat4 Matrix4; +} // namespace Math } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Math/Transform.cpp b/src/Engine/Math/Transform.cpp index 1c8ea40..4ef9e79 100644 --- a/src/Engine/Math/Transform.cpp +++ b/src/Engine/Math/Transform.cpp @@ -2,6 +2,7 @@ #include using namespace Seele; +using namespace Seele::Math; Transform::Transform() : position(Vector4(0, 0, 0, 0)), rotation(Quaternion(1, 0, 0, 0)), scale(Vector4(1, 1, 1, 0)) @@ -44,7 +45,7 @@ Vector Transform::inverseTransformPosition(const Vector &v) const { return (unrotateVector(rotation, v - Vector(position))) * getSafeScaleReciprocal(scale); } -Matrix4 Transform::toMatrix() +Matrix4 Transform::toMatrix() const { Matrix4 mat; @@ -197,20 +198,26 @@ void Transform::add(Transform *outTransform, const Transform *a, const Transform Transform &Transform::operator=(const Transform &other) { - position = other.position; - rotation = other.rotation; - scale = other.scale; + if(&other != this) + { + position = other.position; + rotation = other.rotation; + scale = other.scale; + } return *this; } Transform &Transform::operator=(Transform &&other) { - position = other.position; - rotation = other.rotation; - scale = other.scale; - other.position = Vector4(0, 0, 0, 0); - other.rotation = Quaternion(1, 0, 0, 0); - other.scale = Vector4(0, 0, 0, 0); + if(&other != this) + { + position = other.position; + rotation = other.rotation; + scale = other.scale; + other.position = Vector4(0, 0, 0, 0); + other.rotation = Quaternion(1, 0, 0, 0); + other.scale = Vector4(0, 0, 0, 0); + } return *this; } diff --git a/src/Engine/Math/Transform.h b/src/Engine/Math/Transform.h index 3863faf..7def04f 100644 --- a/src/Engine/Math/Transform.h +++ b/src/Engine/Math/Transform.h @@ -1,9 +1,11 @@ #pragma once -#include "Vector.h" -#include "Matrix.h" +#include "Math/Vector.h" +#include "Math/Matrix.h" namespace Seele { +namespace Math +{ class Transform { public: @@ -16,7 +18,7 @@ public: Transform(Quaternion rotation, Vector scale); ~Transform(); Vector inverseTransformPosition(const Vector &v) const; - Matrix4 toMatrix(); + Matrix4 toMatrix() const; static Vector getSafeScaleReciprocal(const Vector4 &inScale, float tolerance = 0.000000001f); Vector transformPosition(const Vector &v) const; @@ -41,4 +43,5 @@ private: Quaternion rotation; Vector4 scale; }; +} // namespace Math } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Math/Vector.cpp b/src/Engine/Math/Vector.cpp index e57c2fb..dc89855 100644 --- a/src/Engine/Math/Vector.cpp +++ b/src/Engine/Math/Vector.cpp @@ -1,25 +1,25 @@ #include "Vector.h" #include -using namespace Seele; +using namespace Seele::Math; -std::ostream& Seele::operator<<(std::ostream& stream, const Vector2& vector) +std::ostream& operator<<(std::ostream& stream, const Vector2& vector) { stream << "(" << vector.x << ", " << vector.y << ")"; return stream; } -std::ostream& Seele::operator<<(std::ostream& stream, const Vector& vector) +std::ostream& operator<<(std::ostream& stream, const Vector& vector) { stream << "(" << vector.x << ", " << vector.y << ", " << vector.z << ")"; return stream; } -std::ostream& Seele::operator<<(std::ostream& stream, const Vector4& vector) +std::ostream& operator<<(std::ostream& stream, const Vector4& vector) { stream << "(" << vector.x << ", " << vector.y << ", " << vector.z << ", " << vector.w << ")"; return stream; } -Vector Seele::parseVector(const char* str) +Vector Seele::Math::parseVector(const char* str) { //regex pattern consisting of 'float3(xComp, yComp, zComp)', more also matches for invalid floats, but that will throw later std::regex pattern("float3\\(\\s*([0-9.]+f?)\\s*,\\s*([0-9.]+f?)\\s*,\\s*([0-9.]+f?)\\s*\\)"); diff --git a/src/Engine/Math/Vector.h b/src/Engine/Math/Vector.h index 4e460a7..6233e49 100644 --- a/src/Engine/Math/Vector.h +++ b/src/Engine/Math/Vector.h @@ -1,11 +1,16 @@ #pragma once +#pragma warning(push) +#pragma warning(disable: 4201) #include #include #include #include +#pragma warning(pop) namespace Seele { +namespace Math +{ typedef glm::vec2 Vector2; typedef glm::vec3 Vector; typedef glm::vec4 Vector4; @@ -95,4 +100,5 @@ static inline Vector toRotator(const Quaternion &other) } return rotatorFromQuat; } +} // namespace Math } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Scene/Actor/Actor.cpp b/src/Engine/Scene/Actor/Actor.cpp index 1912345..3b3d00a 100644 --- a/src/Engine/Scene/Actor/Actor.cpp +++ b/src/Engine/Scene/Actor/Actor.cpp @@ -1,61 +1,19 @@ #include "Actor.h" -#include "Scene/Components/Component.h" #include "Scene/Scene.h" using namespace Seele; -Actor::Actor() +Actor::Actor(PScene scene) + : Entity(scene) { - + scene->attachComponent(identifier); } + Actor::~Actor() { } -void Actor::launchStart() -{ - rootComponent->launchStart(); - for(auto child : children) - { - child->launchStart(); - } - start(); -} -void Actor::launchTick(float deltaTime) const -{ - rootComponent->launchTick(deltaTime); - for(auto child : children) - { - child->launchTick(deltaTime); - } - tick(deltaTime); -} - -void Actor::launchUpdate() -{ - rootComponent->launchUpdate(); - for(auto child : children) - { - child->launchUpdate(); - } - update(); -} -void Actor::notifySceneAttach(PScene scene) -{ - owningScene = scene; - rootComponent->notifySceneAttach(scene); - for(auto child : children) - { - child->notifySceneAttach(scene); - } -} - -PScene Actor::getScene() -{ - return owningScene; -} - void Actor::setParent(PActor newParent) { if(parent != nullptr) @@ -68,86 +26,19 @@ void Actor::addChild(PActor child) { children.add(child); child->setParent(this); - child->notifySceneAttach(owningScene); } void Actor::removeChild(PActor child) { children.remove(children.find(child), false); child->setParent(nullptr); - child->notifySceneAttach(nullptr); } -//void Actor::setAbsoluteLocation(Vector location) -//{ -// rootComponent->setWorldLocation(location); -//} -// -//void Actor::setAbsoluteRotation(Quaternion rotation) -//{ -// rootComponent->setAbsoluteRotation(rotation); -//} -//void Actor::setAbsoluteRotation(Vector rotation) -//{ -// rootComponent->setAbsoluteRotation(rotation); -//} -//void Actor::setWorldScale(Vector scale) -//{ -// rootComponent->setWorldScale(scale); -//} -void Actor::setRelativeLocation(Vector location) +const Component::Transform& Actor::getTransform() const { - rootComponent->setRelativeLocation(location); -} -void Actor::setRelativeRotation(Quaternion rotation) -{ - rootComponent->setRelativeRotation(rotation); -} -void Actor::setRelativeRotation(Vector rotation) -{ - rootComponent->setRelativeRotation(rotation); -} -void Actor::setRelativeScale(Vector scale) -{ - rootComponent->setRelativeScale(scale); -} -//void Actor::addAbsoluteTranslation(Vector translation) -//{ -// rootComponent->addAbsoluteTranslation(translation); -//} -//void Actor::addAbsoluteRotation(Quaternion rotation) -//{ -// rootComponent->addAbsoluteRotation(rotation); -//} -//void Actor::addAbsoluteRotation(Vector rotation) -//{ -// rootComponent->addAbsoluteRotation(rotation); -//} -void Actor::addRelativeLocation(Vector translation) -{ - rootComponent->addRelativeLocation(translation); -} -void Actor::addRelativeRotation(Quaternion rotation) -{ - rootComponent->addRelativeRotation(rotation); -} -void Actor::addRelativeRotation(Vector rotation) -{ - rootComponent->addRelativeRotation(rotation); -} -PComponent Actor::getRootComponent() -{ - return rootComponent; -} -void Actor::setRootComponent(PComponent newRoot) -{ - if(rootComponent != nullptr) - { - rootComponent->owner = nullptr; - } - rootComponent = newRoot; - rootComponent->owner = this; + return scene->accessComponent(identifier); } -Transform Actor::getTransform() const -{ - return rootComponent->getTransform(); -} +//Component::Transform& Actor::getTransform() +//{ +// return scene->accessComponent(identifier); +//} + diff --git a/src/Engine/Scene/Actor/Actor.h b/src/Engine/Scene/Actor/Actor.h index f61a420..cb18bf0 100644 --- a/src/Engine/Scene/Actor/Actor.h +++ b/src/Engine/Scene/Actor/Actor.h @@ -1,60 +1,31 @@ #pragma once -#include "MinimalEngine.h" -#include "Math/Transform.h" +#include "Entity.h" +#include "Scene/Component/Transform.h" namespace Seele { DECLARE_REF(Actor) -DECLARE_REF(Component) -DECLARE_REF(Scene) -class Actor +// Actors are entities that are part of the scene hierarchy +// In order for that hierarchy to make sense it requires at least a transform component +class Actor : public Entity { public: - Actor(); + Actor(PScene scene); virtual ~Actor(); - virtual void launchStart(); - virtual void start() {} - void launchTick(float deltaTime) const; - virtual void tick(float) const { }//co_return; } - void launchUpdate(); - virtual void update() { }//co_return; } - void notifySceneAttach(PScene scene); - PScene getScene(); PActor getParent(); void addChild(PActor child); void removeChild(PActor child); Array getChildren(); - //void setAbsoluteLocation(Vector location); - //void setAbsoluteRotation(Quaternion rotation); - //void setAbsoluteRotation(Vector rotation); - //void setWorldScale(Vector scale); - - void setRelativeLocation(Vector location); - void setRelativeRotation(Quaternion rotation); - void setRelativeRotation(Vector rotation); - void setRelativeScale(Vector scale); - - //void addAbsoluteTranslation(Vector translation); - //void addAbsoluteRotation(Quaternion rotation); - //void addAbsoluteRotation(Vector rotation); - - void addRelativeLocation(Vector translation); - void addRelativeRotation(Quaternion rotation); - void addRelativeRotation(Vector rotation); - - PComponent getRootComponent(); - void setRootComponent(PComponent newRoot); - + // Returns a read-only copy of the actors transform - Transform getTransform() const; + const Component::Transform& getTransform() const; protected: + //Component::Transform& getTransform(); void setParent(PActor parent); - PScene owningScene; PActor parent; Array children; - PComponent rootComponent; }; DEFINE_REF(Actor) } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Scene/Actor/CMakeLists.txt b/src/Engine/Scene/Actor/CMakeLists.txt index 710a0b1..6946cd4 100644 --- a/src/Engine/Scene/Actor/CMakeLists.txt +++ b/src/Engine/Scene/Actor/CMakeLists.txt @@ -3,4 +3,6 @@ target_sources(Engine Actor.cpp Actor.h CameraActor.cpp - CameraActor.h) \ No newline at end of file + CameraActor.h + Entity.cpp + Entity.h) \ No newline at end of file diff --git a/src/Engine/Scene/Actor/CameraActor.cpp b/src/Engine/Scene/Actor/CameraActor.cpp index 2b9e16a..9dc2b94 100644 --- a/src/Engine/Scene/Actor/CameraActor.cpp +++ b/src/Engine/Scene/Actor/CameraActor.cpp @@ -1,21 +1,25 @@ #include "CameraActor.h" -#include "Scene/Components/Component.h" -#include "Scene/Components/CameraComponent.h" +#include "Scene/Scene.h" using namespace Seele; -CameraActor::CameraActor() +CameraActor::CameraActor(PScene scene) + : Actor(scene) { - sceneComponent = new Component(); - setRootComponent(sceneComponent); - - cameraComponent = new CameraComponent(); - cameraComponent->fieldOfView = 70.0f; - cameraComponent->setParent(sceneComponent); - cameraComponent->setOwner(this); - sceneComponent->addChildComponent(cameraComponent); + scene->attachComponent(identifier); + scene->accessComponent(identifier).setRelativeLocation(Math::Vector(10, 5, 14)); } CameraActor::~CameraActor() { +} + +Component::Camera& CameraActor::getCameraComponent() +{ + return scene->accessComponent(identifier); +} + +const Component::Camera& CameraActor::getCameraComponent() const +{ + return scene->accessComponent(identifier); } \ No newline at end of file diff --git a/src/Engine/Scene/Actor/CameraActor.h b/src/Engine/Scene/Actor/CameraActor.h index 39a61e0..7cd1e9a 100644 --- a/src/Engine/Scene/Actor/CameraActor.h +++ b/src/Engine/Scene/Actor/CameraActor.h @@ -1,21 +1,17 @@ #pragma once #include "Actor.h" +#include "Scene/Component/Camera.h" namespace Seele { -DECLARE_REF(CameraComponent) class CameraActor : public Actor { public: - CameraActor(); + CameraActor(PScene scene); virtual ~CameraActor(); - PCameraComponent getCameraComponent() const - { - return cameraComponent; - } + Component::Camera& getCameraComponent(); + const Component::Camera& getCameraComponent() const; private: - PCameraComponent cameraComponent; - PComponent sceneComponent; // This will be the root, camera will be the child }; DEFINE_REF(CameraActor) } // namespace Seele diff --git a/src/Engine/Scene/Actor/Entity.cpp b/src/Engine/Scene/Actor/Entity.cpp new file mode 100644 index 0000000..9641d99 --- /dev/null +++ b/src/Engine/Scene/Actor/Entity.cpp @@ -0,0 +1,15 @@ +#include "Entity.h" + +using namespace Seele; + +Entity::Entity(PScene scene) + : identifier(scene->createEntity()) + , scene(scene) +{ +} + + +Entity::~Entity() +{ + +} \ No newline at end of file diff --git a/src/Engine/Scene/Actor/Entity.h b/src/Engine/Scene/Actor/Entity.h new file mode 100644 index 0000000..0bbac17 --- /dev/null +++ b/src/Engine/Scene/Actor/Entity.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include "MinimalEngine.h" +#include "Scene/Scene.h" +namespace Seele +{ +// An entity describes a part of a scene +// It is just a wrapper the ID of a registry +class Entity +{ +public: + Entity(PScene scene); + virtual ~Entity(); + + template + void attachComponent(Args... args) + { + scene->attachComponent(identifier, args...); + } +protected: + PScene scene; + entt::entity identifier; +}; +DEFINE_REF(Entity) +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Scene/CMakeLists.txt b/src/Engine/Scene/CMakeLists.txt index 9a3c354..fa7ee3b 100644 --- a/src/Engine/Scene/CMakeLists.txt +++ b/src/Engine/Scene/CMakeLists.txt @@ -5,4 +5,5 @@ target_sources(Engine Scene.h) add_subdirectory(Actor/) -add_subdirectory(Components/) \ No newline at end of file +add_subdirectory(Component/) +add_subdirectory(System/) \ No newline at end of file diff --git a/src/Engine/Scene/Component/CMakeLists.txt b/src/Engine/Scene/Component/CMakeLists.txt new file mode 100644 index 0000000..0d183a6 --- /dev/null +++ b/src/Engine/Scene/Component/CMakeLists.txt @@ -0,0 +1,8 @@ +target_sources(Engine + PUBLIC + Component.h + Camera.h + Camera.cpp + StaticMesh.h + Transform.h + Transform.cpp) \ No newline at end of file diff --git a/src/Engine/Scene/Components/CameraComponent.cpp b/src/Engine/Scene/Component/Camera.cpp similarity index 63% rename from src/Engine/Scene/Components/CameraComponent.cpp rename to src/Engine/Scene/Component/Camera.cpp index 5b30009..a70b60f 100644 --- a/src/Engine/Scene/Components/CameraComponent.cpp +++ b/src/Engine/Scene/Component/Camera.cpp @@ -1,13 +1,15 @@ -#include "CameraComponent.h" +#include "Camera.h" #include "Scene/Actor/Actor.h" #include #include using namespace Seele; +using namespace Seele::Component; +using namespace Seele::Math; -CameraComponent::CameraComponent() +Camera::Camera() : aspectRatio(0) - , fieldOfView(0) + , fieldOfView(glm::radians(70.f)) , bNeedsViewBuild(true) , bNeedsProjectionBuild(true) , viewMatrix(Matrix4()) @@ -15,14 +17,13 @@ CameraComponent::CameraComponent() { yaw = 0; pitch = 0; - setRelativeLocation(Vector(0, 10, -50)); } -CameraComponent::~CameraComponent() +Camera::~Camera() { } -void CameraComponent::mouseMove(float deltaYaw, float deltaPitch) +void Camera::mouseMove(float deltaYaw, float deltaPitch) { yaw -= deltaYaw / 500.f; pitch += deltaPitch / 500.f; @@ -31,29 +32,29 @@ void CameraComponent::mouseMove(float deltaYaw, float deltaPitch) Vector xyz = glm::cross(cameraDirection, Vector(0, 0, 1)); Quaternion result = Quaternion(glm::dot(cameraDirection, Vector(0, 0, 1)) + 1, xyz.x, xyz.y, xyz.z); //std::cout << "Result " << Vector(0, 0, 1) * glm::normalize(result) << " cameraDirection: " << cameraDirection << std::endl; - setRelativeRotation(result); + getTransform().setRelativeRotation(result); bNeedsViewBuild = true; } -void CameraComponent::mouseScroll(float x) +void Camera::mouseScroll(float x) { - addRelativeLocation(getTransform().getForward()*x); + getTransform().addRelativeLocation(getTransform().getForward()*x); bNeedsViewBuild = true; } -void CameraComponent::moveX(float amount) +void Camera::moveX(float amount) { - addRelativeLocation(getTransform().getForward()*amount); + getTransform().addRelativeLocation(getTransform().getForward()*amount); bNeedsViewBuild = true; } -void CameraComponent::moveY(float amount) +void Camera::moveY(float amount) { - addRelativeLocation(getTransform().getRight()*amount); + getTransform().addRelativeLocation(getTransform().getRight()*amount); bNeedsViewBuild = true; } -void CameraComponent::setViewport(Gfx::PViewport newViewport) +void Camera::setViewport(Gfx::PViewport newViewport) { viewport = newViewport; aspectRatio = viewport->getSizeX() / (float)viewport->getSizeY(); @@ -61,17 +62,17 @@ void CameraComponent::setViewport(Gfx::PViewport newViewport) bNeedsProjectionBuild = true; } -void CameraComponent::buildViewMatrix() +void Camera::buildViewMatrix() { - Vector eyePos = getAbsoluteTransform().getPosition(); - Vector lookAt = eyePos + glm::normalize(Vector(cos(yaw) * cos(pitch), sin(pitch), sin(yaw) * cos(pitch))); + Vector eyePos = getTransform().getPosition();//getAbsoluteTransform().getPosition(); + Vector lookAt = Vector(0, 0, 0);//eyePos + glm::normalize(Vector(cos(yaw) * cos(pitch), sin(pitch), sin(yaw) * cos(pitch))); //std::cout << "Eye: " << eyePos << " lookAt: " << lookAt << std::endl; viewMatrix = glm::lookAt(eyePos, lookAt, Vector(0, 1, 0)); bNeedsViewBuild = false; } -void CameraComponent::buildProjectionMatrix() +void Camera::buildProjectionMatrix() { projectionMatrix = glm::perspective(fieldOfView, aspectRatio, 1.0f, 1000.f); static Matrix4 correctionMatrix = diff --git a/src/Engine/Scene/Components/CameraComponent.h b/src/Engine/Scene/Component/Camera.h similarity index 62% rename from src/Engine/Scene/Components/CameraComponent.h rename to src/Engine/Scene/Component/Camera.h index 69eb24a..d139dc6 100644 --- a/src/Engine/Scene/Components/CameraComponent.h +++ b/src/Engine/Scene/Component/Camera.h @@ -2,32 +2,30 @@ #include "Component.h" #include "Math/Matrix.h" #include "Graphics/GraphicsResources.h" +#include "Transform.h" namespace Seele { -class CameraComponent : public Component +namespace Component { -public: - CameraComponent(); - virtual ~CameraComponent(); +struct Camera +{ + REQUIRE_COMPONENT(Transform) + + Camera(); + ~Camera(); - Matrix4 getViewMatrix() + Math::Matrix4 getViewMatrix() { - if (bNeedsViewBuild) - { - buildViewMatrix(); - } + assert (!bNeedsViewBuild); return viewMatrix; } - Matrix4 getProjectionMatrix() + Math::Matrix4 getProjectionMatrix() { - if (bNeedsProjectionBuild) - { - buildProjectionMatrix(); - } + assert (!bNeedsProjectionBuild); return projectionMatrix; } - Vector getCameraPosition() + Math::Vector getCameraPosition() { return getTransform().getPosition(); } @@ -38,19 +36,19 @@ public: void moveY(float amount); float aspectRatio; float fieldOfView; + void buildViewMatrix(); + void buildProjectionMatrix(); private: bool bNeedsViewBuild; bool bNeedsProjectionBuild; - void buildViewMatrix(); - void buildProjectionMatrix(); Gfx::PViewport viewport; //Transforms relative to actor - Matrix4 viewMatrix; - Matrix4 projectionMatrix; + Math::Matrix4 viewMatrix; + Math::Matrix4 projectionMatrix; float yaw; float pitch; }; -DEFINE_REF(CameraComponent) +} // namespace Component } // namespace Seele diff --git a/src/Engine/Scene/Component/Component.h b/src/Engine/Scene/Component/Component.h new file mode 100644 index 0000000..d9cc2e7 --- /dev/null +++ b/src/Engine/Scene/Component/Component.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include + +namespace Seele +{ +template +struct Dependencies; +template<> +struct Dependencies<> +{}; +template +struct Dependencies : public Dependencies +{ + template + Dependencies operator|(const Dependencies& other) + { + return Dependencies(); + } +}; + +namespace Component +{ +#pragma warning(disable: 4505) +template +static int accessComponent(Comp& comp); +} + +template +concept is_component = std::same_as>; + +#define REQUIRE_COMPONENT(x) \ + private: \ + x& get##x() { return *tl_##x; } \ + const x& get##x() const { return *tl_##x; }; \ + public: \ + static Dependencies dependencies; + +#define DECLARE_COMPONENT(x) \ + thread_local extern x* tl_##x; \ + template<> \ + int accessComponent(x& val) { tl_##x = &val; return 0; } + +#define DEFINE_COMPONENT(x) \ + thread_local x* Seele::Component::tl_##x; + +} // namespace Seele diff --git a/src/Engine/Scene/Component/StaticMesh.h b/src/Engine/Scene/Component/StaticMesh.h new file mode 100644 index 0000000..4db2ab8 --- /dev/null +++ b/src/Engine/Scene/Component/StaticMesh.h @@ -0,0 +1,15 @@ +#pragma once +#include "Graphics/GraphicsResources.h" + +namespace Seele +{ +namespace Component +{ +struct StaticMesh +{ + PVertexShaderInput vertexBuffer; + Gfx::PIndexBuffer indexBuffer; + PMaterialAsset material; +}; +} // namespace Component +} // namespace Seele diff --git a/src/Engine/Scene/Component/Transform.cpp b/src/Engine/Scene/Component/Transform.cpp new file mode 100644 index 0000000..9adb741 --- /dev/null +++ b/src/Engine/Scene/Component/Transform.cpp @@ -0,0 +1,34 @@ +#include "Transform.h" + +using namespace Seele::Component; + +DEFINE_COMPONENT(Transform) + +void Transform::setRelativeLocation(Math::Vector location) +{ + transform = Math::Transform(location, transform.getRotation(), transform.getScale()); +} +void Transform::setRelativeRotation(Math::Vector rotation) +{ + transform = Math::Transform(transform.getPosition(), Math::Quaternion(rotation), transform.getScale()); +} +void Transform::setRelativeRotation(Math::Quaternion rotation) +{ + transform = Math::Transform(transform.getPosition(), rotation, transform.getScale()); +} +void Transform::setRelativeScale(Math::Vector scale) +{ + transform = Math::Transform(transform.getPosition(), transform.getRotation(), scale); +} +void Transform::addRelativeLocation(Math::Vector translation) +{ + transform = Math::Transform(transform.getPosition() + translation, transform.getRotation(), transform.getScale()); +} +void Transform::addRelativeRotation(Math::Vector rotation) +{ + transform = Math::Transform(transform.getPosition(), transform.getRotation() * Math::Quaternion(rotation), transform.getScale()); +} +void Transform::addRelativeRotation(Math::Quaternion rotation) +{ + transform = Math::Transform(transform.getPosition(), transform.getRotation() * rotation, transform.getScale()); +} \ No newline at end of file diff --git a/src/Engine/Scene/Component/Transform.h b/src/Engine/Scene/Component/Transform.h new file mode 100644 index 0000000..1a4bc6f --- /dev/null +++ b/src/Engine/Scene/Component/Transform.h @@ -0,0 +1,52 @@ +#pragma once +#include "Math/Transform.h" +#include "Component.h" + +namespace Seele +{ +namespace Component +{ +struct Transform +{ + Transform() {} + Transform(const Transform& other) : transform(other.transform) {} + Transform(Transform&& other) : transform(other.transform) {} + Transform& operator=(const Transform& other) { + if (&other != this) + { + transform = other.transform; + } + return *this; + } + Transform& operator=(Transform&& other) { + if(&other != this) + { + transform = std::move(other.transform); + } + return *this; + } + Math::Vector getPosition() const { return transform.getPosition(); } + Math::Quaternion getRotation() const { return transform.getRotation(); } + Math::Vector getScale() const { return transform.getScale(); } + + Math::Vector getForward() const { return transform.getForward(); } + Math::Vector getUp() const { return transform.getUp(); } + Math::Vector getRight() const { return transform.getRight(); } + + Math::Matrix4 toMatrix() const { return transform.toMatrix(); } + + void setRelativeLocation(Math::Vector location); + void setRelativeRotation(Math::Quaternion rotation); + void setRelativeRotation(Math::Vector rotation); + void setRelativeScale(Math::Vector scale); + + void addRelativeLocation(Math::Vector translation); + void addRelativeRotation(Math::Quaternion rotation); + void addRelativeRotation(Math::Vector rotation); +private: + Math::Transform transform; +}; +DECLARE_COMPONENT(Transform) + +} // namespace Component +} // namespace Seele diff --git a/src/Engine/Scene/Components/CMakeLists.txt b/src/Engine/Scene/Components/CMakeLists.txt deleted file mode 100644 index 3053d62..0000000 --- a/src/Engine/Scene/Components/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -target_sources(Engine - PUBLIC - CameraComponent.h - CameraComponent.cpp - Component.h - Component.cpp - MyComponent.h - MyComponent.cpp - MyOtherComponent.h - MyOtherComponent.cpp - PrimitiveComponent.cpp - PrimitiveComponent.h) \ No newline at end of file diff --git a/src/Engine/Scene/Components/Component.cpp b/src/Engine/Scene/Components/Component.cpp deleted file mode 100644 index 1ed9e65..0000000 --- a/src/Engine/Scene/Components/Component.cpp +++ /dev/null @@ -1,201 +0,0 @@ -#include "Component.h" -#include "Scene/Actor/Actor.h" -#include "Scene/Scene.h" - -using namespace Seele; - -Component::Component() -{ -} -Component::~Component() -{ -} - -void Component::launchStart() -{ - for(auto child : children) - { - child->launchStart(); - } - start(); -} - -void Component::launchTick(float deltaTime) const -{ - for(auto child : children) - { - child->launchTick(deltaTime); - } - tick(deltaTime); -} - -void Component::launchUpdate() -{ - for(auto child : children) - { - child->launchUpdate(); - } - update(); -} - -PComponent Component::getParent() -{ - return parent; -} -PActor Component::getOwner() -{ - if (owner != nullptr) - { - return owner; - } - if (parent != nullptr) - { - return parent->getOwner(); - } - return nullptr; -} -const Array& Component::getChildComponents() -{ - return children; -} - -void Component::setParent(PComponent newParent) -{ - parent = newParent; -} - -void Component::setOwner(PActor newOwner) -{ - owner = newOwner; -} - -void Component::addChildComponent(PComponent component) -{ - children.add(component); -} - -void Component::notifySceneAttach(PScene scene) -{ - owningScene = scene; - for (auto child : children) - { - child->notifySceneAttach(scene); - } -} - -//void Component::setAbsoluteLocation(Vector location) -//{ -// Vector newRelLocation = location; -// if (parent != nullptr) -// { -// Transform parentToWorld = getParent()->getTransform(); -// newRelLocation = parentToWorld.inverseTransformPosition(location); -// } -// setRelativeLocation(newRelLocation); -//} -//void Component::setAbsoluteRotation(Vector rotation) -//{ -// Vector newRelRotator = rotation; -// if (parent == nullptr) -// { -// setRelativeRotation(rotation); -// } -// else -// { -// setAbsoluteRotation(toQuaternion(newRelRotator)); -// } -//} -//void Component::setAbsoluteRotation(Quaternion rotation) -//{ -// Quaternion newRelRotation = getRelativeWorldRotation(rotation); -// setRelativeRotation(newRelRotation); -//} -//void Component::setWorldScale(Vector scale) -//{ -// Vector newRelScale = scale; -// if (parent != nullptr) -// { -// Transform parentToWorld = parent->getTransform(); -// newRelScale = scale * parentToWorld.getSafeScaleReciprocal(Vector4(parentToWorld.getScale(), 0)); -// } -// setRelativeScale(newRelScale); -//} - -void Component::setRelativeLocation(Vector location) -{ - transform = Transform(location, transform.getRotation(), transform.getScale()); - propagateTransformUpdate(); -} -void Component::setRelativeRotation(Vector rotation) -{ - transform = Transform(transform.getPosition(), Quaternion(rotation), transform.getScale()); - propagateTransformUpdate(); -} -void Component::setRelativeRotation(Quaternion rotation) -{ - transform = Transform(transform.getPosition(), rotation, transform.getScale()); - propagateTransformUpdate(); -} -void Component::setRelativeScale(Vector scale) -{ - transform = Transform(transform.getPosition(), transform.getRotation(), scale); - propagateTransformUpdate(); -} - -//void Component::addAbsoluteTranslation(Vector translation) -//{ -// const Vector newWorldLocation = translation + getTransform().getPosition(); -// setAbsoluteLocation(newWorldLocation); -//} -//void Component::addAbsoluteRotation(Vector rotation) -//{ -// const Quaternion newWorldRotation = toQuaternion(rotation) * getTransform().getRotation(); -// setAbsoluteRotation(newWorldRotation); -//} -//void Component::addAbsoluteRotation(Quaternion rotation) -//{ -// const Quaternion newWorldRotation = rotation * getTransform().getRotation(); -// setAbsoluteRotation(newWorldRotation); -//} - -void Component::addRelativeLocation(Vector translation) -{ - transform = Transform(transform.getPosition() + translation, transform.getRotation(), transform.getScale()); - propagateTransformUpdate(); -} -void Component::addRelativeRotation(Vector rotation) -{ - transform = Transform(transform.getPosition(), transform.getRotation() * Quaternion(rotation), transform.getScale()); - propagateTransformUpdate(); -} -void Component::addRelativeRotation(Quaternion rotation) -{ - transform = Transform(transform.getPosition(), transform.getRotation() * rotation, transform.getScale()); - propagateTransformUpdate(); -} - -Transform Component::getTransform() const -{ - return transform; -} - -Transform Component::getAbsoluteTransform() const -{ - return absoluteTransform; -} - -void Component::propagateTransformUpdate() -{ - if(parent != nullptr) - { - absoluteTransform = transform + parent->getAbsoluteTransform(); - } - else - { - absoluteTransform = transform; - } - for(auto child : children) - { - child->propagateTransformUpdate(); - } -} \ No newline at end of file diff --git a/src/Engine/Scene/Components/Component.h b/src/Engine/Scene/Components/Component.h deleted file mode 100644 index dd2b253..0000000 --- a/src/Engine/Scene/Components/Component.h +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once -#include "MinimalEngine.h" -#include "Math/Transform.h" -#include "Scene/Util.h" - -namespace Seele -{ -DECLARE_REF(Actor) -DECLARE_REF(Scene) -DECLARE_REF(Component) -class Component -{ -public: - Component(); - virtual ~Component(); - void launchStart(); - virtual void start() {}; - void launchTick(float deltaTime) const; - virtual void tick(float) const { }//co_return; } - void launchUpdate(); - virtual void update() { }//co_return; } - PComponent getParent(); - PActor getOwner(); - const Array& getChildComponents(); - void setParent(PComponent parent); - void setOwner(PActor owner); - void addChildComponent(PComponent component); - virtual void notifySceneAttach(PScene scene); - - void setRelativeLocation(Vector location); - void setRelativeRotation(Vector rotation); - void setRelativeRotation(Quaternion rotation); - void setRelativeScale(Vector scale); - - void addRelativeLocation(Vector translation); - void addRelativeRotation(Vector rotation); - void addRelativeRotation(Quaternion rotation); - - Transform getTransform() const; - Transform getAbsoluteTransform() const; - - template - RefPtr getComponent() - { - return tryFindComponent(); - } - -private: - template - RefPtr tryFindComponent() - { - for(auto child : children) - { - RefPtr result = child.cast(); - if(result != nullptr) - { - return result; - } - result = parent->tryFindComponent(); - if(result != nullptr) - { - return result; - } - } - return nullptr; - } - void propagateTransformUpdate(); - Transform transform; - Transform absoluteTransform; - PScene owningScene; - PActor owner; - PComponent parent; - Array children; - friend class Actor; -}; -DEFINE_REF(Component) -} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Scene/Components/MyComponent.cpp b/src/Engine/Scene/Components/MyComponent.cpp deleted file mode 100644 index 9d28c62..0000000 --- a/src/Engine/Scene/Components/MyComponent.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "MyComponent.h" - -using namespace Seele; - -MyComponent::MyComponent() -{ -} - -void MyComponent::start() -{ - otherComp = getComponent(); - otherComp.update(); -} - -void MyComponent::tick(float) const -{ - //std::cout << "MyComponent::tick" << std::endl; - ++writable; - //std::cout << "MyComponent::tick finished" << std::endl; - otherComp->data = *writable; - //co_return; -} - -void MyComponent::update() -{ - //std::cout << "MyComponent::update" << std::endl; - writable.update(); - //std::cout << "MyComponent::update finished" << std::endl; - //co_return; -} diff --git a/src/Engine/Scene/Components/MyComponent.h b/src/Engine/Scene/Components/MyComponent.h deleted file mode 100644 index 2788bdd..0000000 --- a/src/Engine/Scene/Components/MyComponent.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once -#include "Component.h" -#include "MyOtherComponent.h" - -namespace Seele -{ -class MyComponent : public Component -{ -public: - MyComponent(); - virtual void start(); - virtual void tick(float deltatime) const; - virtual void update(); -private: - Writable otherComp; - Writable writable = 0; - uint32 notWritable = 10; -}; -DECLARE_REF(MyComponent); -} // namespace Seele diff --git a/src/Engine/Scene/Components/MyOtherComponent.cpp b/src/Engine/Scene/Components/MyOtherComponent.cpp deleted file mode 100644 index 0dc308f..0000000 --- a/src/Engine/Scene/Components/MyOtherComponent.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "MyOtherComponent.h" - -using namespace Seele; - -void MyOtherComponent::tick(float) const -{ - //std::cout << *data << std::endl; - //co_return; -} - -void MyOtherComponent::update() -{ - data.update(); - //co_return; -} diff --git a/src/Engine/Scene/Components/MyOtherComponent.h b/src/Engine/Scene/Components/MyOtherComponent.h deleted file mode 100644 index ed7d957..0000000 --- a/src/Engine/Scene/Components/MyOtherComponent.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include "Component.h" - -namespace Seele -{ -class MyOtherComponent : public Component -{ -public: - virtual void tick(float deltaTime) const; - virtual void update(); - Writable data = Writable(0); -private: -}; -DEFINE_REF(MyOtherComponent); -} // namespace Seele diff --git a/src/Engine/Scene/Components/PrimitiveComponent.cpp b/src/Engine/Scene/Components/PrimitiveComponent.cpp deleted file mode 100644 index 7f83011..0000000 --- a/src/Engine/Scene/Components/PrimitiveComponent.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "PrimitiveComponent.h" -#include "Scene/Scene.h" -#include "Material/MaterialAsset.h" -#include "Asset/MeshAsset.h" -#include "Graphics/VertexShaderInput.h" -#include - -using namespace Seele; - -PrimitiveComponent::PrimitiveComponent() -{ -} - -PrimitiveComponent::PrimitiveComponent(PMeshAsset asset) -{ - auto assetMeshes = asset->getMeshes(); - staticMeshes.resize(assetMeshes.size()); - for (uint32 i = 0; i < assetMeshes.size(); i++) - { - auto& batch = staticMeshes[i]; - batch.material = asset->referencedMaterials[i]; - batch.isBackfaceCullingDisabled = false; - batch.isCastingShadow = true; - batch.primitiveComponent = this; - batch.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - batch.useReverseCulling = false; - batch.useWireframe = false; - batch.vertexInput = assetMeshes[i]->vertexInput; - MeshBatchElement batchElement; - batchElement.baseVertexIndex = 0; - batchElement.firstIndex = 0; - batchElement.indexBuffer = assetMeshes[i]->indexBuffer; - batchElement.indirectArgsBuffer = nullptr; - batchElement.instanceRuns = nullptr; - batchElement.isInstanced = false; - batchElement.numInstances = 1; - batchElement.numPrimitives = assetMeshes[i]->indexBuffer->getNumIndices() / 3; //TODO: hardcoded - batch.elements.push_back(batchElement); - } -} - -PrimitiveComponent::~PrimitiveComponent() -{ -} - -void PrimitiveComponent::notifySceneAttach(PScene scene) -{ - scene->addPrimitiveComponent(this); -} - -Matrix4 PrimitiveComponent::getRenderMatrix() -{ - return getAbsoluteTransform().toMatrix(); -} diff --git a/src/Engine/Scene/Components/PrimitiveComponent.h b/src/Engine/Scene/Components/PrimitiveComponent.h deleted file mode 100644 index 54e32a7..0000000 --- a/src/Engine/Scene/Components/PrimitiveComponent.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once -#include "Component.h" -#include "Graphics/GraphicsResources.h" -#include "Graphics/Mesh.h" -#include "Material/MaterialAsset.h" -#include "Graphics/MeshBatch.h" - -namespace Seele -{ -DECLARE_REF(MeshAsset) -class PrimitiveComponent : public Component -{ -public: - PrimitiveComponent(); - PrimitiveComponent(PMeshAsset asset); - ~PrimitiveComponent(); - virtual void notifySceneAttach(PScene scene) override; - Matrix4 getRenderMatrix(); - std::vector& getStaticMeshes() - { - return staticMeshes; - } -private: - std::vector materials; - Gfx::PUniformBuffer uniformBuffer; - std::vector staticMeshes; - friend class Scene; -}; -DEFINE_REF(PrimitiveComponent) -struct PrimitiveUniformBuffer -{ - Matrix4 localToWorld; - Matrix4 worldToLocal; - Vector4 actorWorldPosition; -}; -} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Scene/Scene.cpp b/src/Engine/Scene/Scene.cpp index 124675a..4d4724d 100644 --- a/src/Engine/Scene/Scene.cpp +++ b/src/Engine/Scene/Scene.cpp @@ -1,7 +1,8 @@ #include "Scene.h" -#include "Components/PrimitiveComponent.h" #include "Material/MaterialAsset.h" #include "Graphics/Graphics.h" +#include "Component/StaticMesh.h" +#include "Component/Transform.h" using namespace Seele; @@ -13,19 +14,6 @@ inline float frand() Scene::Scene(Gfx::PGraphics graphics) : graphics(graphics) { - lightEnv.directionalLights[0].color = Vector4(1, 1, 1, 1); - lightEnv.directionalLights[0].direction = Vector4(1, 1, 0, 1); - lightEnv.directionalLights[0].intensity = Vector4(1, 1, 1, 1); - lightEnv.numDirectionalLights = 1; - srand((unsigned int)time(NULL)); - for(uint32 i = 0; i < 16; ++i) - { - lightEnv.pointLights[i].colorRange = Vector4(frand(), frand(), frand(), frand() * 300); - lightEnv.pointLights[i].positionWS = Vector4(frand() * 100-50, frand(), frand() * 100-50, 1); - } - lightEnv.numPointLights = 16; - lightEnv.pointLights[0].colorRange = Vector4(1, 0, 1, 1000); - lightEnv.pointLights[0].positionWS = Vector4(0, 10, 0, 1); } Scene::~Scene() @@ -34,23 +22,20 @@ Scene::~Scene() void Scene::start() { - for(auto actor : rootActors) - { - actor->launchStart(); - } + //for(auto actor : rootActors) + //{ + // actor->launchStart(); + //} } static int64 lastUpdate; static uint64 numUpdates; -void Scene::beginUpdate(double deltaTime) +void Scene::beginUpdate(double) { //std::cout << "Scene::beginUpdate" << std::endl; auto startTime = std::chrono::high_resolution_clock::now(); - for(auto actor : rootActors) - { - actor->launchTick(static_cast(deltaTime)); - } + // TODO auto endTime = std::chrono::high_resolution_clock::now(); int64 delta = std::chrono::duration_cast(endTime - startTime).count(); lastUpdate += delta; @@ -66,38 +51,67 @@ void Scene::beginUpdate(double deltaTime) void Scene::commitUpdate() { //std::cout << "Scene::commitUpdate" << std::endl; - for(auto actor : rootActors) - { - actor->launchUpdate(); - } + //for(auto actor : rootActors) + //{ + // actor->launchUpdate(); + //} //std::cout << "Scene::commitUpdate finished waiting" << std::endl; } -void Scene::addActor(PActor actor) +Array Scene::getStaticMeshes() { - rootActors.push_back(actor); - actor->notifySceneAttach(this); + Array result; + auto view = registry.view(); + struct PrimitiveSceneData + { + Math::Matrix4 localToWorld; + Math::Matrix4 worldToLocal; + Math::Vector4 actorLocation; + }; + for(auto&& [entity, mesh, transform] : view.each()) + { + PrimitiveSceneData sceneData = { + .localToWorld = transform.toMatrix(), + .worldToLocal = glm::inverse(transform.toMatrix()), + .actorLocation = Math::Vector4(transform.getPosition(), 1.0f) + }; + UniformBufferCreateInfo info = { + .resourceData = { + .size = sizeof(PrimitiveSceneData), + .data = (uint8_t*)&sceneData, + } + }; + Gfx::PUniformBuffer transformBuf = graphics->createUniformBuffer(info); + auto& batch = result.add(); + batch.material = mesh.material; + batch.isBackfaceCullingDisabled = false; + batch.isCastingShadow = true; + batch.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + batch.useReverseCulling = false; + batch.useWireframe = false; + batch.vertexInput = mesh.vertexBuffer; + MeshBatchElement batchElement; + batchElement.baseVertexIndex = 0; + batchElement.firstIndex = 0; + batchElement.indexBuffer = mesh.indexBuffer; + batchElement.indirectArgsBuffer = nullptr; + batchElement.instanceRuns = nullptr; + batchElement.isInstanced = false; + batchElement.numInstances = 1; + batchElement.uniformBuffer = transformBuf; + batchElement.numPrimitives = static_cast(mesh.indexBuffer->getNumIndices() / 3); //TODO: hardcoded + batch.elements.add(batchElement); + } + return result; } -void Scene::addPrimitiveComponent(PPrimitiveComponent comp) +LightEnv Scene::getLightBuffer() const { - primitives.push_back(comp); - for(auto& batch : comp->getStaticMeshes()) - { - PrimitiveUniformBuffer data; - data.actorWorldPosition = Vector4(comp->getTransform().getPosition(), 1); - data.localToWorld = comp->getRenderMatrix(); - data.worldToLocal = glm::inverse(data.localToWorld); - UniformBufferCreateInfo createInfo; - createInfo.resourceData.data = reinterpret_cast(&data); - createInfo.resourceData.owner = Gfx::QueueType::GRAPHICS; - createInfo.resourceData.size = sizeof(data); - createInfo.bDynamic = true; - Gfx::PUniformBuffer uniformBuffer = graphics->createUniformBuffer(createInfo); - for(auto& element : batch.elements) - { - element.uniformBuffer = uniformBuffer; - } - staticMeshes.push_back(batch); - } -} + LightEnv result; + result.directionalLights[0].color = Math::Vector4(0.4, 0.3, 0.5, 1.0); + result.directionalLights[0].direction = Math::Vector4(0.5, 0.5, 0, 0); + result.directionalLights[0].intensity = Math::Vector4(1.0, 0.9, 0.7, 0.5);\ + result.numDirectionalLights = 1; + result.numPointLights = 0; + return result; +} \ No newline at end of file diff --git a/src/Engine/Scene/Scene.h b/src/Engine/Scene/Scene.h index 99e29b2..2358bb9 100644 --- a/src/Engine/Scene/Scene.h +++ b/src/Engine/Scene/Scene.h @@ -1,26 +1,26 @@ #pragma once +#include #include "MinimalEngine.h" -#include "Actor/Actor.h" #include "Graphics/GraphicsResources.h" -#include "Components/PrimitiveComponent.h" #include "Graphics/MeshBatch.h" namespace Seele { DECLARE_REF(Material) +DECLARE_REF(Entity) struct DirectionalLight { - Vector4 color; - Vector4 direction; - Vector4 intensity; + Math::Vector4 color; + Math::Vector4 direction; + Math::Vector4 intensity; }; struct PointLight { - Vector4 positionWS; + Math::Vector4 positionWS; //Vector4 positionVS; - Vector4 colorRange; + Math::Vector4 colorRange; }; #define MAX_DIRECTIONAL_LIGHTS 4 @@ -41,17 +41,31 @@ public: void start(); void beginUpdate(double deltaTime); void commitUpdate(); - void addActor(PActor actor); - void addPrimitiveComponent(PPrimitiveComponent comp); - - const std::vector& getPrimitives() const { return primitives; } - const std::vector& getStaticMeshes() const { return staticMeshes; } - LightEnv& getLightBuffer() { return lightEnv; } + entt::entity createEntity() + { + return registry.create(); + } + template + Component& attachComponent(entt::entity entity, Args... args) + { + return registry.emplace(entity, args...); + } + template + Component& accessComponent(entt::entity entity) + { + return registry.get(entity); + } + template + const Component& accessComponent(entt::entity entity) const + { + return registry.get(entity); + } + Array getStaticMeshes(); + LightEnv getLightBuffer() const; + + entt::registry registry; private: - std::vector staticMeshes; - std::vector rootActors; - std::vector primitives; - LightEnv lightEnv; Gfx::PGraphics graphics; }; +DEFINE_REF(Scene) } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Scene/SceneUpdater.cpp b/src/Engine/Scene/SceneUpdater.cpp deleted file mode 100644 index 98991ba..0000000 --- a/src/Engine/Scene/SceneUpdater.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "SceneUpdater.h" -#include "Components/Component.h" -#include "Actor/Actor.h" - -using namespace Seele; - -SceneUpdater::SceneUpdater() - : pendingUpdatesSem(0) -{ - running.store(true); - workers.resize(std::thread::hardware_concurrency()); - for (size_t i = 0; i < workers.size(); i++) - { - workers[i] = std::thread(&SceneUpdater::work, this); - } -} - -SceneUpdater::~SceneUpdater() -{ - running.store(false); - for (size_t i = 0; i < workers.size(); i++) - { - workers[i].join(); - } -} - -void SceneUpdater::registerComponentUpdate(PComponent component) -{ - std::scoped_lock lck(pendingUpdatesLock); - updatesRan.add([component](float delta) mutable { component->tick(delta); }); -} - -void SceneUpdater::registerActorUpdate(PActor actor) -{ - std::scoped_lock lck(pendingUpdatesLock); - updatesRan.add([actor](float delta) mutable { actor->tick(delta); }); -} - -void SceneUpdater::runUpdates(float delta) -{ - - std::scoped_lock pendingLock(pendingUpdatesLock); - frameDelta = delta; - pendingUpdates = std::move(updatesRan); - updatesRan = List>(); - - std::scoped_lock lck(frameFinishedLock); - pendingLock.unlock(); - pendingUpdatesSem.release(pendingUpdates.size()); - frameFinishedCV.wait(lck); -} - -void SceneUpdater::work() -{ - while(running.load()) - { - pendingUpdatesSem.acquire(); - std::function function; - { - std::scoped_lock lck(pendingUpdatesLock); - function = std::move(pendingUpdates.front()); - pendingUpdates.popFront(); - if(pendingUpdates.empty()) - { - std::scoped_lock lck(frameFinishedLock); - frameFinishedCV.notify_all(); - } - } - function(frameDelta); - { - std::scoped_lock lck(pendingUpdatesLock); - updatesRan.add(std::move(function)); - } - } -} diff --git a/src/Engine/Scene/SceneUpdater.h b/src/Engine/Scene/SceneUpdater.h deleted file mode 100644 index cbe0b6a..0000000 --- a/src/Engine/Scene/SceneUpdater.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once -#include "MinimalEngine.h" -#include "Containers/List.h" -#include -//DEPRECATED -namespace Seele -{ -DECLARE_REF(Component); -DECLARE_REF(Actor); -class SceneUpdater -{ -public: - SceneUpdater(); - ~SceneUpdater(); - void registerComponentUpdate(PComponent component); - void registerActorUpdate(PActor actor); - void runUpdates(float delta); -private: - Array workers; - std::mutex pendingUpdatesLock; - std::counting_semaphore<> pendingUpdatesSem; - List> pendingUpdates; - List> updatesRan; - void work(); - float frameDelta; - std::atomic_bool running; - std::mutex frameFinishedLock; - std::condition_variable frameFinishedCV; -}; -DEFINE_REF(SceneUpdater) -} // namespace Seele diff --git a/src/Engine/Scene/System/CMakeLists.txt b/src/Engine/Scene/System/CMakeLists.txt new file mode 100644 index 0000000..1028496 --- /dev/null +++ b/src/Engine/Scene/System/CMakeLists.txt @@ -0,0 +1,7 @@ +target_sources(Engine + PUBLIC + Executor.h + Executor.cpp + CameraSystem.h + CameraSystem.cpp + SystemBase.h) \ No newline at end of file diff --git a/src/Engine/Scene/System/CameraSystem.cpp b/src/Engine/Scene/System/CameraSystem.cpp new file mode 100644 index 0000000..1612115 --- /dev/null +++ b/src/Engine/Scene/System/CameraSystem.cpp @@ -0,0 +1,11 @@ +#include "CameraSystem.h" +#include "Scene/Component/Camera.h" + +using namespace Seele; +using namespace Seele::System; + +void CameraSystem::update(Component::Camera& camera) +{ + camera.buildViewMatrix(); + camera.buildProjectionMatrix(); +} \ No newline at end of file diff --git a/src/Engine/Scene/System/CameraSystem.h b/src/Engine/Scene/System/CameraSystem.h new file mode 100644 index 0000000..e3b7c1d --- /dev/null +++ b/src/Engine/Scene/System/CameraSystem.h @@ -0,0 +1,18 @@ +#pragma once +#include "SystemBase.h" +#include "Scene/Component/Camera.h" + +namespace Seele +{ +namespace System +{ +class CameraSystem : public SystemBase +{ +public: + CameraSystem(entt::registry& registry) : SystemBase(registry) {} + virtual ~CameraSystem() {} + virtual void update(Component::Camera& component); +private: +}; +} // namespace System +} // namespace Seele diff --git a/src/Engine/Scene/System/Executor.cpp b/src/Engine/Scene/System/Executor.cpp new file mode 100644 index 0000000..0301cde --- /dev/null +++ b/src/Engine/Scene/System/Executor.cpp @@ -0,0 +1,4 @@ +#include "Executor.h" + +using namespace Seele; +using namespace Seele::System; \ No newline at end of file diff --git a/src/Engine/Scene/System/Executor.h b/src/Engine/Scene/System/Executor.h new file mode 100644 index 0000000..9312950 --- /dev/null +++ b/src/Engine/Scene/System/Executor.h @@ -0,0 +1,19 @@ +#pragma once +#include "MinimalEngine.h" +#include "SystemBase.h" +#include + +namespace Seele +{ +namespace System +{ +class Executor +{ +public: + Executor(); + ~Executor(); +private: + dp::thread_pool<> pool; +}; +} // namespace System +} // namespace Seele diff --git a/src/Engine/Scene/System/SystemBase.h b/src/Engine/Scene/System/SystemBase.h new file mode 100644 index 0000000..8b73f74 --- /dev/null +++ b/src/Engine/Scene/System/SystemBase.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include +#include "Scene/Component/Component.h" + +namespace Seele +{ +namespace System +{ + +template +class SystemBase +{ +public: + SystemBase(entt::registry& registry) : registry(registry) {} + virtual ~SystemBase() {} + template + auto getDependencies() + { + return Comp::dependencies; + } + template + auto mergeDependencies(Dep... deps) + { + return (deps | ...); + } + template + void setupView(Dependencies, dp::thread_pool<>&) + { + registry.view().each([&](Components&... comp, Deps&... deps){ + //pool.enqueue_detach([&](){ + int ret = (accessComponent(deps) + ...); + assert(ret == 0); + update((comp,...)); + //}); + }); + } + void run(dp::thread_pool<>& pool) + { + setupView(mergeDependencies((getDependencies(),...)), pool); + } + virtual void update(Components&... components) = 0; +private: + entt::registry& registry; +}; +} // namespace System +} // namespace Seele diff --git a/src/Engine/UI/Elements/Element.cpp b/src/Engine/UI/Elements/Element.cpp index b0a9cb7..1291341 100644 --- a/src/Engine/UI/Elements/Element.cpp +++ b/src/Engine/UI/Elements/Element.cpp @@ -59,12 +59,12 @@ bool Element::isEnabled() const return enabled; } -Rect& Element::getBoundingBox() +Math::Rect& Element::getBoundingBox() { return boundingBox; } -const Rect Element::getBoundingBox() const +const Math::Rect Element::getBoundingBox() const { return boundingBox; } \ No newline at end of file diff --git a/src/Engine/UI/Elements/Element.h b/src/Engine/UI/Elements/Element.h index b803b73..c071e26 100644 --- a/src/Engine/UI/Elements/Element.h +++ b/src/Engine/UI/Elements/Element.h @@ -23,13 +23,13 @@ public: bool isEnabled() const; // maybe not the healthiest inteface // non-const version - Rect& getBoundingBox(); + Math::Rect& getBoundingBox(); // The bounding box describes the relative size of any Element // relative to the total view, meaning a bounding box of (0,0), (1,1) // would take up the entire view - const Rect getBoundingBox() const; + const Math::Rect getBoundingBox() const; protected: - Rect boundingBox; + Math::Rect boundingBox; bool dirty; bool enabled; diff --git a/src/Engine/UI/HorizontalLayout.cpp b/src/Engine/UI/HorizontalLayout.cpp index 3363ffa..d191e8d 100644 --- a/src/Engine/UI/HorizontalLayout.cpp +++ b/src/Engine/UI/HorizontalLayout.cpp @@ -18,14 +18,14 @@ HorizontalLayout::~HorizontalLayout() void HorizontalLayout::apply() { Array children = element->getChildren(); - const Rect parent = element->getBoundingBox(); + const Math::Rect parent = element->getBoundingBox(); float xOffset = parent.offset.x; float yOffset = parent.offset.y; float xSize = parent.size.x / children.size(); float ySize = parent.size.y; for(uint32 index = 0; index < children.size(); ++index) { - Rect& child = children[index]->getBoundingBox(); + Math::Rect& child = children[index]->getBoundingBox(); child.offset.x = xOffset + (index * xSize); child.offset.y = yOffset; child.size.x = xSize; diff --git a/src/Engine/UI/RenderHierarchy.h b/src/Engine/UI/RenderHierarchy.h index 0623685..3a1944b 100644 --- a/src/Engine/UI/RenderHierarchy.h +++ b/src/Engine/UI/RenderHierarchy.h @@ -9,9 +9,9 @@ namespace UI { struct RenderElementStyle { - Vector position = Vector(0, 0, 0); - uint32 backgroundImageIndex = -1; - Vector backgroundColor = Vector(1, 1, 1); + Math::Vector position = Math::Vector(0, 0, 0); + uint32 backgroundImageIndex = UINT32_MAX; + Math::Vector backgroundColor = Math::Vector(1, 1, 1); float opacity = 1.0f; //Vector4 borderBottomColor = Vector4(1, 1, 1, 1); //Vector4 borderLeftColor = Vector4(1, 1, 1, 1); @@ -21,7 +21,7 @@ struct RenderElementStyle //float borderBottomRightRadius = 0; //float borderTopLeftRadius = 0; //float borderTopRightRadius = 0; - Vector2 dimensions = Vector2(1, 1); + Math::Vector2 dimensions = Math::Vector2(1, 1); }; class RenderElement { diff --git a/src/Engine/UI/System.cpp b/src/Engine/UI/System.cpp index f87df71..1adaaf6 100644 --- a/src/Engine/UI/System.cpp +++ b/src/Engine/UI/System.cpp @@ -26,9 +26,9 @@ UIPassData System::getUIPassData() { UIPassData uiPassData; RenderElementStyle& style = uiPassData.renderElements.add(); - style.position = Vector(0, 0, -0.1); - style.dimensions = Vector2(0.4, 0.4); - style.backgroundColor = Vector(0.2, 0.3, 0.1); + style.position = Math::Vector(0, 0, -0.1); + style.dimensions = Math::Vector2(0.4, 0.4); + style.backgroundColor = Math::Vector(0.2, 0.3, 0.1); style.backgroundImageIndex = 0; uiPassData.usedTextures.add(AssetRegistry::findTexture("")->getTexture()); return uiPassData; @@ -41,8 +41,8 @@ TextPassData System::getTextPassData() render.font = AssetRegistry::findFont("Calibri"); render.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus quis magna ex. Morbi ullamcorper fringilla risus eget vehicula. Praesent vel quam vel ante molestie gravida vitae ac enim. Donec vitae eleifend orci. Phasellus at sodales lorem, ac eleifend turpis. Vivamus vitae condimentum lacus, a bibendum neque. Ut et est ut felis varius vehicula. Etiam lorem magna, dapibus vitae felis in, vulputate suscipit neque. Aenean facilisis ac risus et scelerisque. Ut tincidunt eros quis posuere iaculis. Curabitur justo lacus, molestie id varius vel, sodales efficitur diam. Integer orci velit, condimentum sit amet turpis sit amet, congue blandit nisl. Donec pretium ligula id mauris pretium commodo. Mauris quis lectus mi. In blandit, dolor non accumsan venenatis, ipsum erat congue neque, quis elementum orci nunc vel justo. "; //render.text = "Seele Engine"; - render.position = Vector2(0.f, 300.f); + render.position = Math::Vector2(0.f, 300.f); render.scale = 0.1f; - render.textColor = Vector4(1, 0, 0, 1); + render.textColor = Math::Vector4(1, 0, 0, 1); return textPassData; } diff --git a/src/Engine/UI/VerticalLayout.cpp b/src/Engine/UI/VerticalLayout.cpp index 76de71d..8e8356c 100644 --- a/src/Engine/UI/VerticalLayout.cpp +++ b/src/Engine/UI/VerticalLayout.cpp @@ -18,14 +18,14 @@ VerticalLayout::~VerticalLayout() void VerticalLayout::apply() { Array children = element->getChildren(); - const Rect parent = element->getBoundingBox(); + const Math::Rect parent = element->getBoundingBox(); float xOffset = parent.offset.x; float yOffset = parent.offset.y; float xSize = parent.size.x; float ySize = parent.size.y / children.size(); for(uint32 index = 0; index < children.size(); ++index) { - Rect& child = children[index]->getBoundingBox(); + Math::Rect& child = children[index]->getBoundingBox(); child.offset.x = xOffset; child.offset.y = yOffset + (index * ySize); child.size.x = xSize; diff --git a/src/Engine/Window/SceneView.cpp b/src/Engine/Window/SceneView.cpp index 7b3a5da..3f5c548 100644 --- a/src/Engine/Window/SceneView.cpp +++ b/src/Engine/Window/SceneView.cpp @@ -1,26 +1,26 @@ #include "SceneView.h" #include "Scene/Scene.h" #include "Window.h" +#include "Graphics/Mesh.h" #include "Graphics/Graphics.h" #include "Asset/MeshAsset.h" #include "Asset/AssetRegistry.h" #include "Scene/Actor/CameraActor.h" -#include "Scene/Components/CameraComponent.h" -#include "Scene/Components/MyComponent.h" -#include "Scene/Components/MyOtherComponent.h" +#include "Scene/Component/Camera.h" +#include "Scene/Component/StaticMesh.h" using namespace Seele; Seele::SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo) : View(graphics, owner, createInfo, "SceneView") - , activeCamera(new CameraActor()) + , scene(new Scene(graphics)) + , activeCamera(new CameraActor(scene)) , depthPrepass(DepthPrepass(graphics, viewport, activeCamera)) , lightCullingPass(LightCullingPass(graphics, viewport, activeCamera)) , basePass(BasePass(graphics, viewport, activeCamera)) + , cameraSystem(scene->registry) { - activeCamera->getCameraComponent()->setViewport(viewport); - scene = new Scene(graphics); - scene->addActor(activeCamera); + activeCamera->getCameraComponent().setViewport(viewport); AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Body_Diffuse.png"); AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Body_Lightmap.png"); AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Face_Diffuse.png"); @@ -28,28 +28,18 @@ Seele::SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const Viewpo AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Hair_Lightmap.png"); AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Tex_FaceLightmap.png"); AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Ayaka.fbx"); - PPrimitiveComponent ayaka = new PrimitiveComponent(AssetRegistry::findMesh("Ayaka")); - ayaka->setRelativeLocation(Vector(0, 0, 0)); - ayaka->setRelativeScale(Vector(10, 10, 10)); - scene->addPrimitiveComponent(ayaka); + auto meshAsset = AssetRegistry::findMesh("Ayaka"); + for(auto mesh : meshAsset->getMeshes()) + { + PActor actor = new Actor(scene); + actor->attachComponent(mesh->vertexInput, mesh->indexBuffer, mesh->referencedMaterial); + } //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->setRelativeScale(Vector(100, 100, 100)); - scene->addPrimitiveComponent(plane); - - for(uint32 i = 0; i < 10; ++i) - { - PMyComponent myComp = new MyComponent(); - PMyOtherComponent myOtherComp = new MyOtherComponent(); - PActor actor = new Actor(); - actor->setRootComponent(myComp); - myComp->addChildComponent(myOtherComp); - scene->addActor(actor); - } - scene->start(); + + cameraSystem.run(pool); PRenderGraphResources resources = new RenderGraphResources(); depthPrepass.setResources(resources); @@ -97,6 +87,7 @@ void SceneView::prepareRender() void SceneView::render() { + cameraSystem.run(pool); depthPrepass.beginFrame(); lightCullingPass.beginFrame(); basePass.beginFrame(); @@ -124,19 +115,19 @@ void SceneView::keyCallback(KeyCode code, InputAction action, KeyModifier mod) { if(code == KeyCode::KEY_W) { - activeCamera->getCameraComponent()->moveX(1); + activeCamera->getCameraComponent().moveX(1); } if(code == KeyCode::KEY_S) { - activeCamera->getCameraComponent()->moveX(-1); + activeCamera->getCameraComponent().moveX(-1); } if(code == KeyCode::KEY_A) { - activeCamera->getCameraComponent()->moveY(1); + activeCamera->getCameraComponent().moveY(1); } if(code == KeyCode::KEY_D) { - activeCamera->getCameraComponent()->moveY(-1); + activeCamera->getCameraComponent().moveY(-1); } } } @@ -152,7 +143,7 @@ void SceneView::mouseMoveCallback(double xPos, double yPos) prevYPos = yPos; if(mouseDown) { - activeCamera->getCameraComponent()->mouseMove((float)deltaX, (float)deltaY); + activeCamera->getCameraComponent().mouseMove((float)deltaX, (float)deltaY); } } @@ -170,7 +161,7 @@ void SceneView::mouseButtonCallback(MouseButton button, InputAction action, KeyM void SceneView::scrollCallback(double, double yOffset) { - activeCamera->getCameraComponent()->mouseScroll(static_cast(yOffset)); + activeCamera->getCameraComponent().mouseScroll(static_cast(yOffset)); } void SceneView::fileCallback(int, const char**) diff --git a/src/Engine/Window/SceneView.h b/src/Engine/Window/SceneView.h index 7e28e59..acd4380 100644 --- a/src/Engine/Window/SceneView.h +++ b/src/Engine/Window/SceneView.h @@ -1,8 +1,10 @@ #pragma once +#include #include "View.h" #include "Graphics/RenderPass/DepthPrepass.h" #include "Graphics/RenderPass/LightCullingPass.h" #include "Graphics/RenderPass/BasePass.h" +#include "Scene/System/CameraSystem.h" namespace Seele { DECLARE_REF(Scene) @@ -33,6 +35,9 @@ private: LightCullingPassData lightCullingPassData; BasePassData basePassData; + dp::thread_pool<> pool; + System::CameraSystem cameraSystem; + virtual void keyCallback(KeyCode code, InputAction action, KeyModifier modifier) override; virtual void mouseMoveCallback(double xPos, double yPos) override; virtual void mouseButtonCallback(MouseButton button, InputAction action, KeyModifier modifier) override; diff --git a/src/Engine/Window/View.cpp b/src/Engine/Window/View.cpp index eea5c6b..d34f91c 100644 --- a/src/Engine/Window/View.cpp +++ b/src/Engine/Window/View.cpp @@ -16,7 +16,7 @@ View::~View() { } -void View::applyArea(URect) +void View::applyArea(Math::URect) { } diff --git a/src/Engine/Window/View.h b/src/Engine/Window/View.h index 0cb94e9..46fca21 100644 --- a/src/Engine/Window/View.h +++ b/src/Engine/Window/View.h @@ -21,7 +21,7 @@ public: // prepare render is also locked, so reading from shared memory is also safe virtual void prepareRender() = 0; virtual void render() = 0; - void applyArea(URect area); + void applyArea(Math::URect area); void setFocused(); const std::string& getName();