Implementing ECS SystemBase and updating slang
This commit is contained in:
@@ -34,3 +34,6 @@
|
|||||||
[submodule "external/entt"]
|
[submodule "external/entt"]
|
||||||
path = external/entt
|
path = external/entt
|
||||||
url = git@github.com:skypjack/entt.git
|
url = git@github.com:skypjack/entt.git
|
||||||
|
[submodule "external/thread-pool"]
|
||||||
|
path = external/thread-pool
|
||||||
|
url = https://github.com/DeveloperPaul123/thread-pool.git
|
||||||
|
|||||||
+13
-10
@@ -9,6 +9,7 @@ set(CMAKE_CXX_STANDARD 20)
|
|||||||
option (USE_SUPERBUILD "Whether or not a superbuild should be invoked" ON)
|
option (USE_SUPERBUILD "Whether or not a superbuild should be invoked" ON)
|
||||||
|
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
set(CMAKE_COMPILE_WARNING_AS_ERROR OFF)
|
||||||
|
|
||||||
set(ENGINE_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/src/Engine)
|
set(ENGINE_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/src/Engine)
|
||||||
set(EXTERNAL_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/external)
|
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(SPIRV_ROOT ${EXTERNAL_ROOT}/SPIRV-Cross)
|
||||||
set(ENTT_ROOT ${EXTERNAL_ROOT}/entt)
|
set(ENTT_ROOT ${EXTERNAL_ROOT}/entt)
|
||||||
set(NSAM_ROOT ${EXTERNAL_ROOT}/aftermath)
|
set(NSAM_ROOT ${EXTERNAL_ROOT}/aftermath)
|
||||||
|
set(THREADPOOL_ROOT ${EXTERNAL_ROOT}/thread-pool)
|
||||||
|
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/)
|
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/)
|
||||||
set(Boost_NO_WARN_NEW_VERSIONS 1)
|
set(Boost_NO_WARN_NEW_VERSIONS 1)
|
||||||
@@ -53,7 +55,8 @@ if(CMAKE_DEBUG_POSTFIX)
|
|||||||
add_compile_definitions(ENABLE_VALIDATION)
|
add_compile_definitions(ENABLE_VALIDATION)
|
||||||
add_compile_definitions(SEELE_DEBUG)
|
add_compile_definitions(SEELE_DEBUG)
|
||||||
endif()
|
endif()
|
||||||
add_library(Engine "")
|
|
||||||
|
add_library(Engine SHARED "")
|
||||||
add_executable(Editor "")
|
add_executable(Editor "")
|
||||||
target_compile_definitions(Engine PUBLIC GLFW_WINDOWS)
|
target_compile_definitions(Engine PUBLIC GLFW_WINDOWS)
|
||||||
target_include_directories(Engine PUBLIC src/Engine)
|
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 ktx)
|
||||||
target_link_libraries(Engine PUBLIC stb)
|
target_link_libraries(Engine PUBLIC stb)
|
||||||
target_link_libraries(Engine PUBLIC nlohmann_json::nlohmann_json)
|
target_link_libraries(Engine PUBLIC nlohmann_json::nlohmann_json)
|
||||||
|
target_link_libraries(Engine PUBLIC dp::thread-pool)
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
target_link_libraries(Engine Threads::Threads)
|
target_link_libraries(Engine Threads::Threads)
|
||||||
target_link_libraries(Engine dl)
|
target_link_libraries(Engine dl)
|
||||||
endif()
|
endif()
|
||||||
target_precompile_headers(Engine
|
target_precompile_headers(Engine
|
||||||
PUBLIC
|
PUBLIC
|
||||||
@@ -89,20 +93,19 @@ target_precompile_headers(Engine
|
|||||||
<mutex>
|
<mutex>
|
||||||
<string>
|
<string>
|
||||||
<thread>
|
<thread>
|
||||||
<boost/serialization/serialization.hpp>
|
<boost/serialization/serialization.hpp>)
|
||||||
<boost/crc.hpp>)
|
|
||||||
|
|
||||||
target_link_libraries(Editor PRIVATE Engine)
|
|
||||||
|
|
||||||
add_subdirectory(src/)
|
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
set(_CRT_SECURE_NO_WARNINGS)
|
set(_CRT_SECURE_NO_WARNINGS)
|
||||||
target_compile_options(Engine PUBLIC -Zi -MP -DEBUG)
|
target_compile_options(Engine PUBLIC /Zi /MP /W4 /DEBUG "/WX-")
|
||||||
else()
|
else()
|
||||||
target_compile_options(Engine PUBLIC -g -Wall -Wextra -Wno-delete-incomplete -pedantic -fcoroutines)
|
target_compile_options(Engine PUBLIC -g -Wall -Wextra -Wno-delete-incomplete -pedantic -fcoroutines)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(Editor PUBLIC Engine)
|
||||||
|
|
||||||
|
add_subdirectory(src/)
|
||||||
|
|
||||||
add_executable(Seele_unit_tests "")
|
add_executable(Seele_unit_tests "")
|
||||||
add_subdirectory(test/)
|
add_subdirectory(test/)
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ add_subdirectory(${JSON_ROOT})
|
|||||||
|
|
||||||
#--------------GLM------------------------------
|
#--------------GLM------------------------------
|
||||||
add_subdirectory(${GLM_ROOT})
|
add_subdirectory(${GLM_ROOT})
|
||||||
|
target_compile_options(glm_shared INTERFACE /W0)
|
||||||
|
|
||||||
#--------------GLFW------------------------------
|
#--------------GLFW------------------------------
|
||||||
set(ENKITS_BUILD_EXAMPLES OFF CACHE BOOL "Build basic example applications" )
|
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 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)
|
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------------------------------
|
#--------------SLang------------------------------
|
||||||
string(TOLOWER release_${CMAKE_PLATFORM} SLANG_CONFIG)
|
string(TOLOWER release_${CMAKE_PLATFORM} SLANG_CONFIG)
|
||||||
|
|||||||
Vendored
+1
-1
Submodule external/slang updated: ec530b3005...cedd93690c
+1
Submodule external/thread-pool added at dad69c1661
@@ -1,8 +1,7 @@
|
|||||||
import Common;
|
import Common;
|
||||||
import Material;
|
import Material;
|
||||||
import VERTEX_INPUT_IMPORT;
|
|
||||||
import MATERIAL_IMPORT;
|
|
||||||
import PrimitiveSceneData;
|
import PrimitiveSceneData;
|
||||||
|
import StaticMeshVertexInput;
|
||||||
|
|
||||||
|
|
||||||
struct VertexStageOutput
|
struct VertexStageOutput
|
||||||
|
|||||||
@@ -2,9 +2,8 @@ import Common;
|
|||||||
import LightEnv;
|
import LightEnv;
|
||||||
import BRDF;
|
import BRDF;
|
||||||
import Material;
|
import Material;
|
||||||
|
import StaticMeshVertexInput;
|
||||||
|
|
||||||
import VERTEX_INPUT_IMPORT;
|
|
||||||
import MATERIAL_IMPORT;
|
|
||||||
import PrimitiveSceneData;
|
import PrimitiveSceneData;
|
||||||
import MaterialParameter;
|
import MaterialParameter;
|
||||||
|
|
||||||
@@ -13,7 +12,6 @@ StructuredBuffer<uint> lightIndexList;
|
|||||||
layout(set = INDEX_LIGHT_ENV, binding = 5)
|
layout(set = INDEX_LIGHT_ENV, binding = 5)
|
||||||
RWTexture2D<uint2> lightGrid;
|
RWTexture2D<uint2> lightGrid;
|
||||||
|
|
||||||
|
|
||||||
struct VertexStageOutput
|
struct VertexStageOutput
|
||||||
{
|
{
|
||||||
ShaderAttributeInterpolation shaderAttributeInterpolation : Interpolation;
|
ShaderAttributeInterpolation shaderAttributeInterpolation : Interpolation;
|
||||||
@@ -50,7 +48,7 @@ float4 fragmentMain(
|
|||||||
) : SV_Target
|
) : SV_Target
|
||||||
{
|
{
|
||||||
MaterialFragmentParameter materialParams = input.getMaterialParameter(position);
|
MaterialFragmentParameter materialParams = input.getMaterialParameter(position);
|
||||||
TMaterial.BRDF brdf = gMaterial.prepare(materialParams);
|
let brdf = gMaterial.prepare(materialParams);
|
||||||
|
|
||||||
float3 viewDir = normalize(materialParams.viewDir);
|
float3 viewDir = normalize(materialParams.viewDir);
|
||||||
|
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ void tAppendLight(uint lightIndex)
|
|||||||
[shader("compute")]
|
[shader("compute")]
|
||||||
void cullLights(ComputeShaderInput in)
|
void cullLights(ComputeShaderInput in)
|
||||||
{
|
{
|
||||||
int2 texCoord = in.dispatchThreadID.xy;
|
int2 texCoord = int2(in.dispatchThreadID.xy);
|
||||||
float fDepth = depthTextureVS.Load(int3(texCoord, 0)).r;
|
float fDepth = depthTextureVS.Load(int3(texCoord, 0)).r;
|
||||||
|
|
||||||
uint uDepth = asuint(fDepth);
|
uint uDepth = asuint(fDepth);
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
interface IMaterial
|
||||||
|
{
|
||||||
|
float4 sample(float2 texCoord);
|
||||||
|
}
|
||||||
|
|
||||||
|
type_param TMaterial : IMaterial;
|
||||||
|
ParameterBlock<TMaterial> gMaterial;
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import Mat;
|
||||||
|
|
||||||
|
|
||||||
|
struct SimpleMaterial : IMaterial
|
||||||
|
{
|
||||||
|
float4 sample(float2 texCoord)
|
||||||
|
{
|
||||||
|
return float4(1, 0, 1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,5 @@ interface IMaterial
|
|||||||
float getSheen(MaterialFragmentParameter input);
|
float getSheen(MaterialFragmentParameter input);
|
||||||
};
|
};
|
||||||
|
|
||||||
type_param TMaterial : IMaterial;
|
|
||||||
layout(set = INDEX_MATERIAL, binding = 0, std430)
|
layout(set = INDEX_MATERIAL, binding = 0, std430)
|
||||||
ParameterBlock<TMaterial> gMaterial;
|
ParameterBlock<IMaterial> gMaterial;
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ struct ShaderAttributeInterpolation
|
|||||||
#if NUM_MATERIAL_TEXCOORDS
|
#if NUM_MATERIAL_TEXCOORDS
|
||||||
for(int i = 0; i < NUM_MATERIAL_TEXCOORDS; ++i)
|
for(int i = 0; i < NUM_MATERIAL_TEXCOORDS; ++i)
|
||||||
{
|
{
|
||||||
if(i % 2)
|
if(i % 2 == 1)
|
||||||
{
|
{
|
||||||
result.texCoords[i] = packedTexCoords[i / 2].zw;
|
result.texCoords[i] = packedTexCoords[i / 2].zw;
|
||||||
}
|
}
|
||||||
@@ -191,7 +191,7 @@ struct VertexShaderInput
|
|||||||
result.viewPosition = vertexParams.viewPosition;
|
result.viewPosition = vertexParams.viewPosition;
|
||||||
for(int i = 0; i < NUM_MATERIAL_TEXCOORDS; ++i)
|
for(int i = 0; i < NUM_MATERIAL_TEXCOORDS; ++i)
|
||||||
{
|
{
|
||||||
if(i % 2)
|
if(i % 2 == 1)
|
||||||
{
|
{
|
||||||
result.packedTexCoords[i / 2].zw = vertexParams.texCoords[i];
|
result.packedTexCoords[i / 2].zw = vertexParams.texCoords[i];
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-481
@@ -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<SimpleMaterial>`, 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<B:IBRDF>(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<B:IBRDF>(SurfaceGeometry g, B brdf, float3 wo)
|
|
||||||
{
|
|
||||||
return intensity * brdf.evaluate(wo, direction, g.normal);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
struct PointLight : ILightEnv
|
|
||||||
{
|
|
||||||
float3 position;
|
|
||||||
float3 intensity;
|
|
||||||
|
|
||||||
float3 illuminate<B:IBRDF>(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<L : ILightEnv, let N : int> : 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<B:IBRDF>(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<T,U>` 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<T : ILightEnv, U : ILightEnv> : ILightEnv
|
|
||||||
{
|
|
||||||
T first;
|
|
||||||
U second;
|
|
||||||
|
|
||||||
float3 illuminate<B:IBRDF>(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<B:IBRDF>(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<PerView> gViewParams;
|
|
||||||
|
|
||||||
// Declaring a block for per-model parameter data is
|
|
||||||
// similarly simple.
|
|
||||||
//
|
|
||||||
struct PerModel
|
|
||||||
{
|
|
||||||
float4x4 modelTransform;
|
|
||||||
float4x4 inverseTransposeModelTransform;
|
|
||||||
};
|
|
||||||
ParameterBlock<PerModel> 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<L>` 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<TLightEnv> 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<TMaterial> 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")]
|
[shader("fragment")]
|
||||||
float4 fragmentMain(
|
float4 fragmentMain(float2 texCoord)
|
||||||
CoarseVertex coarseVertex : CoarseVertex) : SV_Target
|
|
||||||
{
|
{
|
||||||
// We start by using our interpolated vertex attributes
|
return gMaterial.sample(texCoord);
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
#include "Window/WindowManager.h"
|
#include "Window/WindowManager.h"
|
||||||
#include "Scene/Components/PrimitiveComponent.h"
|
|
||||||
#include "Window/SceneView.h"
|
#include "Window/SceneView.h"
|
||||||
#include "Window/InspectorView.h"
|
#include "Window/InspectorView.h"
|
||||||
#include "Asset/AssetRegistry.h"
|
#include "Asset/AssetRegistry.h"
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ public:
|
|||||||
std::scoped_lock lck(lock);
|
std::scoped_lock lck(lock);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
inline void setStatus(Status status)
|
inline void setStatus(Status _status)
|
||||||
{
|
{
|
||||||
std::scoped_lock lck(lock);
|
std::scoped_lock lck(lock);
|
||||||
this->status = status;
|
status = _status;
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
std::mutex lock;
|
std::mutex lock;
|
||||||
|
|||||||
@@ -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();
|
AssetRegistry ® = get();
|
||||||
reg.rootFolder = rootFolder;
|
reg.rootFolder = _rootFolder;
|
||||||
reg.fontLoader = new FontLoader(graphics);
|
reg.fontLoader = new FontLoader(graphics);
|
||||||
reg.meshLoader = new MeshLoader(graphics);
|
reg.meshLoader = new MeshLoader(graphics);
|
||||||
reg.textureLoader = new TextureLoader(graphics);
|
reg.textureLoader = new TextureLoader(graphics);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "MinimalEngine.h"
|
#include "MinimalEngine.h"
|
||||||
#include "Asset.h"
|
#include "Asset.h"
|
||||||
|
#include "Material/MaterialAsset.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ void FontAsset::load()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Glyph& glyph = glyphs[c];
|
Glyph& glyph = glyphs[c];
|
||||||
glyph.size = IVector2(face->glyph->bitmap.width, face->glyph->bitmap.rows);
|
glyph.size = Math::IVector2(face->glyph->bitmap.width, face->glyph->bitmap.rows);
|
||||||
glyph.bearing = IVector2(face->glyph->bitmap_left, face->glyph->bitmap_top);
|
glyph.bearing = Math::IVector2(face->glyph->bitmap_left, face->glyph->bitmap_top);
|
||||||
glyph.advance = face->glyph->advance.x;
|
glyph.advance = face->glyph->advance.x;
|
||||||
TextureCreateInfo imageData;
|
TextureCreateInfo imageData;
|
||||||
imageData.format = Gfx::SE_FORMAT_R8_UINT;
|
imageData.format = Gfx::SE_FORMAT_R8_UINT;
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ public:
|
|||||||
struct Glyph
|
struct Glyph
|
||||||
{
|
{
|
||||||
Gfx::PTexture2D texture;
|
Gfx::PTexture2D texture;
|
||||||
IVector2 size;
|
Math::IVector2 size;
|
||||||
IVector2 bearing;
|
Math::IVector2 bearing;
|
||||||
uint32 advance;
|
uint32 advance;
|
||||||
};
|
};
|
||||||
const std::map<uint32, Glyph> getGlyphData() const { return glyphs; }
|
const std::map<uint32, Glyph> getGlyphData() const { return glyphs; }
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ void MeshLoader::importAsset(const std::filesystem::path &path)
|
|||||||
import(path, asset);
|
import(path, asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshLoader::loadMaterials(const aiScene* scene, Array<PMaterialAsset>& globalMaterials, Gfx::PGraphics graphics)
|
void MeshLoader::loadMaterials(const aiScene* scene, Array<PMaterialAsset>& globalMaterials)
|
||||||
{
|
{
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
for(uint32 i = 0; i < scene->mNumMaterials; ++i)
|
for(uint32 i = 0; i < scene->mNumMaterials; ++i)
|
||||||
@@ -111,44 +111,44 @@ void findMeshRoots(aiNode *node, List<aiNode *> &meshNodes)
|
|||||||
}
|
}
|
||||||
VertexStreamComponent createVertexStream(uint32 size, aiVector3D* sourceData, Gfx::PGraphics graphics)
|
VertexStreamComponent createVertexStream(uint32 size, aiVector3D* sourceData, Gfx::PGraphics graphics)
|
||||||
{
|
{
|
||||||
Array<Vector> buffer(size);
|
Array<Math::Vector> buffer(size);
|
||||||
for(uint32 i = 0; i < size; ++i)
|
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;
|
VertexBufferCreateInfo vbInfo;
|
||||||
vbInfo.numVertices = size;
|
vbInfo.numVertices = size;
|
||||||
vbInfo.vertexSize = sizeof(Vector);
|
vbInfo.vertexSize = sizeof(Math::Vector);
|
||||||
vbInfo.resourceData.data = (uint8 *)buffer.data();
|
vbInfo.resourceData.data = (uint8 *)buffer.data();
|
||||||
vbInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
|
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);
|
Gfx::PVertexBuffer vertexBuffer = graphics->createVertexBuffer(vbInfo);
|
||||||
vertexBuffer->transferOwnership(Gfx::QueueType::GRAPHICS);
|
vertexBuffer->transferOwnership(Gfx::QueueType::GRAPHICS);
|
||||||
return VertexStreamComponent(vertexBuffer, 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32B32_SFLOAT);
|
return VertexStreamComponent(vertexBuffer, 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32B32_SFLOAT);
|
||||||
}
|
}
|
||||||
VertexStreamComponent createVertexStream(uint32 size, aiVector2D* sourceData, Gfx::PGraphics graphics)
|
VertexStreamComponent createVertexStream(uint32 size, aiVector2D* sourceData, Gfx::PGraphics graphics)
|
||||||
{
|
{
|
||||||
Array<Vector2> buffer(size);
|
Array<Math::Vector2> buffer(size);
|
||||||
for(uint32 i = 0; i < size; ++i)
|
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;
|
VertexBufferCreateInfo vbInfo;
|
||||||
vbInfo.numVertices = size;
|
vbInfo.numVertices = size;
|
||||||
vbInfo.vertexSize = sizeof(Vector2);
|
vbInfo.vertexSize = sizeof(Math::Vector2);
|
||||||
vbInfo.resourceData.data = (uint8 *)buffer.data();
|
vbInfo.resourceData.data = (uint8 *)buffer.data();
|
||||||
vbInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
|
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);
|
Gfx::PVertexBuffer vertexBuffer = graphics->createVertexBuffer(vbInfo);
|
||||||
vertexBuffer->transferOwnership(Gfx::QueueType::GRAPHICS);
|
vertexBuffer->transferOwnership(Gfx::QueueType::GRAPHICS);
|
||||||
return VertexStreamComponent(vertexBuffer, 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32_SFLOAT);
|
return VertexStreamComponent(vertexBuffer, 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32_SFLOAT);
|
||||||
}
|
}
|
||||||
void MeshLoader::loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMeshes, const Array<PMaterialAsset>& materials, Gfx::PGraphics graphics)
|
void MeshLoader::loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMeshes, const Array<PMaterialAsset>& materials)
|
||||||
{
|
{
|
||||||
for (uint32 meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex)
|
for (uint32 meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex)
|
||||||
{
|
{
|
||||||
aiMesh *mesh = scene->mMeshes[meshIndex];
|
aiMesh *mesh = scene->mMeshes[meshIndex];
|
||||||
|
PMaterialAsset material = materials[mesh->mMaterialIndex];
|
||||||
PStaticMeshVertexInput vertexShaderInput = new StaticMeshVertexInput(std::string(mesh->mName.C_Str()));
|
PStaticMeshVertexInput vertexShaderInput = new StaticMeshVertexInput(std::string(mesh->mName.C_Str()));
|
||||||
StaticMeshDataType data;
|
StaticMeshDataType data;
|
||||||
data.positionStream = createVertexStream(mesh->mNumVertices, mesh->mVertices, graphics);
|
data.positionStream = createVertexStream(mesh->mNumVertices, mesh->mVertices, graphics);
|
||||||
@@ -188,7 +188,7 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMesh
|
|||||||
idxInfo.indexType = Gfx::SE_INDEX_TYPE_UINT32;
|
idxInfo.indexType = Gfx::SE_INDEX_TYPE_UINT32;
|
||||||
idxInfo.resourceData.data = (uint8 *)indices.data();
|
idxInfo.resourceData.data = (uint8 *)indices.data();
|
||||||
idxInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
|
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);
|
Gfx::PIndexBuffer indexBuffer = graphics->createIndexBuffer(idxInfo);
|
||||||
indexBuffer->transferOwnership(Gfx::QueueType::GRAPHICS);
|
indexBuffer->transferOwnership(Gfx::QueueType::GRAPHICS);
|
||||||
|
|
||||||
@@ -249,10 +249,10 @@ void MeshLoader::import(std::filesystem::path path, PMeshAsset meshAsset)
|
|||||||
|
|
||||||
Array<PMaterialAsset> globalMaterials(scene->mNumMaterials);
|
Array<PMaterialAsset> globalMaterials(scene->mNumMaterials);
|
||||||
loadTextures(scene, path.parent_path());
|
loadTextures(scene, path.parent_path());
|
||||||
loadMaterials(scene, globalMaterials, graphics);
|
loadMaterials(scene, globalMaterials);
|
||||||
|
|
||||||
Array<PMesh> globalMeshes(scene->mNumMeshes);
|
Array<PMesh> globalMeshes(scene->mNumMeshes);
|
||||||
loadGlobalMeshes(scene, globalMeshes, globalMaterials, graphics);
|
loadGlobalMeshes(scene, globalMeshes, globalMaterials);
|
||||||
|
|
||||||
|
|
||||||
List<aiNode *> meshNodes;
|
List<aiNode *> meshNodes;
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ public:
|
|||||||
~MeshLoader();
|
~MeshLoader();
|
||||||
void importAsset(const std::filesystem::path& filePath);
|
void importAsset(const std::filesystem::path& filePath);
|
||||||
private:
|
private:
|
||||||
void loadMaterials(const aiScene* scene, Array<PMaterialAsset>& globalMaterials, Gfx::PGraphics graphics);
|
void loadMaterials(const aiScene* scene, Array<PMaterialAsset>& globalMaterials);
|
||||||
void loadTextures(const aiScene* scene, const std::filesystem::path& meshPath);
|
void loadTextures(const aiScene* scene, const std::filesystem::path& meshPath);
|
||||||
void loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMeshes, const Array<PMaterialAsset>& materials, Gfx::PGraphics graphics);
|
void loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMeshes, const Array<PMaterialAsset>& materials);
|
||||||
void convertAssimpARGB(unsigned char* dst, aiTexel* src, uint32 numPixels);
|
void convertAssimpARGB(unsigned char* dst, aiTexel* src, uint32 numPixels);
|
||||||
|
|
||||||
void import(std::filesystem::path path, PMeshAsset meshAsset);
|
void import(std::filesystem::path path, PMeshAsset meshAsset);
|
||||||
|
|||||||
@@ -50,10 +50,10 @@ void TextureAsset::load()
|
|||||||
createInfo.mipLevels = kTexture->numLevels;
|
createInfo.mipLevels = kTexture->numLevels;
|
||||||
createInfo.usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT;
|
createInfo.usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT;
|
||||||
createInfo.resourceData.data = ktxTexture_GetData(ktxTexture(kTexture));
|
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;
|
createInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
|
||||||
Gfx::PTexture2D texture = WindowManager::getGraphics()->createTexture2D(createInfo);
|
Gfx::PTexture2D tex = WindowManager::getGraphics()->createTexture2D(createInfo);
|
||||||
texture->transferOwnership(Gfx::QueueType::GRAPHICS);
|
tex->transferOwnership(Gfx::QueueType::GRAPHICS);
|
||||||
setTexture(texture);
|
setTexture(tex);
|
||||||
setStatus(Asset::Status::Ready);
|
setStatus(Asset::Status::Ready);
|
||||||
}
|
}
|
||||||
@@ -12,10 +12,10 @@ public:
|
|||||||
virtual ~TextureAsset();
|
virtual ~TextureAsset();
|
||||||
virtual void save() override;
|
virtual void save() override;
|
||||||
virtual void load() override;
|
virtual void load() override;
|
||||||
void setTexture(Gfx::PTexture texture)
|
void setTexture(Gfx::PTexture _texture)
|
||||||
{
|
{
|
||||||
std::scoped_lock lck(lock);
|
std::scoped_lock lck(lock);
|
||||||
this->texture = texture;
|
texture = _texture;
|
||||||
}
|
}
|
||||||
Gfx::PTexture getTexture()
|
Gfx::PTexture getTexture()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -679,6 +679,16 @@ public:
|
|||||||
beginIt = iterator(_data);
|
beginIt = iterator(_data);
|
||||||
endIt = iterator(_data + N);
|
endIt = iterator(_data + N);
|
||||||
}
|
}
|
||||||
|
StaticArray(std::initializer_list<T> init)
|
||||||
|
{
|
||||||
|
assert(init.size() == N);
|
||||||
|
auto beg = init.begin();
|
||||||
|
for (int i = 0; i < N; ++i)
|
||||||
|
{
|
||||||
|
_data[i] = *beg;
|
||||||
|
beg++;
|
||||||
|
}
|
||||||
|
}
|
||||||
~StaticArray()
|
~StaticArray()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-18
@@ -40,8 +40,8 @@ private:
|
|||||||
size_t rightChild;
|
size_t rightChild;
|
||||||
Pair<K, V> pair;
|
Pair<K, V> pair;
|
||||||
Node()
|
Node()
|
||||||
: leftChild(-1)
|
: leftChild(SIZE_MAX)
|
||||||
, rightChild(-1)
|
, rightChild(SIZE_MAX)
|
||||||
, pair()
|
, pair()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -50,8 +50,8 @@ private:
|
|||||||
Node& operator=(const Node& other) = default;
|
Node& operator=(const Node& other) = default;
|
||||||
Node& operator=(Node&& other) = default;
|
Node& operator=(Node&& other) = default;
|
||||||
Node(K key)
|
Node(K key)
|
||||||
: leftChild(-1)
|
: leftChild(SIZE_MAX)
|
||||||
, rightChild(-1)
|
, rightChild(SIZE_MAX)
|
||||||
, pair(std::move(key))
|
, pair(std::move(key))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ public:
|
|||||||
using reference = PairType&;
|
using reference = PairType&;
|
||||||
using pointer = PairType*;
|
using pointer = PairType*;
|
||||||
|
|
||||||
IteratorBase(size_t x = -1)
|
IteratorBase(size_t x = SIZE_MAX)
|
||||||
: node(x)
|
: node(x)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -199,9 +199,9 @@ public:
|
|||||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||||
|
|
||||||
constexpr Map() noexcept
|
constexpr Map() noexcept
|
||||||
: root(-1)
|
: root(SIZE_MAX)
|
||||||
, beginIt(-1)
|
, beginIt(SIZE_MAX)
|
||||||
, endIt(-1)
|
, endIt(SIZE_MAX)
|
||||||
, iteratorsDirty(true)
|
, iteratorsDirty(true)
|
||||||
, _size(0)
|
, _size(0)
|
||||||
, comp(Compare())
|
, comp(Compare())
|
||||||
@@ -209,9 +209,9 @@ public:
|
|||||||
}
|
}
|
||||||
constexpr explicit Map(const Compare& comp, const Allocator& alloc = Allocator()) noexcept(noexcept(Allocator()))
|
constexpr explicit Map(const Compare& comp, const Allocator& alloc = Allocator()) noexcept(noexcept(Allocator()))
|
||||||
: nodeContainer(alloc)
|
: nodeContainer(alloc)
|
||||||
, root(-1)
|
, root(SIZE_MAX)
|
||||||
, beginIt(-1)
|
, beginIt(SIZE_MAX)
|
||||||
, endIt(-1)
|
, endIt(SIZE_MAX)
|
||||||
, iteratorsDirty(true)
|
, iteratorsDirty(true)
|
||||||
, _size(0)
|
, _size(0)
|
||||||
, comp(comp)
|
, comp(comp)
|
||||||
@@ -219,9 +219,9 @@ public:
|
|||||||
}
|
}
|
||||||
constexpr explicit Map(const Allocator& alloc) noexcept(noexcept(Compare))
|
constexpr explicit Map(const Allocator& alloc) noexcept(noexcept(Compare))
|
||||||
: nodeContainer(alloc)
|
: nodeContainer(alloc)
|
||||||
, root(-1)
|
, root(SIZE_MAX)
|
||||||
, beginIt(-1)
|
, beginIt(SIZE_MAX)
|
||||||
, endIt(-1)
|
, endIt(SIZE_MAX)
|
||||||
, iteratorsDirty(true)
|
, iteratorsDirty(true)
|
||||||
, _size(0)
|
, _size(0)
|
||||||
, comp(Compare())
|
, comp(Compare())
|
||||||
@@ -335,7 +335,7 @@ public:
|
|||||||
constexpr void clear()
|
constexpr void clear()
|
||||||
{
|
{
|
||||||
nodeContainer.clear();
|
nodeContainer.clear();
|
||||||
root = -1;
|
root = SIZE_MAX;
|
||||||
_size = 0;
|
_size = 0;
|
||||||
markIteratorsDirty();
|
markIteratorsDirty();
|
||||||
}
|
}
|
||||||
@@ -510,13 +510,13 @@ private:
|
|||||||
{
|
{
|
||||||
newNode->rightChild = r;
|
newNode->rightChild = r;
|
||||||
newNode->leftChild = node->leftChild;
|
newNode->leftChild = node->leftChild;
|
||||||
node->leftChild = -1;
|
node->leftChild = SIZE_MAX;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
newNode->leftChild = r;
|
newNode->leftChild = r;
|
||||||
newNode->rightChild = node->rightChild;
|
newNode->rightChild = node->rightChild;
|
||||||
node->rightChild = -1;
|
node->rightChild = SIZE_MAX;
|
||||||
}
|
}
|
||||||
return nodeContainer.size() - 1;
|
return nodeContainer.size() - 1;
|
||||||
}
|
}
|
||||||
@@ -525,7 +525,7 @@ private:
|
|||||||
{
|
{
|
||||||
size_t temp;
|
size_t temp;
|
||||||
if (!isValid(r))
|
if (!isValid(r))
|
||||||
return -1;
|
return SIZE_MAX;
|
||||||
|
|
||||||
r = splay(r, key);
|
r = splay(r, key);
|
||||||
Node* node = getNode(r);
|
Node* node = getNode(r);
|
||||||
|
|||||||
@@ -18,10 +18,10 @@ PVertexBuffer Graphics::getNullVertexBuffer()
|
|||||||
{
|
{
|
||||||
VertexBufferCreateInfo createInfo;
|
VertexBufferCreateInfo createInfo;
|
||||||
createInfo.numVertices = 1;
|
createInfo.numVertices = 1;
|
||||||
createInfo.vertexSize = sizeof(Vector4);
|
createInfo.vertexSize = sizeof(Math::Vector4);
|
||||||
Vector4 data = Vector4(1, 1, 1, 1);
|
Math::Vector4 data = Math::Vector4(1, 1, 1, 1);
|
||||||
createInfo.resourceData.data = reinterpret_cast<uint8*>(&data);
|
createInfo.resourceData.data = reinterpret_cast<uint8*>(&data);
|
||||||
createInfo.resourceData.size = sizeof(Vector4);
|
createInfo.resourceData.size = sizeof(Math::Vector4);
|
||||||
nullVertexBuffer = createVertexBuffer(createInfo);
|
nullVertexBuffer = createVertexBuffer(createInfo);
|
||||||
}
|
}
|
||||||
return nullVertexBuffer;
|
return nullVertexBuffer;
|
||||||
|
|||||||
@@ -50,7 +50,8 @@ struct ViewportCreateInfo
|
|||||||
// doesnt own the data, only proxy it
|
// doesnt own the data, only proxy it
|
||||||
struct BulkResourceData
|
struct BulkResourceData
|
||||||
{
|
{
|
||||||
uint32 size = 0;
|
uint64 size = 0;
|
||||||
|
uint64 offset = 0;
|
||||||
uint8 *data = nullptr;
|
uint8 *data = nullptr;
|
||||||
Gfx::QueueType owner = Gfx::QueueType::GRAPHICS;
|
Gfx::QueueType owner = Gfx::QueueType::GRAPHICS;
|
||||||
};
|
};
|
||||||
@@ -111,8 +112,9 @@ struct StructuredBufferCreateInfo
|
|||||||
};
|
};
|
||||||
struct ShaderCreateInfo
|
struct ShaderCreateInfo
|
||||||
{
|
{
|
||||||
|
std::string mainModule;
|
||||||
//It's possible to input multiple source files for materials or vertexFactories
|
//It's possible to input multiple source files for materials or vertexFactories
|
||||||
Array<std::string> shaderCode;
|
Array<std::string> additionalModules;
|
||||||
std::string name; // Debug info
|
std::string name; // Debug info
|
||||||
std::string entryPoint;
|
std::string entryPoint;
|
||||||
Array<const char*> typeParameter;
|
Array<const char*> typeParameter;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include "Graphics.h"
|
#include "Graphics.h"
|
||||||
#include "RenderPass/DepthPrepass.h"
|
#include "RenderPass/DepthPrepass.h"
|
||||||
#include "RenderPass/BasePass.h"
|
#include "RenderPass/BasePass.h"
|
||||||
|
#include "Material/MaterialAsset.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
using namespace Seele::Gfx;
|
using namespace Seele::Gfx;
|
||||||
@@ -11,9 +12,9 @@ std::string getShaderNameFromRenderPassType(Gfx::RenderPassType type)
|
|||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case Gfx::RenderPassType::DepthPrepass:
|
case Gfx::RenderPassType::DepthPrepass:
|
||||||
return "DepthPrepass.slang";
|
return "DepthPrepass";
|
||||||
case Gfx::RenderPassType::BasePass:
|
case Gfx::RenderPassType::BasePass:
|
||||||
return "ForwardPlus.slang";
|
return "ForwardPlus";
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -64,8 +65,6 @@ ShaderCollection& ShaderMap::createShaders(
|
|||||||
ShaderCreateInfo createInfo;
|
ShaderCreateInfo createInfo;
|
||||||
createInfo.entryPoint = "vertexMain";
|
createInfo.entryPoint = "vertexMain";
|
||||||
createInfo.typeParameter = {material->getName().c_str()};
|
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["NUM_MATERIAL_TEXCOORDS"] = "1";
|
||||||
createInfo.defines["USE_INSTANCING"] = "0";
|
createInfo.defines["USE_INSTANCING"] = "0";
|
||||||
modifyRenderPassMacros(renderPass, createInfo.defines);
|
modifyRenderPassMacros(renderPass, createInfo.defines);
|
||||||
@@ -73,7 +72,9 @@ ShaderCollection& ShaderMap::createShaders(
|
|||||||
|
|
||||||
std::ifstream codeStream("./shaders/" + getShaderNameFromRenderPassType(renderPass));
|
std::ifstream codeStream("./shaders/" + getShaderNameFromRenderPassType(renderPass));
|
||||||
|
|
||||||
createInfo.shaderCode.add(std::string(std::istreambuf_iterator<char>{codeStream}, {}));
|
createInfo.mainModule = getShaderNameFromRenderPassType(renderPass);
|
||||||
|
createInfo.additionalModules.add(vertexInput->getShaderFilename());
|
||||||
|
createInfo.additionalModules.add(material->getName());
|
||||||
|
|
||||||
collection.vertexShader = graphics->createVertexShader(createInfo);
|
collection.vertexShader = graphics->createVertexShader(createInfo);
|
||||||
|
|
||||||
@@ -227,7 +228,7 @@ VertexBuffer::VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint3
|
|||||||
VertexBuffer::~VertexBuffer()
|
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)
|
: Buffer(mapping, startQueueType)
|
||||||
, indexType(indexType)
|
, indexType(indexType)
|
||||||
{
|
{
|
||||||
@@ -264,6 +265,129 @@ const Array<VertexElement> VertexStream::getVertexDescriptions() const
|
|||||||
{
|
{
|
||||||
return vertexDescription;
|
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()
|
VertexDeclaration::VertexDeclaration()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,10 @@
|
|||||||
#include "Containers/Array.h"
|
#include "Containers/Array.h"
|
||||||
#include "Containers/List.h"
|
#include "Containers/List.h"
|
||||||
#include "GraphicsInitializer.h"
|
#include "GraphicsInitializer.h"
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable: 4701)
|
||||||
#include <boost/crc.hpp>
|
#include <boost/crc.hpp>
|
||||||
|
#pragma warning(pop)
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
|
||||||
@@ -372,6 +375,8 @@ public:
|
|||||||
return vertexSize;
|
return vertexSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void updateRegion(BulkResourceData update) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Inherited via QueueOwnedResource
|
// Inherited via QueueOwnedResource
|
||||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||||
@@ -385,9 +390,9 @@ DEFINE_REF(VertexBuffer)
|
|||||||
class IndexBuffer : public Buffer
|
class IndexBuffer : public Buffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IndexBuffer(QueueFamilyMapping mapping, uint32 size, Gfx::SeIndexType index, QueueType startQueueType);
|
IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexType index, QueueType startQueueType);
|
||||||
virtual ~IndexBuffer();
|
virtual ~IndexBuffer();
|
||||||
constexpr uint32 getNumIndices() const
|
constexpr uint64 getNumIndices() const
|
||||||
{
|
{
|
||||||
return numIndices;
|
return numIndices;
|
||||||
}
|
}
|
||||||
@@ -402,7 +407,7 @@ protected:
|
|||||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
|
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
|
||||||
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
|
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
|
||||||
Gfx::SeIndexType indexType;
|
Gfx::SeIndexType indexType;
|
||||||
uint32 numIndices;
|
uint64 numIndices;
|
||||||
};
|
};
|
||||||
DEFINE_REF(IndexBuffer)
|
DEFINE_REF(IndexBuffer)
|
||||||
|
|
||||||
@@ -442,7 +447,6 @@ protected:
|
|||||||
uint32 stride;
|
uint32 stride;
|
||||||
};
|
};
|
||||||
DEFINE_REF(StructuredBuffer)
|
DEFINE_REF(StructuredBuffer)
|
||||||
|
|
||||||
class VertexStream
|
class VertexStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -459,6 +463,34 @@ public:
|
|||||||
uint8 instanced;
|
uint8 instanced;
|
||||||
};
|
};
|
||||||
DEFINE_REF(VertexStream)
|
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<uint64, VertexDataAllocation> freeRanges;
|
||||||
|
Map<uint64, VertexDataAllocation> activeAllocations;
|
||||||
|
uint64 currentSize;
|
||||||
|
uint64 inUse;
|
||||||
|
PVertexBuffer buffer;
|
||||||
|
PGraphics graphics;
|
||||||
|
};
|
||||||
|
DEFINE_REF(VertexDataManager)
|
||||||
|
|
||||||
class VertexDeclaration
|
class VertexDeclaration
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public:
|
|||||||
};
|
};
|
||||||
struct MeshBatch
|
struct MeshBatch
|
||||||
{
|
{
|
||||||
std::vector<MeshBatchElement> elements;
|
Array<MeshBatchElement> elements;
|
||||||
|
|
||||||
uint8 useReverseCulling : 1;
|
uint8 useReverseCulling : 1;
|
||||||
uint8 isBackfaceCullingDisabled : 1;
|
uint8 isBackfaceCullingDisabled : 1;
|
||||||
@@ -73,10 +73,8 @@ struct MeshBatch
|
|||||||
MeshBatch& operator=(const MeshBatch& other) = default;
|
MeshBatch& operator=(const MeshBatch& other) = default;
|
||||||
MeshBatch& operator=(MeshBatch&& other) = default;
|
MeshBatch& operator=(MeshBatch&& other) = default;
|
||||||
};
|
};
|
||||||
DECLARE_REF(PrimitiveComponent)
|
|
||||||
struct StaticMeshBatch : public MeshBatch
|
struct StaticMeshBatch : public MeshBatch
|
||||||
{
|
{
|
||||||
uint32 index;
|
uint32 index;
|
||||||
PPrimitiveComponent primitiveComponent;
|
|
||||||
};
|
};
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
#include "BasePass.h"
|
#include "BasePass.h"
|
||||||
#include "Graphics/Graphics.h"
|
#include "Graphics/Graphics.h"
|
||||||
#include "Window/Window.h"
|
#include "Window/Window.h"
|
||||||
#include "Scene/Components/CameraComponent.h"
|
#include "Scene/Component/Camera.h"
|
||||||
#include "Scene/Actor/CameraActor.h"
|
#include "Scene/Actor/CameraActor.h"
|
||||||
#include "Math/Vector.h"
|
#include "Math/Vector.h"
|
||||||
#include "RenderGraph.h"
|
#include "RenderGraph.h"
|
||||||
|
#include "Material/MaterialAsset.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
@@ -73,7 +74,7 @@ BasePass::BasePass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActo
|
|||||||
: RenderPass(graphics, viewport)
|
: RenderPass(graphics, viewport)
|
||||||
, processor(new BasePassMeshProcessor(viewport, graphics, false))
|
, processor(new BasePassMeshProcessor(viewport, graphics, false))
|
||||||
, descriptorSets(4)
|
, descriptorSets(4)
|
||||||
, source(source->getCameraComponent())
|
, source(source)
|
||||||
{
|
{
|
||||||
UniformBufferCreateInfo uniformInitializer;
|
UniformBufferCreateInfo uniformInitializer;
|
||||||
basePassLayout = graphics->createPipelineLayout();
|
basePassLayout = graphics->createPipelineLayout();
|
||||||
@@ -120,11 +121,11 @@ void BasePass::beginFrame()
|
|||||||
primitiveLayout->reset();
|
primitiveLayout->reset();
|
||||||
BulkResourceData uniformUpdate;
|
BulkResourceData uniformUpdate;
|
||||||
|
|
||||||
viewParams.viewMatrix = source->getViewMatrix();
|
viewParams.viewMatrix = source->getCameraComponent().getViewMatrix();
|
||||||
viewParams.projectionMatrix = source->getProjectionMatrix();
|
viewParams.projectionMatrix = source->getCameraComponent().getProjectionMatrix();
|
||||||
viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0);
|
viewParams.cameraPosition = Math::Vector4(source->getCameraComponent().getCameraPosition(), 0);
|
||||||
viewParams.inverseProjectionMatrix = glm::inverse(viewParams.projectionMatrix);
|
viewParams.inverseProjectionMatrix = glm::inverse(viewParams.projectionMatrix);
|
||||||
viewParams.screenDimensions = Vector2(static_cast<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY()));
|
viewParams.screenDimensions = Math::Vector2(static_cast<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY()));
|
||||||
uniformUpdate.size = sizeof(ViewParameter);
|
uniformUpdate.size = sizeof(ViewParameter);
|
||||||
uniformUpdate.data = (uint8*)&viewParams;
|
uniformUpdate.data = (uint8*)&viewParams;
|
||||||
viewParamBuffer->updateContents(uniformUpdate);
|
viewParamBuffer->updateContents(uniformUpdate);
|
||||||
|
|||||||
@@ -27,10 +27,9 @@ private:
|
|||||||
};
|
};
|
||||||
DEFINE_REF(BasePassMeshProcessor)
|
DEFINE_REF(BasePassMeshProcessor)
|
||||||
DECLARE_REF(CameraActor)
|
DECLARE_REF(CameraActor)
|
||||||
DECLARE_REF(CameraComponent)
|
|
||||||
struct BasePassData
|
struct BasePassData
|
||||||
{
|
{
|
||||||
std::vector<StaticMeshBatch> staticDrawList;
|
Array<StaticMeshBatch> staticDrawList;
|
||||||
};
|
};
|
||||||
class BasePass : public RenderPass<BasePassData>
|
class BasePass : public RenderPass<BasePassData>
|
||||||
{
|
{
|
||||||
@@ -49,7 +48,7 @@ private:
|
|||||||
UPBasePassMeshProcessor processor;
|
UPBasePassMeshProcessor processor;
|
||||||
|
|
||||||
Array<Gfx::PDescriptorSet> descriptorSets;
|
Array<Gfx::PDescriptorSet> descriptorSets;
|
||||||
PCameraComponent source;
|
PCameraActor source;
|
||||||
Gfx::PPipelineLayout basePassLayout;
|
Gfx::PPipelineLayout basePassLayout;
|
||||||
// Set 0: Light environment
|
// Set 0: Light environment
|
||||||
static constexpr uint32 INDEX_LIGHT_ENV = 0;
|
static constexpr uint32 INDEX_LIGHT_ENV = 0;
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
#include "DepthPrepass.h"
|
#include "DepthPrepass.h"
|
||||||
#include "Graphics/Graphics.h"
|
#include "Graphics/Graphics.h"
|
||||||
#include "Window/Window.h"
|
#include "Window/Window.h"
|
||||||
#include "Scene/Components/CameraComponent.h"
|
#include "Scene/Component/Camera.h"
|
||||||
#include "Scene/Actor/CameraActor.h"
|
#include "Scene/Actor/CameraActor.h"
|
||||||
#include "Math/Vector.h"
|
#include "Math/Vector.h"
|
||||||
#include "RenderGraph.h"
|
#include "RenderGraph.h"
|
||||||
|
#include "Material/MaterialAsset.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
@@ -72,7 +73,7 @@ DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCa
|
|||||||
: RenderPass(graphics, viewport)
|
: RenderPass(graphics, viewport)
|
||||||
, processor(new DepthPrepassMeshProcessor(viewport, graphics))
|
, processor(new DepthPrepassMeshProcessor(viewport, graphics))
|
||||||
, descriptorSets(3)
|
, descriptorSets(3)
|
||||||
, source(source->getCameraComponent())
|
, source(source)
|
||||||
{
|
{
|
||||||
UniformBufferCreateInfo uniformInitializer;
|
UniformBufferCreateInfo uniformInitializer;
|
||||||
|
|
||||||
@@ -103,11 +104,11 @@ void DepthPrepass::beginFrame()
|
|||||||
primitiveLayout->reset();
|
primitiveLayout->reset();
|
||||||
BulkResourceData uniformUpdate;
|
BulkResourceData uniformUpdate;
|
||||||
|
|
||||||
viewParams.viewMatrix = source->getViewMatrix();
|
viewParams.viewMatrix = source->getCameraComponent().getViewMatrix();
|
||||||
viewParams.projectionMatrix = source->getProjectionMatrix();
|
viewParams.projectionMatrix = source->getCameraComponent().getProjectionMatrix();
|
||||||
viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0);
|
viewParams.cameraPosition = Math::Vector4(source->getCameraComponent().getCameraPosition(), 0);
|
||||||
viewParams.inverseProjectionMatrix = glm::inverse(viewParams.projectionMatrix);
|
viewParams.inverseProjectionMatrix = glm::inverse(viewParams.projectionMatrix);
|
||||||
viewParams.screenDimensions = Vector2(static_cast<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY()));
|
viewParams.screenDimensions = Math::Vector2(static_cast<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY()));
|
||||||
uniformUpdate.size = sizeof(ViewParameter);
|
uniformUpdate.size = sizeof(ViewParameter);
|
||||||
uniformUpdate.data = (uint8*)&viewParams;
|
uniformUpdate.data = (uint8*)&viewParams;
|
||||||
viewParamBuffer->updateContents(uniformUpdate);
|
viewParamBuffer->updateContents(uniformUpdate);
|
||||||
|
|||||||
@@ -24,10 +24,9 @@ private:
|
|||||||
};
|
};
|
||||||
DEFINE_REF(DepthPrepassMeshProcessor)
|
DEFINE_REF(DepthPrepassMeshProcessor)
|
||||||
DECLARE_REF(CameraActor)
|
DECLARE_REF(CameraActor)
|
||||||
DECLARE_REF(CameraComponent)
|
|
||||||
struct DepthPrepassData
|
struct DepthPrepassData
|
||||||
{
|
{
|
||||||
std::vector<StaticMeshBatch> staticDrawList;
|
Array<StaticMeshBatch> staticDrawList;
|
||||||
};
|
};
|
||||||
class DepthPrepass : public RenderPass<DepthPrepassData>
|
class DepthPrepass : public RenderPass<DepthPrepassData>
|
||||||
{
|
{
|
||||||
@@ -46,7 +45,7 @@ private:
|
|||||||
UPDepthPrepassMeshProcessor processor;
|
UPDepthPrepassMeshProcessor processor;
|
||||||
|
|
||||||
Array<Gfx::PDescriptorSet> descriptorSets;
|
Array<Gfx::PDescriptorSet> descriptorSets;
|
||||||
PCameraComponent source;
|
PCameraActor source;
|
||||||
Gfx::PPipelineLayout depthPrepassLayout;
|
Gfx::PPipelineLayout depthPrepassLayout;
|
||||||
// Set 0: viewParameter
|
// Set 0: viewParameter
|
||||||
static constexpr uint32 INDEX_VIEW_PARAMS = 0;
|
static constexpr uint32 INDEX_VIEW_PARAMS = 0;
|
||||||
|
|||||||
@@ -2,14 +2,14 @@
|
|||||||
#include "Graphics/Graphics.h"
|
#include "Graphics/Graphics.h"
|
||||||
#include "Scene/Scene.h"
|
#include "Scene/Scene.h"
|
||||||
#include "Scene/Actor/CameraActor.h"
|
#include "Scene/Actor/CameraActor.h"
|
||||||
#include "Scene/Components/CameraComponent.h"
|
#include "Scene/Component/Camera.h"
|
||||||
#include "RenderGraph.h"
|
#include "RenderGraph.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
LightCullingPass::LightCullingPass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor camera)
|
LightCullingPass::LightCullingPass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor camera)
|
||||||
: RenderPass(graphics, viewport)
|
: RenderPass(graphics, viewport)
|
||||||
, source(camera->getCameraComponent())
|
, source(camera)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,11 +24,11 @@ void LightCullingPass::beginFrame()
|
|||||||
uint32_t viewportHeight = viewport->getSizeY();
|
uint32_t viewportHeight = viewport->getSizeY();
|
||||||
|
|
||||||
BulkResourceData uniformUpdate;
|
BulkResourceData uniformUpdate;
|
||||||
viewParams.viewMatrix = source->getViewMatrix();
|
viewParams.viewMatrix = source->getCameraComponent().getViewMatrix();
|
||||||
viewParams.projectionMatrix = source->getProjectionMatrix();
|
viewParams.projectionMatrix = source->getCameraComponent().getProjectionMatrix();
|
||||||
viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0);
|
viewParams.cameraPosition = Math::Vector4(source->getCameraComponent().getCameraPosition(), 0);
|
||||||
viewParams.inverseProjectionMatrix = glm::inverse(viewParams.projectionMatrix);
|
viewParams.inverseProjectionMatrix = glm::inverse(viewParams.projectionMatrix);
|
||||||
viewParams.screenDimensions = Vector2(static_cast<float>(viewportWidth), static_cast<float>(viewportHeight));
|
viewParams.screenDimensions = Math::Vector2(static_cast<float>(viewportWidth), static_cast<float>(viewportHeight));
|
||||||
uniformUpdate.size = sizeof(ViewParameter);
|
uniformUpdate.size = sizeof(ViewParameter);
|
||||||
uniformUpdate.data = (uint8*)&viewParams;
|
uniformUpdate.data = (uint8*)&viewParams;
|
||||||
viewParamsBuffer->updateContents(uniformUpdate);
|
viewParamsBuffer->updateContents(uniformUpdate);
|
||||||
@@ -162,13 +162,7 @@ void LightCullingPass::publishOutputs()
|
|||||||
ShaderCreateInfo createInfo;
|
ShaderCreateInfo createInfo;
|
||||||
createInfo.name = "Culling";
|
createInfo.name = "Culling";
|
||||||
|
|
||||||
std::ifstream codeStream("./shaders/LightCulling.slang", std::ios::ate);
|
createInfo.mainModule = "LightCulling";
|
||||||
auto fileSize = codeStream.tellg();
|
|
||||||
codeStream.seekg(0);
|
|
||||||
Array<char> buffer(static_cast<uint32>(fileSize));
|
|
||||||
codeStream.read(buffer.data(), fileSize);
|
|
||||||
|
|
||||||
createInfo.shaderCode.add(std::string(buffer.data()));
|
|
||||||
createInfo.entryPoint = "cullLights";
|
createInfo.entryPoint = "cullLights";
|
||||||
createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
|
createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
|
||||||
createInfo.defines["INDEX_LIGHT_ENV"] = "1";
|
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));
|
glm::uvec3 numThreadGroups = glm::ceil(glm::vec3(numThreads.x / (float)BLOCK_SIZE, numThreads.y / (float)BLOCK_SIZE, 1));
|
||||||
|
|
||||||
viewParams = {
|
viewParams = {
|
||||||
.viewMatrix = source->getViewMatrix(),
|
.viewMatrix = source->getCameraComponent().getViewMatrix(),
|
||||||
.projectionMatrix = source->getProjectionMatrix(),
|
.projectionMatrix = source->getCameraComponent().getProjectionMatrix(),
|
||||||
.inverseProjectionMatrix = glm::inverse(source->getProjectionMatrix()),
|
.inverseProjectionMatrix = glm::inverse(source->getCameraComponent().getProjectionMatrix()),
|
||||||
.cameraPosition = Vector4(source->getCameraPosition(), 0),
|
.cameraPosition = Math::Vector4(source->getTransform().getPosition(), 0),
|
||||||
.screenDimensions = glm::vec2(viewportWidth, viewportHeight),
|
.screenDimensions = glm::vec2(viewportWidth, viewportHeight),
|
||||||
};
|
};
|
||||||
dispatchParams.numThreads = numThreads;
|
dispatchParams.numThreads = numThreads;
|
||||||
@@ -288,13 +282,7 @@ void LightCullingPass::setupFrustums()
|
|||||||
ShaderCreateInfo createInfo;
|
ShaderCreateInfo createInfo;
|
||||||
createInfo.name = "Frustum";
|
createInfo.name = "Frustum";
|
||||||
|
|
||||||
std::ifstream codeStream("./shaders/ComputeFrustums.slang", std::ios::ate);
|
createInfo.mainModule = "ComputeFrustums";
|
||||||
auto fileSize = codeStream.tellg();
|
|
||||||
codeStream.seekg(0);
|
|
||||||
Array<char> buffer(static_cast<uint32>(fileSize));
|
|
||||||
codeStream.read(buffer.data(), fileSize);
|
|
||||||
|
|
||||||
createInfo.shaderCode.add(std::string(buffer.data()));
|
|
||||||
createInfo.entryPoint = "computeFrustums";
|
createInfo.entryPoint = "computeFrustums";
|
||||||
createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
|
createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
|
||||||
frustumShader = graphics->createComputeShader(createInfo);
|
frustumShader = graphics->createComputeShader(createInfo);
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
DECLARE_REF(CameraActor)
|
DECLARE_REF(CameraActor)
|
||||||
DECLARE_REF(CameraComponent)
|
|
||||||
DECLARE_REF(Scene)
|
DECLARE_REF(Scene)
|
||||||
DECLARE_REF(Viewport)
|
DECLARE_REF(Viewport)
|
||||||
struct LightCullingPassData
|
struct LightCullingPassData
|
||||||
@@ -37,7 +36,7 @@ private:
|
|||||||
} dispatchParams;
|
} dispatchParams;
|
||||||
struct Plane
|
struct Plane
|
||||||
{
|
{
|
||||||
Vector n;
|
Math::Vector n;
|
||||||
float d;
|
float d;
|
||||||
};
|
};
|
||||||
struct Frustum
|
struct Frustum
|
||||||
@@ -72,7 +71,7 @@ private:
|
|||||||
Gfx::PComputeShader cullingShader;
|
Gfx::PComputeShader cullingShader;
|
||||||
Gfx::PPipelineLayout cullingLayout;
|
Gfx::PPipelineLayout cullingLayout;
|
||||||
Gfx::PComputePipeline cullingPipeline;
|
Gfx::PComputePipeline cullingPipeline;
|
||||||
PCameraComponent source;
|
PCameraActor source;
|
||||||
};
|
};
|
||||||
DEFINE_REF(LightCullingPass)
|
DEFINE_REF(LightCullingPass)
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
|
|||||||
@@ -26,15 +26,16 @@ public:
|
|||||||
virtual void endFrame() = 0;
|
virtual void endFrame() = 0;
|
||||||
virtual void publishOutputs() = 0;
|
virtual void publishOutputs() = 0;
|
||||||
virtual void createRenderPass() = 0;
|
virtual void createRenderPass() = 0;
|
||||||
void setResources(PRenderGraphResources resources) { this->resources = resources; }
|
void setResources(PRenderGraphResources _resources) { resources = _resources; }
|
||||||
protected:
|
protected:
|
||||||
struct ViewParameter
|
struct ViewParameter
|
||||||
{
|
{
|
||||||
Matrix4 viewMatrix;
|
Math::Matrix4 viewMatrix;
|
||||||
Matrix4 projectionMatrix;
|
Math::Matrix4 projectionMatrix;
|
||||||
Matrix4 inverseProjectionMatrix;
|
Math::Matrix4 inverseProjectionMatrix;
|
||||||
Vector4 cameraPosition;
|
Math::Vector4 cameraPosition;
|
||||||
Vector2 screenDimensions;
|
Math::Vector2 screenDimensions;
|
||||||
|
Math::Vector2 pad0;
|
||||||
} viewParams;
|
} viewParams;
|
||||||
PRenderGraphResources resources;
|
PRenderGraphResources resources;
|
||||||
RenderPassDataType passData;
|
RenderPassDataType passData;
|
||||||
|
|||||||
@@ -20,16 +20,16 @@ void TextPass::beginFrame()
|
|||||||
{
|
{
|
||||||
for(TextRender& render : passData.texts)
|
for(TextRender& render : passData.texts)
|
||||||
{
|
{
|
||||||
FontData& fontData = getFontData(render.font);
|
FontData& fd = getFontData(render.font);
|
||||||
TextResources& resources = textResources[render.font].add();
|
TextResources& res = textResources[render.font].add();
|
||||||
Array<GlyphInstanceData> instanceData;
|
Array<GlyphInstanceData> instanceData;
|
||||||
float x = render.position.x;
|
float x = render.position.x;
|
||||||
float y = render.position.y;
|
float y = render.position.y;
|
||||||
for(uint32 c : render.text)
|
for(uint32 c : render.text)
|
||||||
{
|
{
|
||||||
const GlyphData& glyph = fontData.glyphDataSet[fontData.characterToGlyphIndex[c]];
|
const GlyphData& glyph = fd.glyphDataSet[fd.characterToGlyphIndex[c]];
|
||||||
Vector2 bearing = glyph.bearing;
|
Math::Vector2 bearing = glyph.bearing;
|
||||||
Vector2 size = glyph.size;
|
Math::Vector2 size = glyph.size;
|
||||||
float xpos = x + bearing.x * render.scale;
|
float xpos = x + bearing.x * render.scale;
|
||||||
float ypos = y - (size.y - bearing.y) * render.scale;
|
float ypos = y - (size.y - bearing.y) * render.scale;
|
||||||
|
|
||||||
@@ -37,9 +37,9 @@ void TextPass::beginFrame()
|
|||||||
float h = size.y * render.scale;
|
float h = size.y * render.scale;
|
||||||
|
|
||||||
instanceData.add(GlyphInstanceData{
|
instanceData.add(GlyphInstanceData{
|
||||||
.position = Vector2(xpos, ypos),
|
.position = Math::Vector2(xpos, ypos),
|
||||||
.widthHeight = Vector2(w, h),
|
.widthHeight = Math::Vector2(w, h),
|
||||||
.glyphIndex = fontData.characterToGlyphIndex[c],
|
.glyphIndex = fd.characterToGlyphIndex[c],
|
||||||
});
|
});
|
||||||
x += (glyph.advance >> 6) * render.scale;
|
x += (glyph.advance >> 6) * render.scale;
|
||||||
}
|
}
|
||||||
@@ -51,11 +51,11 @@ void TextPass::beginFrame()
|
|||||||
.vertexSize = sizeof(GlyphInstanceData),
|
.vertexSize = sizeof(GlyphInstanceData),
|
||||||
.numVertices = static_cast<uint32>(instanceData.size()),
|
.numVertices = static_cast<uint32>(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,
|
.textColor = render.textColor,
|
||||||
.scale = render.scale,
|
.scale = render.scale,
|
||||||
};
|
};
|
||||||
@@ -67,12 +67,12 @@ void TextPass::render()
|
|||||||
{
|
{
|
||||||
graphics->beginRenderPass(renderPass);
|
graphics->beginRenderPass(renderPass);
|
||||||
Array<Gfx::PRenderCommand> commands;
|
Array<Gfx::PRenderCommand> commands;
|
||||||
for(const auto& [fontAsset, resources] : textResources)
|
for(const auto& [fontAsset, res] : textResources)
|
||||||
{
|
{
|
||||||
Gfx::PRenderCommand command = graphics->createRenderCommand("TextPassCommand");
|
Gfx::PRenderCommand command = graphics->createRenderCommand("TextPassCommand");
|
||||||
command->setViewport(viewport);
|
command->setViewport(viewport);
|
||||||
command->bindPipeline(pipeline);
|
command->bindPipeline(pipeline);
|
||||||
for(const auto& resource : resources)
|
for(const auto& resource : res)
|
||||||
{
|
{
|
||||||
command->bindDescriptor({generalSet, resource.textureArraySet});
|
command->bindDescriptor({generalSet, resource.textureArraySet});
|
||||||
command->bindVertexBuffer({VertexInputStream(0, 0, resource.vertexBuffer)});
|
command->bindVertexBuffer({VertexInputStream(0, 0, resource.vertexBuffer)});
|
||||||
@@ -100,14 +100,8 @@ void TextPass::publishOutputs()
|
|||||||
void TextPass::createRenderPass()
|
void TextPass::createRenderPass()
|
||||||
{
|
{
|
||||||
depthAttachment = resources->requestRenderTarget("UIPASS_DEPTH");
|
depthAttachment = resources->requestRenderTarget("UIPASS_DEPTH");
|
||||||
std::ifstream codeStream("./shaders/TextPass.slang", std::ios::ate);
|
|
||||||
auto fileSize = codeStream.tellg();
|
|
||||||
codeStream.seekg(0);
|
|
||||||
Array<char> buffer(static_cast<uint32>(fileSize));
|
|
||||||
codeStream.read(buffer.data(), fileSize);
|
|
||||||
|
|
||||||
ShaderCreateInfo createInfo;
|
ShaderCreateInfo createInfo;
|
||||||
createInfo.shaderCode.add(std::string(buffer.data()));
|
createInfo.mainModule = "TextPass";
|
||||||
createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
|
createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
|
||||||
createInfo.name = "TextVertex";
|
createInfo.name = "TextVertex";
|
||||||
createInfo.entryPoint = "vertexMain";
|
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->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 256, Gfx::SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT);
|
||||||
textureArrayLayout->create();
|
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({
|
projectionBuffer = graphics->createUniformBuffer({
|
||||||
.resourceData = {
|
.resourceData = {
|
||||||
.size = sizeof(Matrix4),
|
.size = sizeof(Math::Matrix4),
|
||||||
.data = (uint8*)&projectionMatrix,
|
.data = (uint8*)&projectionMatrix,
|
||||||
},
|
},
|
||||||
.bDynamic = false,
|
.bDynamic = false,
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ struct TextRender
|
|||||||
{
|
{
|
||||||
std::string text;
|
std::string text;
|
||||||
PFontAsset font;
|
PFontAsset font;
|
||||||
Vector4 textColor;
|
Math::Vector4 textColor;
|
||||||
Vector2 position;
|
Math::Vector2 position;
|
||||||
float scale;
|
float scale;
|
||||||
};
|
};
|
||||||
struct TextPassData
|
struct TextPassData
|
||||||
@@ -35,19 +35,19 @@ public:
|
|||||||
private:
|
private:
|
||||||
struct GlyphData
|
struct GlyphData
|
||||||
{
|
{
|
||||||
Vector2 bearing;
|
Math::Vector2 bearing;
|
||||||
Vector2 size;
|
Math::Vector2 size;
|
||||||
uint32 advance;
|
uint32 advance;
|
||||||
};
|
};
|
||||||
struct GlyphInstanceData
|
struct GlyphInstanceData
|
||||||
{
|
{
|
||||||
Vector2 position;
|
Math::Vector2 position;
|
||||||
Vector2 widthHeight;
|
Math::Vector2 widthHeight;
|
||||||
uint32 glyphIndex;
|
uint32 glyphIndex;
|
||||||
};
|
};
|
||||||
struct TextData
|
struct TextData
|
||||||
{
|
{
|
||||||
Vector4 textColor;
|
Math::Vector4 textColor;
|
||||||
float scale;
|
float scale;
|
||||||
};
|
};
|
||||||
struct FontData
|
struct FontData
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ void UIPass::beginFrame()
|
|||||||
.numVertices = (uint32)passData.renderElements.size(),
|
.numVertices = (uint32)passData.renderElements.size(),
|
||||||
};
|
};
|
||||||
elementBuffer = graphics->createVertexBuffer(info);
|
elementBuffer = graphics->createVertexBuffer(info);
|
||||||
uint32 numTextures = passData.usedTextures.size();
|
uint32 numTextures = static_cast<uint32>(passData.usedTextures.size());
|
||||||
numTexturesBuffer->updateContents({
|
numTexturesBuffer->updateContents({
|
||||||
.size = sizeof(uint32),
|
.size = sizeof(uint32),
|
||||||
.data = (uint8*)&numTextures,
|
.data = (uint8*)&numTextures,
|
||||||
@@ -45,7 +45,7 @@ void UIPass::render()
|
|||||||
command->bindPipeline(pipeline);
|
command->bindPipeline(pipeline);
|
||||||
command->bindVertexBuffer({VertexInputStream(0, 0, elementBuffer)});
|
command->bindVertexBuffer({VertexInputStream(0, 0, elementBuffer)});
|
||||||
command->bindDescriptor(descriptorSet);
|
command->bindDescriptor(descriptorSet);
|
||||||
command->draw(4, passData.renderElements.size(), 0, 0);
|
command->draw(4, static_cast<uint32>(passData.renderElements.size()), 0, 0);
|
||||||
graphics->executeCommands(Array<Gfx::PRenderCommand>({command}));
|
graphics->executeCommands(Array<Gfx::PRenderCommand>({command}));
|
||||||
graphics->endRenderPass();
|
graphics->endRenderPass();
|
||||||
//co_return;
|
//co_return;
|
||||||
@@ -76,14 +76,8 @@ void UIPass::publishOutputs()
|
|||||||
|
|
||||||
void UIPass::createRenderPass()
|
void UIPass::createRenderPass()
|
||||||
{
|
{
|
||||||
std::ifstream codeStream("./shaders/UIPass.slang", std::ios::ate);
|
|
||||||
auto fileSize = codeStream.tellg();
|
|
||||||
codeStream.seekg(0);
|
|
||||||
Array<char> buffer(static_cast<uint32>(fileSize));
|
|
||||||
codeStream.read(buffer.data(), fileSize);
|
|
||||||
|
|
||||||
ShaderCreateInfo createInfo;
|
ShaderCreateInfo createInfo;
|
||||||
createInfo.shaderCode.add(std::string(buffer.data()));
|
createInfo.mainModule = "UIPass";
|
||||||
createInfo.name = "UIVertex";
|
createInfo.name = "UIVertex";
|
||||||
createInfo.entryPoint = "vertexMain";
|
createInfo.entryPoint = "vertexMain";
|
||||||
vertexShader = graphics->createVertexShader(createInfo);
|
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->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();
|
descriptorLayout->create();
|
||||||
|
|
||||||
Matrix4 projectionMatrix = glm::ortho(0, 1, 1, 0);
|
Math::Matrix4 projectionMatrix = glm::ortho(0, 1, 1, 0);
|
||||||
UniformBufferCreateInfo info = {
|
UniformBufferCreateInfo info = {
|
||||||
.resourceData = {
|
.resourceData = {
|
||||||
.size = sizeof(Matrix4),
|
.size = sizeof(Math::Matrix4),
|
||||||
.data = (uint8*)&projectionMatrix,
|
.data = (uint8*)&projectionMatrix,
|
||||||
},
|
},
|
||||||
.bDynamic = false,
|
.bDynamic = false,
|
||||||
|
|||||||
@@ -54,16 +54,16 @@ void StaticMeshVertexInput::init(Gfx::PGraphics graphics)
|
|||||||
{
|
{
|
||||||
elements.add(accessStreamComponent(
|
elements.add(accessStreamComponent(
|
||||||
data.textureCoordinates[coordinateIndex],
|
data.textureCoordinates[coordinateIndex],
|
||||||
baseTexCoordAttribute + coordinateIndex
|
static_cast<uint8>(baseTexCoordAttribute + coordinateIndex)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
initDeclaration(graphics, elements);
|
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")
|
IMPLEMENT_VERTEX_INPUT_TYPE(StaticMeshVertexInput, "StaticMeshVertexInput")
|
||||||
@@ -43,7 +43,7 @@ const char* VertexInputType::getName()
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* VertexInputType::getShaderFilename()
|
std::string VertexInputType::getShaderFilename()
|
||||||
{
|
{
|
||||||
return shaderFilename;
|
return shaderFilename;
|
||||||
}
|
}
|
||||||
@@ -90,20 +90,22 @@ Gfx::VertexElement VertexShaderInput::accessStreamComponent(const VertexStreamCo
|
|||||||
{
|
{
|
||||||
VertexStream vertexStream;
|
VertexStream vertexStream;
|
||||||
vertexStream.vertexBuffer = component.vertexBuffer;
|
vertexStream.vertexBuffer = component.vertexBuffer;
|
||||||
vertexStream.stride = component.stride;
|
assert(component.stride < UINT8_MAX && component.offset < UINT8_MAX && component.offset < UINT8_MAX);
|
||||||
vertexStream.offset = component.offset;
|
vertexStream.stride = static_cast<uint8>(component.stride);
|
||||||
|
vertexStream.offset = static_cast<uint8>(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<uint8>(component.offset), component.type, attributeIndex, vertexStream.stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::VertexElement VertexShaderInput::accessPositionStreamComponent(const VertexStreamComponent& component, uint8 attributeIndex)
|
Gfx::VertexElement VertexShaderInput::accessPositionStreamComponent(const VertexStreamComponent& component, uint8 attributeIndex)
|
||||||
{
|
{
|
||||||
VertexStream vertexStream;
|
VertexStream vertexStream;
|
||||||
vertexStream.vertexBuffer = component.vertexBuffer;
|
vertexStream.vertexBuffer = component.vertexBuffer;
|
||||||
vertexStream.stride = component.stride;
|
assert(component.stride < UINT8_MAX && component.offset < UINT8_MAX && component.offset < UINT8_MAX);
|
||||||
vertexStream.offset = component.offset;
|
vertexStream.stride = static_cast<uint8>(component.stride);
|
||||||
|
vertexStream.offset = static_cast<uint8>(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<uint8>(component.offset), component.type, attributeIndex, vertexStream.stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexShaderInput::initDeclaration(Gfx::PGraphics graphics, Array<Gfx::VertexElement>& elements)
|
void VertexShaderInput::initDeclaration(Gfx::PGraphics graphics, Array<Gfx::VertexElement>& elements)
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ public:
|
|||||||
virtual ~VertexInputType();
|
virtual ~VertexInputType();
|
||||||
|
|
||||||
const char* getName();
|
const char* getName();
|
||||||
const char* getShaderFilename();
|
std::string getShaderFilename();
|
||||||
private:
|
private:
|
||||||
const char* name;
|
const char* name;
|
||||||
const char* shaderFilename;
|
const char* shaderFilename;
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ PSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDevice
|
|||||||
VkDeviceSize allocatedOffset = it.first;
|
VkDeviceSize allocatedOffset = it.first;
|
||||||
PSubAllocation freeAllocation = it.second;
|
PSubAllocation freeAllocation = it.second;
|
||||||
assert(allocatedOffset == freeAllocation->allocatedOffset);
|
assert(allocatedOffset == freeAllocation->allocatedOffset);
|
||||||
VkDeviceSize alignedOffset = align(allocatedOffset, alignment);
|
VkDeviceSize alignedOffset = Math::align(allocatedOffset, alignment);
|
||||||
VkDeviceSize alignmentAdjustment = alignedOffset - allocatedOffset;
|
VkDeviceSize alignmentAdjustment = alignedOffset - allocatedOffset;
|
||||||
VkDeviceSize size = alignmentAdjustment + requestedSize;
|
VkDeviceSize size = alignmentAdjustment + requestedSize;
|
||||||
if (freeAllocation->size == size)
|
if (freeAllocation->size == size)
|
||||||
@@ -171,6 +171,8 @@ void Allocation::markFree(SubAllocation *allocation)
|
|||||||
allocHandle = foundAlloc->second;
|
allocHandle = foundAlloc->second;
|
||||||
allocHandle->allocatedOffset -= allocation->allocatedSize;
|
allocHandle->allocatedOffset -= allocation->allocatedSize;
|
||||||
allocHandle->alignedOffset -= allocation->allocatedSize;
|
allocHandle->alignedOffset -= allocation->allocatedSize;
|
||||||
|
allocHandle->size += allocation->allocatedSize;
|
||||||
|
allocHandle->allocatedSize += allocation->allocatedSize;
|
||||||
// place back at correct offset
|
// place back at correct offset
|
||||||
freeRanges[allocHandle->allocatedOffset] = allocHandle;
|
freeRanges[allocHandle->allocatedOffset] = allocHandle;
|
||||||
// remove from offset map since key changes
|
// 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);
|
std::scoped_lock l(lock);
|
||||||
for (auto it = freeBuffers.begin(); it != freeBuffers.end(); ++it)
|
for (auto it = freeBuffers.begin(); it != freeBuffers.end(); ++it)
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ public:
|
|||||||
{
|
{
|
||||||
return allocation->getOffset();
|
return allocation->getOffset();
|
||||||
}
|
}
|
||||||
uint32 getSize() const
|
uint64 getSize() const
|
||||||
{
|
{
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
@@ -203,7 +203,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
PSubAllocation allocation;
|
PSubAllocation allocation;
|
||||||
VkBuffer buffer;
|
VkBuffer buffer;
|
||||||
uint32 size;
|
uint64 size;
|
||||||
VkBufferUsageFlags usage;
|
VkBufferUsageFlags usage;
|
||||||
uint8 bReadable;
|
uint8 bReadable;
|
||||||
friend class StagingManager;
|
friend class StagingManager;
|
||||||
@@ -215,7 +215,7 @@ class StagingManager
|
|||||||
public:
|
public:
|
||||||
StagingManager(PGraphics graphics, PAllocator allocator);
|
StagingManager(PGraphics graphics, PAllocator allocator);
|
||||||
~StagingManager();
|
~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 releaseStagingBuffer(PStagingBuffer buffer);
|
||||||
void clearPending();
|
void clearPending();
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ using namespace Seele::Vulkan;
|
|||||||
|
|
||||||
struct PendingBuffer
|
struct PendingBuffer
|
||||||
{
|
{
|
||||||
|
uint64 offset;
|
||||||
|
uint64 size;
|
||||||
PStagingBuffer stagingBuffer;
|
PStagingBuffer stagingBuffer;
|
||||||
Gfx::QueueType prevQueue;
|
Gfx::QueueType prevQueue;
|
||||||
bool bWriteOnly;
|
bool bWriteOnly;
|
||||||
@@ -16,7 +18,7 @@ struct PendingBuffer
|
|||||||
|
|
||||||
static std::map<ShaderBuffer *, PendingBuffer> pendingBuffers;
|
static std::map<ShaderBuffer *, PendingBuffer> 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)
|
: graphics(graphics)
|
||||||
, currentBuffer(0)
|
, currentBuffer(0)
|
||||||
, size(size)
|
, size(size)
|
||||||
@@ -63,7 +65,7 @@ ShaderBuffer::~ShaderBuffer()
|
|||||||
{
|
{
|
||||||
PCmdBuffer cmdBuffer = graphics->getQueueCommands(owner)->getCommands();
|
PCmdBuffer cmdBuffer = graphics->getQueueCommands(owner)->getCommands();
|
||||||
VkDevice device = graphics->getDevice();
|
VkDevice device = graphics->getDevice();
|
||||||
auto deletionLambda = [cmdBuffer, device](VkBuffer buffer) -> void
|
auto deletionLambda = [cmdBuffer, device](VkBuffer) -> void
|
||||||
{
|
{
|
||||||
//co_await cmdBuffer->asyncWait();
|
//co_await cmdBuffer->asyncWait();
|
||||||
//vkDestroyBuffer(device, buffer, nullptr);
|
//vkDestroyBuffer(device, buffer, nullptr);
|
||||||
@@ -169,6 +171,11 @@ void ShaderBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineSta
|
|||||||
}
|
}
|
||||||
|
|
||||||
void *ShaderBuffer::lock(bool bWriteOnly)
|
void *ShaderBuffer::lock(bool bWriteOnly)
|
||||||
|
{
|
||||||
|
return lockRegion(0, size, bWriteOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *ShaderBuffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnly)
|
||||||
{
|
{
|
||||||
void *data = nullptr;
|
void *data = nullptr;
|
||||||
|
|
||||||
@@ -189,10 +196,12 @@ void *ShaderBuffer::lock(bool bWriteOnly)
|
|||||||
PendingBuffer pending;
|
PendingBuffer pending;
|
||||||
pending.bWriteOnly = bWriteOnly;
|
pending.bWriteOnly = bWriteOnly;
|
||||||
pending.prevQueue = owner;
|
pending.prevQueue = owner;
|
||||||
|
pending.offset = regionOffset;
|
||||||
|
pending.size = regionSize;
|
||||||
if (bWriteOnly)
|
if (bWriteOnly)
|
||||||
{
|
{
|
||||||
//requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
|
//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();
|
data = stagingBuffer->getMappedPointer();
|
||||||
pending.stagingBuffer = stagingBuffer;
|
pending.stagingBuffer = stagingBuffer;
|
||||||
}
|
}
|
||||||
@@ -255,7 +264,8 @@ void ShaderBuffer::unlock()
|
|||||||
|
|
||||||
VkBufferCopy region;
|
VkBufferCopy region;
|
||||||
std::memset(®ion, 0, sizeof(VkBufferCopy));
|
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);
|
vkCmdCopyBuffer(cmdHandle, stagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, ®ion);
|
||||||
graphics->getQueueCommands(owner)->submitCommands();
|
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)
|
void VertexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
|
||||||
{
|
{
|
||||||
Gfx::QueueOwnedResource::transferOwnership(newOwner);
|
Gfx::QueueOwnedResource::transferOwnership(newOwner);
|
||||||
|
|||||||
@@ -302,7 +302,7 @@ void RenderCommand::pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStag
|
|||||||
void RenderCommand::draw(const MeshBatchElement& data)
|
void RenderCommand::draw(const MeshBatchElement& data)
|
||||||
{
|
{
|
||||||
assert(threadId == std::this_thread::get_id());
|
assert(threadId == std::this_thread::get_id());
|
||||||
vkCmdDrawIndexed(handle, data.indexBuffer->getNumIndices(), data.numInstances, data.minVertexIndex, data.baseVertexIndex, 0);
|
vkCmdDrawIndexed(handle, static_cast<uint32>(data.indexBuffer->getNumIndices()), data.numInstances, data.minVertexIndex, data.baseVertexIndex, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderCommand::draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance)
|
void RenderCommand::draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance)
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ public:
|
|||||||
virtual Gfx::PPipelineLayout createPipelineLayout(Gfx::PPipelineLayout baseLayout = nullptr) override;
|
virtual Gfx::PPipelineLayout createPipelineLayout(Gfx::PPipelineLayout baseLayout = nullptr) override;
|
||||||
|
|
||||||
virtual void copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) override;
|
virtual void copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Array<const char *> getRequiredExtensions();
|
Array<const char *> getRequiredExtensions();
|
||||||
void initInstance(GraphicsInitializer initInfo);
|
void initInstance(GraphicsInitializer initInfo);
|
||||||
|
|||||||
@@ -1390,7 +1390,7 @@ Gfx::SeCompareOp Seele::Vulkan::cast(const VkCompareOp &op)
|
|||||||
VkClearValue Seele::Vulkan::cast(const Gfx::SeClearValue& clear)
|
VkClearValue Seele::Vulkan::cast(const Gfx::SeClearValue& clear)
|
||||||
{
|
{
|
||||||
VkClearValue result;
|
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[0] = clear.color.float32[0];
|
||||||
result.color.float32[1] = clear.color.float32[1];
|
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 Seele::Vulkan::cast(const VkClearValue& clear)
|
||||||
{
|
{
|
||||||
Gfx::SeClearValue result;
|
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[0] = clear.color.float32[0];
|
||||||
result.color.float32[1] = clear.color.float32[1];
|
result.color.float32[1] = clear.color.float32[1];
|
||||||
|
|||||||
@@ -72,13 +72,13 @@ DEFINE_REF(VertexDeclaration)
|
|||||||
class ShaderBuffer
|
class ShaderBuffer
|
||||||
{
|
{
|
||||||
public:
|
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();
|
virtual ~ShaderBuffer();
|
||||||
VkBuffer getHandle() const
|
VkBuffer getHandle() const
|
||||||
{
|
{
|
||||||
return buffers[currentBuffer].buffer;
|
return buffers[currentBuffer].buffer;
|
||||||
}
|
}
|
||||||
uint32 getSize() const
|
uint64 getSize() const
|
||||||
{
|
{
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
@@ -88,6 +88,7 @@ public:
|
|||||||
currentBuffer = (currentBuffer + 1) % numBuffers;
|
currentBuffer = (currentBuffer + 1) % numBuffers;
|
||||||
}
|
}
|
||||||
virtual void *lock(bool bWriteOnly = true);
|
virtual void *lock(bool bWriteOnly = true);
|
||||||
|
virtual void *lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnly = true);
|
||||||
virtual void unlock();
|
virtual void unlock();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -98,7 +99,7 @@ protected:
|
|||||||
};
|
};
|
||||||
PGraphics graphics;
|
PGraphics graphics;
|
||||||
uint32 currentBuffer;
|
uint32 currentBuffer;
|
||||||
uint32 size;
|
uint64 size;
|
||||||
Gfx::QueueType& owner;
|
Gfx::QueueType& owner;
|
||||||
BufferAllocation buffers[Gfx::numFramesBuffered];
|
BufferAllocation buffers[Gfx::numFramesBuffered];
|
||||||
uint32 numBuffers;
|
uint32 numBuffers;
|
||||||
@@ -168,6 +169,8 @@ public:
|
|||||||
VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData);
|
VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData);
|
||||||
virtual ~VertexBuffer();
|
virtual ~VertexBuffer();
|
||||||
|
|
||||||
|
virtual void updateRegion(BulkResourceData update) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Inherited via Vulkan::Buffer
|
// Inherited via Vulkan::Buffer
|
||||||
virtual VkAccessFlags getSourceAccessMask();
|
virtual VkAccessFlags getSourceAccessMask();
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
#include "VulkanGraphics.h"
|
#include "VulkanGraphics.h"
|
||||||
#include "VulkanDescriptorSets.h"
|
#include "VulkanDescriptorSets.h"
|
||||||
#include "slang.h"
|
#include "slang.h"
|
||||||
|
#include "slang-com-ptr.h"
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
|
|
||||||
using namespace slang;
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
using namespace Seele::Vulkan;
|
using namespace Seele::Vulkan;
|
||||||
|
|
||||||
@@ -33,85 +33,130 @@ uint32 Seele::Vulkan::Shader::getShaderHash() const
|
|||||||
return hash;
|
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)
|
void Shader::create(const ShaderCreateInfo& createInfo)
|
||||||
{
|
{
|
||||||
entryPointName = createInfo.entryPoint;
|
entryPointName = createInfo.entryPoint;
|
||||||
static SlangSession* session = spCreateSession(nullptr);
|
thread_local Slang::ComPtr<slang::IGlobalSession> globalSession;
|
||||||
|
if(!globalSession)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
spAddTranslationUnitSourceString(
|
slang::createGlobalSession(globalSession.writeRef());
|
||||||
request,
|
}
|
||||||
translationUnitIndex,
|
slang::SessionDesc sessionDesc;
|
||||||
entryPointName.c_str(),
|
sessionDesc.flags = 0;
|
||||||
code.data()
|
sessionDesc.defaultMatrixLayoutMode = SLANG_MATRIX_LAYOUT_COLUMN_MAJOR;
|
||||||
|
Array<slang::PreprocessorMacroDesc> macros;
|
||||||
|
for(auto define : createInfo.defines)
|
||||||
|
{
|
||||||
|
macros.add(slang::PreprocessorMacroDesc{
|
||||||
|
.name = define.key,
|
||||||
|
.value = define.value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
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<const char*, 3> searchPaths = {"shaders/", "shaders/lib/", "shaders/generated/"};
|
||||||
|
sessionDesc.searchPaths = searchPaths.data();
|
||||||
|
sessionDesc.searchPathCount = searchPaths.size();
|
||||||
|
|
||||||
|
Slang::ComPtr<slang::ISession> session;
|
||||||
|
globalSession->createSession(sessionDesc, session.writeRef());
|
||||||
|
|
||||||
|
Slang::ComPtr<slang::IBlob> diagnostics;
|
||||||
|
Array<slang::IComponentType*> modules;
|
||||||
|
Slang::ComPtr<slang::IEntryPoint> entrypoint;
|
||||||
|
|
||||||
|
for (auto moduleName : createInfo.additionalModules)
|
||||||
|
{
|
||||||
|
modules.add(session->loadModule(moduleName.c_str(), diagnostics.writeRef()));
|
||||||
|
if(diagnostics)
|
||||||
|
{
|
||||||
|
std::cout << (const char*)diagnostics->getBufferPointer() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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<slang::ITypeConformance> 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<slang::IComponentType> conformingModule;
|
||||||
|
session->createCompositeComponentType(modules.data(), modules.size(), conformingModule.writeRef(), diagnostics.writeRef());
|
||||||
|
*/
|
||||||
|
Slang::ComPtr<slang::IComponentType> 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<slang::SpecializationArg> specialization;
|
||||||
|
for(auto typeArg : createInfo.typeParameter)
|
||||||
|
{
|
||||||
|
specialization.add(slang::SpecializationArg::fromType(reflection->findTypeByName(typeArg)));
|
||||||
|
}
|
||||||
|
Slang::ComPtr<slang::IComponentType> specializedComponent;
|
||||||
|
linkedProgram->specialize(specialization.data(), specialization.size(), specializedComponent.writeRef(), diagnostics.writeRef());
|
||||||
|
if(diagnostics)
|
||||||
|
{
|
||||||
|
std::cout << (const char*)diagnostics->getBufferPointer() << std::endl;
|
||||||
|
}
|
||||||
|
Slang::ComPtr<slang::IBlob> kernelBlob;
|
||||||
|
specializedComponent->getEntryPointCode(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
kernelBlob.writeRef(),
|
||||||
|
diagnostics.writeRef()
|
||||||
);
|
);
|
||||||
}
|
if(diagnostics)
|
||||||
for(auto define : createInfo.defines)
|
|
||||||
{
|
{
|
||||||
spAddPreprocessorDefine(request, define.key, define.value);
|
std::cout << (const char*)diagnostics->getBufferPointer() << std::endl;
|
||||||
}
|
}
|
||||||
spAddSearchPath(request, "shaders/lib/");
|
|
||||||
spAddSearchPath(request, "shaders/generated/");
|
|
||||||
|
|
||||||
spSetGlobalGenericArgs(request, (int)createInfo.typeParameter.size(), createInfo.typeParameter.data());
|
|
||||||
|
|
||||||
int entryPointIndex = spAddEntryPoint(request, translationUnitIndex, entryPointName.c_str(), getStageFromShaderType(type));
|
|
||||||
if(spCompile(request))
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
std::cout << define.key << ": " << define.value << 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<const uint32*>(spGetEntryPointCode(request, entryPointIndex, &dataSize));
|
|
||||||
|
|
||||||
VkShaderModuleCreateInfo moduleInfo;
|
VkShaderModuleCreateInfo moduleInfo;
|
||||||
moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||||
moduleInfo.pNext = nullptr;
|
moduleInfo.pNext = nullptr;
|
||||||
moduleInfo.flags = 0;
|
moduleInfo.flags = 0;
|
||||||
moduleInfo.codeSize = dataSize;
|
moduleInfo.codeSize = kernelBlob->getBufferSize();
|
||||||
moduleInfo.pCode = data;
|
moduleInfo.pCode = (uint32_t*)kernelBlob->getBufferPointer();
|
||||||
VK_CHECK(vkCreateShaderModule(graphics->getDevice(), &moduleInfo, nullptr, &module));
|
VK_CHECK(vkCreateShaderModule(graphics->getDevice(), &moduleInfo, nullptr, &module));
|
||||||
|
|
||||||
boost::crc_32_type result;
|
boost::crc_32_type result;
|
||||||
result.process_bytes(entryPointName.data(), entryPointName.size());
|
result.process_bytes(entryPointName.data(), entryPointName.size());
|
||||||
result.process_bytes(data, dataSize);
|
result.process_bytes(kernelBlob->getBufferPointer(), kernelBlob->getBufferSize());
|
||||||
hash = result.checksum();
|
hash = result.checksum();
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,6 @@ void MaterialAsset::load()
|
|||||||
std::ofstream codeStream("./shaders/generated/"+materialName+".slang");
|
std::ofstream codeStream("./shaders/generated/"+materialName+".slang");
|
||||||
std::string profile = j["profile"].get<std::string>();
|
std::string profile = j["profile"].get<std::string>();
|
||||||
|
|
||||||
codeStream << "import VERTEX_INPUT_IMPORT;" << std::endl;
|
|
||||||
codeStream << "import Material;" << std::endl;
|
codeStream << "import Material;" << std::endl;
|
||||||
codeStream << "import BRDF;" << std::endl;
|
codeStream << "import BRDF;" << std::endl;
|
||||||
codeStream << "import MaterialParameter;" << std::endl << std::endl;
|
codeStream << "import MaterialParameter;" << std::endl << std::endl;
|
||||||
@@ -94,7 +93,7 @@ void MaterialAsset::load()
|
|||||||
uniformBufferOffset += 12;
|
uniformBufferOffset += 12;
|
||||||
if(defaultValue != param.value().end())
|
if(defaultValue != param.value().end())
|
||||||
{
|
{
|
||||||
p->data = parseVector(defaultValue.value().get<std::string>().c_str());
|
p->data = Math::parseVector(defaultValue.value().get<std::string>().c_str());
|
||||||
}
|
}
|
||||||
parameters.add(p);
|
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)
|
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);
|
return shaderMap.createShaders(graphics, renderPass, this, vertexInput, false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ private:
|
|||||||
uint8* uniformData;
|
uint8* uniformData;
|
||||||
int32 uniformBinding;
|
int32 uniformBinding;
|
||||||
std::string materialName;
|
std::string materialName;
|
||||||
|
// With draw-indirect, we batch vertex data into big vertex buffers
|
||||||
|
// Gfx::PVertexDataManager vertexData;
|
||||||
};
|
};
|
||||||
DEFINE_REF(MaterialAsset)
|
DEFINE_REF(MaterialAsset)
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ VectorParameter::~VectorParameter()
|
|||||||
|
|
||||||
void VectorParameter::updateDescriptorSet(Gfx::PDescriptorSet, uint8* dst)
|
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)
|
TextureParameter::TextureParameter(std::string name, uint32 byteOffset, uint32 binding)
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ struct FloatParameter : public ShaderParameter
|
|||||||
DEFINE_REF(FloatParameter)
|
DEFINE_REF(FloatParameter)
|
||||||
struct VectorParameter : public ShaderParameter
|
struct VectorParameter : public ShaderParameter
|
||||||
{
|
{
|
||||||
Vector data;
|
Math::Vector data;
|
||||||
VectorParameter(std::string name, uint32 byteOffset, uint32 binding);
|
VectorParameter(std::string name, uint32 byteOffset, uint32 binding);
|
||||||
virtual ~VectorParameter();
|
virtual ~VectorParameter();
|
||||||
virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) override;
|
virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) override;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ target_sources(Engine
|
|||||||
PUBLIC
|
PUBLIC
|
||||||
Math.h
|
Math.h
|
||||||
Matrix.h
|
Matrix.h
|
||||||
Vector.h
|
|
||||||
Vector.cpp
|
|
||||||
Transform.h
|
Transform.h
|
||||||
Transform.cpp)
|
Transform.cpp
|
||||||
|
Vector.h
|
||||||
|
Vector.cpp)
|
||||||
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
|
namespace Math
|
||||||
|
{
|
||||||
struct Rect
|
struct Rect
|
||||||
{
|
{
|
||||||
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));
|
return (T)(((uint64_t)ptr + alignment - 1) & ~(alignment - 1));
|
||||||
}
|
}
|
||||||
|
} // namespace Math
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
@@ -5,7 +5,10 @@
|
|||||||
#include <glm/mat4x4.hpp>
|
#include <glm/mat4x4.hpp>
|
||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
|
namespace Math
|
||||||
|
{
|
||||||
typedef glm::mat2 Matrix2;
|
typedef glm::mat2 Matrix2;
|
||||||
typedef glm::mat3 Matrix3;
|
typedef glm::mat3 Matrix3;
|
||||||
typedef glm::mat4 Matrix4;
|
typedef glm::mat4 Matrix4;
|
||||||
|
} // namespace Math
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
#include <glm/gtx/quaternion.hpp>
|
#include <glm/gtx/quaternion.hpp>
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
using namespace Seele::Math;
|
||||||
|
|
||||||
Transform::Transform()
|
Transform::Transform()
|
||||||
: position(Vector4(0, 0, 0, 0)), rotation(Quaternion(1, 0, 0, 0)), scale(Vector4(1, 1, 1, 0))
|
: 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);
|
return (unrotateVector(rotation, v - Vector(position))) * getSafeScaleReciprocal(scale);
|
||||||
}
|
}
|
||||||
Matrix4 Transform::toMatrix()
|
Matrix4 Transform::toMatrix() const
|
||||||
{
|
{
|
||||||
Matrix4 mat;
|
Matrix4 mat;
|
||||||
|
|
||||||
@@ -197,20 +198,26 @@ void Transform::add(Transform *outTransform, const Transform *a, const Transform
|
|||||||
|
|
||||||
Transform &Transform::operator=(const Transform &other)
|
Transform &Transform::operator=(const Transform &other)
|
||||||
{
|
{
|
||||||
|
if(&other != this)
|
||||||
|
{
|
||||||
position = other.position;
|
position = other.position;
|
||||||
rotation = other.rotation;
|
rotation = other.rotation;
|
||||||
scale = other.scale;
|
scale = other.scale;
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Transform &Transform::operator=(Transform &&other)
|
Transform &Transform::operator=(Transform &&other)
|
||||||
{
|
{
|
||||||
|
if(&other != this)
|
||||||
|
{
|
||||||
position = other.position;
|
position = other.position;
|
||||||
rotation = other.rotation;
|
rotation = other.rotation;
|
||||||
scale = other.scale;
|
scale = other.scale;
|
||||||
other.position = Vector4(0, 0, 0, 0);
|
other.position = Vector4(0, 0, 0, 0);
|
||||||
other.rotation = Quaternion(1, 0, 0, 0);
|
other.rotation = Quaternion(1, 0, 0, 0);
|
||||||
other.scale = Vector4(0, 0, 0, 0);
|
other.scale = Vector4(0, 0, 0, 0);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Vector.h"
|
#include "Math/Vector.h"
|
||||||
#include "Matrix.h"
|
#include "Math/Matrix.h"
|
||||||
|
|
||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
|
namespace Math
|
||||||
|
{
|
||||||
class Transform
|
class Transform
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -16,7 +18,7 @@ public:
|
|||||||
Transform(Quaternion rotation, Vector scale);
|
Transform(Quaternion rotation, Vector scale);
|
||||||
~Transform();
|
~Transform();
|
||||||
Vector inverseTransformPosition(const Vector &v) const;
|
Vector inverseTransformPosition(const Vector &v) const;
|
||||||
Matrix4 toMatrix();
|
Matrix4 toMatrix() const;
|
||||||
static Vector getSafeScaleReciprocal(const Vector4 &inScale, float tolerance = 0.000000001f);
|
static Vector getSafeScaleReciprocal(const Vector4 &inScale, float tolerance = 0.000000001f);
|
||||||
Vector transformPosition(const Vector &v) const;
|
Vector transformPosition(const Vector &v) const;
|
||||||
|
|
||||||
@@ -41,4 +43,5 @@ private:
|
|||||||
Quaternion rotation;
|
Quaternion rotation;
|
||||||
Vector4 scale;
|
Vector4 scale;
|
||||||
};
|
};
|
||||||
|
} // namespace Math
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
@@ -1,25 +1,25 @@
|
|||||||
#include "Vector.h"
|
#include "Vector.h"
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
||||||
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 << ")";
|
stream << "(" << vector.x << ", " << vector.y << ")";
|
||||||
return stream;
|
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 << ")";
|
stream << "(" << vector.x << ", " << vector.y << ", " << vector.z << ")";
|
||||||
return stream;
|
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 << ")";
|
stream << "(" << vector.x << ", " << vector.y << ", " << vector.z << ", " << vector.w << ")";
|
||||||
return stream;
|
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
|
//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*\\)");
|
std::regex pattern("float3\\(\\s*([0-9.]+f?)\\s*,\\s*([0-9.]+f?)\\s*,\\s*([0-9.]+f?)\\s*\\)");
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable: 4201)
|
||||||
#include <glm/vec2.hpp>
|
#include <glm/vec2.hpp>
|
||||||
#include <glm/vec3.hpp>
|
#include <glm/vec3.hpp>
|
||||||
#include <glm/vec4.hpp>
|
#include <glm/vec4.hpp>
|
||||||
|
|
||||||
#include <glm/gtc/quaternion.hpp>
|
#include <glm/gtc/quaternion.hpp>
|
||||||
|
#pragma warning(pop)
|
||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
|
namespace Math
|
||||||
|
{
|
||||||
typedef glm::vec2 Vector2;
|
typedef glm::vec2 Vector2;
|
||||||
typedef glm::vec3 Vector;
|
typedef glm::vec3 Vector;
|
||||||
typedef glm::vec4 Vector4;
|
typedef glm::vec4 Vector4;
|
||||||
@@ -95,4 +100,5 @@ static inline Vector toRotator(const Quaternion &other)
|
|||||||
}
|
}
|
||||||
return rotatorFromQuat;
|
return rotatorFromQuat;
|
||||||
}
|
}
|
||||||
|
} // namespace Math
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
@@ -1,61 +1,19 @@
|
|||||||
#include "Actor.h"
|
#include "Actor.h"
|
||||||
#include "Scene/Components/Component.h"
|
|
||||||
#include "Scene/Scene.h"
|
#include "Scene/Scene.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
Actor::Actor()
|
Actor::Actor(PScene scene)
|
||||||
|
: Entity(scene)
|
||||||
{
|
{
|
||||||
|
scene->attachComponent<Component::Transform>(identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
Actor::~Actor()
|
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)
|
void Actor::setParent(PActor newParent)
|
||||||
{
|
{
|
||||||
if(parent != nullptr)
|
if(parent != nullptr)
|
||||||
@@ -68,86 +26,19 @@ void Actor::addChild(PActor child)
|
|||||||
{
|
{
|
||||||
children.add(child);
|
children.add(child);
|
||||||
child->setParent(this);
|
child->setParent(this);
|
||||||
child->notifySceneAttach(owningScene);
|
|
||||||
}
|
}
|
||||||
void Actor::removeChild(PActor child)
|
void Actor::removeChild(PActor child)
|
||||||
{
|
{
|
||||||
children.remove(children.find(child), false);
|
children.remove(children.find(child), false);
|
||||||
child->setParent(nullptr);
|
child->setParent(nullptr);
|
||||||
child->notifySceneAttach(nullptr);
|
|
||||||
}
|
}
|
||||||
//void Actor::setAbsoluteLocation(Vector location)
|
const Component::Transform& Actor::getTransform() const
|
||||||
//{
|
|
||||||
// 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)
|
|
||||||
{
|
{
|
||||||
rootComponent->setRelativeLocation(location);
|
return scene->accessComponent<Component::Transform>(identifier);
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Transform Actor::getTransform() const
|
//Component::Transform& Actor::getTransform()
|
||||||
{
|
//{
|
||||||
return rootComponent->getTransform();
|
// return scene->accessComponent<Component::Transform>(identifier);
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
|||||||
@@ -1,60 +1,31 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "MinimalEngine.h"
|
#include "Entity.h"
|
||||||
#include "Math/Transform.h"
|
#include "Scene/Component/Transform.h"
|
||||||
|
|
||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
DECLARE_REF(Actor)
|
DECLARE_REF(Actor)
|
||||||
DECLARE_REF(Component)
|
// Actors are entities that are part of the scene hierarchy
|
||||||
DECLARE_REF(Scene)
|
// In order for that hierarchy to make sense it requires at least a transform component
|
||||||
class Actor
|
class Actor : public Entity
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Actor();
|
Actor(PScene scene);
|
||||||
virtual ~Actor();
|
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();
|
PActor getParent();
|
||||||
void addChild(PActor child);
|
void addChild(PActor child);
|
||||||
void removeChild(PActor child);
|
void removeChild(PActor child);
|
||||||
Array<PActor> getChildren();
|
Array<PActor> 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
|
// Returns a read-only copy of the actors transform
|
||||||
Transform getTransform() const;
|
const Component::Transform& getTransform() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
//Component::Transform& getTransform();
|
||||||
void setParent(PActor parent);
|
void setParent(PActor parent);
|
||||||
PScene owningScene;
|
|
||||||
PActor parent;
|
PActor parent;
|
||||||
Array<PActor> children;
|
Array<PActor> children;
|
||||||
PComponent rootComponent;
|
|
||||||
};
|
};
|
||||||
DEFINE_REF(Actor)
|
DEFINE_REF(Actor)
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
@@ -3,4 +3,6 @@ target_sources(Engine
|
|||||||
Actor.cpp
|
Actor.cpp
|
||||||
Actor.h
|
Actor.h
|
||||||
CameraActor.cpp
|
CameraActor.cpp
|
||||||
CameraActor.h)
|
CameraActor.h
|
||||||
|
Entity.cpp
|
||||||
|
Entity.h)
|
||||||
@@ -1,21 +1,25 @@
|
|||||||
#include "CameraActor.h"
|
#include "CameraActor.h"
|
||||||
#include "Scene/Components/Component.h"
|
#include "Scene/Scene.h"
|
||||||
#include "Scene/Components/CameraComponent.h"
|
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
CameraActor::CameraActor()
|
CameraActor::CameraActor(PScene scene)
|
||||||
|
: Actor(scene)
|
||||||
{
|
{
|
||||||
sceneComponent = new Component();
|
scene->attachComponent<Component::Camera>(identifier);
|
||||||
setRootComponent(sceneComponent);
|
scene->accessComponent<Component::Transform>(identifier).setRelativeLocation(Math::Vector(10, 5, 14));
|
||||||
|
|
||||||
cameraComponent = new CameraComponent();
|
|
||||||
cameraComponent->fieldOfView = 70.0f;
|
|
||||||
cameraComponent->setParent(sceneComponent);
|
|
||||||
cameraComponent->setOwner(this);
|
|
||||||
sceneComponent->addChildComponent(cameraComponent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CameraActor::~CameraActor()
|
CameraActor::~CameraActor()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component::Camera& CameraActor::getCameraComponent()
|
||||||
|
{
|
||||||
|
return scene->accessComponent<Component::Camera>(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Component::Camera& CameraActor::getCameraComponent() const
|
||||||
|
{
|
||||||
|
return scene->accessComponent<Component::Camera>(identifier);
|
||||||
|
}
|
||||||
@@ -1,21 +1,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Actor.h"
|
#include "Actor.h"
|
||||||
|
#include "Scene/Component/Camera.h"
|
||||||
|
|
||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
DECLARE_REF(CameraComponent)
|
|
||||||
class CameraActor : public Actor
|
class CameraActor : public Actor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CameraActor();
|
CameraActor(PScene scene);
|
||||||
virtual ~CameraActor();
|
virtual ~CameraActor();
|
||||||
PCameraComponent getCameraComponent() const
|
Component::Camera& getCameraComponent();
|
||||||
{
|
const Component::Camera& getCameraComponent() const;
|
||||||
return cameraComponent;
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
PCameraComponent cameraComponent;
|
|
||||||
PComponent sceneComponent; // This will be the root, camera will be the child
|
|
||||||
};
|
};
|
||||||
DEFINE_REF(CameraActor)
|
DEFINE_REF(CameraActor)
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#include "Entity.h"
|
||||||
|
|
||||||
|
using namespace Seele;
|
||||||
|
|
||||||
|
Entity::Entity(PScene scene)
|
||||||
|
: identifier(scene->createEntity())
|
||||||
|
, scene(scene)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Entity::~Entity()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <entt/entt.hpp>
|
||||||
|
#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<typename Component, typename... Args>
|
||||||
|
void attachComponent(Args... args)
|
||||||
|
{
|
||||||
|
scene->attachComponent<Component>(identifier, args...);
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
PScene scene;
|
||||||
|
entt::entity identifier;
|
||||||
|
};
|
||||||
|
DEFINE_REF(Entity)
|
||||||
|
} // namespace Seele
|
||||||
@@ -5,4 +5,5 @@ target_sources(Engine
|
|||||||
Scene.h)
|
Scene.h)
|
||||||
|
|
||||||
add_subdirectory(Actor/)
|
add_subdirectory(Actor/)
|
||||||
add_subdirectory(Components/)
|
add_subdirectory(Component/)
|
||||||
|
add_subdirectory(System/)
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
target_sources(Engine
|
||||||
|
PUBLIC
|
||||||
|
Component.h
|
||||||
|
Camera.h
|
||||||
|
Camera.cpp
|
||||||
|
StaticMesh.h
|
||||||
|
Transform.h
|
||||||
|
Transform.cpp)
|
||||||
+19
-18
@@ -1,13 +1,15 @@
|
|||||||
#include "CameraComponent.h"
|
#include "Camera.h"
|
||||||
#include "Scene/Actor/Actor.h"
|
#include "Scene/Actor/Actor.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
using namespace Seele::Component;
|
||||||
|
using namespace Seele::Math;
|
||||||
|
|
||||||
CameraComponent::CameraComponent()
|
Camera::Camera()
|
||||||
: aspectRatio(0)
|
: aspectRatio(0)
|
||||||
, fieldOfView(0)
|
, fieldOfView(glm::radians(70.f))
|
||||||
, bNeedsViewBuild(true)
|
, bNeedsViewBuild(true)
|
||||||
, bNeedsProjectionBuild(true)
|
, bNeedsProjectionBuild(true)
|
||||||
, viewMatrix(Matrix4())
|
, viewMatrix(Matrix4())
|
||||||
@@ -15,14 +17,13 @@ CameraComponent::CameraComponent()
|
|||||||
{
|
{
|
||||||
yaw = 0;
|
yaw = 0;
|
||||||
pitch = 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;
|
yaw -= deltaYaw / 500.f;
|
||||||
pitch += deltaPitch / 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));
|
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);
|
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;
|
//std::cout << "Result " << Vector(0, 0, 1) * glm::normalize(result) << " cameraDirection: " << cameraDirection << std::endl;
|
||||||
setRelativeRotation(result);
|
getTransform().setRelativeRotation(result);
|
||||||
bNeedsViewBuild = true;
|
bNeedsViewBuild = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraComponent::mouseScroll(float x)
|
void Camera::mouseScroll(float x)
|
||||||
{
|
{
|
||||||
addRelativeLocation(getTransform().getForward()*x);
|
getTransform().addRelativeLocation(getTransform().getForward()*x);
|
||||||
bNeedsViewBuild = true;
|
bNeedsViewBuild = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraComponent::moveX(float amount)
|
void Camera::moveX(float amount)
|
||||||
{
|
{
|
||||||
addRelativeLocation(getTransform().getForward()*amount);
|
getTransform().addRelativeLocation(getTransform().getForward()*amount);
|
||||||
bNeedsViewBuild = true;
|
bNeedsViewBuild = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraComponent::moveY(float amount)
|
void Camera::moveY(float amount)
|
||||||
{
|
{
|
||||||
addRelativeLocation(getTransform().getRight()*amount);
|
getTransform().addRelativeLocation(getTransform().getRight()*amount);
|
||||||
bNeedsViewBuild = true;
|
bNeedsViewBuild = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraComponent::setViewport(Gfx::PViewport newViewport)
|
void Camera::setViewport(Gfx::PViewport newViewport)
|
||||||
{
|
{
|
||||||
viewport = newViewport;
|
viewport = newViewport;
|
||||||
aspectRatio = viewport->getSizeX() / (float)viewport->getSizeY();
|
aspectRatio = viewport->getSizeX() / (float)viewport->getSizeY();
|
||||||
@@ -61,17 +62,17 @@ void CameraComponent::setViewport(Gfx::PViewport newViewport)
|
|||||||
bNeedsProjectionBuild = true;
|
bNeedsProjectionBuild = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraComponent::buildViewMatrix()
|
void Camera::buildViewMatrix()
|
||||||
{
|
{
|
||||||
Vector eyePos = getAbsoluteTransform().getPosition();
|
Vector eyePos = getTransform().getPosition();//getAbsoluteTransform().getPosition();
|
||||||
Vector lookAt = eyePos + glm::normalize(Vector(cos(yaw) * cos(pitch), sin(pitch), sin(yaw) * cos(pitch)));
|
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;
|
//std::cout << "Eye: " << eyePos << " lookAt: " << lookAt << std::endl;
|
||||||
viewMatrix = glm::lookAt(eyePos, lookAt, Vector(0, 1, 0));
|
viewMatrix = glm::lookAt(eyePos, lookAt, Vector(0, 1, 0));
|
||||||
|
|
||||||
bNeedsViewBuild = false;
|
bNeedsViewBuild = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraComponent::buildProjectionMatrix()
|
void Camera::buildProjectionMatrix()
|
||||||
{
|
{
|
||||||
projectionMatrix = glm::perspective(fieldOfView, aspectRatio, 1.0f, 1000.f);
|
projectionMatrix = glm::perspective(fieldOfView, aspectRatio, 1.0f, 1000.f);
|
||||||
static Matrix4 correctionMatrix =
|
static Matrix4 correctionMatrix =
|
||||||
+18
-20
@@ -2,32 +2,30 @@
|
|||||||
#include "Component.h"
|
#include "Component.h"
|
||||||
#include "Math/Matrix.h"
|
#include "Math/Matrix.h"
|
||||||
#include "Graphics/GraphicsResources.h"
|
#include "Graphics/GraphicsResources.h"
|
||||||
|
#include "Transform.h"
|
||||||
|
|
||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
class CameraComponent : public Component
|
namespace Component
|
||||||
{
|
{
|
||||||
public:
|
struct Camera
|
||||||
CameraComponent();
|
{
|
||||||
virtual ~CameraComponent();
|
REQUIRE_COMPONENT(Transform)
|
||||||
|
|
||||||
Matrix4 getViewMatrix()
|
Camera();
|
||||||
|
~Camera();
|
||||||
|
|
||||||
|
Math::Matrix4 getViewMatrix()
|
||||||
{
|
{
|
||||||
if (bNeedsViewBuild)
|
assert (!bNeedsViewBuild);
|
||||||
{
|
|
||||||
buildViewMatrix();
|
|
||||||
}
|
|
||||||
return viewMatrix;
|
return viewMatrix;
|
||||||
}
|
}
|
||||||
Matrix4 getProjectionMatrix()
|
Math::Matrix4 getProjectionMatrix()
|
||||||
{
|
{
|
||||||
if (bNeedsProjectionBuild)
|
assert (!bNeedsProjectionBuild);
|
||||||
{
|
|
||||||
buildProjectionMatrix();
|
|
||||||
}
|
|
||||||
return projectionMatrix;
|
return projectionMatrix;
|
||||||
}
|
}
|
||||||
Vector getCameraPosition()
|
Math::Vector getCameraPosition()
|
||||||
{
|
{
|
||||||
return getTransform().getPosition();
|
return getTransform().getPosition();
|
||||||
}
|
}
|
||||||
@@ -38,19 +36,19 @@ public:
|
|||||||
void moveY(float amount);
|
void moveY(float amount);
|
||||||
float aspectRatio;
|
float aspectRatio;
|
||||||
float fieldOfView;
|
float fieldOfView;
|
||||||
|
void buildViewMatrix();
|
||||||
|
void buildProjectionMatrix();
|
||||||
private:
|
private:
|
||||||
bool bNeedsViewBuild;
|
bool bNeedsViewBuild;
|
||||||
bool bNeedsProjectionBuild;
|
bool bNeedsProjectionBuild;
|
||||||
void buildViewMatrix();
|
|
||||||
void buildProjectionMatrix();
|
|
||||||
|
|
||||||
Gfx::PViewport viewport;
|
Gfx::PViewport viewport;
|
||||||
|
|
||||||
//Transforms relative to actor
|
//Transforms relative to actor
|
||||||
Matrix4 viewMatrix;
|
Math::Matrix4 viewMatrix;
|
||||||
Matrix4 projectionMatrix;
|
Math::Matrix4 projectionMatrix;
|
||||||
float yaw;
|
float yaw;
|
||||||
float pitch;
|
float pitch;
|
||||||
};
|
};
|
||||||
DEFINE_REF(CameraComponent)
|
} // namespace Component
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <concepts>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
namespace Seele
|
||||||
|
{
|
||||||
|
template<typename... Types>
|
||||||
|
struct Dependencies;
|
||||||
|
template<>
|
||||||
|
struct Dependencies<>
|
||||||
|
{};
|
||||||
|
template<typename This, typename... Rest>
|
||||||
|
struct Dependencies<This, Rest...> : public Dependencies<Rest...>
|
||||||
|
{
|
||||||
|
template<typename... Right>
|
||||||
|
Dependencies<This, Rest..., Right...> operator|(const Dependencies<Right...>& other)
|
||||||
|
{
|
||||||
|
return Dependencies<This, Rest..., Right...>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Component
|
||||||
|
{
|
||||||
|
#pragma warning(disable: 4505)
|
||||||
|
template<typename Comp>
|
||||||
|
static int accessComponent(Comp& comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename... Deps>
|
||||||
|
concept is_component = std::same_as<decltype(T::dependencies), Dependencies<Deps...>>;
|
||||||
|
|
||||||
|
#define REQUIRE_COMPONENT(x) \
|
||||||
|
private: \
|
||||||
|
x& get##x() { return *tl_##x; } \
|
||||||
|
const x& get##x() const { return *tl_##x; }; \
|
||||||
|
public: \
|
||||||
|
static Dependencies<x> dependencies;
|
||||||
|
|
||||||
|
#define DECLARE_COMPONENT(x) \
|
||||||
|
thread_local extern x* tl_##x; \
|
||||||
|
template<> \
|
||||||
|
int accessComponent<x>(x& val) { tl_##x = &val; return 0; }
|
||||||
|
|
||||||
|
#define DEFINE_COMPONENT(x) \
|
||||||
|
thread_local x* Seele::Component::tl_##x;
|
||||||
|
|
||||||
|
} // namespace Seele
|
||||||
@@ -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
|
||||||
@@ -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());
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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)
|
|
||||||
@@ -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<PComponent>& 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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<PComponent>& 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<typename ComponentType>
|
|
||||||
RefPtr<ComponentType> getComponent()
|
|
||||||
{
|
|
||||||
return tryFindComponent<ComponentType>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template<typename ComponentType>
|
|
||||||
RefPtr<ComponentType> tryFindComponent()
|
|
||||||
{
|
|
||||||
for(auto child : children)
|
|
||||||
{
|
|
||||||
RefPtr<ComponentType> result = child.cast<ComponentType>();
|
|
||||||
if(result != nullptr)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = parent->tryFindComponent<ComponentType>();
|
|
||||||
if(result != nullptr)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
void propagateTransformUpdate();
|
|
||||||
Transform transform;
|
|
||||||
Transform absoluteTransform;
|
|
||||||
PScene owningScene;
|
|
||||||
PActor owner;
|
|
||||||
PComponent parent;
|
|
||||||
Array<PComponent> children;
|
|
||||||
friend class Actor;
|
|
||||||
};
|
|
||||||
DEFINE_REF(Component)
|
|
||||||
} // namespace Seele
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
#include "MyComponent.h"
|
|
||||||
|
|
||||||
using namespace Seele;
|
|
||||||
|
|
||||||
MyComponent::MyComponent()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void MyComponent::start()
|
|
||||||
{
|
|
||||||
otherComp = getComponent<MyOtherComponent>();
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
@@ -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<PMyOtherComponent> otherComp;
|
|
||||||
Writable<uint32> writable = 0;
|
|
||||||
uint32 notWritable = 10;
|
|
||||||
};
|
|
||||||
DECLARE_REF(MyComponent);
|
|
||||||
} // namespace Seele
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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<uint32> data = Writable<uint32>(0);
|
|
||||||
private:
|
|
||||||
};
|
|
||||||
DEFINE_REF(MyOtherComponent);
|
|
||||||
} // namespace Seele
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
#include "PrimitiveComponent.h"
|
|
||||||
#include "Scene/Scene.h"
|
|
||||||
#include "Material/MaterialAsset.h"
|
|
||||||
#include "Asset/MeshAsset.h"
|
|
||||||
#include "Graphics/VertexShaderInput.h"
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
@@ -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<StaticMeshBatch>& getStaticMeshes()
|
|
||||||
{
|
|
||||||
return staticMeshes;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
std::vector<PMaterialAsset> materials;
|
|
||||||
Gfx::PUniformBuffer uniformBuffer;
|
|
||||||
std::vector<StaticMeshBatch> staticMeshes;
|
|
||||||
friend class Scene;
|
|
||||||
};
|
|
||||||
DEFINE_REF(PrimitiveComponent)
|
|
||||||
struct PrimitiveUniformBuffer
|
|
||||||
{
|
|
||||||
Matrix4 localToWorld;
|
|
||||||
Matrix4 worldToLocal;
|
|
||||||
Vector4 actorWorldPosition;
|
|
||||||
};
|
|
||||||
} // namespace Seele
|
|
||||||
+64
-50
@@ -1,7 +1,8 @@
|
|||||||
#include "Scene.h"
|
#include "Scene.h"
|
||||||
#include "Components/PrimitiveComponent.h"
|
|
||||||
#include "Material/MaterialAsset.h"
|
#include "Material/MaterialAsset.h"
|
||||||
#include "Graphics/Graphics.h"
|
#include "Graphics/Graphics.h"
|
||||||
|
#include "Component/StaticMesh.h"
|
||||||
|
#include "Component/Transform.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
@@ -13,19 +14,6 @@ inline float frand()
|
|||||||
Scene::Scene(Gfx::PGraphics graphics)
|
Scene::Scene(Gfx::PGraphics graphics)
|
||||||
: graphics(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()
|
Scene::~Scene()
|
||||||
@@ -34,23 +22,20 @@ Scene::~Scene()
|
|||||||
|
|
||||||
void Scene::start()
|
void Scene::start()
|
||||||
{
|
{
|
||||||
for(auto actor : rootActors)
|
//for(auto actor : rootActors)
|
||||||
{
|
//{
|
||||||
actor->launchStart();
|
// actor->launchStart();
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64 lastUpdate;
|
static int64 lastUpdate;
|
||||||
static uint64 numUpdates;
|
static uint64 numUpdates;
|
||||||
|
|
||||||
void Scene::beginUpdate(double deltaTime)
|
void Scene::beginUpdate(double)
|
||||||
{
|
{
|
||||||
//std::cout << "Scene::beginUpdate" << std::endl;
|
//std::cout << "Scene::beginUpdate" << std::endl;
|
||||||
auto startTime = std::chrono::high_resolution_clock::now();
|
auto startTime = std::chrono::high_resolution_clock::now();
|
||||||
for(auto actor : rootActors)
|
// TODO
|
||||||
{
|
|
||||||
actor->launchTick(static_cast<float>(deltaTime));
|
|
||||||
}
|
|
||||||
auto endTime = std::chrono::high_resolution_clock::now();
|
auto endTime = std::chrono::high_resolution_clock::now();
|
||||||
int64 delta = std::chrono::duration_cast<std::chrono::microseconds>(endTime - startTime).count();
|
int64 delta = std::chrono::duration_cast<std::chrono::microseconds>(endTime - startTime).count();
|
||||||
lastUpdate += delta;
|
lastUpdate += delta;
|
||||||
@@ -66,38 +51,67 @@ void Scene::beginUpdate(double deltaTime)
|
|||||||
void Scene::commitUpdate()
|
void Scene::commitUpdate()
|
||||||
{
|
{
|
||||||
//std::cout << "Scene::commitUpdate" << std::endl;
|
//std::cout << "Scene::commitUpdate" << std::endl;
|
||||||
for(auto actor : rootActors)
|
//for(auto actor : rootActors)
|
||||||
{
|
//{
|
||||||
actor->launchUpdate();
|
// actor->launchUpdate();
|
||||||
}
|
//}
|
||||||
//std::cout << "Scene::commitUpdate finished waiting" << std::endl;
|
//std::cout << "Scene::commitUpdate finished waiting" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::addActor(PActor actor)
|
Array<StaticMeshBatch> Scene::getStaticMeshes()
|
||||||
{
|
{
|
||||||
rootActors.push_back(actor);
|
Array<StaticMeshBatch> result;
|
||||||
actor->notifySceneAttach(this);
|
auto view = registry.view<Component::StaticMesh, Component::Transform>();
|
||||||
|
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<uint32>(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);
|
LightEnv result;
|
||||||
for(auto& batch : comp->getStaticMeshes())
|
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);
|
||||||
PrimitiveUniformBuffer data;
|
result.directionalLights[0].intensity = Math::Vector4(1.0, 0.9, 0.7, 0.5);\
|
||||||
data.actorWorldPosition = Vector4(comp->getTransform().getPosition(), 1);
|
result.numDirectionalLights = 1;
|
||||||
data.localToWorld = comp->getRenderMatrix();
|
result.numPointLights = 0;
|
||||||
data.worldToLocal = glm::inverse(data.localToWorld);
|
return result;
|
||||||
UniformBufferCreateInfo createInfo;
|
|
||||||
createInfo.resourceData.data = reinterpret_cast<uint8*>(&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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+30
-16
@@ -1,26 +1,26 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <entt/entt.hpp>
|
||||||
#include "MinimalEngine.h"
|
#include "MinimalEngine.h"
|
||||||
#include "Actor/Actor.h"
|
|
||||||
#include "Graphics/GraphicsResources.h"
|
#include "Graphics/GraphicsResources.h"
|
||||||
#include "Components/PrimitiveComponent.h"
|
|
||||||
#include "Graphics/MeshBatch.h"
|
#include "Graphics/MeshBatch.h"
|
||||||
|
|
||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
DECLARE_REF(Material)
|
DECLARE_REF(Material)
|
||||||
|
DECLARE_REF(Entity)
|
||||||
|
|
||||||
struct DirectionalLight
|
struct DirectionalLight
|
||||||
{
|
{
|
||||||
Vector4 color;
|
Math::Vector4 color;
|
||||||
Vector4 direction;
|
Math::Vector4 direction;
|
||||||
Vector4 intensity;
|
Math::Vector4 intensity;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PointLight
|
struct PointLight
|
||||||
{
|
{
|
||||||
Vector4 positionWS;
|
Math::Vector4 positionWS;
|
||||||
//Vector4 positionVS;
|
//Vector4 positionVS;
|
||||||
Vector4 colorRange;
|
Math::Vector4 colorRange;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_DIRECTIONAL_LIGHTS 4
|
#define MAX_DIRECTIONAL_LIGHTS 4
|
||||||
@@ -41,17 +41,31 @@ public:
|
|||||||
void start();
|
void start();
|
||||||
void beginUpdate(double deltaTime);
|
void beginUpdate(double deltaTime);
|
||||||
void commitUpdate();
|
void commitUpdate();
|
||||||
void addActor(PActor actor);
|
entt::entity createEntity()
|
||||||
void addPrimitiveComponent(PPrimitiveComponent comp);
|
{
|
||||||
|
return registry.create();
|
||||||
|
}
|
||||||
|
template<typename Component, typename... Args>
|
||||||
|
Component& attachComponent(entt::entity entity, Args... args)
|
||||||
|
{
|
||||||
|
return registry.emplace<Component>(entity, args...);
|
||||||
|
}
|
||||||
|
template<typename Component>
|
||||||
|
Component& accessComponent(entt::entity entity)
|
||||||
|
{
|
||||||
|
return registry.get<Component>(entity);
|
||||||
|
}
|
||||||
|
template<typename Component>
|
||||||
|
const Component& accessComponent(entt::entity entity) const
|
||||||
|
{
|
||||||
|
return registry.get<Component>(entity);
|
||||||
|
}
|
||||||
|
Array<StaticMeshBatch> getStaticMeshes();
|
||||||
|
LightEnv getLightBuffer() const;
|
||||||
|
|
||||||
const std::vector<PPrimitiveComponent>& getPrimitives() const { return primitives; }
|
entt::registry registry;
|
||||||
const std::vector<StaticMeshBatch>& getStaticMeshes() const { return staticMeshes; }
|
|
||||||
LightEnv& getLightBuffer() { return lightEnv; }
|
|
||||||
private:
|
private:
|
||||||
std::vector<StaticMeshBatch> staticMeshes;
|
|
||||||
std::vector<PActor> rootActors;
|
|
||||||
std::vector<PPrimitiveComponent> primitives;
|
|
||||||
LightEnv lightEnv;
|
|
||||||
Gfx::PGraphics graphics;
|
Gfx::PGraphics graphics;
|
||||||
};
|
};
|
||||||
|
DEFINE_REF(Scene)
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
@@ -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::function<void(float)>>();
|
|
||||||
|
|
||||||
std::scoped_lock lck(frameFinishedLock);
|
|
||||||
pendingLock.unlock();
|
|
||||||
pendingUpdatesSem.release(pendingUpdates.size());
|
|
||||||
frameFinishedCV.wait(lck);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SceneUpdater::work()
|
|
||||||
{
|
|
||||||
while(running.load())
|
|
||||||
{
|
|
||||||
pendingUpdatesSem.acquire();
|
|
||||||
std::function<void(float)> 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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "MinimalEngine.h"
|
|
||||||
#include "Containers/List.h"
|
|
||||||
#include <semaphore>
|
|
||||||
//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<std::thread> workers;
|
|
||||||
std::mutex pendingUpdatesLock;
|
|
||||||
std::counting_semaphore<> pendingUpdatesSem;
|
|
||||||
List<std::function<void(float)>> pendingUpdates;
|
|
||||||
List<std::function<void(float)>> updatesRan;
|
|
||||||
void work();
|
|
||||||
float frameDelta;
|
|
||||||
std::atomic_bool running;
|
|
||||||
std::mutex frameFinishedLock;
|
|
||||||
std::condition_variable frameFinishedCV;
|
|
||||||
};
|
|
||||||
DEFINE_REF(SceneUpdater)
|
|
||||||
} // namespace Seele
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
target_sources(Engine
|
||||||
|
PUBLIC
|
||||||
|
Executor.h
|
||||||
|
Executor.cpp
|
||||||
|
CameraSystem.h
|
||||||
|
CameraSystem.cpp
|
||||||
|
SystemBase.h)
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "SystemBase.h"
|
||||||
|
#include "Scene/Component/Camera.h"
|
||||||
|
|
||||||
|
namespace Seele
|
||||||
|
{
|
||||||
|
namespace System
|
||||||
|
{
|
||||||
|
class CameraSystem : public SystemBase<Component::Camera>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CameraSystem(entt::registry& registry) : SystemBase(registry) {}
|
||||||
|
virtual ~CameraSystem() {}
|
||||||
|
virtual void update(Component::Camera& component);
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
} // namespace System
|
||||||
|
} // namespace Seele
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
#include "Executor.h"
|
||||||
|
|
||||||
|
using namespace Seele;
|
||||||
|
using namespace Seele::System;
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "MinimalEngine.h"
|
||||||
|
#include "SystemBase.h"
|
||||||
|
#include <thread_pool/thread_pool.h>
|
||||||
|
|
||||||
|
namespace Seele
|
||||||
|
{
|
||||||
|
namespace System
|
||||||
|
{
|
||||||
|
class Executor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Executor();
|
||||||
|
~Executor();
|
||||||
|
private:
|
||||||
|
dp::thread_pool<> pool;
|
||||||
|
};
|
||||||
|
} // namespace System
|
||||||
|
} // namespace Seele
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <entt/entt.hpp>
|
||||||
|
#include <thread_pool/thread_pool.h>
|
||||||
|
#include "Scene/Component/Component.h"
|
||||||
|
|
||||||
|
namespace Seele
|
||||||
|
{
|
||||||
|
namespace System
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename... Components>
|
||||||
|
class SystemBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SystemBase(entt::registry& registry) : registry(registry) {}
|
||||||
|
virtual ~SystemBase() {}
|
||||||
|
template<typename Comp>
|
||||||
|
auto getDependencies()
|
||||||
|
{
|
||||||
|
return Comp::dependencies;
|
||||||
|
}
|
||||||
|
template<typename... Dep>
|
||||||
|
auto mergeDependencies(Dep... deps)
|
||||||
|
{
|
||||||
|
return (deps | ...);
|
||||||
|
}
|
||||||
|
template<typename... Deps>
|
||||||
|
void setupView(Dependencies<Deps...>, dp::thread_pool<>&)
|
||||||
|
{
|
||||||
|
registry.view<Components..., Deps...>().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<Components>(),...)), pool);
|
||||||
|
}
|
||||||
|
virtual void update(Components&... components) = 0;
|
||||||
|
private:
|
||||||
|
entt::registry& registry;
|
||||||
|
};
|
||||||
|
} // namespace System
|
||||||
|
} // namespace Seele
|
||||||
@@ -59,12 +59,12 @@ bool Element::isEnabled() const
|
|||||||
return enabled;
|
return enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rect& Element::getBoundingBox()
|
Math::Rect& Element::getBoundingBox()
|
||||||
{
|
{
|
||||||
return boundingBox;
|
return boundingBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Rect Element::getBoundingBox() const
|
const Math::Rect Element::getBoundingBox() const
|
||||||
{
|
{
|
||||||
return boundingBox;
|
return boundingBox;
|
||||||
}
|
}
|
||||||
@@ -23,13 +23,13 @@ public:
|
|||||||
bool isEnabled() const;
|
bool isEnabled() const;
|
||||||
// maybe not the healthiest inteface
|
// maybe not the healthiest inteface
|
||||||
// non-const version
|
// non-const version
|
||||||
Rect& getBoundingBox();
|
Math::Rect& getBoundingBox();
|
||||||
// The bounding box describes the relative size of any Element
|
// The bounding box describes the relative size of any Element
|
||||||
// relative to the total view, meaning a bounding box of (0,0), (1,1)
|
// relative to the total view, meaning a bounding box of (0,0), (1,1)
|
||||||
// would take up the entire view
|
// would take up the entire view
|
||||||
const Rect getBoundingBox() const;
|
const Math::Rect getBoundingBox() const;
|
||||||
protected:
|
protected:
|
||||||
Rect boundingBox;
|
Math::Rect boundingBox;
|
||||||
bool dirty;
|
bool dirty;
|
||||||
|
|
||||||
bool enabled;
|
bool enabled;
|
||||||
|
|||||||
@@ -18,14 +18,14 @@ HorizontalLayout::~HorizontalLayout()
|
|||||||
void HorizontalLayout::apply()
|
void HorizontalLayout::apply()
|
||||||
{
|
{
|
||||||
Array<PElement> children = element->getChildren();
|
Array<PElement> children = element->getChildren();
|
||||||
const Rect parent = element->getBoundingBox();
|
const Math::Rect parent = element->getBoundingBox();
|
||||||
float xOffset = parent.offset.x;
|
float xOffset = parent.offset.x;
|
||||||
float yOffset = parent.offset.y;
|
float yOffset = parent.offset.y;
|
||||||
float xSize = parent.size.x / children.size();
|
float xSize = parent.size.x / children.size();
|
||||||
float ySize = parent.size.y;
|
float ySize = parent.size.y;
|
||||||
for(uint32 index = 0; index < children.size(); ++index)
|
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.x = xOffset + (index * xSize);
|
||||||
child.offset.y = yOffset;
|
child.offset.y = yOffset;
|
||||||
child.size.x = xSize;
|
child.size.x = xSize;
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ namespace UI
|
|||||||
{
|
{
|
||||||
struct RenderElementStyle
|
struct RenderElementStyle
|
||||||
{
|
{
|
||||||
Vector position = Vector(0, 0, 0);
|
Math::Vector position = Math::Vector(0, 0, 0);
|
||||||
uint32 backgroundImageIndex = -1;
|
uint32 backgroundImageIndex = UINT32_MAX;
|
||||||
Vector backgroundColor = Vector(1, 1, 1);
|
Math::Vector backgroundColor = Math::Vector(1, 1, 1);
|
||||||
float opacity = 1.0f;
|
float opacity = 1.0f;
|
||||||
//Vector4 borderBottomColor = Vector4(1, 1, 1, 1);
|
//Vector4 borderBottomColor = Vector4(1, 1, 1, 1);
|
||||||
//Vector4 borderLeftColor = Vector4(1, 1, 1, 1);
|
//Vector4 borderLeftColor = Vector4(1, 1, 1, 1);
|
||||||
@@ -21,7 +21,7 @@ struct RenderElementStyle
|
|||||||
//float borderBottomRightRadius = 0;
|
//float borderBottomRightRadius = 0;
|
||||||
//float borderTopLeftRadius = 0;
|
//float borderTopLeftRadius = 0;
|
||||||
//float borderTopRightRadius = 0;
|
//float borderTopRightRadius = 0;
|
||||||
Vector2 dimensions = Vector2(1, 1);
|
Math::Vector2 dimensions = Math::Vector2(1, 1);
|
||||||
};
|
};
|
||||||
class RenderElement
|
class RenderElement
|
||||||
{
|
{
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user