Merge remote-tracking branch 'origin/master'
This commit is contained in:
Vendored
+1
-2
@@ -10,7 +10,6 @@
|
||||
},
|
||||
"git.ignoreSubmodules": true,
|
||||
"cmake.parallelJobs": 0,
|
||||
"cmake.buildDirectory": "${workspaceFolder}/build",
|
||||
"C_Cpp.files.exclude": {
|
||||
"**/.vs": true,
|
||||
"**/.vscode": true,
|
||||
@@ -23,7 +22,7 @@
|
||||
"lldb.showDisassembly": "auto",
|
||||
"lldb.dereferencePointers": true,
|
||||
"lldb.consoleMode": "commands",
|
||||
"cmake.generator": "Xcode",
|
||||
"cmake.generator": "Ninja",
|
||||
"editor.tabSize": 4,
|
||||
"slang.additionalSearchPaths": [
|
||||
"res/shaders/",
|
||||
|
||||
+3
-15
@@ -23,7 +23,7 @@ set(CMAKE_TOOLCHAIN_FILE ${EXTERNAL_ROOT}/vcpkg/scripts/buildsystems/vcpkg.cmake
|
||||
set(CRCPP_ROOT ${EXTERNAL_ROOT}/CRCpp)
|
||||
set(METAL_ROOT ${EXTERNAL_ROOT}/metal-cpp)
|
||||
if(WIN32)
|
||||
set(VCPKG_BASE_FOLDER ${VCPKG_INSTALLED_DIR}/x64-windows/)
|
||||
set(VCPKG_BASE_FOLDER ${CMAKE_BINARY_DIR}/vcpkg_installed/x64-windows/)
|
||||
elseif(APPLE)
|
||||
set(VCPKG_BASE_FOLDER ${CMAKE_CURRENT_SOURCE_DIR}/build/vcpkg_installed/arm64-osx/)
|
||||
endif()
|
||||
@@ -34,18 +34,6 @@ project (Seele)
|
||||
|
||||
include(cmake/SuperBuild.cmake)
|
||||
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/build)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/build)
|
||||
#Workaround for vs, because it places artifacts into an additional subfolder
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/build)
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/build)
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_CURRENT_SOURCE_DIR}/build)
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_CURRENT_SOURCE_DIR}/build)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/build)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/build)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_CURRENT_SOURCE_DIR}/build)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_CURRENT_SOURCE_DIR}/build)
|
||||
|
||||
find_package(Vulkan REQUIRED)
|
||||
find_package(assimp CONFIG REQUIRED)
|
||||
find_package(Stb REQUIRED)
|
||||
@@ -57,7 +45,7 @@ find_package(glm CONFIG REQUIRED)
|
||||
find_package(Ktx CONFIG REQUIRED)
|
||||
find_package(nlohmann_json CONFIG REQUIRED)
|
||||
find_package(fmt CONFIG REQUIRED)
|
||||
find_package(unofficial-lunasvg CONFIG REQUIRED)
|
||||
find_package(lunasvg CONFIG REQUIRED)
|
||||
find_package(VulkanMemoryAllocator CONFIG REQUIRED)
|
||||
|
||||
if(UNIX)
|
||||
@@ -85,7 +73,7 @@ target_link_libraries(Engine PUBLIC KTX::ktx)
|
||||
target_link_libraries(Engine PUBLIC nlohmann_json::nlohmann_json)
|
||||
target_link_libraries(Engine PUBLIC crcpp)
|
||||
target_link_libraries(Engine PUBLIC fmt::fmt)
|
||||
target_link_libraries(Engine PUBLIC unofficial::lunasvg::lunasvg)
|
||||
target_link_libraries(Engine PUBLIC lunasvg::lunasvg)
|
||||
target_link_libraries(Engine PUBLIC GPUOpen::VulkanMemoryAllocator)
|
||||
if(WIN32)
|
||||
target_link_libraries(Engine PUBLIC ${VCPKG_BASE_FOLDER}/lib/slang.lib)
|
||||
|
||||
+63
-63
@@ -1,65 +1,65 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Debug",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"configurationType": "Debug",
|
||||
"generator": "Ninja",
|
||||
"intelliSenseMode": "windows-msvc-x64",
|
||||
"inheritEnvironments": [ "msvc_x64" ],
|
||||
"cmakeCommandArgs": "-DCMAKE_DEBUG_POSTFIX=\"\" -DCMAKE_PLATFORM=x64",
|
||||
"buildRoot": "${workspaceRoot}/build",
|
||||
"installRoot": "C:/Program Files/Seele"
|
||||
},
|
||||
{
|
||||
"name": "Release",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Release",
|
||||
"buildRoot": "${workspaceRoot}/build",
|
||||
"cmakeCommandArgs": "-DCMAKE_DEBUG_POSTFIX=\"\" -DCMAKE_PLATFORM=x64",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "msvc_x64" ],
|
||||
"intelliSenseMode": "windows-msvc-x64",
|
||||
"installRoot": "C:/Program Files/Seele"
|
||||
},
|
||||
{
|
||||
"name": "RelWithDebInfo",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "RelWithDebInfo",
|
||||
"buildRoot": "${workspaceRoot}/build",
|
||||
"installRoot": "C:/Program Files/Seele",
|
||||
"cmakeCommandArgs": "-DCMAKE_DEBUG_POSTFIX=\"\" -DCMAKE_PLATFORM=x64",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "msvc_x64" ],
|
||||
"intelliSenseMode": "windows-msvc-x64"
|
||||
},
|
||||
{
|
||||
"name": "AddressSanitizer",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"configurationType": "Debug",
|
||||
"generator": "Ninja",
|
||||
"intelliSenseMode": "windows-msvc-x64",
|
||||
"inheritEnvironments": [ "msvc_x64" ],
|
||||
"cmakeCommandArgs": "-DCMAKE_DEBUG_POSTFIX=\"\" -DCMAKE_PLATFORM=x64",
|
||||
"buildRoot": "${workspaceRoot}/build",
|
||||
"installRoot": "C:/Program Files/Seele",
|
||||
"addressSanitizerEnabled": true
|
||||
},
|
||||
{
|
||||
"name": "MinSizeRel",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "MinSizeRel",
|
||||
"buildRoot": "${workspaceRoot}/build",
|
||||
"installRoot": "C:/Program Files/Seele",
|
||||
"cmakeCommandArgs": "-DCMAKE_DEBUG_POSTFIX=\"\" -DCMAKE_PLATFORM=x64",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "msvc_x64" ],
|
||||
"intelliSenseMode": "windows-msvc-x64"
|
||||
}
|
||||
]
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Debug",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"configurationType": "Debug",
|
||||
"generator": "Ninja",
|
||||
"intelliSenseMode": "windows-msvc-x64",
|
||||
"inheritEnvironments": [ "msvc_x64" ],
|
||||
"cmakeCommandArgs": "-DCMAKE_DEBUG_POSTFIX=\"\" -DCMAKE_PLATFORM=x64",
|
||||
"buildRoot": "${workspaceRoot}/build",
|
||||
"installRoot": "C:/Program Files/Seele"
|
||||
},
|
||||
{
|
||||
"name": "Release",
|
||||
"generator": "Ninja Multi-Config",
|
||||
"configurationType": "Release",
|
||||
"buildRoot": "${workspaceRoot}/build/",
|
||||
"cmakeCommandArgs": "-DCMAKE_DEBUG_POSTFIX=\"\" -DCMAKE_PLATFORM=x64",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "msvc_x64" ],
|
||||
"intelliSenseMode": "windows-msvc-x64",
|
||||
"installRoot": "C:/Program Files/Seele"
|
||||
},
|
||||
{
|
||||
"name": "RelWithDebInfo",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "RelWithDebInfo",
|
||||
"buildRoot": "${workspaceRoot}/build",
|
||||
"installRoot": "C:/Program Files/Seele",
|
||||
"cmakeCommandArgs": "-DCMAKE_DEBUG_POSTFIX=\"\" -DCMAKE_PLATFORM=x64",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "msvc_x64" ],
|
||||
"intelliSenseMode": "windows-msvc-x64"
|
||||
},
|
||||
{
|
||||
"name": "AddressSanitizer",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"configurationType": "Debug",
|
||||
"generator": "Ninja Multi-Config",
|
||||
"intelliSenseMode": "windows-msvc-x64",
|
||||
"inheritEnvironments": [ "msvc_x64" ],
|
||||
"cmakeCommandArgs": "-DCMAKE_DEBUG_POSTFIX=\"\" -DCMAKE_PLATFORM=x64",
|
||||
"buildRoot": "${workspaceRoot}/build",
|
||||
"installRoot": "C:/Program Files/Seele",
|
||||
"addressSanitizerEnabled": true
|
||||
},
|
||||
{
|
||||
"name": "MinSizeRel",
|
||||
"generator": "Ninja Multi-Config",
|
||||
"configurationType": "MinSizeRel",
|
||||
"buildRoot": "${workspaceRoot}/build",
|
||||
"installRoot": "C:/Program Files/Seele",
|
||||
"cmakeCommandArgs": "-DCMAKE_DEBUG_POSTFIX=\"\" -DCMAKE_PLATFORM=x64",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "msvc_x64" ],
|
||||
"intelliSenseMode": "windows-msvc-x64"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -146,7 +146,6 @@ Here is the material generated from the above JSON example:
|
||||
```cpp
|
||||
import VERTEX_INPUT_IMPORT;
|
||||
import Material;
|
||||
import BRDF;
|
||||
import MaterialParameter;
|
||||
|
||||
struct Placeholder: IMaterial {
|
||||
|
||||
Vendored
+1
-1
Submodule external/vcpkg updated: ab42fb3032...f9a99aa79c
@@ -30,6 +30,6 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target
|
||||
uint lightIndex = pLightCullingData.lightIndexList[startOffset + i];
|
||||
result += pLightEnv.pointLights[lightIndex].illuminate(lightingParams, brdf);
|
||||
}
|
||||
result += brdf.evaluateAmbient();
|
||||
result += brdf.evaluateAmbient(lightingParams.viewDir_WS);
|
||||
return float4(result, brdf.getAlpha());
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
const static float3 vertices[] = {
|
||||
// Right
|
||||
float3( 1, -1, 1),
|
||||
float3( 1, 1, 1),
|
||||
float3( 1, -1, -1),
|
||||
|
||||
float3( 1, -1, -1),
|
||||
float3( 1, 1, 1),
|
||||
float3( 1, 1, -1),
|
||||
|
||||
// Left
|
||||
float3(-1, -1, -1),
|
||||
float3(-1, 1, -1),
|
||||
float3(-1, -1, 1),
|
||||
|
||||
float3(-1, -1, 1),
|
||||
float3(-1, 1, -1),
|
||||
float3(-1, 1, 1),
|
||||
|
||||
// Bottom
|
||||
float3(-1, 1, 1),
|
||||
float3(-1, 1, -1),
|
||||
float3( 1, 1, 1),
|
||||
|
||||
float3( 1, 1, 1),
|
||||
float3(-1, 1, -1),
|
||||
float3( 1, 1, -1),
|
||||
|
||||
// Top
|
||||
float3(-1, -1, -1),
|
||||
float3(-1, -1, 1),
|
||||
float3( 1, -1, -1),
|
||||
|
||||
float3( 1, -1, -1),
|
||||
float3(-1, -1, 1),
|
||||
float3( 1, -1, 1),
|
||||
|
||||
// Back
|
||||
float3(-1, -1, 1),
|
||||
float3(-1, 1, 1),
|
||||
float3( 1, -1, 1),
|
||||
|
||||
float3( 1, -1, 1),
|
||||
float3(-1, 1, 1),
|
||||
float3( 1, 1, 1),
|
||||
|
||||
// Front
|
||||
float3( 1, -1, -1),
|
||||
float3( 1, 1, -1),
|
||||
float3(-1, -1, -1),
|
||||
|
||||
float3(-1, -1, -1),
|
||||
float3( 1, 1, -1),
|
||||
float3(-1, 1, -1),
|
||||
};
|
||||
|
||||
struct ViewParams
|
||||
{
|
||||
float4x4 view[6];
|
||||
float4x4 projection;
|
||||
Texture2D equirectangularMap;
|
||||
SamplerState sampler;
|
||||
TextureCube cubeMap;
|
||||
};
|
||||
ParameterBlock<ViewParams> pViewParams;
|
||||
struct VertexOutput
|
||||
{
|
||||
float4 svPos : SV_Position;
|
||||
float3 localPos : LOCALPOS;
|
||||
};
|
||||
[shader("vertex")]
|
||||
VertexOutput vertMain(uint vertexIndex : SV_VertexID, uint viewIndex : SV_ViewID)
|
||||
{
|
||||
VertexOutput output;
|
||||
output.localPos = vertices[vertexIndex];
|
||||
output.svPos = mul(pViewParams.projection, mul(pViewParams.view[viewIndex], float4(output.localPos, 1)));
|
||||
return output;
|
||||
}
|
||||
|
||||
const static float2 invAtan = float2(0.1591, 0.3183);
|
||||
float2 sampleSphericalMap(float3 v)
|
||||
{
|
||||
float2 uv = float2(atan2(v.z, v.x), asin(v.y));
|
||||
uv *= invAtan;
|
||||
uv += 0.5;
|
||||
return uv;
|
||||
}
|
||||
|
||||
[shader("pixel")]
|
||||
float4 computeCubemap(float3 localPos : LOCALPOS) : SV_Target
|
||||
{
|
||||
float2 uv = sampleSphericalMap(normalize(localPos));
|
||||
float3 color = pViewParams.equirectangularMap.Sample(pViewParams.sampler, uv).rgb;
|
||||
return float4(color, 1);
|
||||
}
|
||||
|
||||
static const float PI = 3.14159265359;
|
||||
[shader("pixel")]
|
||||
float4 convolveCubemap(float3 localPos : LOCALPOS) : SV_Target
|
||||
{
|
||||
float3 normal = normalize(localPos);
|
||||
|
||||
float3 irradiance = float3(0);
|
||||
|
||||
float3 up = float3(0, 1, 0);
|
||||
float3 right = normalize(cross(up, normal));
|
||||
up = normalize(cross(normal, right));
|
||||
|
||||
float sampleDelta = 0.025;
|
||||
float nrSamples = 0.0f;
|
||||
for(float phi = 0; phi < 2.0 * PI; phi += sampleDelta)
|
||||
{
|
||||
for(float theta = 0; theta < 0.5 * PI; theta += sampleDelta)
|
||||
{
|
||||
float3 tangentSample = float3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));
|
||||
float3 sampleVec = tangentSample.x * right + tangentSample.y * up + tangentSample.z * normal;
|
||||
|
||||
irradiance += pViewParams.cubeMap.Sample(pViewParams.sampler, sampleVec).rgb * cos(theta) * sin(theta);
|
||||
nrSamples++;
|
||||
}
|
||||
}
|
||||
irradiance = PI * irradiance * (1.0 / nrSamples);
|
||||
|
||||
return float4(irradiance, 1);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "Placeholder",
|
||||
"params": {
|
||||
},
|
||||
"code": [
|
||||
{
|
||||
"exp": "BRDF",
|
||||
"profile": "BlinnPhong",
|
||||
"values": {
|
||||
"baseColor": "float3(0, 1, 0)",
|
||||
"normal": "float3(0, 0, 1)"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
+57
-57
@@ -12,66 +12,66 @@ struct SkyboxData
|
||||
};
|
||||
ParameterBlock<SkyboxData> pSkyboxData;
|
||||
|
||||
const static float3 vertices[] = {
|
||||
// Back
|
||||
float3(-512, -512, 512),
|
||||
float3(-512, 512, 512),
|
||||
float3( 512, -512, 512),
|
||||
|
||||
float3( 512, -512, 512),
|
||||
float3(-512, 512, 512),
|
||||
float3( 512, 512, 512),
|
||||
|
||||
// Front
|
||||
float3( 512, -512, -512),
|
||||
float3( 512, 512, -512),
|
||||
float3(-512, -512, -512),
|
||||
|
||||
float3(-512, -512, -512),
|
||||
float3( 512, 512, -512),
|
||||
float3(-512, 512, -512),
|
||||
|
||||
// Top
|
||||
float3(-512, -512, -512),
|
||||
float3(-512, -512, 512),
|
||||
float3( 512, -512, -512),
|
||||
|
||||
float3( 512, -512, -512),
|
||||
float3(-512, -512, 512),
|
||||
float3( 512, -512, 512),
|
||||
|
||||
// Bottom
|
||||
float3(-512, 512, 512),
|
||||
float3(-512, 512, -512),
|
||||
float3( 512, 512, 512),
|
||||
|
||||
float3( 512, 512, 512),
|
||||
float3(-512, 512, -512),
|
||||
float3( 512, 512, -512),
|
||||
|
||||
// Left
|
||||
float3(-512, -512, -512),
|
||||
float3(-512, 512, -512),
|
||||
float3(-512, -512, 512),
|
||||
|
||||
float3(-512, -512, 512),
|
||||
float3(-512, 512, -512),
|
||||
float3(-512, 512, 512),
|
||||
|
||||
// Right
|
||||
float3( 512, -512, 512),
|
||||
float3( 512, 512, 512),
|
||||
float3( 512, -512, -512),
|
||||
|
||||
float3( 512, -512, -512),
|
||||
float3( 512, 512, 512),
|
||||
float3( 512, 512, -512),
|
||||
};
|
||||
|
||||
[shader("vertex")]
|
||||
VertexShaderOutput vertexMain(
|
||||
uint vertexIndex : SV_VertexId)
|
||||
{
|
||||
const float3 vertices[] = {
|
||||
// Back
|
||||
float3(-512, -512, 512),
|
||||
float3(-512, 512, 512),
|
||||
float3( 512, -512, 512),
|
||||
|
||||
float3( 512, -512, 512),
|
||||
float3(-512, 512, 512),
|
||||
float3( 512, 512, 512),
|
||||
|
||||
// Front
|
||||
float3( 512, -512, -512),
|
||||
float3( 512, 512, -512),
|
||||
float3(-512, -512, -512),
|
||||
|
||||
float3(-512, -512, -512),
|
||||
float3( 512, 512, -512),
|
||||
float3(-512, 512, -512),
|
||||
|
||||
// Top
|
||||
float3(-512, -512, -512),
|
||||
float3(-512, -512, 512),
|
||||
float3( 512, -512, -512),
|
||||
|
||||
float3( 512, -512, -512),
|
||||
float3(-512, -512, 512),
|
||||
float3( 512, -512, 512),
|
||||
|
||||
// Bottom
|
||||
float3(-512, 512, 512),
|
||||
float3(-512, 512, -512),
|
||||
float3( 512, 512, 512),
|
||||
|
||||
float3( 512, 512, 512),
|
||||
float3(-512, 512, -512),
|
||||
float3( 512, 512, -512),
|
||||
|
||||
// Left
|
||||
float3(-512, -512, -512),
|
||||
float3(-512, 512, -512),
|
||||
float3(-512, -512, 512),
|
||||
|
||||
float3(-512, -512, 512),
|
||||
float3(-512, 512, -512),
|
||||
float3(-512, 512, 512),
|
||||
|
||||
// Right
|
||||
float3( 512, -512, 512),
|
||||
float3( 512, 512, 512),
|
||||
float3( 512, -512, -512),
|
||||
|
||||
float3( 512, -512, -512),
|
||||
float3( 512, 512, 512),
|
||||
float3( 512, 512, -512),
|
||||
};
|
||||
|
||||
VertexShaderOutput output;
|
||||
float3x3 cameraRotation = float3x3(pViewParams.viewMatrix);
|
||||
float4 worldPos = float4(mul(cameraRotation, vertices[vertexIndex]), 1.0f);
|
||||
@@ -101,5 +101,5 @@ float4 fragmentMain(
|
||||
|
||||
float factor = (output.texCoords.y - lowerLimit) / (upperLimit - lowerLimit);
|
||||
factor = clamp(factor, 0.0, 1.0);
|
||||
return lerp(float4(pSkyboxData.fogBlend.xyz, 1), finalColor, factor) * 100;
|
||||
return lerp(float4(pSkyboxData.fogBlend.xyz, 1), finalColor, factor);
|
||||
}
|
||||
+18
-18
@@ -1,23 +1,5 @@
|
||||
import Common;
|
||||
|
||||
struct GlyphInstanceData
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float width;
|
||||
float height;
|
||||
uint glyphIndex;
|
||||
};
|
||||
|
||||
struct TextData
|
||||
{
|
||||
StructuredBuffer<GlyphInstanceData> glyphs;
|
||||
SamplerState glyphSampler;
|
||||
Texture2D<float> glyphTextures[];
|
||||
};
|
||||
ParameterBlock<TextData> pText;
|
||||
|
||||
struct VertexInput
|
||||
{
|
||||
uint vertexId : SV_VertexID;
|
||||
@@ -31,6 +13,24 @@ struct VertexOutput
|
||||
uint glyphIndex : GLYPHINDEX;
|
||||
};
|
||||
|
||||
struct GlyphInstanceData
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float width;
|
||||
float height;
|
||||
uint glyphIndex;
|
||||
};
|
||||
struct TextData
|
||||
{
|
||||
StructuredBuffer<GlyphInstanceData> glyphs;
|
||||
SamplerState glyphSampler;
|
||||
Texture2D<float> glyphTextures[];
|
||||
};
|
||||
ParameterBlock<TextData> pText;
|
||||
|
||||
|
||||
[shader("vertex")]
|
||||
VertexOutput vertexMain(VertexInput input)
|
||||
{
|
||||
|
||||
@@ -109,7 +109,7 @@ float4 toneMapping(float2 uv : UV) : SV_Target
|
||||
{
|
||||
float3 hdrValue = pToneMappingParams.hdrInputTexture.Sample(pToneMappingParams.hdrSampler, uv).rgb;
|
||||
|
||||
float3 value = agx(hdrValue / 1000);
|
||||
float3 value = agx(hdrValue);
|
||||
value = agxLook(value);
|
||||
value = agxEotf(value);
|
||||
|
||||
|
||||
@@ -1,291 +0,0 @@
|
||||
import Common;
|
||||
|
||||
interface IBRDF
|
||||
{
|
||||
float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor);
|
||||
[mutating] void transformNormal(float3x3 tangentToWorld);
|
||||
float3 getNormal();
|
||||
float3 getBaseColor();
|
||||
float3 evaluateAmbient();
|
||||
float getAlpha();
|
||||
float3 getEmissive();
|
||||
};
|
||||
|
||||
struct Phong : IBRDF
|
||||
{
|
||||
float3 baseColor;
|
||||
float alpha;
|
||||
float3 specular;
|
||||
float3 normal;
|
||||
float3 ambient;
|
||||
float shininess;
|
||||
float3 emissive;
|
||||
|
||||
__init()
|
||||
{
|
||||
baseColor = float3(0, 0, 0);
|
||||
alpha = 1;
|
||||
specular = float3(0, 0, 0);
|
||||
normal = float3(0, 0, 1);
|
||||
ambient = float3(0, 0, 0);
|
||||
shininess = 0;
|
||||
emissive = float3(0, 0, 0);
|
||||
}
|
||||
|
||||
float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor)
|
||||
{
|
||||
float3 normal_WS = normal;
|
||||
float3 nDotL = dot(normal_WS, lightDir_WS);
|
||||
float3 r = 2 * (nDotL) * normal_WS - lightDir_WS;
|
||||
float rDotV = dot(r, viewDir_WS);
|
||||
|
||||
return lightColor * (baseColor * max(nDotL, 0.0)) + specular * pow(max(rDotV, 0.0), max(shininess, 1));
|
||||
}
|
||||
[mutating]
|
||||
void transformNormal(float3x3 tangentToWorld)
|
||||
{
|
||||
normal = normalize(mul(tangentToWorld, normal));
|
||||
}
|
||||
float3 getNormal()
|
||||
{
|
||||
return normal;
|
||||
}
|
||||
float3 getBaseColor()
|
||||
{
|
||||
return baseColor;
|
||||
}
|
||||
float3 evaluateAmbient()
|
||||
{
|
||||
return ambient;
|
||||
}
|
||||
float getAlpha()
|
||||
{
|
||||
return alpha;
|
||||
}
|
||||
float3 getEmissive()
|
||||
{
|
||||
return emissive;
|
||||
}
|
||||
};
|
||||
|
||||
struct BlinnPhong : IBRDF
|
||||
{
|
||||
float3 baseColor;
|
||||
float alpha;
|
||||
float3 specularColor;
|
||||
float3 normal;
|
||||
float shininess;
|
||||
float3 ambient;
|
||||
float3 emissive;
|
||||
|
||||
__init()
|
||||
{
|
||||
baseColor = float3(0, 0, 0);
|
||||
alpha = 1;
|
||||
specularColor = float3(0, 0, 0);
|
||||
normal = float3(0, 0, 1);
|
||||
shininess = 4;
|
||||
ambient = float3(0, 0, 0);
|
||||
emissive = float3(0, 0, 0);
|
||||
}
|
||||
|
||||
float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor)
|
||||
{
|
||||
float3 normal_WS = normal;
|
||||
float diffuse = max(dot(normal_WS, lightDir_WS), 0);
|
||||
float3 h = normalize(lightDir_WS + viewDir_WS);
|
||||
float specular = pow(saturate(dot(normal_WS, h)), shininess);
|
||||
|
||||
return (baseColor * diffuse * lightColor) + (specularColor * specular);
|
||||
}
|
||||
[mutating]
|
||||
void transformNormal(float3x3 tangentToWorld)
|
||||
{
|
||||
normal = normalize(mul(tangentToWorld, normal));
|
||||
}
|
||||
float3 getNormal()
|
||||
{
|
||||
return normal;
|
||||
}
|
||||
float3 getBaseColor()
|
||||
{
|
||||
return baseColor;
|
||||
}
|
||||
float3 evaluateAmbient()
|
||||
{
|
||||
return ambient;
|
||||
}
|
||||
float getAlpha()
|
||||
{
|
||||
return alpha;
|
||||
}
|
||||
float3 getEmissive()
|
||||
{
|
||||
return emissive;
|
||||
}
|
||||
};
|
||||
|
||||
struct CelShading : IBRDF
|
||||
{
|
||||
float3 baseColor;
|
||||
float alpha;
|
||||
float3 normal;
|
||||
float3 emissive;
|
||||
|
||||
__init()
|
||||
{
|
||||
baseColor = float3(0, 0, 0);
|
||||
alpha = 1;
|
||||
normal = float3(0, 0, 1);
|
||||
emissive = float3(0, 0, 0);
|
||||
}
|
||||
float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor)
|
||||
{
|
||||
float3 normal_WS = normal;
|
||||
float nDotL = dot(normal_WS, lightDir_WS);
|
||||
float diffuse = max(nDotL, 0);
|
||||
|
||||
float3 darkenedBase = baseColor * 0.8;
|
||||
if(diffuse > 0.5)
|
||||
{
|
||||
return baseColor * lightColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
return darkenedBase * lightColor;
|
||||
}
|
||||
}
|
||||
[mutating]
|
||||
void transformNormal(float3x3 tangentToWorld)
|
||||
{
|
||||
normal = normalize(mul(tangentToWorld, normal));
|
||||
}
|
||||
float3 getNormal()
|
||||
{
|
||||
return normal;
|
||||
}
|
||||
float3 getBaseColor()
|
||||
{
|
||||
return baseColor;
|
||||
}
|
||||
float3 evaluateAmbient()
|
||||
{
|
||||
return float3(0, 0, 0);
|
||||
}
|
||||
float getAlpha()
|
||||
{
|
||||
return alpha;
|
||||
}
|
||||
float3 getEmissive()
|
||||
{
|
||||
return emissive;
|
||||
}
|
||||
};
|
||||
|
||||
// https://learnopengl.com/PBR/Theory
|
||||
struct CookTorrance : IBRDF
|
||||
{
|
||||
float3 baseColor;
|
||||
float alpha;
|
||||
float3 normal;
|
||||
float roughness;
|
||||
float metallic;
|
||||
float ambientOcclusion;
|
||||
float3 emissive;
|
||||
|
||||
__init()
|
||||
{
|
||||
baseColor = float3(0, 0, 0);
|
||||
alpha = 1;
|
||||
normal = float3(0, 0, 1);
|
||||
roughness = 0;
|
||||
metallic = 0;
|
||||
ambientOcclusion = 1;
|
||||
emissive = float3(0, 0, 0);
|
||||
}
|
||||
|
||||
float TrowbridgeReitzGGX(float3 normal, float3 halfway)
|
||||
{
|
||||
float a_sqr = roughness * roughness;
|
||||
float nDotH = max(dot(normal, halfway), 0.0);
|
||||
float nDotH_sqr = nDotH * nDotH;
|
||||
|
||||
float denom = (nDotH_sqr * (a_sqr - 1.0) + 1.0);
|
||||
|
||||
return a_sqr / (PI * denom * denom);
|
||||
}
|
||||
|
||||
float SchlickGGX(float nDotV, float k)
|
||||
{
|
||||
return nDotV / (nDotV * (1.0 - k) + k);
|
||||
}
|
||||
|
||||
float Smith(float3 normal, float3 view, float3 light)
|
||||
{
|
||||
float k = (roughness + 1);
|
||||
k = (k * k) / 8;
|
||||
float nDotV = max(dot(normal, view), 0.0);
|
||||
float nDotL = max(dot(normal, light), 0.0);
|
||||
float ggx1 = SchlickGGX(nDotV, k);
|
||||
float ggx2 = SchlickGGX(nDotL, k);
|
||||
return ggx1 * ggx2;
|
||||
}
|
||||
|
||||
float3 FresnelSchlick(float cosTheta, float3 F0)
|
||||
{
|
||||
return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);
|
||||
}
|
||||
|
||||
float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor)
|
||||
{
|
||||
float3 n = normal;
|
||||
float3 h = normalize(lightDir_WS + viewDir_WS);
|
||||
|
||||
float3 F0 = float3(0.04);
|
||||
F0 = lerp(F0, baseColor, metallic);
|
||||
|
||||
float3 F = FresnelSchlick(max(dot(h, viewDir_WS), 0.0), F0);
|
||||
|
||||
float NDF = TrowbridgeReitzGGX(n, h);
|
||||
float G = Smith(n, viewDir_WS, lightDir_WS);
|
||||
|
||||
float3 num = NDF * G * F;
|
||||
float denom = 4.0 * max(dot(n, viewDir_WS), 0.0) * max(dot(n, lightDir_WS), 0.0) + 0.000001;
|
||||
float3 specular = num / denom;
|
||||
|
||||
float3 k_s = F;
|
||||
float3 k_d = float3(1.0) - k_s;
|
||||
|
||||
k_d *= 1.0 - metallic;
|
||||
|
||||
float nDotL = max(dot(n, lightDir_WS), 0.0);
|
||||
|
||||
float3 result = (k_d * baseColor / PI + specular) * nDotL * lightColor;
|
||||
return result * ambientOcclusion;
|
||||
}
|
||||
[mutating]
|
||||
void transformNormal(float3x3 tangentToWorld)
|
||||
{
|
||||
normal = normalize(mul(tangentToWorld, normal));
|
||||
}
|
||||
float3 getNormal()
|
||||
{
|
||||
return normal;
|
||||
}
|
||||
float3 getBaseColor()
|
||||
{
|
||||
return baseColor;
|
||||
}
|
||||
float3 evaluateAmbient()
|
||||
{
|
||||
return float3(0.03) * baseColor * ambientOcclusion;
|
||||
}
|
||||
float getAlpha()
|
||||
{
|
||||
return alpha;
|
||||
}
|
||||
float3 getEmissive()
|
||||
{
|
||||
return emissive;
|
||||
}
|
||||
};
|
||||
@@ -1,5 +1,4 @@
|
||||
import Common;
|
||||
import BRDF;
|
||||
import MaterialParameter;
|
||||
|
||||
interface ILightEnv
|
||||
@@ -28,7 +27,7 @@ struct PointLight : ILightEnv
|
||||
{
|
||||
float3 lightDir_WS = position_WS.xyz - params.position_WS;
|
||||
float d = length(lightDir_WS);
|
||||
float illuminance = max(1 - d / colorRange.w, 0);
|
||||
float illuminance = max(1 / (d * d), 0);
|
||||
return illuminance * brdf.evaluate(params.viewDir_WS, normalize(lightDir_WS), colorRange.xyz * position_WS.w);
|
||||
}
|
||||
|
||||
@@ -65,6 +64,312 @@ struct LightEnv
|
||||
uint numDirectionalLights;
|
||||
StructuredBuffer<PointLight> pointLights;
|
||||
uint numPointLights;
|
||||
TextureCube irradianceMap;
|
||||
SamplerState irradianceSampler;
|
||||
};
|
||||
layout(set=3)
|
||||
ParameterBlock<LightEnv> pLightEnv;
|
||||
|
||||
[Differentiable]
|
||||
float polynomial(float a, float b, float c, float x) {
|
||||
return a * x * x + b * x + c;
|
||||
}
|
||||
|
||||
interface IBRDF
|
||||
{
|
||||
float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor);
|
||||
[mutating] void transformNormal(float3x3 tangentToWorld);
|
||||
float3 getNormal();
|
||||
float3 getBaseColor();
|
||||
float3 evaluateAmbient(float3 viewDir_WS);
|
||||
float getAlpha();
|
||||
float3 getEmissive();
|
||||
};
|
||||
|
||||
struct Phong : IBRDF
|
||||
{
|
||||
float3 baseColor;
|
||||
float alpha;
|
||||
float3 specular;
|
||||
float3 normal;
|
||||
float3 ambient;
|
||||
float shininess;
|
||||
float3 emissive;
|
||||
|
||||
__init()
|
||||
{
|
||||
baseColor = float3(0, 0, 0);
|
||||
alpha = 1;
|
||||
specular = float3(0, 0, 0);
|
||||
normal = float3(0, 0, 1);
|
||||
ambient = float3(0, 0, 0);
|
||||
shininess = 0;
|
||||
emissive = float3(0, 0, 0);
|
||||
}
|
||||
|
||||
float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor)
|
||||
{
|
||||
float3 normal_WS = normal;
|
||||
float3 nDotL = dot(normal_WS, lightDir_WS);
|
||||
float3 r = 2 * (nDotL) * normal_WS - lightDir_WS;
|
||||
float rDotV = dot(r, viewDir_WS);
|
||||
|
||||
return lightColor * (baseColor * max(nDotL, 0.0)) + specular * pow(max(rDotV, 0.0), max(shininess, 1));
|
||||
}
|
||||
[mutating]
|
||||
void transformNormal(float3x3 tangentToWorld)
|
||||
{
|
||||
normal = normalize(mul(tangentToWorld, normal));
|
||||
}
|
||||
float3 getNormal()
|
||||
{
|
||||
return normal;
|
||||
}
|
||||
float3 getBaseColor()
|
||||
{
|
||||
return baseColor;
|
||||
}
|
||||
float3 evaluateAmbient(float3 viewDir_WS)
|
||||
{
|
||||
return ambient;
|
||||
}
|
||||
float getAlpha()
|
||||
{
|
||||
return alpha;
|
||||
}
|
||||
float3 getEmissive()
|
||||
{
|
||||
return emissive;
|
||||
}
|
||||
};
|
||||
|
||||
struct BlinnPhong : IBRDF
|
||||
{
|
||||
float3 baseColor;
|
||||
float alpha;
|
||||
float3 specularColor;
|
||||
float3 normal;
|
||||
float shininess;
|
||||
float3 ambient;
|
||||
float3 emissive;
|
||||
|
||||
__init()
|
||||
{
|
||||
baseColor = float3(0, 0, 0);
|
||||
alpha = 1;
|
||||
specularColor = float3(0, 0, 0);
|
||||
normal = float3(0, 0, 1);
|
||||
shininess = 4;
|
||||
ambient = float3(0, 0, 0);
|
||||
emissive = float3(0, 0, 0);
|
||||
}
|
||||
|
||||
float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor)
|
||||
{
|
||||
float3 normal_WS = normal;
|
||||
float diffuse = max(dot(normal_WS, lightDir_WS), 0);
|
||||
float3 h = normalize(lightDir_WS + viewDir_WS);
|
||||
float specular = pow(saturate(dot(normal_WS, h)), shininess);
|
||||
|
||||
return (baseColor * diffuse * lightColor) + (specularColor * specular);
|
||||
}
|
||||
[mutating]
|
||||
void transformNormal(float3x3 tangentToWorld)
|
||||
{
|
||||
normal = normalize(mul(tangentToWorld, normal));
|
||||
}
|
||||
float3 getNormal()
|
||||
{
|
||||
return normal;
|
||||
}
|
||||
float3 getBaseColor()
|
||||
{
|
||||
return baseColor;
|
||||
}
|
||||
float3 evaluateAmbient(float3 viewDir_WS)
|
||||
{
|
||||
return ambient;
|
||||
}
|
||||
float getAlpha()
|
||||
{
|
||||
return alpha;
|
||||
}
|
||||
float3 getEmissive()
|
||||
{
|
||||
return emissive;
|
||||
}
|
||||
};
|
||||
|
||||
struct CelShading : IBRDF
|
||||
{
|
||||
float3 baseColor;
|
||||
float alpha;
|
||||
float3 normal;
|
||||
float3 emissive;
|
||||
|
||||
__init()
|
||||
{
|
||||
baseColor = float3(0, 0, 0);
|
||||
alpha = 1;
|
||||
normal = float3(0, 0, 1);
|
||||
emissive = float3(0, 0, 0);
|
||||
}
|
||||
float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor)
|
||||
{
|
||||
float3 normal_WS = normal;
|
||||
float nDotL = dot(normal_WS, lightDir_WS);
|
||||
float diffuse = max(nDotL, 0);
|
||||
|
||||
float3 darkenedBase = baseColor * 0.8;
|
||||
if(diffuse > 0.5)
|
||||
{
|
||||
return baseColor * lightColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
return darkenedBase * lightColor;
|
||||
}
|
||||
}
|
||||
[mutating]
|
||||
void transformNormal(float3x3 tangentToWorld)
|
||||
{
|
||||
normal = normalize(mul(tangentToWorld, normal));
|
||||
}
|
||||
float3 getNormal()
|
||||
{
|
||||
return normal;
|
||||
}
|
||||
float3 getBaseColor()
|
||||
{
|
||||
return baseColor;
|
||||
}
|
||||
float3 evaluateAmbient(float3 viewDir_WS)
|
||||
{
|
||||
return float3(0, 0, 0);
|
||||
}
|
||||
float getAlpha()
|
||||
{
|
||||
return alpha;
|
||||
}
|
||||
float3 getEmissive()
|
||||
{
|
||||
return emissive;
|
||||
}
|
||||
};
|
||||
|
||||
// https://learnopengl.com/PBR/Theory
|
||||
struct CookTorrance : IBRDF
|
||||
{
|
||||
float3 baseColor;
|
||||
float alpha;
|
||||
float3 normal;
|
||||
float roughness;
|
||||
float metallic;
|
||||
float ambientOcclusion;
|
||||
float3 emissive;
|
||||
|
||||
__init()
|
||||
{
|
||||
baseColor = float3(0, 0, 0);
|
||||
alpha = 1;
|
||||
normal = float3(0, 0, 1);
|
||||
roughness = 0;
|
||||
metallic = 0;
|
||||
ambientOcclusion = 1;
|
||||
emissive = float3(0, 0, 0);
|
||||
}
|
||||
|
||||
float TrowbridgeReitzGGX(float3 normal, float3 halfway)
|
||||
{
|
||||
float a = roughness * roughness;
|
||||
float a2 = a * a;
|
||||
float nDotH = max(dot(normal, halfway), 0.0);
|
||||
float nDotH2 = nDotH * nDotH;
|
||||
|
||||
float nom = a2;
|
||||
float denom = (nDotH * (a2 - 1.0) + 1.0);
|
||||
|
||||
return nom / (PI * denom * denom);
|
||||
}
|
||||
|
||||
float SchlickGGX(float nDotV, float k)
|
||||
{
|
||||
return nDotV / (nDotV * (1.0 - k) + k);
|
||||
}
|
||||
|
||||
float Smith(float3 normal, float3 view, float3 light)
|
||||
{
|
||||
float k = (roughness + 1);
|
||||
k = (k * k) / 8;
|
||||
float nDotV = max(dot(normal, view), 0.0);
|
||||
float nDotL = max(dot(normal, light), 0.0);
|
||||
float ggx1 = SchlickGGX(nDotV, k);
|
||||
float ggx2 = SchlickGGX(nDotL, k);
|
||||
return ggx1 * ggx2;
|
||||
}
|
||||
|
||||
float3 FresnelSchlick(float cosTheta, float3 F0)
|
||||
{
|
||||
return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);
|
||||
}
|
||||
|
||||
float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor)
|
||||
{
|
||||
float3 n = normal;
|
||||
float3 h = normalize(lightDir_WS + viewDir_WS);
|
||||
|
||||
float3 F0 = float3(0.04);
|
||||
F0 = lerp(F0, baseColor, metallic);
|
||||
|
||||
float NDF = TrowbridgeReitzGGX(n, h);
|
||||
float G = Smith(n, viewDir_WS, lightDir_WS);
|
||||
float3 F = FresnelSchlick(max(dot(h, viewDir_WS), 0.0), F0);
|
||||
|
||||
float3 num = NDF * G * F;
|
||||
float denom = 4.0 * max(dot(n, viewDir_WS), 0.0) * max(dot(n, lightDir_WS), 0.0) + 0.000001;
|
||||
float3 specular = num / denom;
|
||||
|
||||
float3 k_s = F;
|
||||
float3 k_d = float3(1.0) - k_s;
|
||||
|
||||
k_d *= 1.0 - metallic;
|
||||
|
||||
float nDotL = max(dot(n, lightDir_WS), 0.0);
|
||||
|
||||
float3 result = (k_d * baseColor / PI + specular) * nDotL * lightColor;
|
||||
return result;
|
||||
}
|
||||
[mutating]
|
||||
void transformNormal(float3x3 tangentToWorld)
|
||||
{
|
||||
normal = normalize(mul(tangentToWorld, normal));
|
||||
}
|
||||
float3 getNormal()
|
||||
{
|
||||
return normal;
|
||||
}
|
||||
float3 getBaseColor()
|
||||
{
|
||||
return baseColor;
|
||||
}
|
||||
float3 evaluateAmbient(float3 viewDir_WS)
|
||||
{
|
||||
float3 F0 = float3(0.04);
|
||||
F0 = lerp(F0, baseColor, metallic);
|
||||
float3 k_s = FresnelSchlick(max(dot(normal, viewDir_WS), 0.0), F0);
|
||||
float3 k_d = 1 - k_s;
|
||||
k_d *= 1 - metallic;
|
||||
float3 irradiance = pLightEnv.irradianceMap.Sample(pLightEnv.irradianceSampler, normal).rgb;
|
||||
float3 diffuse = irradiance * baseColor;
|
||||
return (k_d * diffuse) * ambientOcclusion;
|
||||
}
|
||||
float getAlpha()
|
||||
{
|
||||
return alpha;
|
||||
}
|
||||
float3 getEmissive()
|
||||
{
|
||||
return emissive;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import Common;
|
||||
import BRDF;
|
||||
import MaterialParameter;
|
||||
import Scene;
|
||||
|
||||
|
||||
@@ -16,8 +16,9 @@ struct StaticMeshVertexData
|
||||
#ifndef POS_ONLY
|
||||
//attributes.qTangent = qTangent[index];
|
||||
attributes.normal_MS = float3(normals[index * 3 + 0], normals[index * 3 + 1], normals[index * 3 + 2]);
|
||||
attributes.tangent_MS = float3(tangents[index * 3 + 0], tangents[index * 3 + 1], tangents[index * 3 + 2]);
|
||||
attributes.biTangent_MS = float3(biTangents[index * 3 + 0], biTangents[index * 3 + 1], biTangents[index * 3 + 2]);
|
||||
float4 tangentSign = float4(tangents[index * 4 + 0], tangents[index * 4 + 1], tangents[index * 4 + 2], tangents[index * 4 + 3]);
|
||||
attributes.tangent_MS = tangentSign.xyz;
|
||||
attributes.biTangent_MS = cross(attributes.normal_MS, attributes.tangent_MS) * -tangentSign.w;
|
||||
for(uint i = 0; i < MAX_TEXCOORDS; ++i)
|
||||
{
|
||||
attributes.texCoords[i] = float2(uint16ToFloat(texCoords[i][index * 2 + 0]), uint16ToFloat(texCoords[i][index * 2 + 1]));
|
||||
@@ -27,9 +28,9 @@ struct StaticMeshVertexData
|
||||
return attributes;
|
||||
}
|
||||
StructuredBuffer<float> positions;
|
||||
//StructuredBuffer<float> qTangents;
|
||||
StructuredBuffer<float> normals;
|
||||
StructuredBuffer<float> tangents;
|
||||
StructuredBuffer<float> biTangents;
|
||||
StructuredBuffer<uint16_t> color;
|
||||
StructuredBuffer<uint16_t> texCoords[MAX_TEXCOORDS];
|
||||
};
|
||||
|
||||
@@ -147,7 +147,7 @@ void closestHit(inout RayPayload hitValue, in BuiltInTriangleIntersectionAttribu
|
||||
if (rnd.z >= p) return;
|
||||
}
|
||||
|
||||
hitValue.light += brdf.getEmissive() * hitValue.emissive + brdf.evaluateAmbient();
|
||||
hitValue.light += brdf.getEmissive() * hitValue.emissive + brdf.evaluateAmbient(lightingParams.viewDir_WS);
|
||||
//-- Ideal DIFFUSE reflection
|
||||
//if(bool(useNEE)) {
|
||||
// accrad += nextEventEstimation(accmat, r.d, params.x, params.nl, kt, false, rnd);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import MaterialParameter;
|
||||
import BRDF;
|
||||
|
||||
struct RayTracingParams
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ int main(int, char**) {
|
||||
Array<Vector> texCoords1(mesh->mNumVertices);
|
||||
if (mesh->HasTextureCoords(2))
|
||||
abort();
|
||||
for (int32 i = 0; i < mesh->mNumVertices; ++i) {
|
||||
for (uint32 i = 0; i < mesh->mNumVertices; ++i) {
|
||||
positions[i] = Vector(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z);
|
||||
|
||||
if (mesh->mTextureCoords[0] != nullptr)
|
||||
@@ -65,7 +65,7 @@ int main(int, char**) {
|
||||
return 0.5 * glm::length(glm::cross(p2 - p1, p3 - p1));
|
||||
};
|
||||
Array<Tri> tris(mesh->mNumFaces);
|
||||
for (int32 faceIndex = 0; faceIndex < mesh->mNumFaces; ++faceIndex) {
|
||||
for (uint32 faceIndex = 0; faceIndex < mesh->mNumFaces; ++faceIndex) {
|
||||
tris[faceIndex].p[0] = mesh->mFaces[faceIndex].mIndices[0];
|
||||
tris[faceIndex].p[1] = mesh->mFaces[faceIndex].mIndices[1];
|
||||
tris[faceIndex].p[2] = mesh->mFaces[faceIndex].mIndices[2];
|
||||
@@ -74,7 +74,7 @@ int main(int, char**) {
|
||||
uint32 p0 = tris[i].p[0];
|
||||
uint32 p1 = tris[i].p[1];
|
||||
uint32 p2 = tris[i].p[2];
|
||||
uint32 p3 = positions.size();
|
||||
uint32 p3 = (uint32)positions.size();
|
||||
positions.add(interpolate(positions[p0], positions[p1], positions[p2]));
|
||||
|
||||
if (mesh->mTextureCoords[0] != nullptr)
|
||||
@@ -102,7 +102,7 @@ int main(int, char**) {
|
||||
//for (uint32 i = 0; i < tris.size(); ++i) {
|
||||
// stats << calcArea(tris[i]) << std::endl;
|
||||
//}
|
||||
bool tess = false;
|
||||
//bool tess = false;
|
||||
//while (!tess) {
|
||||
// tess = true;
|
||||
// for (uint32 i = 0; i < tris.size(); ++i) {
|
||||
@@ -143,7 +143,7 @@ int main(int, char**) {
|
||||
mesh->mBitangents = newBit;
|
||||
}
|
||||
|
||||
uint32 numFaces = tris.size();
|
||||
uint32 numFaces = (uint32)tris.size();
|
||||
aiFace* newFaces = new aiFace[numFaces];
|
||||
for (uint32 i = 0; i < numFaces; ++i) {
|
||||
newFaces[i].mNumIndices = 3;
|
||||
@@ -153,10 +153,10 @@ int main(int, char**) {
|
||||
newFaces[i].mIndices[2] = tris[i].p[2];
|
||||
}
|
||||
|
||||
mesh->mNumVertices = positions.size();
|
||||
mesh->mNumVertices = (uint32)positions.size();
|
||||
mesh->mVertices = newPos;
|
||||
mesh->mFaces = newFaces;
|
||||
mesh->mNumFaces = tris.size();
|
||||
mesh->mNumFaces = (uint32)tris.size();
|
||||
}
|
||||
|
||||
Assimp::Exporter exporter;
|
||||
|
||||
@@ -28,7 +28,6 @@ PlayView::PlayView(Gfx::PGraphics graphics, PWindow window, const ViewportCreate
|
||||
"VisibilityMS,"
|
||||
<< std::endl;
|
||||
uint64 start = 0;
|
||||
uint64 prevBegin = 0;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
stats << std::fixed << std::setprecision(0);
|
||||
while (getGlobals().running) {
|
||||
@@ -37,8 +36,8 @@ PlayView::PlayView(Gfx::PGraphics graphics, PWindow window, const ViewportCreate
|
||||
auto baseResults = baseQuery->getResults();
|
||||
auto lightCullResults = lightCullQuery->getResults();
|
||||
auto visiblityResults = visibilityQuery->getResults();
|
||||
int64 renderBegin = renderTimestamp->getResult().time;
|
||||
int64 renderEnd = renderTimestamp->getResult().time;
|
||||
//int64 renderBegin = renderTimestamp->getResult().time;
|
||||
//int64 renderEnd = renderTimestamp->getResult().time;
|
||||
Map<std::string, uint64> results;
|
||||
for (uint32 i = 0; i < 11; ++i) {
|
||||
auto ts = timestamps->getResult();
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "MaterialLoader.h"
|
||||
#include "MeshLoader.h"
|
||||
#include "TextureLoader.h"
|
||||
|
||||
#include "EnvironmentLoader.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
@@ -40,12 +40,21 @@ void AssetImporter::importMaterial(MaterialImportArgs args) {
|
||||
get().materialLoader->importAsset(args);
|
||||
}
|
||||
|
||||
void Seele::AssetImporter::importEnvironmentMap(EnvironmentImportArgs args) {
|
||||
if (get().registry->getOrCreateFolder(args.importPath)->materials.contains(args.filePath.stem().string())) {
|
||||
// skip importing duplicates
|
||||
return;
|
||||
}
|
||||
get().environmentLoader->importAsset(args);
|
||||
}
|
||||
|
||||
void AssetImporter::init(Gfx::PGraphics graphics) {
|
||||
get().registry = AssetRegistry::getInstance();
|
||||
get().meshLoader = new MeshLoader(graphics);
|
||||
get().textureLoader = new TextureLoader(graphics);
|
||||
get().materialLoader = new MaterialLoader(graphics);
|
||||
get().fontLoader = new FontLoader(graphics);
|
||||
get().environmentLoader = new EnvironmentLoader(graphics);
|
||||
}
|
||||
|
||||
AssetImporter& AssetImporter::get() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#include "Asset/AssetRegistry.h"
|
||||
#include "MinimalEngine.h"
|
||||
#include "Asset/AssetRegistry.h"
|
||||
|
||||
|
||||
namespace Seele {
|
||||
@@ -8,12 +8,14 @@ DECLARE_REF(TextureLoader)
|
||||
DECLARE_REF(FontLoader)
|
||||
DECLARE_REF(MeshLoader)
|
||||
DECLARE_REF(MaterialLoader)
|
||||
DECLARE_REF(EnvironmentLoader)
|
||||
class AssetImporter {
|
||||
public:
|
||||
static void importMesh(struct MeshImportArgs args);
|
||||
static void importTexture(struct TextureImportArgs args);
|
||||
static void importFont(struct FontImportArgs args);
|
||||
static void importMaterial(struct MaterialImportArgs args);
|
||||
static void importEnvironmentMap(struct EnvironmentImportArgs args);
|
||||
static void init(Gfx::PGraphics graphics);
|
||||
|
||||
private:
|
||||
@@ -22,6 +24,7 @@ class AssetImporter {
|
||||
UPFontLoader fontLoader;
|
||||
UPMeshLoader meshLoader;
|
||||
UPMaterialLoader materialLoader;
|
||||
UPEnvironmentLoader environmentLoader;
|
||||
AssetRegistry* registry;
|
||||
};
|
||||
} // namespace Seele
|
||||
@@ -2,6 +2,8 @@ target_sources(Editor
|
||||
PRIVATE
|
||||
AssetImporter.h
|
||||
AssetImporter.cpp
|
||||
EnvironmentLoader.h
|
||||
EnvironmentLoader.cpp
|
||||
FontLoader.h
|
||||
FontLoader.cpp
|
||||
MaterialLoader.h
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
#include "EnvironmentLoader.h"
|
||||
#include "Asset/AssetRegistry.h"
|
||||
#include "Asset/EnvironmentMapAsset.h"
|
||||
#include "Graphics/Descriptor.h"
|
||||
#include "stb_image.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
static constexpr uint32 SOURCE_RESOLUTION = 2048;
|
||||
static constexpr uint32 CONVOLUTED_RESOLUTION = 64;
|
||||
|
||||
EnvironmentLoader::EnvironmentLoader(Gfx::PGraphics graphics) : graphics(graphics) {
|
||||
cubeRenderViewport = graphics->createViewport(nullptr, ViewportCreateInfo{
|
||||
.dimensions =
|
||||
{
|
||||
.size = {SOURCE_RESOLUTION, SOURCE_RESOLUTION},
|
||||
.offset = {0, 0},
|
||||
},
|
||||
});
|
||||
convolutionViewport = graphics->createViewport(nullptr, ViewportCreateInfo{
|
||||
.dimensions =
|
||||
{
|
||||
.size = {CONVOLUTED_RESOLUTION, CONVOLUTED_RESOLUTION},
|
||||
.offset = {0, 0},
|
||||
},
|
||||
});
|
||||
cubeSampler = graphics->createSampler({
|
||||
.magFilter = Gfx::SE_FILTER_LINEAR,
|
||||
.minFilter = Gfx::SE_FILTER_LINEAR,
|
||||
.addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||
.addressModeV = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||
.addressModeW = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||
});
|
||||
|
||||
cubeRenderLayout = graphics->createDescriptorLayout("pViewParams");
|
||||
cubeRenderLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "view",
|
||||
.uniformLength = sizeof(Matrix4) * 6,
|
||||
});
|
||||
cubeRenderLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "projection",
|
||||
.uniformLength = sizeof(Matrix4),
|
||||
});
|
||||
cubeRenderLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "equirectangularMap",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
});
|
||||
cubeRenderLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "sampler",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
|
||||
});
|
||||
cubeRenderLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "cubeMap",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
});
|
||||
cubeRenderLayout->create();
|
||||
|
||||
cubePipelineLayout = graphics->createPipelineLayout("CubeRenderLayout");
|
||||
cubePipelineLayout->addDescriptorLayout(cubeRenderLayout);
|
||||
|
||||
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||
.name = "CubeRenderPipeline",
|
||||
.modules = {"EnvironmentMapping"},
|
||||
.entryPoints =
|
||||
{
|
||||
{"vertMain", "EnvironmentMapping"},
|
||||
{"computeCubemap", "EnvironmentMapping"},
|
||||
{"convolveCubemap", "EnvironmentMapping"},
|
||||
},
|
||||
.rootSignature = cubePipelineLayout,
|
||||
});
|
||||
cubePipelineLayout->create();
|
||||
|
||||
cubeRenderVertex = graphics->createVertexShader({0});
|
||||
cubeRenderFrag = graphics->createFragmentShader({1});
|
||||
convolutionFrag = graphics->createFragmentShader({2});
|
||||
}
|
||||
|
||||
EnvironmentLoader::~EnvironmentLoader() {}
|
||||
|
||||
void EnvironmentLoader::importAsset(EnvironmentImportArgs args) {
|
||||
std::filesystem::path assetPath = args.filePath.filename();
|
||||
assetPath.replace_extension("asset");
|
||||
OEnvironmentMapAsset asset = new EnvironmentMapAsset(args.importPath, assetPath.stem().string());
|
||||
asset->setStatus(Asset::Status::Loading);
|
||||
// the registry takes ownership, but we need to edit the reference
|
||||
PEnvironmentMapAsset ref = asset;
|
||||
AssetRegistry::get().registerEnvironmentMap(std::move(asset));
|
||||
import(args, ref);
|
||||
}
|
||||
|
||||
void EnvironmentLoader::import(EnvironmentImportArgs args, PEnvironmentMapAsset asset) {
|
||||
stbi_set_flip_vertically_on_load(true);
|
||||
int width, height, nrComponents;
|
||||
float* data = stbi_loadf(args.filePath.string().c_str(), &width, &height, &nrComponents, 4);
|
||||
stbi_set_flip_vertically_on_load(false);
|
||||
assert(data);
|
||||
Gfx::OTexture2D hdrTexture = graphics->createTexture2D(TextureCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = width * height * 4 * sizeof(float),
|
||||
.data = (uint8*)data,
|
||||
},
|
||||
.format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.width = (uint32)width,
|
||||
.height = (uint32)height,
|
||||
.name = "HDRRaw",
|
||||
});
|
||||
Matrix4 captureProjection = glm::perspective(glm::radians(90.0f), 1.0f, 0.1f, 10.0f);
|
||||
Matrix4 captureViews[] = {
|
||||
glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(1.0f, 0.0f, 0.0f), Vector(0.0f, 1.0f, 0.0f)),
|
||||
glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(-1.0f, 0.0f, 0.0f), Vector(0.0f, 1.0f, 0.0f)),
|
||||
glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, 1.0f, 0.0f), Vector(0.0f, 0.0f, 1.0f)),
|
||||
glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, -1.0f, 0.0f), Vector(0.0f, 0.0f, -1.0f)),
|
||||
glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, 0.0f, 1.0f), Vector(0.0f, 1.0f, 0.0f)),
|
||||
glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, 0.0f, -1.0f), Vector(0.0f, 1.0f, 0.0f)),
|
||||
};
|
||||
Gfx::PDescriptorSet set = cubeRenderLayout->allocateDescriptorSet();
|
||||
set->updateConstants("view", 0, captureViews);
|
||||
set->updateConstants("projection", 0, &captureProjection);
|
||||
set->updateTexture("equirectangularMap", 0, Gfx::PTexture2D(hdrTexture));
|
||||
set->updateSampler("sampler", 0, cubeSampler);
|
||||
set->writeChanges();
|
||||
Gfx::OTextureCube cubeMap = graphics->createTextureCube(TextureCreateInfo{
|
||||
.format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.width = SOURCE_RESOLUTION,
|
||||
.height = SOURCE_RESOLUTION,
|
||||
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_SAMPLED_BIT,
|
||||
});
|
||||
Gfx::ORenderPass cubeRenderPass = graphics->createRenderPass(
|
||||
Gfx::RenderTargetLayout{
|
||||
.colorAttachments = {Gfx::RenderTargetAttachment(cubeMap, Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
||||
Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE)},
|
||||
},
|
||||
{},
|
||||
URect{
|
||||
.size = {SOURCE_RESOLUTION, SOURCE_RESOLUTION},
|
||||
.offset = {0, 0},
|
||||
},
|
||||
"EnvironmentRenderPass", {0b111111}, {0b111111});
|
||||
cubeRenderPipeline = graphics->createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo{
|
||||
.vertexShader = cubeRenderVertex,
|
||||
.fragmentShader = cubeRenderFrag,
|
||||
.renderPass = cubeRenderPass,
|
||||
.pipelineLayout = cubePipelineLayout,
|
||||
.colorBlend =
|
||||
{
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
});
|
||||
graphics->beginRenderPass(cubeRenderPass);
|
||||
Gfx::ORenderCommand renderCommand = graphics->createRenderCommand("CubeMapRender");
|
||||
renderCommand->bindPipeline(cubeRenderPipeline);
|
||||
renderCommand->bindDescriptor({set});
|
||||
renderCommand->setViewport(cubeRenderViewport);
|
||||
renderCommand->draw(36, 1, 0, 0);
|
||||
graphics->executeCommands(std::move(renderCommand));
|
||||
graphics->endRenderPass();
|
||||
|
||||
Gfx::OTextureCube convolutedMap = graphics->createTextureCube(TextureCreateInfo{
|
||||
.format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.width = CONVOLUTED_RESOLUTION,
|
||||
.height = CONVOLUTED_RESOLUTION,
|
||||
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||
});
|
||||
Gfx::ORenderPass convolutionPass = graphics->createRenderPass(
|
||||
Gfx::RenderTargetLayout{
|
||||
.colorAttachments = {Gfx::RenderTargetAttachment(convolutedMap, Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
||||
Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE)},
|
||||
},
|
||||
{},
|
||||
URect{
|
||||
.size = {CONVOLUTED_RESOLUTION, CONVOLUTED_RESOLUTION},
|
||||
.offset = {0, 0},
|
||||
},
|
||||
"EnvironmentRenderPass", {0b111111}, {0b111111});
|
||||
convolutionPipeline = graphics->createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo{
|
||||
.vertexShader = cubeRenderVertex,
|
||||
.fragmentShader = convolutionFrag,
|
||||
.renderPass = convolutionPass,
|
||||
.pipelineLayout = cubePipelineLayout,
|
||||
.colorBlend =
|
||||
{
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
});
|
||||
|
||||
set = cubeRenderLayout->allocateDescriptorSet();
|
||||
set->updateConstants("view", 0, captureViews);
|
||||
set->updateConstants("projection", 0, &captureProjection);
|
||||
set->updateSampler("sampler", 0, cubeSampler);
|
||||
set->updateTexture("cubeMap", 0, Gfx::PTextureCube(cubeMap));
|
||||
set->writeChanges();
|
||||
|
||||
graphics->beginRenderPass(convolutionPass);
|
||||
Gfx::ORenderCommand cmd = graphics->createRenderCommand("ConvolutionPass");
|
||||
cmd->bindPipeline(convolutionPipeline);
|
||||
cmd->bindDescriptor({set});
|
||||
cmd->setViewport(convolutionViewport);
|
||||
cmd->draw(36, 1, 0, 0);
|
||||
graphics->executeCommands(std::move(cmd));
|
||||
graphics->endRenderPass();
|
||||
|
||||
asset->skybox = std::move(cubeMap);
|
||||
asset->irradianceMap = std::move(convolutedMap);
|
||||
asset->specularMap = std::move(cubeMap);
|
||||
graphics->waitDeviceIdle();
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include "MinimalEngine.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/Shader.h"
|
||||
#include <filesystem>
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
DECLARE_REF(EnvironmentMapAsset)
|
||||
struct EnvironmentImportArgs {
|
||||
std::filesystem::path filePath;
|
||||
std::string importPath;
|
||||
};
|
||||
class EnvironmentLoader {
|
||||
public:
|
||||
EnvironmentLoader(Gfx::PGraphics graphic);
|
||||
~EnvironmentLoader();
|
||||
void importAsset(EnvironmentImportArgs args);
|
||||
|
||||
private:
|
||||
void import(EnvironmentImportArgs args, PEnvironmentMapAsset asset);
|
||||
Gfx::PGraphics graphics;
|
||||
Gfx::OVertexShader cubeRenderVertex;
|
||||
Gfx::OFragmentShader cubeRenderFrag;
|
||||
Gfx::ODescriptorLayout cubeRenderLayout;
|
||||
Gfx::OPipelineLayout cubePipelineLayout;
|
||||
Gfx::PGraphicsPipeline cubeRenderPipeline;
|
||||
Gfx::OFragmentShader convolutionFrag;
|
||||
Gfx::PGraphicsPipeline convolutionPipeline;
|
||||
Gfx::OViewport cubeRenderViewport;
|
||||
Gfx::OViewport convolutionViewport;
|
||||
Gfx::OSampler cubeSampler;
|
||||
};
|
||||
}
|
||||
@@ -151,7 +151,7 @@ void MeshLoader::loadMaterials(const aiScene* scene, const Array<PTextureAsset>&
|
||||
uint32 uvIndex = 0;
|
||||
aiTextureMapMode mapMode = aiTextureMapMode_Clamp;
|
||||
float blend = std::numeric_limits<float>::max();
|
||||
aiTextureOp op;
|
||||
aiTextureOp op = aiTextureOp_Add;
|
||||
if (material->GetTexture(type, index, &texPath, &mapping, &uvIndex, nullptr, nullptr, nullptr) != AI_SUCCESS) {
|
||||
std::cout << "fuck" << std::endl;
|
||||
}
|
||||
@@ -488,23 +488,23 @@ Vector4 MeshLoader::encodeQTangent(Matrix3 m) {
|
||||
Vector4 r;
|
||||
if (t > 2.9999999) {
|
||||
r = Vector4(0.0, 0.0, 0.0, 1.0);
|
||||
} else if (t > 0.0000001) {
|
||||
float s = sqrt(1.0 + t) * 2.0;
|
||||
r = Vector4(Vector(m[1][2] - m[2][1], m[2][0] - m[0][2], m[0][1] - m[1][0]) / s, s * 0.25);
|
||||
} else if (t > 0.0000001f) {
|
||||
float s = sqrt(1.0f + t) * 2.0f;
|
||||
r = Vector4(Vector(m[1][2] - m[2][1], m[2][0] - m[0][2], m[0][1] - m[1][0]) / s, s * 0.25f);
|
||||
} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {
|
||||
float s = sqrt(1.0 + (m[0][0] - (m[1][1] + m[2][2]))) * 2.0;
|
||||
float s = sqrt(1.0f + (m[0][0] - (m[1][1] + m[2][2]))) * 2.0;
|
||||
r = Vector4(s * 0.25, Vector(m[1][0] - m[0][1], m[2][0] - m[0][2], m[0][2] - m[2][1]) / s);
|
||||
} else if (m[1][1] > m[2][2]) {
|
||||
float s = sqrt(1.0 + (m[1][1] - (m[0][0] + m[2][2]))) * 2.0;
|
||||
r = Vector4(Vector(m[1][0] + m[0][1], m[2][1] + m[1][2], m[2][0] - m[0][2]) / s, s * 0.25);
|
||||
float s = sqrt(1.0f + (m[1][1] - (m[0][0] + m[2][2]))) * 2.0f;
|
||||
r = Vector4(Vector(m[1][0] + m[0][1], m[2][1] + m[1][2], m[2][0] - m[0][2]) / s, s * 0.25f);
|
||||
r = Vector4(r.x, r.w, r.y, r.z);
|
||||
} else {
|
||||
float s = sqrt(1.0 + (m[2][2] - (m[0][0] + m[1][1]))) * 2.0;
|
||||
r = Vector4(Vector(m[2][0] + m[0][2], m[2][1] + m[1][2], m[0][1] - m[1][0]) / s, s * 0.25);
|
||||
float s = sqrt(1.0f + (m[2][2] - (m[0][0] + m[1][1]))) * 2.0f;
|
||||
r = Vector4(Vector(m[2][0] + m[0][2], m[2][1] + m[1][2], m[0][1] - m[1][0]) / s, s * 0.25f);
|
||||
r = Vector4(r.x, r.y, r.w, r.z);
|
||||
}
|
||||
r = normalize(r);
|
||||
const float threshold = 1.0 / 32767.0;
|
||||
const float threshold = 1.0f / 32767.0f;
|
||||
if (r.w <= threshold) {
|
||||
r = Vector4(Vector(r) * (float)sqrt(1.0 - (threshold * threshold)), (r.w > 0.0) ? threshold : -threshold);
|
||||
}
|
||||
@@ -516,7 +516,7 @@ Vector4 MeshLoader::encodeQTangent(Matrix3 m) {
|
||||
void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterialInstanceAsset>& materials, Array<OMesh>& globalMeshes,
|
||||
Component::Collider& collider) {
|
||||
List<std::function<void()>> work;
|
||||
for (int32 meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex) {
|
||||
for (uint32 meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex) {
|
||||
aiMesh* mesh = scene->mMeshes[meshIndex];
|
||||
if (!(mesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE))
|
||||
continue;
|
||||
@@ -536,12 +536,12 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterialIns
|
||||
}
|
||||
Array<StaticMeshVertexData::NormalType> normals(mesh->mNumVertices);
|
||||
Array<StaticMeshVertexData::TangentType> tangents(mesh->mNumVertices);
|
||||
Array<StaticMeshVertexData::BiTangentType> biTangents(mesh->mNumVertices);
|
||||
//Array<StaticMeshVertexData::BiTangentType> biTangents(mesh->mNumVertices);
|
||||
Array<StaticMeshVertexData::ColorType> colors(mesh->mNumVertices);
|
||||
|
||||
for (int32 i = 0; i < mesh->mNumVertices; ++i) {
|
||||
for (uint32 i = 0; i < mesh->mNumVertices; ++i) {
|
||||
positions[i] = Vector(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z);
|
||||
for (size_t j = 0; j < MAX_TEXCOORDS; ++j) {
|
||||
for (uint32 j = 0; j < MAX_TEXCOORDS; ++j) {
|
||||
if (mesh->HasTextureCoords(j)) {
|
||||
texCoords[j][i] = U16Vector2(mesh->mTextureCoords[j][i].x * 65535, mesh->mTextureCoords[j][i].y * 65535);
|
||||
} else {
|
||||
@@ -555,10 +555,15 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterialIns
|
||||
tangent = Vector(mesh->mTangents[i].x, mesh->mTangents[i].y, mesh->mTangents[i].z);
|
||||
biTangent = Vector(mesh->mBitangents[i].x, mesh->mBitangents[i].y, mesh->mBitangents[i].z);
|
||||
}
|
||||
normals[i] = normal; // encodeQTangent(Matrix3(tangent, biTangent, normal));
|
||||
tangents[i] = tangent;
|
||||
biTangents[i] = biTangent;
|
||||
|
||||
normals[i] = normal; // encodeQTangent(Matrix3(tangent, biTangent, normal));
|
||||
// the fourth component encodes the sign of the bitangent.
|
||||
// in the shader we calc n x t, and b = (n x t) * sign
|
||||
// so we try to cross the two, and see what is the result, and if it is
|
||||
// the same as b, the dot product is 1, and if they are inverse, the dot product is
|
||||
// -1, which is the sign we need
|
||||
tangents[i] = Vector4(tangent, dot(glm::cross(normal, tangent), biTangent));
|
||||
|
||||
if (mesh->HasVertexColors(0)) {
|
||||
colors[i] = StaticMeshVertexData::ColorType(mesh->mColors[0][i].r * 65535, mesh->mColors[0][i].g * 65535, mesh->mColors[0][i].b * 65535);
|
||||
} else {
|
||||
@@ -572,7 +577,7 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterialIns
|
||||
}
|
||||
vertexData->loadNormals(offset, normals);
|
||||
vertexData->loadTangents(offset, tangents);
|
||||
vertexData->loadBitangents(offset, biTangents);
|
||||
//vertexData->loadBitangents(offset, biTangents);
|
||||
vertexData->loadColors(offset, colors);
|
||||
|
||||
Array<uint32> indices(mesh->mNumFaces * 3);
|
||||
|
||||
@@ -42,7 +42,7 @@ void TextureLoader::importAsset(TextureImportArgs args) {
|
||||
PTextureAsset ref = asset;
|
||||
asset->setStatus(Asset::Status::Loading);
|
||||
AssetRegistry::get().registerTexture(std::move(asset));
|
||||
import(args, ref);
|
||||
getThreadPool().runAsync([=]() { import(args, ref); });
|
||||
}
|
||||
|
||||
PTextureAsset TextureLoader::getPlaceholderTexture() { return placeholderAsset; }
|
||||
@@ -67,7 +67,7 @@ void TextureLoader::import(TextureImportArgs args, PTextureAsset textureAsset) {
|
||||
.numLevels = 1,
|
||||
.numLayers = 1,
|
||||
.isArray = false,
|
||||
.generateMipmaps = false,
|
||||
.generateMipmaps = true,
|
||||
};
|
||||
|
||||
if (args.type == TextureImportType::TEXTURE_CUBEMAP) {
|
||||
@@ -110,13 +110,14 @@ void TextureLoader::import(TextureImportArgs args, PTextureAsset textureAsset) {
|
||||
}
|
||||
ktxBasisParams basisParams = {
|
||||
.structSize = sizeof(ktxBasisParams),
|
||||
.uastc = true,
|
||||
.uastc = false,
|
||||
.threadCount = 1,
|
||||
.uastcFlags = KTX_PACK_UASTC_LEVEL_FASTEST,
|
||||
.compressionLevel = KTX_ETC1S_DEFAULT_COMPRESSION_LEVEL,
|
||||
.uastcFlags = KTX_PACK_UASTC_LEVEL_DEFAULT,
|
||||
.uastcRDO = true,
|
||||
};
|
||||
// KTX_ASSERT(ktxTexture2_CompressBasisEx(kTexture, &basisParams));
|
||||
// KTX_ASSERT(ktxTexture2_DeflateZstd(kTexture, 20));
|
||||
KTX_ASSERT(ktxTexture2_CompressBasisEx(kTexture, &basisParams));
|
||||
//KTX_ASSERT(ktxTexture2_DeflateZstd(kTexture, 10));
|
||||
|
||||
char writer[100];
|
||||
snprintf(writer, sizeof(writer), "%s version %s", "SeeleEngine", "0.0.1");
|
||||
@@ -148,4 +149,5 @@ void TextureLoader::import(TextureImportArgs args, PTextureAsset textureAsset) {
|
||||
AssetRegistry::saveAsset(textureAsset, TextureAsset::IDENTIFIER, textureAsset->getFolderPath(), textureAsset->getName());
|
||||
|
||||
textureAsset->setStatus(Asset::Status::Ready);
|
||||
std::cout << "Done importing " << textureAsset->getName() << std::endl;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ void InspectorView::prepareRender() {}
|
||||
|
||||
void InspectorView::render() { renderGraph.render(Component::Camera()); }
|
||||
|
||||
void InspectorView::applyArea(URect area) {}
|
||||
void InspectorView::applyArea(URect ) {}
|
||||
|
||||
void InspectorView::keyCallback(KeyCode, InputAction, KeyModifier) {}
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ void PlayView::keyCallback(KeyCode code, InputAction action, KeyModifier modifie
|
||||
if (code == KeyCode::KEY_R && action == InputAction::RELEASE) {
|
||||
getGlobals().useRayTracing = !getGlobals().useRayTracing;
|
||||
}
|
||||
//if (code == KeyCode::KEY_B && action == InputAction::RELEASE && modifier & KeyModifier::MOD_CONTROL) {
|
||||
//}
|
||||
if (code == KeyCode::KEY_H && action == InputAction::RELEASE) {
|
||||
MemoryManager::printAllocations();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ ViewportControl::ViewportControl(const URect& viewportDimensions, Vector initial
|
||||
|
||||
ViewportControl::~ViewportControl() {}
|
||||
|
||||
void ViewportControl::update(Component::Camera& camera, float deltaTime) {
|
||||
void ViewportControl::update(Component::Camera&, float deltaTime) {
|
||||
float cameraMove = deltaTime * 20;
|
||||
if (keys[KeyCode::KEY_LEFT_SHIFT]) {
|
||||
cameraMove *= 4;
|
||||
|
||||
+20
-95
@@ -4,6 +4,7 @@
|
||||
#include "Asset/MaterialLoader.h"
|
||||
#include "Asset/MeshLoader.h"
|
||||
#include "Asset/TextureLoader.h"
|
||||
#include "Asset/EnvironmentLoader.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#ifdef __APPLE__
|
||||
#include "Graphics/Metal/Graphics.h"
|
||||
@@ -23,54 +24,11 @@ using namespace Seele::Editor;
|
||||
// make it global so it gets deleted last and automatically
|
||||
static Gfx::OGraphics graphics;
|
||||
|
||||
struct Halfedge {
|
||||
uint32 vertexID;
|
||||
uint32 nextID;
|
||||
uint32 prevID;
|
||||
uint32 twinID;
|
||||
};
|
||||
Array<Halfedge> generateEdges() {
|
||||
Array<UVector> indices = {UVector(0, 1, 4), UVector(4, 1, 5), UVector(1, 2, 5), UVector(5, 2, 6), UVector(2, 3, 6),
|
||||
UVector(6, 3, 7), UVector(4, 5, 8), UVector(8, 5, 9), UVector(5, 6, 9), UVector(9, 6, 10),
|
||||
UVector(6, 7, 10), UVector(10, 7, 11), UVector(8, 9, 12), UVector(12, 9, 13), UVector(9, 10, 13),
|
||||
UVector(13, 10, 14), UVector(10, 11, 14), UVector(14, 11, 15)};
|
||||
Array<Halfedge> edges;
|
||||
for (auto ind : indices) {
|
||||
uint32 baseIndex = edges.size();
|
||||
edges.add(Halfedge{ind.x, baseIndex + 1, baseIndex + 2, UINT32_MAX});
|
||||
edges.add(Halfedge{ind.y, baseIndex + 2, baseIndex, UINT32_MAX});
|
||||
edges.add(Halfedge{ind.z, baseIndex, baseIndex + 1, UINT32_MAX});
|
||||
}
|
||||
for (uint32 i = 0; i < edges.size(); ++i) {
|
||||
if (edges[i].twinID == UINT32_MAX) {
|
||||
for (uint32 j = 0; j < edges.size(); ++j) {
|
||||
if (edges[i].vertexID == edges[edges[j].nextID].vertexID && edges[edges[i].nextID].vertexID == edges[j].vertexID) {
|
||||
edges[i].twinID = j;
|
||||
edges[j].twinID = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return edges;
|
||||
}
|
||||
|
||||
Array<uint32> generateArray() { return Array<uint32>(); }
|
||||
|
||||
int main() {
|
||||
std::string gameName = "MeshShadingDemo";
|
||||
#ifdef WIN32
|
||||
std::filesystem::path outputPath = "C:/Users/Dynamitos/MeshShadingDemoGame";
|
||||
std::filesystem::path sourcePath = "C:/Users/Dynamitos/MeshShadingDemo";
|
||||
std::filesystem::path binaryPath = sourcePath / "bin" / "MeshShadingDemo.dll";
|
||||
#elif __APPLE__
|
||||
std::filesystem::path outputPath = "/Users/dynamitos/MeshShadingDemoGame";
|
||||
std::filesystem::path sourcePath = "/Users/dynamitos/MeshShadingDemo";
|
||||
std::filesystem::path binaryPath = sourcePath / "cmake" / "libMeshShadingDemo.dylib";
|
||||
#else
|
||||
std::filesystem::path outputPath = "/home/dynamitos/MeshShadingDemoGame";
|
||||
std::filesystem::path sourcePath = "/home/dynamitos/MeshShadingDemo";
|
||||
std::filesystem::path binaryPath = sourcePath / "cmake" / "libMeshShadingDemo.so";
|
||||
#endif
|
||||
std::string gameName = "MinecraftClone";
|
||||
std::filesystem::path outputPath = fmt::format("../../{0}Game", gameName);
|
||||
std::filesystem::path sourcePath = fmt::format("../../{0}", gameName);
|
||||
std::filesystem::path binaryPath = sourcePath / "bin" / fmt::format("{0}.dll", gameName);
|
||||
std::filesystem::path cmakePath = outputPath / "cmake";
|
||||
if (true) {
|
||||
#ifdef __APPLE__
|
||||
@@ -89,45 +47,12 @@ int main() {
|
||||
AssetImporter::importFont(FontImportArgs{
|
||||
.filePath = "./fonts/arial.ttf",
|
||||
});
|
||||
AssetImporter::importMesh(MeshImportArgs{
|
||||
.filePath = sourcePath / "import/models/cube.fbx",
|
||||
AssetImporter::importEnvironmentMap(EnvironmentImportArgs{
|
||||
.filePath = sourcePath / "import" / "textures" / "newport_loft.hdr",
|
||||
});
|
||||
// AssetImporter::importMesh(MeshImportArgs{
|
||||
// .filePath = sourcePath / "import/models/culling.fbx",
|
||||
//});
|
||||
AssetImporter::importTexture(TextureImportArgs{
|
||||
.filePath = sourcePath / "import/textures/skybox.jpg",
|
||||
.type = TextureImportType::TEXTURE_CUBEMAP,
|
||||
});
|
||||
// AssetImporter::importMesh(MeshImportArgs{
|
||||
// .filePath = sourcePath / "import/models/ship.fbx",
|
||||
// .importPath = "ship",
|
||||
// });
|
||||
// AssetImporter::importTexture(TextureImportArgs{
|
||||
// .filePath = sourcePath / "import/textures/azeroth.png",
|
||||
//});
|
||||
// AssetImporter::importTexture(TextureImportArgs{
|
||||
// .filePath = sourcePath / "import/textures/azeroth_height.png",
|
||||
//});
|
||||
// AssetImporter::importTexture(TextureImportArgs{
|
||||
// .filePath = sourcePath / "import/textures/wgen.png",
|
||||
//});
|
||||
AssetImporter::importMesh(MeshImportArgs{
|
||||
.filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.glb",
|
||||
.importPath = "Whitechapel",
|
||||
});
|
||||
//AssetImporter::importMesh(MeshImportArgs{
|
||||
// .filePath = sourcePath / "import/models/box.glb",
|
||||
// .importPath = "",
|
||||
//});
|
||||
AssetImporter::importMesh(MeshImportArgs{
|
||||
.filePath = sourcePath / "import/models/rttest.glb",
|
||||
.importPath = "",
|
||||
});
|
||||
//AssetImporter::importMesh(MeshImportArgs{
|
||||
// .filePath = sourcePath / "import/models/town_hall.glb",
|
||||
// .importPath = "",
|
||||
//});
|
||||
AssetImporter::importTexture(TextureImportArgs{.filePath = sourcePath / "import" / "texture" / "Dirt.png", .importPath = ""});
|
||||
|
||||
|
||||
getThreadPool().waitIdle();
|
||||
vd->commitMeshes();
|
||||
WindowCreateInfo mainWindowInfo = {
|
||||
@@ -146,16 +71,16 @@ int main() {
|
||||
};
|
||||
OGameView sceneView = new Editor::PlayView(graphics, window, sceneViewInfo, binaryPath.generic_string());
|
||||
sceneView->setFocused();
|
||||
//OInspectorView inspectorView = new Editor::InspectorView(graphics, window,
|
||||
// ViewportCreateInfo{
|
||||
// .dimensions =
|
||||
// {
|
||||
// .size = {1920, 1080},
|
||||
// .offset = {0, 0},
|
||||
// },
|
||||
// .fieldOfView = 0,
|
||||
// .numSamples = Gfx::SE_SAMPLE_COUNT_1_BIT,
|
||||
// });
|
||||
// OInspectorView inspectorView = new Editor::InspectorView(graphics, window,
|
||||
// ViewportCreateInfo{
|
||||
// .dimensions =
|
||||
// {
|
||||
// .size = {1920, 1080},
|
||||
// .offset = {0, 0},
|
||||
// },
|
||||
// .fieldOfView = 0,
|
||||
// .numSamples = Gfx::SE_SAMPLE_COUNT_1_BIT,
|
||||
// });
|
||||
//
|
||||
window->show();
|
||||
while (windowManager->isActive() && getGlobals().running) {
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
#include "AssetRegistry.h"
|
||||
#include "Asset/FontAsset.h"
|
||||
#include "Asset/MaterialAsset.h"
|
||||
#include "Asset/MaterialInstanceAsset.h"
|
||||
#include "Asset/MeshAsset.h"
|
||||
#include "Asset/EnvironmentMapAsset.h"
|
||||
#include "Asset/SVGAsset.h"
|
||||
#include "Asset/TextureAsset.h"
|
||||
#include "FontAsset.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/Mesh.h"
|
||||
#include "MaterialAsset.h"
|
||||
#include "MaterialInstanceAsset.h"
|
||||
#include "MeshAsset.h"
|
||||
#include "SVGAsset.h"
|
||||
#include "TextureAsset.h"
|
||||
#include "Window/WindowManager.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
@@ -56,6 +58,15 @@ PSVGAsset AssetRegistry::findSVG(std::string_view folderPath, std::string_view f
|
||||
return folder->svgs.at(std::string(filePath));
|
||||
}
|
||||
|
||||
PEnvironmentMapAsset AssetRegistry::findEnvironmentMap(std::string_view folderPath, std::string_view filePath) {
|
||||
std::unique_lock l(get().assetLock);
|
||||
AssetFolder* folder = get().assetRoot;
|
||||
if (!folderPath.empty()) {
|
||||
folder = get().getOrCreateFolder(folderPath);
|
||||
}
|
||||
return folder->envs.at(std::string(filePath));
|
||||
}
|
||||
|
||||
PMaterialAsset AssetRegistry::findMaterial(std::string_view folderPath, std::string_view filePath) {
|
||||
std::unique_lock l(get().assetLock);
|
||||
AssetFolder* folder = get().assetRoot;
|
||||
@@ -94,6 +105,11 @@ void AssetRegistry::registerSVG(OSVGAsset svg) {
|
||||
get().registerSVGInternal(std::move(svg));
|
||||
}
|
||||
|
||||
void AssetRegistry::registerEnvironmentMap(OEnvironmentMapAsset env) {
|
||||
std::unique_lock l(get().assetLock);
|
||||
get().registerEnvironmentMapInternal(std::move(env));
|
||||
}
|
||||
|
||||
void AssetRegistry::registerMaterial(OMaterialAsset material) {
|
||||
std::unique_lock l(get().assetLock);
|
||||
get().registerMaterialInternal(std::move(material));
|
||||
@@ -146,6 +162,9 @@ void AssetRegistry::loadAsset(ArchiveBuffer& buffer) {
|
||||
case SVGAsset::IDENTIFIER:
|
||||
asset = PSVGAsset(folder->svgs.at(name));
|
||||
break;
|
||||
case EnvironmentMapAsset::IDENTIFIER:
|
||||
asset = PEnvironmentMapAsset(folder->envs.at(name));
|
||||
break;
|
||||
default:
|
||||
throw new std::logic_error("Unknown Identifier");
|
||||
}
|
||||
@@ -176,13 +195,9 @@ AssetRegistry::AssetRegistry() : assetRoot(nullptr) {}
|
||||
|
||||
AssetRegistry* AssetRegistry::getInstance() { return _instance; }
|
||||
|
||||
void AssetRegistry::loadRegistry() {
|
||||
get().loadRegistryInternal();
|
||||
}
|
||||
void AssetRegistry::loadRegistry() { get().loadRegistryInternal(); }
|
||||
|
||||
void AssetRegistry::saveRegistry() {
|
||||
get().saveRegistryInternal();
|
||||
}
|
||||
void AssetRegistry::saveRegistry() { get().saveRegistryInternal(); }
|
||||
|
||||
AssetRegistry::AssetFolder* AssetRegistry::getOrCreateFolder(std::string_view fullPath) {
|
||||
AssetFolder* result = assetRoot;
|
||||
@@ -209,11 +224,19 @@ void AssetRegistry::initialize(const std::filesystem::path& _rootFolder, Gfx::PG
|
||||
this->graphics = _graphics;
|
||||
this->rootFolder = _rootFolder;
|
||||
this->assetRoot = new AssetFolder("");
|
||||
if (!std::filesystem::exists(rootFolder))
|
||||
{
|
||||
std::filesystem::create_directories(rootFolder);
|
||||
}
|
||||
else if (!std::filesystem::is_directory(rootFolder))
|
||||
{
|
||||
throw std::logic_error("Asset Folder is not a directory!!");
|
||||
}
|
||||
loadRegistryInternal();
|
||||
}
|
||||
|
||||
void AssetRegistry::loadRegistryInternal() {
|
||||
Array<Pair<PAsset, ArchiveBuffer>> peeked;
|
||||
Array<Pair<PAsset, ArchiveBuffer>> peeked;
|
||||
{
|
||||
std::unique_lock l(get().assetLock);
|
||||
peeked = peekFolder(assetRoot);
|
||||
@@ -295,13 +318,16 @@ Pair<PAsset, ArchiveBuffer> AssetRegistry::peekAsset(ArchiveBuffer& buffer) {
|
||||
folder->svgs[name] = new SVGAsset(folderPath, name);
|
||||
asset = PSVGAsset(folder->svgs[name]);
|
||||
break;
|
||||
case EnvironmentMapAsset::IDENTIFIER:
|
||||
folder->envs[name] = new EnvironmentMapAsset(folderPath, name);
|
||||
asset = PEnvironmentMapAsset(folder->envs[name]);
|
||||
break;
|
||||
default:
|
||||
throw new std::logic_error("Unknown Identifier");
|
||||
}
|
||||
return {asset, std::move(buffer)};
|
||||
}
|
||||
|
||||
|
||||
void AssetRegistry::saveRegistryInternal() { saveFolder("", assetRoot); }
|
||||
|
||||
void AssetRegistry::saveFolder(const std::filesystem::path& folderPath, AssetFolder* folder) {
|
||||
@@ -324,6 +350,9 @@ void AssetRegistry::saveFolder(const std::filesystem::path& folderPath, AssetFol
|
||||
for (const auto& [name, svg] : folder->svgs) {
|
||||
saveAsset(PSVGAsset(svg), SVGAsset::IDENTIFIER, folderPath, name);
|
||||
}
|
||||
for (const auto& [name, env] : folder->envs) {
|
||||
saveAsset(PEnvironmentMapAsset(env), EnvironmentMapAsset::IDENTIFIER, folderPath, name);
|
||||
}
|
||||
for (auto& [name, child] : folder->children) {
|
||||
saveFolder(folderPath / name, child);
|
||||
}
|
||||
@@ -351,6 +380,11 @@ void AssetRegistry::registerSVGInternal(OSVGAsset svg) {
|
||||
folder->svgs[svg->getName()] = std::move(svg);
|
||||
}
|
||||
|
||||
void AssetRegistry::registerEnvironmentMapInternal(OEnvironmentMapAsset env) {
|
||||
AssetFolder* folder = getOrCreateFolder(env->getFolderPath());
|
||||
folder->envs[env->getName()] = std::move(env);
|
||||
}
|
||||
|
||||
void AssetRegistry::registerMaterialInternal(OMaterialAsset material) {
|
||||
AssetFolder* folder = getOrCreateFolder(material->getFolderPath());
|
||||
folder->materials[material->getName()] = std::move(material);
|
||||
|
||||
@@ -12,6 +12,7 @@ DECLARE_REF(TextureAsset)
|
||||
DECLARE_REF(FontAsset)
|
||||
DECLARE_REF(SVGAsset)
|
||||
DECLARE_REF(MeshAsset)
|
||||
DECLARE_REF(EnvironmentMapAsset)
|
||||
DECLARE_REF(MaterialAsset)
|
||||
DECLARE_REF(MaterialInstanceAsset)
|
||||
DECLARE_NAME_REF(Gfx, Graphics)
|
||||
@@ -26,6 +27,7 @@ class AssetRegistry {
|
||||
static PTextureAsset findTexture(std::string_view folderPath, std::string_view filePath);
|
||||
static PFontAsset findFont(std::string_view folderPath, std::string_view name);
|
||||
static PSVGAsset findSVG(std::string_view folderPath, std::string_view name);
|
||||
static PEnvironmentMapAsset findEnvironmentMap(std::string_view folder, std::string_view name);
|
||||
static PMaterialAsset findMaterial(std::string_view folderPath, std::string_view filePath);
|
||||
static PMaterialInstanceAsset findMaterialInstance(std::string_view folderPath, std::string_view filePath);
|
||||
|
||||
@@ -33,6 +35,7 @@ class AssetRegistry {
|
||||
static void registerTexture(OTextureAsset texture);
|
||||
static void registerFont(OFontAsset font);
|
||||
static void registerSVG(OSVGAsset svg);
|
||||
static void registerEnvironmentMap(OEnvironmentMapAsset env);
|
||||
static void registerMaterial(OMaterialAsset material);
|
||||
static void registerMaterialInstance(OMaterialInstanceAsset instance);
|
||||
|
||||
@@ -52,6 +55,7 @@ class AssetRegistry {
|
||||
Map<std::string, OTextureAsset> textures;
|
||||
Map<std::string, OFontAsset> fonts;
|
||||
Map<std::string, OSVGAsset> svgs;
|
||||
Map<std::string, OEnvironmentMapAsset> envs;
|
||||
Map<std::string, OMeshAsset> meshes;
|
||||
Map<std::string, OMaterialAsset> materials;
|
||||
Map<std::string, OMaterialInstanceAsset> instances;
|
||||
@@ -75,6 +79,7 @@ class AssetRegistry {
|
||||
void registerTextureInternal(OTextureAsset texture);
|
||||
void registerFontInternal(OFontAsset font);
|
||||
void registerSVGInternal(OSVGAsset svg);
|
||||
void registerEnvironmentMapInternal(OEnvironmentMapAsset env);
|
||||
void registerMaterialInternal(OMaterialAsset material);
|
||||
void registerMaterialInstanceInternal(OMaterialInstanceAsset instance);
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ target_sources(Engine
|
||||
Asset.cpp
|
||||
AssetRegistry.h
|
||||
AssetRegistry.cpp
|
||||
EnvironmentMapAsset.h
|
||||
EnvironmentMapAsset.cpp
|
||||
FontAsset.h
|
||||
FontAsset.cpp
|
||||
LevelAsset.h
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#include "EnvironmentMapAsset.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
EnvironmentMapAsset::EnvironmentMapAsset() {}
|
||||
|
||||
EnvironmentMapAsset::EnvironmentMapAsset(std::string_view folderPath, std::string_view name) : Asset(folderPath, name) {}
|
||||
|
||||
EnvironmentMapAsset::~EnvironmentMapAsset() {}
|
||||
|
||||
void EnvironmentMapAsset::save(ArchiveBuffer& buffer) const {}
|
||||
|
||||
void EnvironmentMapAsset::load(ArchiveBuffer& buffer) {}
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
#include "Asset.h"
|
||||
#include "Graphics/Texture.h"
|
||||
|
||||
namespace Seele {
|
||||
class EnvironmentMapAsset : public Asset {
|
||||
public:
|
||||
static constexpr uint64 IDENTIFIER = 0x80;
|
||||
EnvironmentMapAsset();
|
||||
EnvironmentMapAsset(std::string_view folderPath, std::string_view name);
|
||||
virtual ~EnvironmentMapAsset();
|
||||
virtual void save(ArchiveBuffer& buffer) const override;
|
||||
virtual void load(ArchiveBuffer& buffer) override;
|
||||
Gfx::PTextureCube getSkybox() const { return skybox; }
|
||||
Gfx::PTextureCube getIrradianceMap() const { return irradianceMap; }
|
||||
Gfx::PTextureCube getSpecularMap() const { return specularMap; }
|
||||
private:
|
||||
Gfx::OTextureCube skybox;
|
||||
Gfx::OTextureCube irradianceMap;
|
||||
Gfx::OTextureCube specularMap;
|
||||
friend class EnvironmentLoader;
|
||||
};
|
||||
} // namespace Seele
|
||||
@@ -28,16 +28,16 @@ void FontAsset::load(ArchiveBuffer& buffer) {
|
||||
}
|
||||
|
||||
void FontAsset::loadFace() {
|
||||
FT_Error error = FT_New_Memory_Face(ft, (unsigned char*)ttfFile.data(), ttfFile.size(), 0, &ft_face);
|
||||
FT_Error error = FT_New_Memory_Face(ft, (unsigned char*)ttfFile.data(), (uint32)ttfFile.size(), 0, &ft_face);
|
||||
assert(!error);
|
||||
blob = hb_blob_create(ttfFile.data(), ttfFile.size(), HB_MEMORY_MODE_DUPLICATE, nullptr, nullptr);
|
||||
blob = hb_blob_create(ttfFile.data(), (uint32)ttfFile.size(), HB_MEMORY_MODE_DUPLICATE, nullptr, nullptr);
|
||||
hb_face = hb_face_create(blob, 0);
|
||||
hb_font = hb_font_create(hb_face);
|
||||
}
|
||||
UVector2 FontAsset::shapeText(std::string_view view, uint32 fontSize, Array<RenderGlyph>& render) {
|
||||
loadGlyphs(fontSize);
|
||||
hb_buffer_t* buf = hb_buffer_create();
|
||||
hb_buffer_add_utf8(buf, view.data(), view.size(), 0, -1);
|
||||
hb_buffer_add_utf8(buf, view.data(), (uint32)view.size(), 0, -1);
|
||||
hb_buffer_set_language(buf, hb_language_from_string("en", -1));
|
||||
hb_buffer_set_script(buf, HB_SCRIPT_LATIN);
|
||||
hb_buffer_set_direction(buf, HB_DIRECTION_LTR);
|
||||
@@ -52,10 +52,10 @@ UVector2 FontAsset::shapeText(std::string_view view, uint32 fontSize, Array<Rend
|
||||
Vector2 cursor = Vector2(0);
|
||||
for (uint32 i = 0; i < num_glyphs; ++i) {
|
||||
hb_codepoint_t glyphid = glyphs[i].codepoint;
|
||||
float xOffset = positions[i].x_offset * fontSize / xppem;
|
||||
float yOffset = positions[i].y_offset * fontSize / yppem;
|
||||
float xAdvance = positions[i].x_advance * fontSize / xppem;
|
||||
float yAdvance = positions[i].y_advance * fontSize / yppem;
|
||||
float xOffset = (float)positions[i].x_offset * fontSize / xppem;
|
||||
float yOffset = (float)positions[i].y_offset * fontSize / yppem;
|
||||
float xAdvance = (float)positions[i].x_advance * fontSize / xppem;
|
||||
float yAdvance = (float)positions[i].y_advance * fontSize / yppem;
|
||||
Vector2 position = cursor + Vector2(xOffset, yOffset);
|
||||
Vector2 dimensions = fontSizes[fontSize].glyphs[glyphid].size;
|
||||
render.add(RenderGlyph{
|
||||
@@ -73,7 +73,7 @@ UVector2 FontAsset::shapeText(std::string_view view, uint32 fontSize, Array<Rend
|
||||
|
||||
void FontAsset::loadGlyphs(uint32 fontSize) {
|
||||
FT_Set_Pixel_Sizes(ft_face, 0, fontSize);
|
||||
for (uint32 i = 0; i < ft_face->num_glyphs; ++i) {
|
||||
for (int i = 0; i < ft_face->num_glyphs; ++i) {
|
||||
assert(FT_Load_Glyph(ft_face, i, FT_LOAD_RENDER) == 0);
|
||||
FontAsset::Glyph& glyph = fontSizes[fontSize].glyphs[i];
|
||||
glyph.size = IVector2(ft_face->glyph->bitmap.width, ft_face->glyph->bitmap.rows);
|
||||
|
||||
@@ -9,6 +9,6 @@ LevelAsset::LevelAsset(std::string_view folderPath, std::string_view name) : Ass
|
||||
|
||||
LevelAsset::~LevelAsset() {}
|
||||
|
||||
void LevelAsset::save(ArchiveBuffer& buffer) const { }
|
||||
void LevelAsset::save(ArchiveBuffer&) const { }
|
||||
|
||||
void LevelAsset::load(ArchiveBuffer& buffer) { }
|
||||
void LevelAsset::load(ArchiveBuffer&) { }
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
namespace Seele {
|
||||
class LevelAsset : public Asset {
|
||||
public:
|
||||
static constexpr uint64 IDENTIFIER = 0x20;
|
||||
static constexpr uint64 IDENTIFIER = 0x40;
|
||||
LevelAsset();
|
||||
LevelAsset(std::string_view folderPath, std::string_view name);
|
||||
virtual ~LevelAsset();
|
||||
|
||||
@@ -30,6 +30,6 @@ PMaterialInstanceAsset MaterialAsset::instantiate(const InstantiationParameter&
|
||||
asset->setBase(this);
|
||||
PMaterialInstanceAsset ref = asset;
|
||||
AssetRegistry::registerMaterialInstance(std::move(asset));
|
||||
AssetRegistry::saveAsset(ref, MaterialInstanceAsset::IDENTIFIER, ref->getFolderPath(), ref->getName());
|
||||
AssetRegistry::saveAsset(PAsset(ref), MaterialInstanceAsset::IDENTIFIER, ref->getFolderPath(), ref->getName());
|
||||
return ref;
|
||||
}
|
||||
|
||||
@@ -31,9 +31,7 @@ void TextureAsset::load(ArchiveBuffer& buffer) {
|
||||
Serialization::load(buffer, ktxData);
|
||||
KTX_ASSERT(
|
||||
ktxTexture_CreateFromMemory(ktxData.data(), ktxData.size(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, (ktxTexture**)&ktxHandle));
|
||||
|
||||
ktxTexture2_TranscodeBasis(ktxHandle, KTX_TTF_RGBA32, 0);
|
||||
// ktxTexture2_DeflateZstd(ktxHandle, 0);
|
||||
|
||||
Gfx::PGraphics graphics = buffer.getGraphics();
|
||||
TextureCreateInfo createInfo = {
|
||||
@@ -47,7 +45,6 @@ void TextureAsset::load(ArchiveBuffer& buffer) {
|
||||
.width = ktxHandle->baseWidth,
|
||||
.height = ktxHandle->baseHeight,
|
||||
.depth = ktxHandle->baseDepth,
|
||||
.layers = ktxHandle->numFaces,
|
||||
.elements = ktxHandle->numLayers,
|
||||
.useMip = true,
|
||||
.usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT,
|
||||
|
||||
@@ -5,14 +5,14 @@ namespace Seele {
|
||||
namespace Component {
|
||||
struct KeyboardInput {
|
||||
Seele::StaticArray<bool, static_cast<size_t>(Seele::KeyCode::KEY_LAST)> keys;
|
||||
bool mouse1;
|
||||
bool mouse2;
|
||||
float mouseX;
|
||||
float mouseY;
|
||||
float deltaX;
|
||||
float deltaY;
|
||||
float scrollX;
|
||||
float scrollY;
|
||||
bool mouse1 = false;
|
||||
bool mouse2 = false;
|
||||
float mouseX = 0.0f;
|
||||
float mouseY = 0.0f;
|
||||
float deltaX = 0.0f;
|
||||
float deltaY = 0.0f;
|
||||
float scrollX = 0.0f;
|
||||
float scrollY = 0.0f;
|
||||
};
|
||||
} // namespace Component
|
||||
} // namespace Seele
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "EngineTypes.h"
|
||||
#include "Concepts.h"
|
||||
#include "EngineTypes.h"
|
||||
#include "MemoryResource.h"
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include <initializer_list>
|
||||
@@ -12,7 +13,7 @@
|
||||
#endif
|
||||
|
||||
namespace Seele {
|
||||
template <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> struct Array {
|
||||
template <typename T> struct Array {
|
||||
public:
|
||||
template <typename X> class IteratorBase {
|
||||
public:
|
||||
@@ -67,7 +68,7 @@ template <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> s
|
||||
};
|
||||
|
||||
using value_type = T;
|
||||
using allocator_type = Allocator;
|
||||
using allocator_type = std::pmr::polymorphic_allocator<T>;
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = T*;
|
||||
@@ -82,12 +83,8 @@ template <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> s
|
||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
|
||||
constexpr Array() noexcept(noexcept(Allocator())) : arraySize(0), allocated(DEFAULT_ALLOC_SIZE), allocator(Allocator()) {
|
||||
_data = allocateArray(DEFAULT_ALLOC_SIZE);
|
||||
assert(_data != nullptr);
|
||||
}
|
||||
|
||||
constexpr explicit Array(const allocator_type& alloc) noexcept : arraySize(0), allocated(DEFAULT_ALLOC_SIZE), allocator(alloc) {
|
||||
constexpr Array(const allocator_type& alloc = allocator_type()) noexcept
|
||||
: arraySize(0), allocated(DEFAULT_ALLOC_SIZE), allocator(alloc) {
|
||||
_data = allocateArray(DEFAULT_ALLOC_SIZE);
|
||||
assert(_data != nullptr);
|
||||
}
|
||||
@@ -138,7 +135,8 @@ template <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> s
|
||||
assert(_data != nullptr);
|
||||
std::uninitialized_copy(other.begin(), other.end(), begin());
|
||||
}
|
||||
constexpr Array(const Array& other, const Allocator& alloc) : arraySize(other.arraySize), allocated(other.allocated), allocator(alloc) {
|
||||
constexpr Array(const Array& other, const allocator_type& alloc)
|
||||
: arraySize(other.arraySize), allocated(other.allocated), allocator(alloc) {
|
||||
_data = allocateArray(other.allocated);
|
||||
assert(_data != nullptr);
|
||||
std::uninitialized_copy(other.begin(), other.end(), begin());
|
||||
@@ -150,7 +148,7 @@ template <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> s
|
||||
other.allocated = 0;
|
||||
other.arraySize = 0;
|
||||
}
|
||||
constexpr Array(Array&& other, const Allocator& alloc) noexcept
|
||||
constexpr Array(Array&& other, const allocator_type& alloc) noexcept
|
||||
: arraySize(std::move(other.arraySize)), allocated(std::move(other.allocated)), allocator(alloc) {
|
||||
_data = allocateArray(other.allocated);
|
||||
std::uninitialized_move(other.begin(), other.end(), begin());
|
||||
@@ -179,8 +177,8 @@ template <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> s
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Array& operator=(Array&& other) noexcept(std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
|
||||
std::allocator_traits<Allocator>::is_always_equal::value) {
|
||||
Array& operator=(Array&& other) noexcept(std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value ||
|
||||
std::allocator_traits<allocator_type>::is_always_equal::value) {
|
||||
if (this != &other) {
|
||||
if (_data != nullptr) {
|
||||
clear();
|
||||
@@ -294,7 +292,7 @@ template <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> s
|
||||
requires std::predicate<Pred, value_type>
|
||||
constexpr void remove_if(Pred&& pred, bool keepOrder = true) {
|
||||
Iterator it;
|
||||
while((it = find(pred)) != end()) {
|
||||
while ((it = find(pred)) != end()) {
|
||||
erase(it, keepOrder);
|
||||
}
|
||||
}
|
||||
@@ -389,7 +387,11 @@ template <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> s
|
||||
assert(result != nullptr);
|
||||
return result;
|
||||
}
|
||||
void deallocateArray(T* ptr, size_type size) { if(ptr == nullptr) return; allocator.deallocate(ptr, size); }
|
||||
void deallocateArray(T* ptr, size_type size) {
|
||||
if (ptr == nullptr)
|
||||
return;
|
||||
allocator.deallocate(ptr, size);
|
||||
}
|
||||
template <typename Type> T& addInternal(Type&& t) noexcept {
|
||||
if (arraySize == allocated) {
|
||||
size_type newSize = arraySize + 1;
|
||||
@@ -449,7 +451,7 @@ template <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> s
|
||||
allocator_type allocator;
|
||||
};
|
||||
|
||||
template <class Type, class Alloc> constexpr bool operator==(const Array<Type, Alloc>& lhs, const Array<Type, Alloc>& rhs) {
|
||||
template <class Type> constexpr bool operator==(const Array<Type>& lhs, const Array<Type>& rhs) {
|
||||
if (lhs.size() != rhs.size()) {
|
||||
return false;
|
||||
}
|
||||
@@ -461,7 +463,7 @@ template <class Type, class Alloc> constexpr bool operator==(const Array<Type, A
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class Type, class Alloc> constexpr auto operator<=>(const Array<Type, Alloc>& lhs, const Array<Type, Alloc>& rhs) {
|
||||
template <class Type> constexpr auto operator<=>(const Array<Type>& lhs, const Array<Type>& rhs) {
|
||||
return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ target_sources(Engine
|
||||
Array.h
|
||||
List.h
|
||||
Map.h
|
||||
MemoryResource.h
|
||||
MemoryResource.cpp
|
||||
Pair.h
|
||||
Set.h
|
||||
Tree.h)
|
||||
@@ -13,6 +15,7 @@ target_sources(Engine
|
||||
Array.h
|
||||
List.h
|
||||
Map.h
|
||||
MemoryResource.h
|
||||
Pair.h
|
||||
Set.h
|
||||
Tree.h)
|
||||
@@ -5,12 +5,11 @@
|
||||
#include "Tree.h"
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace Seele {
|
||||
template <typename KeyType, typename PairType> struct _KeyFun {
|
||||
const KeyType& operator()(const PairType& pair) const { return pair.key; }
|
||||
};
|
||||
template <typename K, typename V, typename Compare = std::less<K>, typename Allocator = std::pmr::polymorphic_allocator<Pair<const K, V>>>
|
||||
template <typename K, typename V, typename Compare = std::less<K>, typename Allocator = std::pmr::polymorphic_allocator<Pair<K, V>>>
|
||||
struct Map : public Tree<K, Pair<K, V>, _KeyFun<K, Pair<K, V>>, Compare, Allocator> {
|
||||
using Super = Tree<K, Pair<K, V>, _KeyFun<K, Pair<K, V>>, Compare, Allocator>;
|
||||
using key_type = Super::key_type;
|
||||
@@ -35,8 +34,8 @@ struct Map : public Tree<K, Pair<K, V>, _KeyFun<K, Pair<K, V>>, Compare, Allocat
|
||||
: Super(comp, alloc) {}
|
||||
constexpr explicit Map(const Allocator& alloc) noexcept(noexcept(Compare())) : Super(alloc) {}
|
||||
constexpr Map(std::initializer_list<Pair<K, V>> init) : Super(init) {}
|
||||
constexpr mapped_type& operator[](const key_type& key) {
|
||||
auto [it, inserted] = Super::insert(Pair<K, V>(key, V()));
|
||||
constexpr mapped_type& operator[](const key_type& key) {
|
||||
auto [it, _] = Super::insert(Pair<K, V>(key));
|
||||
return it->value;
|
||||
}
|
||||
constexpr const mapped_type& operator[](const key_type& key) const { return Super::find(key)->value; }
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#include "MemoryResource.h"
|
||||
#include "Map.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
|
||||
RefPtr<uint64> MemoryManager::getAllocationCounter(const std::string& name) {
|
||||
std::unique_lock l(getInstance().allocationMutex);
|
||||
if (!getInstance().allocationCounters.contains(name)) {
|
||||
getInstance().allocationCounters[name] = new uint64(0);
|
||||
}
|
||||
return getInstance().allocationCounters[name];
|
||||
}
|
||||
|
||||
void MemoryManager::printAllocations() {
|
||||
std::unique_lock l(getInstance().allocationMutex);
|
||||
for (const auto& [name, counter] : getInstance().allocationCounters) {
|
||||
if (name.empty()) {
|
||||
std::cout << name << ": " << **counter << std::endl;
|
||||
} else {
|
||||
std::cout << name << ": " << **counter << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MemoryManager& MemoryManager::getInstance() {
|
||||
static MemoryManager instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
debug_resource* debug_resource::get(const std::string& name) {
|
||||
static std::mutex resourcesMutex;
|
||||
static std::map<std::string, debug_resource> debugResources;
|
||||
std::unique_lock l(resourcesMutex);
|
||||
if (!debugResources.count(name)) {
|
||||
debugResources.emplace(std::pair(name, debug_resource(name)));
|
||||
}
|
||||
return &debugResources[name];
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
#include <memory_resource>
|
||||
#include <map>
|
||||
#include "MinimalEngine.h"
|
||||
|
||||
namespace Seele {
|
||||
class MemoryManager {
|
||||
public:
|
||||
static RefPtr<uint64> getAllocationCounter(const std::string& name);
|
||||
static void printAllocations();
|
||||
|
||||
private:
|
||||
static MemoryManager& getInstance();
|
||||
std::mutex allocationMutex;
|
||||
std::map<std::string, OwningPtr<uint64>> allocationCounters;
|
||||
};
|
||||
|
||||
class debug_resource : public std::pmr::memory_resource {
|
||||
public:
|
||||
static debug_resource* get(const std::string& name);
|
||||
debug_resource() : name(""), upstream(std::pmr::get_default_resource()), counter(MemoryManager::getAllocationCounter(name)) {}
|
||||
debug_resource(std::string name, std::pmr::memory_resource* up = std::pmr::get_default_resource())
|
||||
: name(name), upstream(up), counter(MemoryManager::getAllocationCounter(name)) {}
|
||||
debug_resource(const debug_resource& other) = delete;
|
||||
debug_resource(debug_resource&& other) = default;
|
||||
debug_resource& operator=(const debug_resource& other) = delete;
|
||||
debug_resource& operator=(debug_resource&& other) = default;
|
||||
|
||||
void* do_allocate(size_t bytes, size_t alignment) override {
|
||||
// std::cout << name << " + " << bytes << std::endl;
|
||||
*counter.getHandle() += bytes;
|
||||
return upstream->allocate(bytes, alignment);
|
||||
}
|
||||
|
||||
void do_deallocate(void* ptr, size_t bytes, size_t alignment) override {
|
||||
upstream->deallocate(ptr, bytes, alignment);
|
||||
// std::cout << name << " - " << bytes << std::endl;
|
||||
*counter.getHandle() -= bytes;
|
||||
}
|
||||
|
||||
bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override { return this == &other; }
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
std::pmr::memory_resource* upstream;
|
||||
RefPtr<uint64> counter;
|
||||
};
|
||||
} // namespace Seele
|
||||
@@ -3,14 +3,6 @@
|
||||
namespace Seele {
|
||||
template <typename K, typename V> struct Pair {
|
||||
public:
|
||||
constexpr Pair() : key(K()), value(V()) {}
|
||||
constexpr Pair(const K& key, const V& value) : key(key), value(value) {}
|
||||
template <class U1 = K, class U2 = V> constexpr Pair(U1&& x, U2&& y) : key(std::forward<U1>(x)), value(std::forward<U2>(y)) {}
|
||||
Pair(const Pair& other) = default;
|
||||
Pair(Pair&& other) = default;
|
||||
~Pair() {}
|
||||
Pair& operator=(const Pair& other) = default;
|
||||
Pair& operator=(Pair&& other) = default;
|
||||
constexpr friend bool operator<(const Pair& left, const Pair& right) {
|
||||
return left.key < right.key || (!(right.key < left.key) && left.value < right.value);
|
||||
}
|
||||
|
||||
@@ -1,18 +1,31 @@
|
||||
#pragma once
|
||||
#include "Pair.h"
|
||||
#include "Array.h"
|
||||
#include <memory_resource>
|
||||
|
||||
#include "List.h"
|
||||
#include "Pair.h"
|
||||
|
||||
namespace Seele {
|
||||
template <typename KeyType, typename NodeData, typename KeyFun, typename Compare, typename Allocator> struct Tree {
|
||||
protected:
|
||||
struct Node {
|
||||
Node() {}
|
||||
Node(Node* left, Node* right, const NodeData& nodeData) : leftChild(left), rightChild(right), data(nodeData) {}
|
||||
Node(Node* left, Node* right, NodeData&& nodeData) : leftChild(left), rightChild(right), data(std::move(nodeData)) {}
|
||||
Node* leftChild;
|
||||
Node* rightChild;
|
||||
Node* leftChild = nullptr;
|
||||
Node* rightChild = nullptr;
|
||||
Node* parent = nullptr;
|
||||
NodeData data;
|
||||
void setLeftChild(Node* child) {
|
||||
leftChild = child;
|
||||
if (child != nullptr) {
|
||||
child->parent = this;
|
||||
}
|
||||
}
|
||||
void setRightChild(Node* child) {
|
||||
rightChild = child;
|
||||
if (child != nullptr) {
|
||||
child->parent = this;
|
||||
}
|
||||
}
|
||||
};
|
||||
using NodeAlloc = std::allocator_traits<Allocator>::template rebind_alloc<Node>;
|
||||
|
||||
@@ -25,49 +38,65 @@ template <typename KeyType, typename NodeData, typename KeyFun, typename Compare
|
||||
using reference = IterType&;
|
||||
using pointer = IterType*;
|
||||
|
||||
constexpr IteratorBase(Node* x = nullptr, Array<Node*>&& beginIt = Array<Node*>()) : node(x), traversal(std::move(beginIt)) {}
|
||||
constexpr IteratorBase(const IteratorBase& i) : node(i.node), traversal(i.traversal) {}
|
||||
constexpr IteratorBase(IteratorBase&& i) noexcept : node(std::move(i.node)), traversal(std::move(i.traversal)) {}
|
||||
constexpr IteratorBase(Node* x = nullptr) : node(x) {}
|
||||
constexpr IteratorBase(const IteratorBase& i) : node(i.node) {}
|
||||
constexpr IteratorBase(IteratorBase&& i) noexcept : node(std::move(i.node)) {}
|
||||
constexpr IteratorBase& operator=(const IteratorBase& other) {
|
||||
if (this != &other) {
|
||||
node = other.node;
|
||||
traversal = other.traversal;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
constexpr IteratorBase& operator=(IteratorBase&& other) noexcept {
|
||||
if (this != &other) {
|
||||
node = std::move(other.node);
|
||||
traversal = std::move(other.traversal);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
constexpr reference operator*() const { return node->data; }
|
||||
constexpr pointer operator->() const { return &(node->data); }
|
||||
constexpr pointer operator->() const { return std::pointer_traits<pointer>::pointer_to(**this); }
|
||||
constexpr bool operator!=(const IteratorBase& other) { return node != other.node; }
|
||||
constexpr bool operator==(const IteratorBase& other) { return node == other.node; }
|
||||
constexpr std::strong_ordering operator<=>(const IteratorBase& other) { return node <=> other.node; }
|
||||
constexpr IteratorBase& operator++() {
|
||||
node = node->rightChild;
|
||||
while (node != nullptr && node->leftChild != nullptr) {
|
||||
traversal.add(node);
|
||||
node = node->leftChild;
|
||||
}
|
||||
if (node == nullptr && traversal.size() > 0) {
|
||||
node = traversal.back();
|
||||
traversal.pop();
|
||||
// if current node has no right subtree
|
||||
if (node->rightChild == nullptr) {
|
||||
Node* temp = node;
|
||||
node = node->parent;
|
||||
// walk up hierarchy until we were the left subtree of any parent
|
||||
// this means that that parent is the correct next element
|
||||
while (node->rightChild == temp) {
|
||||
temp = node;
|
||||
node = node->parent;
|
||||
}
|
||||
} else {
|
||||
// if there is a right subtree, descend there
|
||||
node = node->rightChild;
|
||||
// and find the leftmost node in that tree
|
||||
while (node->leftChild != nullptr) {
|
||||
node = node->leftChild;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
constexpr IteratorBase& operator--() {
|
||||
node = node->leftChild;
|
||||
while (node != nullptr && node->rightChild != nullptr) {
|
||||
traversal.add(node);
|
||||
node = node->rightchild;
|
||||
}
|
||||
if (node == nullptr && traversal.size() > 0) {
|
||||
node = traversal.back();
|
||||
traversal.pop();
|
||||
// if current node has no left subtree
|
||||
if (node->leftChild == nullptr) {
|
||||
Node* temp = node;
|
||||
node = node->parent;
|
||||
// walk up hierarchy until we were the right subtree of any parent
|
||||
// this means that that parent is the correct next element
|
||||
while (node->leftChild == temp) {
|
||||
temp = node;
|
||||
node = node->parent;
|
||||
}
|
||||
} else {
|
||||
// if there is a left subtree, descend there
|
||||
node = node->leftChild;
|
||||
// and find the rightmost node in that tree
|
||||
while (node->rightChild != nullptr) {
|
||||
node = node->rightChild;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -81,11 +110,10 @@ template <typename KeyType, typename NodeData, typename KeyFun, typename Compare
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
Node* getNode() { return node; }
|
||||
Node* getNode() const { return node; }
|
||||
|
||||
private:
|
||||
Node* node;
|
||||
Array<Node*> traversal;
|
||||
};
|
||||
using Iterator = IteratorBase<NodeData>;
|
||||
using ConstIterator = IteratorBase<const NodeData>;
|
||||
@@ -123,8 +151,8 @@ template <typename KeyType, typename NodeData, typename KeyFun, typename Compare
|
||||
}
|
||||
}
|
||||
constexpr Tree(Tree&& other) noexcept
|
||||
: alloc(std::move(other.alloc)), root(std::move(other.root)), iteratorsDirty(true), _size(std::move(other._size)),
|
||||
comp(std::move(other.comp)) {
|
||||
: alloc(std::move(other.alloc)), root(std::move(other.root)), pseudoRoot(std::move(other.pseudoRoot)), iteratorsDirty(true),
|
||||
_size(std::move(other._size)), comp(std::move(other.comp)) {
|
||||
other._size = 0;
|
||||
}
|
||||
constexpr ~Tree() noexcept { clear(); }
|
||||
@@ -148,6 +176,7 @@ template <typename KeyType, typename NodeData, typename KeyFun, typename Compare
|
||||
alloc = std::move(other.alloc);
|
||||
}
|
||||
root = std::move(other.root);
|
||||
pseudoRoot = std::move(other.pseudoRoot);
|
||||
_size = std::move(other._size);
|
||||
comp = std::move(other.comp);
|
||||
other._size = 0;
|
||||
@@ -160,6 +189,7 @@ template <typename KeyType, typename NodeData, typename KeyFun, typename Compare
|
||||
root = _remove(root, keyFun(root->data));
|
||||
}
|
||||
root = nullptr;
|
||||
pseudoRoot.setLeftChild(nullptr);
|
||||
markIteratorsDirty();
|
||||
}
|
||||
constexpr iterator begin() {
|
||||
@@ -192,6 +222,7 @@ template <typename KeyType, typename NodeData, typename KeyFun, typename Compare
|
||||
protected:
|
||||
constexpr iterator find(const key_type& key) {
|
||||
root = _splay(root, key);
|
||||
pseudoRoot.setLeftChild(root);
|
||||
if (root == nullptr || !equal(root->data, key)) {
|
||||
return end();
|
||||
}
|
||||
@@ -214,15 +245,18 @@ template <typename KeyType, typename NodeData, typename KeyFun, typename Compare
|
||||
constexpr Pair<iterator, bool> insert(const NodeData& data) {
|
||||
auto [r, inserted] = _insert(root, data);
|
||||
root = r;
|
||||
pseudoRoot.setLeftChild(root);
|
||||
return Pair<iterator, bool>(iterator(root), inserted);
|
||||
}
|
||||
constexpr Pair<iterator, bool> insert(NodeData&& data) {
|
||||
auto [r, inserted] = _insert(root, std::move(data));
|
||||
root = r;
|
||||
pseudoRoot.setLeftChild(root);
|
||||
return Pair<iterator, bool>(iterator(root), inserted);
|
||||
}
|
||||
constexpr iterator remove(const key_type& key) {
|
||||
root = _remove(root, key);
|
||||
pseudoRoot.setLeftChild(root);
|
||||
return iterator(root);
|
||||
}
|
||||
|
||||
@@ -241,29 +275,18 @@ template <typename KeyType, typename NodeData, typename KeyFun, typename Compare
|
||||
iteratorsDirty = false;
|
||||
}
|
||||
constexpr Iterator calcBeginIterator() const {
|
||||
Node* begin = root;
|
||||
Array<Node*> beginTraversal;
|
||||
while (begin != nullptr) {
|
||||
beginTraversal.add(begin);
|
||||
// start at pseudoroot so that if no regular nodes exist begin == end
|
||||
Node* begin = const_cast<Node*>(&pseudoRoot);
|
||||
while (begin != nullptr && begin->leftChild != nullptr) {
|
||||
begin = begin->leftChild;
|
||||
}
|
||||
if (!beginTraversal.empty()) {
|
||||
begin = beginTraversal.back();
|
||||
beginTraversal.pop();
|
||||
}
|
||||
return Iterator(begin, std::move(beginTraversal));
|
||||
}
|
||||
constexpr Iterator calcEndIterator() const {
|
||||
Node* endIndex = root;
|
||||
Array<Node*> endTraversal;
|
||||
while (endIndex != nullptr) {
|
||||
endTraversal.add(endIndex);
|
||||
endIndex = endIndex->rightChild;
|
||||
}
|
||||
return Iterator(endIndex, std::move(endTraversal));
|
||||
return Iterator(begin);
|
||||
}
|
||||
constexpr Iterator calcEndIterator() const { return Iterator(const_cast<Node*>(&pseudoRoot)); }
|
||||
NodeAlloc alloc;
|
||||
Node* root;
|
||||
// where the end iterator points to
|
||||
Node pseudoRoot;
|
||||
Iterator beginIt;
|
||||
Iterator endIt;
|
||||
bool iteratorsDirty;
|
||||
@@ -272,14 +295,14 @@ template <typename KeyType, typename NodeData, typename KeyFun, typename Compare
|
||||
KeyFun keyFun = KeyFun();
|
||||
Node* rotateLeft(Node* x) {
|
||||
Node* y = x->rightChild;
|
||||
x->rightChild = y->leftChild;
|
||||
y->leftChild = x;
|
||||
x->setRightChild(y->leftChild);
|
||||
y->setLeftChild(x);
|
||||
return y;
|
||||
}
|
||||
Node* rotateRight(Node* x) {
|
||||
Node* y = x->leftChild;
|
||||
x->leftChild = y->rightChild;
|
||||
y->rightChild = x;
|
||||
x->setLeftChild(y->rightChild);
|
||||
y->setRightChild(x);
|
||||
return y;
|
||||
}
|
||||
template <class NodeDataType> Pair<Node*, bool> _insert(Node* r, NodeDataType&& data) {
|
||||
@@ -299,13 +322,13 @@ template <typename KeyType, typename NodeData, typename KeyFun, typename Compare
|
||||
std::allocator_traits<NodeAlloc>::construct(alloc, newNode, nullptr, nullptr, std::forward<NodeDataType>(data));
|
||||
|
||||
if (comp(keyFun(newNode->data), keyFun(r->data))) {
|
||||
newNode->rightChild = r;
|
||||
newNode->leftChild = r->leftChild;
|
||||
r->leftChild = nullptr;
|
||||
newNode->setRightChild(r);
|
||||
newNode->setLeftChild(r->leftChild);
|
||||
r->setLeftChild(nullptr);
|
||||
} else {
|
||||
newNode->leftChild = r;
|
||||
newNode->rightChild = r->rightChild;
|
||||
r->rightChild = nullptr;
|
||||
newNode->setLeftChild(r);
|
||||
newNode->setRightChild(r->rightChild);
|
||||
r->setRightChild(nullptr);
|
||||
}
|
||||
_size++;
|
||||
return Pair<Node*, bool>(newNode, true);
|
||||
@@ -328,7 +351,7 @@ template <typename KeyType, typename NodeData, typename KeyFun, typename Compare
|
||||
temp = r;
|
||||
|
||||
r = _splay(r->leftChild, key);
|
||||
r->rightChild = temp->rightChild;
|
||||
r->setRightChild(temp->rightChild);
|
||||
}
|
||||
std::allocator_traits<NodeAlloc>::destroy(alloc, temp);
|
||||
alloc.deallocate(temp, 1);
|
||||
@@ -345,11 +368,11 @@ template <typename KeyType, typename NodeData, typename KeyFun, typename Compare
|
||||
return r;
|
||||
|
||||
if (comp(key, keyFun(r->leftChild->data))) {
|
||||
r->leftChild->leftChild = _splay(r->leftChild->leftChild, key);
|
||||
r->leftChild->setLeftChild(_splay(r->leftChild->leftChild, key));
|
||||
|
||||
r = rotateRight(r);
|
||||
} else if (comp(keyFun(r->leftChild->data), key)) {
|
||||
r->leftChild->rightChild = _splay(r->leftChild->rightChild, key);
|
||||
r->leftChild->setRightChild(_splay(r->leftChild->rightChild, key));
|
||||
|
||||
if (r->leftChild->rightChild != nullptr) {
|
||||
r->leftChild = rotateLeft(r->leftChild);
|
||||
@@ -361,13 +384,13 @@ template <typename KeyType, typename NodeData, typename KeyFun, typename Compare
|
||||
return r;
|
||||
|
||||
if (comp(key, keyFun(r->rightChild->data))) {
|
||||
r->rightChild->leftChild = _splay(r->rightChild->leftChild, key);
|
||||
r->rightChild->setLeftChild(_splay(r->rightChild->leftChild, key));
|
||||
|
||||
if (r->rightChild->leftChild != nullptr) {
|
||||
r->rightChild = rotateRight(r->rightChild);
|
||||
r->setRightChild(rotateRight(r->rightChild));
|
||||
}
|
||||
} else if (comp(keyFun(r->rightChild->data), key)) {
|
||||
r->rightChild->rightChild = _splay(r->rightChild->rightChild, key);
|
||||
r->rightChild->setRightChild(_splay(r->rightChild->rightChild, key));
|
||||
|
||||
r = rotateLeft(r);
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ class IndexBuffer : public Buffer {
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
Gfx::SeIndexType indexType;
|
||||
uint64 numIndices;
|
||||
uint64 numIndices = 0;
|
||||
};
|
||||
DEFINE_REF(IndexBuffer)
|
||||
|
||||
@@ -81,7 +81,7 @@ class ShaderBuffer : public Buffer {
|
||||
virtual void updateContents(uint64 offset, uint64 size, void* data) = 0;
|
||||
virtual void* map() = 0;
|
||||
virtual void unmap() = 0;
|
||||
constexpr uint32 getNumElements() const { return numElements; }
|
||||
constexpr uint64 getNumElements() const { return numElements; }
|
||||
|
||||
virtual void clear() = 0;
|
||||
|
||||
@@ -91,7 +91,7 @@ class ShaderBuffer : public Buffer {
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
|
||||
uint32 numElements;
|
||||
uint64 numElements;
|
||||
};
|
||||
DEFINE_REF(ShaderBuffer)
|
||||
} // namespace Gfx
|
||||
|
||||
@@ -120,7 +120,7 @@ uint32_t find_msb_64(uint64_t x) {
|
||||
|
||||
CPUMesh Seele::generateCPUMesh(uint32 cbtNumElements) {
|
||||
CPUMesh result;
|
||||
result.totalNumElements = edges.size() + cbtNumElements;
|
||||
result.totalNumElements = (uint32)edges.size() + cbtNumElements;
|
||||
|
||||
result.heapIDArray.resize(result.totalNumElements);
|
||||
result.neighborsArray.resize(result.totalNumElements);
|
||||
@@ -193,7 +193,6 @@ Matrix3 decodeSubdivisionMatrix(uint64 heapID) {
|
||||
void LebMatrixCache::init(Gfx::PGraphics graphics, uint32 depth) {
|
||||
cacheDepth = depth;
|
||||
uint32 matrixCount = 2ULL << cacheDepth;
|
||||
Matrix3 m;
|
||||
std::vector<Matrix3> table(matrixCount);
|
||||
table[0] = Matrix3({1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f});
|
||||
for (uint64 heapID = 1ULL; heapID < (2ULL << cacheDepth); ++heapID) {
|
||||
@@ -799,7 +798,7 @@ void MeshUpdater::update(CBTMesh& mesh, Gfx::PDescriptorSet viewParamsSet, Gfx::
|
||||
}
|
||||
|
||||
void MeshUpdater::validation(CBTMesh& mesh, Gfx::PUniformBuffer geometryCB) {
|
||||
uint32 numGroups = (mesh.totalNumElements + WORKGROUP_SIZE - 1) / WORKGROUP_SIZE;
|
||||
//uint32 numGroups = (mesh.totalNumElements + WORKGROUP_SIZE - 1) / WORKGROUP_SIZE;
|
||||
|
||||
/*Gfx::PDescriptorSet set = layout->allocateDescriptorSet();
|
||||
set->updateBuffer(GEOMETRY_CB, 0, geometryCB);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
add_subdirectory(CBT/)
|
||||
#add_subdirectory(CBT/)
|
||||
|
||||
target_sources(Engine
|
||||
PRIVATE
|
||||
|
||||
@@ -38,6 +38,4 @@ void PipelineLayout::addDescriptorLayout(PDescriptorLayout layout) { descriptorS
|
||||
|
||||
void PipelineLayout::addPushConstants(const SePushConstantRange& pushConstant) { pushConstants.add(pushConstant); }
|
||||
|
||||
void PipelineLayout::addMapping(std::string name, uint32 index) {
|
||||
parameterMapping[name] = index;
|
||||
}
|
||||
void PipelineLayout::addMapping(std::string mappingName, uint32 index) { parameterMapping[mappingName] = index; }
|
||||
|
||||
@@ -68,9 +68,7 @@ class DescriptorSet {
|
||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer indexBuffer) = 0;
|
||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer indexBuffer) = 0;
|
||||
virtual void updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) = 0;
|
||||
virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTexture2D texture) = 0;
|
||||
virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTexture3D texture) = 0;
|
||||
virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTextureCube texture) = 0;
|
||||
virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTexture texture) = 0;
|
||||
virtual void updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as) = 0;
|
||||
bool operator<(PDescriptorSet other);
|
||||
|
||||
|
||||
@@ -55,8 +55,8 @@ class Graphics {
|
||||
virtual OWindow createWindow(const WindowCreateInfo& createInfo) = 0;
|
||||
virtual OViewport createViewport(PWindow owner, const ViewportCreateInfo& createInfo) = 0;
|
||||
|
||||
virtual ORenderPass createRenderPass(RenderTargetLayout layout, Array<SubPassDependency> dependencies, PViewport renderArea,
|
||||
std::string name = "") = 0;
|
||||
virtual ORenderPass createRenderPass(RenderTargetLayout layout, Array<SubPassDependency> dependencies, URect renderArea,
|
||||
std::string name = "", Array<uint32> viewMasks = {0}, Array<uint32> correlationMasks = {}) = 0;
|
||||
virtual void beginRenderPass(PRenderPass renderPass) = 0;
|
||||
virtual void endRenderPass() = 0;
|
||||
virtual void waitDeviceIdle() = 0;
|
||||
|
||||
@@ -49,7 +49,6 @@ struct TextureCreateInfo {
|
||||
uint32 width = 1;
|
||||
uint32 height = 1;
|
||||
uint32 depth = 1;
|
||||
uint32 layers = 1;
|
||||
uint32 elements = 1;
|
||||
uint32 samples = 1;
|
||||
bool useMip = false;
|
||||
|
||||
@@ -25,7 +25,7 @@ void buildAdjacency(const uint32 numVerts, const Array<uint32>& indices, Adjacen
|
||||
triangleOffset += info.trianglesPerVertex[j];
|
||||
}
|
||||
|
||||
uint32 numTriangles = indices.size() / 3;
|
||||
uint32 numTriangles = (uint32)indices.size() / 3;
|
||||
info.triangleData.resize(triangleOffset);
|
||||
Array<uint32> offsets = info.indexBufferOffset;
|
||||
for (uint32 k = 0; k < numTriangles; ++k) {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "RayTracing.h"
|
||||
#include "RayTracing.h"
|
||||
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "Resources.h"
|
||||
#include "Graphics/Descriptor.h"
|
||||
|
||||
namespace Seele {
|
||||
namespace Gfx {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "BasePass.h"
|
||||
#include "Actor/CameraActor.h"
|
||||
#include "Asset/AssetRegistry.h"
|
||||
#include "Asset/EnvironmentMapAsset.h"
|
||||
#include "Component/Camera.h"
|
||||
#include "Component/Mesh.h"
|
||||
#include "Component/WaterTile.h"
|
||||
@@ -78,8 +79,8 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics)
|
||||
});
|
||||
}
|
||||
skybox = Seele::Component::Skybox{
|
||||
.day = AssetRegistry::findTexture("", "skybox")->getTexture().cast<Gfx::TextureCube>(),
|
||||
.night = AssetRegistry::findTexture("", "skybox")->getTexture().cast<Gfx::TextureCube>(),
|
||||
.day = scene->getLightEnvironment()->getEnvironmentMap()->getIrradianceMap(),
|
||||
.night = scene->getLightEnvironment()->getEnvironmentMap()->getIrradianceMap(),
|
||||
.fogColor = Vector(0.1, 0.1, 0.8),
|
||||
.blendFactor = 0,
|
||||
};
|
||||
@@ -156,8 +157,7 @@ void BasePass::render() {
|
||||
vertexData->getInstanceDataSet()->updateBuffer(VertexData::CULLINGDATA_NAME, 0, cullingBuffer);
|
||||
vertexData->getInstanceDataSet()->writeChanges();
|
||||
permutation.setVertexData(vertexData->getTypeName());
|
||||
const auto& materials = vertexData->getMaterialData();
|
||||
for (const auto& materialData : materials) {
|
||||
for (const auto& materialData : vertexData->getMaterialData()) {
|
||||
// material not used for any active meshes, skip
|
||||
if (materialData.instances.size() == 0)
|
||||
continue;
|
||||
@@ -200,8 +200,7 @@ void BasePass::render() {
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
};
|
||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
command->bindPipeline(pipeline);
|
||||
command->bindPipeline(graphics->createGraphicsPipeline(std::move(pipelineInfo)));
|
||||
} else {
|
||||
Gfx::LegacyPipelineCreateInfo pipelineInfo = {
|
||||
.vertexShader = collection->vertexShader,
|
||||
@@ -221,8 +220,7 @@ void BasePass::render() {
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
};
|
||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
command->bindPipeline(pipeline);
|
||||
command->bindPipeline(graphics->createGraphicsPipeline(std::move(pipelineInfo)));
|
||||
}
|
||||
command->bindDescriptor({viewParamsSet, vertexData->getVertexDataSet(), vertexData->getInstanceDataSet(),
|
||||
scene->getLightEnvironment()->getDescriptorSet(), Material::getDescriptorSet(), opaqueCulling});
|
||||
@@ -231,7 +229,7 @@ void BasePass::render() {
|
||||
Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
|
||||
0, sizeof(VertexData::DrawCallOffsets), &drawCall.offsets);
|
||||
if (graphics->supportMeshShading()) {
|
||||
command->drawMesh(drawCall.instanceMeshData.size(), 1, 1);
|
||||
command->drawMesh((uint32)drawCall.instanceMeshData.size(), 1, 1);
|
||||
} else {
|
||||
command->bindIndexBuffer(vertexData->getIndexBuffer());
|
||||
for (const auto& meshData : drawCall.instanceMeshData) {
|
||||
@@ -252,7 +250,7 @@ void BasePass::render() {
|
||||
{
|
||||
Gfx::ORenderCommand skyboxCommand = graphics->createRenderCommand("SkyboxRender");
|
||||
skyboxCommand->setViewport(viewport);
|
||||
skyboxCommand->bindPipeline(pipeline);
|
||||
skyboxCommand->bindPipeline(skyboxPipeline);
|
||||
skyboxCommand->bindDescriptor({viewParamsSet, skyboxDataSet, textureSet});
|
||||
skyboxCommand->draw(36, 1, 0, 0);
|
||||
graphics->executeCommands(std::move(skyboxCommand));
|
||||
@@ -409,8 +407,8 @@ void BasePass::publishOutputs() {
|
||||
});
|
||||
|
||||
depthAttachment =
|
||||
Gfx::RenderTargetAttachment(basePassDepth, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_DONT_CARE);
|
||||
Gfx::RenderTargetAttachment(Gfx::PTexture2D(basePassDepth), Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||
|
||||
msDepthAttachment =
|
||||
Gfx::RenderTargetAttachment(msBasePassDepth, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
@@ -474,7 +472,7 @@ void BasePass::createRenderPass() {
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
},
|
||||
};
|
||||
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport, "BasePass");
|
||||
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport->getRenderArea(), "BasePass");
|
||||
oLightIndexList = resources->requestBuffer("LIGHTCULLING_OLIGHTLIST");
|
||||
tLightIndexList = resources->requestBuffer("LIGHTCULLING_TLIGHTLIST");
|
||||
oLightGrid = resources->requestTexture("LIGHTCULLING_OLIGHTGRID");
|
||||
@@ -623,6 +621,6 @@ void BasePass::createRenderPass() {
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
};
|
||||
pipeline = graphics->createGraphicsPipeline(std::move(gfxInfo));
|
||||
skyboxPipeline = graphics->createGraphicsPipeline(std::move(gfxInfo));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include "MinimalEngine.h"
|
||||
#include "RenderPass.h"
|
||||
#include "WaterRenderer.h"
|
||||
#include "TerrainRenderer.h"
|
||||
|
||||
namespace Seele {
|
||||
DECLARE_REF(CameraActor)
|
||||
@@ -56,7 +55,7 @@ class BasePass : public RenderPass {
|
||||
Gfx::PShaderBuffer cullingBuffer;
|
||||
|
||||
//OWaterRenderer waterRenderer;
|
||||
OTerrainRenderer terrainRenderer;
|
||||
//OTerrainRenderer terrainRenderer;
|
||||
|
||||
// Debug rendering
|
||||
Gfx::OVertexInput debugVertexInput;
|
||||
@@ -74,7 +73,7 @@ class BasePass : public RenderPass {
|
||||
Gfx::OVertexShader vertexShader;
|
||||
Gfx::OFragmentShader fragmentShader;
|
||||
Gfx::OPipelineLayout pipelineLayout;
|
||||
Gfx::PGraphicsPipeline pipeline;
|
||||
Gfx::PGraphicsPipeline skyboxPipeline;
|
||||
Gfx::OSampler skyboxSampler;
|
||||
struct SkyboxData {
|
||||
Matrix4 transformMatrix;
|
||||
|
||||
@@ -15,8 +15,8 @@ target_sources(Engine
|
||||
RenderGraphResources.cpp
|
||||
RenderPass.h
|
||||
RenderPass.cpp
|
||||
TerrainRenderer.h
|
||||
TerrainRenderer.cpp
|
||||
#TerrainRenderer.h
|
||||
#TerrainRenderer.cpp
|
||||
ToneMappingPass.h
|
||||
ToneMappingPass.cpp
|
||||
UIPass.h
|
||||
@@ -38,6 +38,6 @@ target_sources(Engine
|
||||
RenderGraph.h
|
||||
RenderGraphResources.h
|
||||
RenderPass.h
|
||||
TerrainRenderer.h
|
||||
#TerrainRenderer.h
|
||||
UIPass.h
|
||||
VisibilityPass.h)
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "CachedDepthPass.h"
|
||||
#include "Graphics/Shader.h"
|
||||
#include "Graphics/Pipeline.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
@@ -111,7 +112,7 @@ void CachedDepthPass::render() {
|
||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets),
|
||||
&offsets);
|
||||
if (graphics->supportMeshShading()) {
|
||||
command->drawMesh(vertexData->getNumInstances(), 1, 1);
|
||||
command->drawMesh((uint32)vertexData->getNumInstances(), 1, 1);
|
||||
} else {
|
||||
const auto& materials = vertexData->getMaterialData();
|
||||
for (const auto& materialData : materials) {
|
||||
@@ -202,5 +203,5 @@ void CachedDepthPass::createRenderPass() {
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
},
|
||||
};
|
||||
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport, "CachedDepthPass");
|
||||
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport->getRenderArea(), "CachedDepthPass");
|
||||
}
|
||||
|
||||
@@ -185,7 +185,7 @@ void DepthCullingPass::render() {
|
||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets),
|
||||
&offsets);
|
||||
if (graphics->supportMeshShading()) {
|
||||
command->drawMesh(vertexData->getNumInstances(), 1, 1);
|
||||
command->drawMesh((uint32)vertexData->getNumInstances(), 1, 1);
|
||||
} else {
|
||||
const auto& materials = vertexData->getMaterialData();
|
||||
for (const auto& materialData : materials) {
|
||||
@@ -306,5 +306,5 @@ void DepthCullingPass::createRenderPass() {
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
},
|
||||
};
|
||||
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport, "DepthCullingPass");
|
||||
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport->getRenderArea(), "DepthCullingPass");
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "Component/Camera.h"
|
||||
#include "Graphics/Command.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/Pipeline.h"
|
||||
#include "Math/Vector.h"
|
||||
#include "RenderGraph.h"
|
||||
#include "Scene/Scene.h"
|
||||
@@ -48,8 +49,8 @@ void LightCullingPass::render() {
|
||||
cullingDescriptorSet->updateBuffer(TLIGHTINDEXCOUNTER_NAME, 0, tLightIndexCounter);
|
||||
cullingDescriptorSet->updateBuffer(OLIGHTINDEXLIST_NAME, 0, oLightIndexList);
|
||||
cullingDescriptorSet->updateBuffer(TLIGHTINDEXLIST_NAME, 0, tLightIndexList);
|
||||
cullingDescriptorSet->updateTexture(OLIGHTGRID_NAME, 0, oLightGrid);
|
||||
cullingDescriptorSet->updateTexture(TLIGHTGRID_NAME, 0, tLightGrid);
|
||||
cullingDescriptorSet->updateTexture(OLIGHTGRID_NAME, 0, Gfx::PTexture2D(oLightGrid));
|
||||
cullingDescriptorSet->updateTexture(TLIGHTGRID_NAME, 0, Gfx::PTexture2D(tLightGrid));
|
||||
cullingDescriptorSet->writeChanges();
|
||||
Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("CullingCommand");
|
||||
if (getGlobals().useLightCulling) {
|
||||
@@ -278,7 +279,7 @@ void LightCullingPass::setupFrustums() {
|
||||
frustumBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
|
||||
Gfx::PDescriptorSet dispatchParamsSet = dispatchParamsLayout->allocateDescriptorSet();
|
||||
dispatchParamsSet = dispatchParamsLayout->allocateDescriptorSet();
|
||||
dispatchParamsSet->updateConstants("numThreadGroups", 0, &numThreadGroups);
|
||||
dispatchParamsSet->updateConstants("numThreads", 0, &numThreads);
|
||||
dispatchParamsSet->updateBuffer(FRUSTUMBUFFER_NAME, 0, frustumBuffer);
|
||||
@@ -292,8 +293,5 @@ void LightCullingPass::setupFrustums() {
|
||||
commands.add(std::move(command));
|
||||
graphics->executeCommands(std::move(commands));
|
||||
frustumBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
Frustum* frustums = (Frustum*)frustumBuffer->map();
|
||||
graphics->waitDeviceIdle();
|
||||
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "RayTracingPass.h"
|
||||
#include "Asset/AssetRegistry.h"
|
||||
#include "Asset/MeshAsset.h"
|
||||
#include "Asset/EnvironmentMapAsset.h"
|
||||
#include "Graphics/Mesh.h"
|
||||
#include "Graphics/RayTracing.h"
|
||||
#include "Graphics/Shader.h"
|
||||
@@ -59,7 +60,7 @@ RayTracingPass::RayTracingPass(Gfx::PGraphics graphics, PScene scene) : RenderPa
|
||||
.useMaterial = true,
|
||||
.rayTracing = true,
|
||||
});
|
||||
skyBox = AssetRegistry::findTexture("", "skybox")->getTexture().cast<Gfx::TextureCube>();
|
||||
skyBox = AssetRegistry::findEnvironmentMap("", "newport_loft")->getIrradianceMap();
|
||||
skyBoxSampler = graphics->createSampler({});
|
||||
}
|
||||
|
||||
@@ -74,6 +75,8 @@ void RayTracingPass::beginFrame(const Component::Camera& cam) {
|
||||
}
|
||||
|
||||
void RayTracingPass::render() {
|
||||
texture->changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR);
|
||||
Array<Gfx::RayTracingHitGroup> callableGroups;
|
||||
Array<Gfx::PBottomLevelAS> accelerationStructures;
|
||||
Array<InstanceData> instanceData;
|
||||
@@ -129,7 +132,18 @@ void RayTracingPass::render() {
|
||||
}
|
||||
}
|
||||
pipeline = graphics->createRayTracingPipeline(Gfx::RayTracingPipelineCreateInfo{
|
||||
.pipelineLayout = pipelineLayout, .rayGenGroup = {.shader = rayGen}, .hitGroups = callableGroups, .missGroups = {{.shader = miss}},
|
||||
.pipelineLayout = pipelineLayout,
|
||||
.rayGenGroup =
|
||||
{
|
||||
.shader = rayGen,
|
||||
},
|
||||
.hitGroups = callableGroups,
|
||||
.missGroups =
|
||||
{
|
||||
{
|
||||
.shader = miss,
|
||||
},
|
||||
},
|
||||
//.callableGroups = callableGroups,
|
||||
});
|
||||
tlas = graphics->createTopLevelAccelerationStructure(Gfx::TopLevelASCreateInfo{
|
||||
@@ -138,8 +152,8 @@ void RayTracingPass::render() {
|
||||
});
|
||||
Gfx::PDescriptorSet desc = paramsLayout->allocateDescriptorSet();
|
||||
desc->updateAccelerationStructure(TLAS_NAME, 0, tlas);
|
||||
desc->updateTexture(ACCUMULATOR_NAME, 0, radianceAccumulator);
|
||||
desc->updateTexture(TEXTURE_NAME, 0, texture);
|
||||
desc->updateTexture(ACCUMULATOR_NAME, 0, Gfx::PTexture2D(radianceAccumulator));
|
||||
desc->updateTexture(TEXTURE_NAME, 0, Gfx::PTexture2D(texture));
|
||||
desc->updateBuffer(INDEXBUFFER_NAME, 0, StaticMeshVertexData::getInstance()->getIndexBuffer());
|
||||
desc->updateTexture(SKYBOX_NAME, 0, skyBox);
|
||||
desc->updateSampler(SKYSAMPLER_NAME, 0, skyBoxSampler);
|
||||
@@ -168,15 +182,9 @@ void RayTracingPass::render() {
|
||||
}
|
||||
pass++;
|
||||
std::cout << pass << std::endl;
|
||||
texture->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR,
|
||||
Gfx::SE_ACCESS_TRANSFER_READ_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
Array<Gfx::ORenderCommand> commands;
|
||||
commands.add(std::move(command));
|
||||
graphics->executeCommands(std::move(commands));
|
||||
viewport->getOwner()->getBackBuffer()->changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, Gfx::SE_ACCESS_NONE,
|
||||
Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, Gfx::SE_ACCESS_TRANSFER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
graphics->copyTexture(Gfx::PTexture2D(texture), viewport->getOwner()->getBackBuffer());
|
||||
}
|
||||
|
||||
void RayTracingPass::endFrame() {}
|
||||
@@ -200,6 +208,8 @@ void RayTracingPass::publishOutputs() {
|
||||
texture->changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL, Gfx::SE_ACCESS_NONE, Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR);
|
||||
resources->registerRenderPassOutput("BASEPASS_COLOR", Gfx::RenderTargetAttachment(texture, Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
||||
Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
|
||||
ShaderCompilationInfo compileInfo = {
|
||||
.name = "RayGenMiss",
|
||||
.modules = {"RayGen", "AnyHit", "Miss"},
|
||||
|
||||
@@ -25,7 +25,7 @@ TerrainRenderer::TerrainRenderer(Gfx::PGraphics graphics, PScene scene, Gfx::PDe
|
||||
plainMesh.gpuCBT.bufferCount = 2;
|
||||
for (uint32 i = 0; i < 2; ++i) {
|
||||
uint32 bufferSize = cbt.bufferSize(i);
|
||||
uint32 elementSize = cbt.elementSize(i);
|
||||
//uint32 elementSize = cbt.elementSize(i);
|
||||
plainMesh.gpuCBT.bufferArray[i] = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
@@ -189,7 +189,7 @@ TerrainRenderer::TerrainRenderer(Gfx::PGraphics graphics, PScene scene, Gfx::PDe
|
||||
baseMesh.vertexBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
uint32 indexBufferSize = cpuMesh.totalNumElements * sizeof(UVector);
|
||||
//uint32 indexBufferSize = cpuMesh.totalNumElements * sizeof(UVector);
|
||||
Array<uint32> indices;
|
||||
for (uint32 i = 0; i < cpuMesh.totalNumElements * 3; ++i)
|
||||
indices.add(i);
|
||||
|
||||
@@ -131,7 +131,7 @@ void ToneMappingPass::render() {
|
||||
Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
|
||||
histogramLayout->reset();
|
||||
Gfx::PDescriptorSet histogramSet = histogramLayout->allocateDescriptorSet();
|
||||
histogramSet = histogramLayout->allocateDescriptorSet();
|
||||
histogramSet->updateConstants("minLogLum", 0, &minLogLum);
|
||||
histogramSet->updateConstants("inverseLogLumRange", 0, &inverseLogLumRange);
|
||||
histogramSet->updateConstants("timeCoeff", 0, &timeCoeff);
|
||||
@@ -216,7 +216,7 @@ void ToneMappingPass::createRenderPass() {
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
},
|
||||
};
|
||||
renderPass = graphics->createRenderPass(targetLayout, dependency, viewport, "ToneMappingPass");
|
||||
renderPass = graphics->createRenderPass(targetLayout, dependency, viewport->getRenderArea(), "ToneMappingPass");
|
||||
pipeline = graphics->createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo{
|
||||
.vertexShader = vert,
|
||||
.fragmentShader = frag,
|
||||
|
||||
@@ -62,9 +62,9 @@ void UIPass::beginFrame(const Component::Camera& cam) {
|
||||
float x = render.position.x;
|
||||
float y = render.position.y;
|
||||
//todo: convert using actual tree depth
|
||||
uint32 textureIndex = -1ul;
|
||||
uint32 textureIndex = std::numeric_limits<uint32>::max();
|
||||
if (render.backgroundTexture != nullptr) {
|
||||
textureIndex = usedTextures.size();
|
||||
textureIndex = (uint32)usedTextures.size();
|
||||
usedTextures.add(render.backgroundTexture);
|
||||
}
|
||||
elements.add(RenderElementStyle{
|
||||
@@ -112,7 +112,7 @@ void UIPass::render() {
|
||||
command->setViewport(viewport);
|
||||
command->bindPipeline(uiPipeline);
|
||||
command->bindDescriptor({viewParamsSet, uiDescriptorSet});
|
||||
command->draw(4, elements.size(), 0, 0);
|
||||
command->draw(4, (uint32)elements.size(), 0, 0);
|
||||
commands.add(std::move(command));
|
||||
graphics->executeCommands(std::move(commands));
|
||||
graphics->endRenderPass();
|
||||
@@ -170,7 +170,7 @@ void UIPass::createRenderPass() {
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
},
|
||||
};
|
||||
renderPass = graphics->createRenderPass(std::move(layout), dependency, viewport, "TextPass");
|
||||
renderPass = graphics->createRenderPass(std::move(layout), dependency, viewport->getRenderArea(), "TextPass");
|
||||
|
||||
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||
.name = "TextVertex",
|
||||
|
||||
@@ -42,7 +42,7 @@ class UIPass : public RenderPass {
|
||||
Vector color;
|
||||
float opacity = 1;
|
||||
float z = 0;
|
||||
uint32 textureIndex = -1ul;
|
||||
uint32 textureIndex = std::numeric_limits<uint32>::max();
|
||||
uint32 pad0;
|
||||
uint32 pad1;
|
||||
};
|
||||
|
||||
@@ -10,8 +10,8 @@ WaterRenderer::WaterRenderer(Gfx::PGraphics graphics, PScene scene, Gfx::PDescri
|
||||
: graphics(graphics), scene(scene) {
|
||||
skyBox = AssetRegistry::findTexture("", "skyboxsun5deg_tn")->getTexture().cast<Gfx::TextureCube>();
|
||||
logN = (int)log2(params.N);
|
||||
threadGroupsX = ceil(params.N / 8.0f);
|
||||
threadGroupsY = ceil(params.N / 8.0f);
|
||||
threadGroupsX = (uint32)ceil(params.N / 8.0f);
|
||||
threadGroupsY = (uint32)ceil(params.N / 8.0f);
|
||||
|
||||
materialUniforms = graphics->createUniformBuffer(UniformBufferCreateInfo{
|
||||
.sourceData =
|
||||
@@ -263,7 +263,7 @@ WaterRenderer::WaterRenderer(Gfx::PGraphics graphics, PScene scene, Gfx::PDescri
|
||||
.windSpeed = 2,
|
||||
.windDirection = 22,
|
||||
.fetch = 100000,
|
||||
.spreadBlend = 0.642,
|
||||
.spreadBlend = 0.642f,
|
||||
.swell = 1,
|
||||
.peakEnhancement = 1,
|
||||
.shortWavesFade = 0.25f,
|
||||
@@ -523,8 +523,8 @@ void WaterRenderer::updateFFTDescriptor() {
|
||||
spectrumBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
|
||||
params.deltaTime = Gfx::getCurrentFrameDelta();
|
||||
params.frameTime = Gfx::getCurrentFrameTime();
|
||||
params.deltaTime = (float)Gfx::getCurrentFrameDelta();
|
||||
params.frameTime = (float)Gfx::getCurrentFrameTime();
|
||||
paramsBuffer->updateContents(0, sizeof(ComputeParams), ¶ms);
|
||||
paramsBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_UNIFORM_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
|
||||
@@ -57,8 +57,8 @@ class WaterRenderer {
|
||||
};
|
||||
StaticArray<DisplaySpectrumSettings, 8> displaySpectrums;
|
||||
struct ComputeParams {
|
||||
float frameTime;
|
||||
float deltaTime;
|
||||
float frameTime = 0.0f;
|
||||
float deltaTime = 0.0f;
|
||||
float gravity = 9.81f;
|
||||
float repeatTime = 200.0f;
|
||||
float depth = 20.0f;
|
||||
|
||||
@@ -9,6 +9,12 @@ RenderTargetAttachment::RenderTargetAttachment(PTexture2D texture, SeImageLayout
|
||||
: clear(), componentFlags(0), texture(texture), initialLayout(initialLayout), finalLayout(finalLayout), loadOp(loadOp),
|
||||
storeOp(storeOp), stencilLoadOp(stencilLoadOp), stencilStoreOp(stencilStoreOp) {}
|
||||
|
||||
RenderTargetAttachment::RenderTargetAttachment(PTextureCube texture, SeImageLayout initialLayout, SeImageLayout finalLayout,
|
||||
SeAttachmentLoadOp loadOp, SeAttachmentStoreOp storeOp, SeAttachmentLoadOp stencilLoadOp,
|
||||
SeAttachmentStoreOp stencilStoreOp)
|
||||
: clear(), componentFlags(0), texture(texture), initialLayout(initialLayout), finalLayout(finalLayout), loadOp(loadOp),
|
||||
storeOp(storeOp), stencilLoadOp(stencilLoadOp), stencilStoreOp(stencilStoreOp) {}
|
||||
|
||||
RenderTargetAttachment::RenderTargetAttachment(PViewport viewport, SeImageLayout initialLayout, SeImageLayout finalLayout,
|
||||
SeAttachmentLoadOp loadOp, SeAttachmentStoreOp storeOp, SeAttachmentLoadOp stencilLoadOp,
|
||||
SeAttachmentStoreOp stencilStoreOp)
|
||||
|
||||
@@ -14,16 +14,21 @@ class RenderTargetAttachment {
|
||||
SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE,
|
||||
SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE);
|
||||
|
||||
RenderTargetAttachment(PTextureCube texture, SeImageLayout initialLayout, SeImageLayout finalLayout,
|
||||
SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD,
|
||||
SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE,
|
||||
SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE);
|
||||
RenderTargetAttachment(PViewport viewport, SeImageLayout initialLayout, SeImageLayout finalLayout,
|
||||
SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD,
|
||||
SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE,
|
||||
SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE);
|
||||
~RenderTargetAttachment();
|
||||
PTexture2D getTexture() const {
|
||||
void setTexture(PTexture _texture) { texture = _texture; }
|
||||
PTexture getTexture() const {
|
||||
if (viewport != nullptr) {
|
||||
return viewport->getOwner()->getBackBuffer();
|
||||
return PTexture(viewport->getOwner()->getBackBuffer());
|
||||
}
|
||||
return texture;
|
||||
}
|
||||
@@ -68,7 +73,7 @@ class RenderTargetAttachment {
|
||||
SeColorComponentFlags componentFlags = 0;
|
||||
|
||||
protected:
|
||||
PTexture2D texture = nullptr;
|
||||
PTexture texture = nullptr;
|
||||
PViewport viewport = nullptr;
|
||||
SeImageLayout initialLayout = SE_IMAGE_LAYOUT_UNDEFINED;
|
||||
SeImageLayout finalLayout = SE_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
||||
@@ -7,9 +7,7 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
extern List<VertexData*> vertexDataList;
|
||||
|
||||
StaticMeshVertexData::StaticMeshVertexData() { vertexDataList.add(this); }
|
||||
StaticMeshVertexData::StaticMeshVertexData() { VertexData::addVertexDataInstance(this); }
|
||||
|
||||
StaticMeshVertexData::~StaticMeshVertexData() {}
|
||||
|
||||
@@ -41,11 +39,12 @@ void StaticMeshVertexData::loadTangents(uint64 offset, const Array<TangentType>&
|
||||
std::memcpy(tanData.data() + offset, data.data(), data.size() * sizeof(TangentType));
|
||||
dirty = true;
|
||||
}
|
||||
void StaticMeshVertexData::loadBitangents(uint64 offset, const Array<BiTangentType>& data) {
|
||||
|
||||
/*void StaticMeshVertexData::loadBitangents(uint64 offset, const Array<BiTangentType>& data) {
|
||||
assert(offset + data.size() <= head);
|
||||
std::memcpy(bitData.data() + offset, data.data(), data.size() * sizeof(BiTangentType));
|
||||
dirty = true;
|
||||
}
|
||||
}*/
|
||||
|
||||
void StaticMeshVertexData::loadColors(uint64 offset, const Array<ColorType>& data) {
|
||||
assert(offset + data.size() <= head);
|
||||
@@ -71,17 +70,17 @@ void StaticMeshVertexData::serializeMesh(MeshId id, ArchiveBuffer& buffer) {
|
||||
Array<PositionType> pos(numVertices);
|
||||
Array<NormalType> nor(numVertices);
|
||||
Array<TangentType> tan(numVertices);
|
||||
Array<BiTangentType> bit(numVertices);
|
||||
//Array<BiTangentType> bit(numVertices);
|
||||
Array<ColorType> col(numVertices);
|
||||
std::memcpy(pos.data(), posData.data() + offset, numVertices * sizeof(PositionType));
|
||||
std::memcpy(nor.data(), norData.data() + offset, numVertices * sizeof(NormalType));
|
||||
std::memcpy(tan.data(), tanData.data() + offset, numVertices * sizeof(TangentType));
|
||||
std::memcpy(bit.data(), bitData.data() + offset, numVertices * sizeof(BiTangentType));
|
||||
//std::memcpy(bit.data(), bitData.data() + offset, numVertices * sizeof(BiTangentType));
|
||||
std::memcpy(col.data(), colData.data() + offset, numVertices * sizeof(ColorType));
|
||||
Serialization::save(buffer, pos);
|
||||
Serialization::save(buffer, nor);
|
||||
Serialization::save(buffer, tan);
|
||||
Serialization::save(buffer, bit);
|
||||
//Serialization::save(buffer, bit);
|
||||
Serialization::save(buffer, col);
|
||||
}
|
||||
|
||||
@@ -101,22 +100,22 @@ uint64 StaticMeshVertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer) {
|
||||
Array<PositionType> pos;
|
||||
Array<NormalType> nor;
|
||||
Array<TangentType> tan;
|
||||
Array<BiTangentType> bit;
|
||||
//Array<BiTangentType> bit;
|
||||
Array<ColorType> col;
|
||||
Serialization::load(buffer, pos);
|
||||
Serialization::load(buffer, nor);
|
||||
Serialization::load(buffer, tan);
|
||||
Serialization::load(buffer, bit);
|
||||
//Serialization::load(buffer, bit);
|
||||
Serialization::load(buffer, col);
|
||||
loadPositions(offset, pos);
|
||||
loadNormals(offset, nor);
|
||||
loadTangents(offset, tan);
|
||||
loadBitangents(offset, bit);
|
||||
//loadBitangents(offset, bit);
|
||||
loadColors(offset, col);
|
||||
result += pos.size() * sizeof(PositionType);
|
||||
result += nor.size() * sizeof(NormalType);
|
||||
result += tan.size() * sizeof(TangentType);
|
||||
result += bit.size() * sizeof(BiTangentType);
|
||||
//result += bit.size() * sizeof(BiTangentType);
|
||||
result += col.size() * sizeof(ColorType);
|
||||
return result;
|
||||
}
|
||||
@@ -136,10 +135,10 @@ void StaticMeshVertexData::init(Gfx::PGraphics _graphics) {
|
||||
.name = TANGENTS_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
/*descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = BITANGENTS_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
});*/
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = COLORS_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
@@ -161,25 +160,17 @@ void StaticMeshVertexData::destroy() {
|
||||
positions = nullptr;
|
||||
normals = nullptr;
|
||||
tangents = nullptr;
|
||||
biTangents = nullptr;
|
||||
//biTangents = nullptr;
|
||||
colors = nullptr;
|
||||
descriptorSet = nullptr;
|
||||
descriptorLayout = nullptr;
|
||||
}
|
||||
|
||||
void StaticMeshVertexData::bindBuffers(Gfx::PRenderCommand) {
|
||||
// TODO: for legacy vertex buffer binding
|
||||
}
|
||||
|
||||
Gfx::PDescriptorLayout StaticMeshVertexData::getVertexDataLayout() { return descriptorLayout; }
|
||||
|
||||
Gfx::PDescriptorSet StaticMeshVertexData::getVertexDataSet() { return descriptorSet; }
|
||||
|
||||
void StaticMeshVertexData::resizeBuffers() {
|
||||
posData.resize(verticesAllocated);
|
||||
norData.resize(verticesAllocated);
|
||||
tanData.resize(verticesAllocated);
|
||||
bitData.resize(verticesAllocated);
|
||||
//bitData.resize(verticesAllocated);
|
||||
colData.resize(verticesAllocated);
|
||||
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
|
||||
texData[i].resize(verticesAllocated);
|
||||
@@ -212,14 +203,14 @@ void StaticMeshVertexData::updateBuffers() {
|
||||
},
|
||||
.name = "Tangents",
|
||||
});
|
||||
biTangents = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
/*biTangents = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = verticesAllocated * sizeof(BiTangentType),
|
||||
.data = (uint8*)bitData.data(),
|
||||
},
|
||||
.name = "BiTangents",
|
||||
});
|
||||
});*/
|
||||
colors = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
@@ -243,9 +234,9 @@ void StaticMeshVertexData::updateBuffers() {
|
||||
descriptorSet->updateBuffer(POSITIONS_NAME, 0, positions);
|
||||
descriptorSet->updateBuffer(NORMALS_NAME, 0, normals);
|
||||
descriptorSet->updateBuffer(TANGENTS_NAME, 0, tangents);
|
||||
descriptorSet->updateBuffer(BITANGENTS_NAME, 0, biTangents);
|
||||
//descriptorSet->updateBuffer(BITANGENTS_NAME, 0, biTangents);
|
||||
descriptorSet->updateBuffer(COLORS_NAME, 0, colors);
|
||||
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
|
||||
for (uint32 i = 0; i < MAX_TEXCOORDS; ++i) {
|
||||
descriptorSet->updateBuffer(TEXCOORDS_NAME, i, texCoords[i]);
|
||||
}
|
||||
descriptorSet->writeChanges();
|
||||
|
||||
@@ -5,14 +5,13 @@
|
||||
#include "VertexData.h"
|
||||
#include "entt/entt.hpp"
|
||||
|
||||
|
||||
namespace Seele {
|
||||
class StaticMeshVertexData : public VertexData {
|
||||
public:
|
||||
using PositionType = Vector;
|
||||
using NormalType = Vector;
|
||||
using TangentType = Vector;
|
||||
using BiTangentType = Vector;
|
||||
using TangentType = Vector4;
|
||||
//using BiTangentType = Vector;
|
||||
using TexCoordType = U16Vector2;
|
||||
using ColorType = U16Vector;
|
||||
|
||||
@@ -23,15 +22,14 @@ class StaticMeshVertexData : public VertexData {
|
||||
void loadTexCoords(uint64 offset, uint64 index, const Array<TexCoordType>& data);
|
||||
void loadNormals(uint64 offset, const Array<NormalType>& data);
|
||||
void loadTangents(uint64 offset, const Array<TangentType>& data);
|
||||
void loadBitangents(uint64 offset, const Array<BiTangentType>& data);
|
||||
//void loadBitangents(uint64 offset, const Array<BiTangentType>& data);
|
||||
void loadColors(uint64 offset, const Array<ColorType>& data);
|
||||
virtual void serializeMesh(MeshId id, ArchiveBuffer& buffer) override;
|
||||
virtual uint64 deserializeMesh(MeshId id, ArchiveBuffer& buffer) override;
|
||||
virtual void init(Gfx::PGraphics graphics) override;
|
||||
virtual void destroy() override;
|
||||
virtual void bindBuffers(Gfx::PRenderCommand command) override;
|
||||
virtual Gfx::PDescriptorLayout getVertexDataLayout() override;
|
||||
virtual Gfx::PDescriptorSet getVertexDataSet() override;
|
||||
virtual Gfx::PDescriptorLayout getVertexDataLayout() override { return descriptorLayout; }
|
||||
virtual Gfx::PDescriptorSet getVertexDataSet() override { return descriptorSet; }
|
||||
virtual std::string getTypeName() const override { return "StaticMeshVertexData"; }
|
||||
virtual Gfx::PShaderBuffer getPositionBuffer() const override { return positions; }
|
||||
|
||||
@@ -39,7 +37,6 @@ class StaticMeshVertexData : public VertexData {
|
||||
virtual void resizeBuffers() override;
|
||||
virtual void updateBuffers() override;
|
||||
|
||||
|
||||
Gfx::OShaderBuffer positions;
|
||||
constexpr static const char* POSITIONS_NAME = "positions";
|
||||
Gfx::OShaderBuffer texCoords[MAX_TEXCOORDS];
|
||||
@@ -48,15 +45,15 @@ class StaticMeshVertexData : public VertexData {
|
||||
constexpr static const char* NORMALS_NAME = "normals";
|
||||
Gfx::OShaderBuffer tangents;
|
||||
constexpr static const char* TANGENTS_NAME = "tangents";
|
||||
Gfx::OShaderBuffer biTangents;
|
||||
constexpr static const char* BITANGENTS_NAME = "biTangents";
|
||||
//Gfx::OShaderBuffer biTangents;
|
||||
//constexpr static const char* BITANGENTS_NAME = "biTangents";
|
||||
Gfx::OShaderBuffer colors;
|
||||
constexpr static const char* COLORS_NAME = "colors";
|
||||
Array<PositionType> posData;
|
||||
Array<TexCoordType> texData[MAX_TEXCOORDS];
|
||||
Array<NormalType> norData;
|
||||
Array<TangentType> tanData;
|
||||
Array<BiTangentType> bitData;
|
||||
//Array<BiTangentType> bitData;
|
||||
Array<ColorType> colData;
|
||||
Gfx::ODescriptorLayout descriptorLayout;
|
||||
Gfx::PDescriptorSet descriptorSet;
|
||||
|
||||
@@ -90,7 +90,7 @@ void VertexData::createDescriptors() {
|
||||
Array<uint32> cullingOffsets;
|
||||
for (auto& mat : materialData) {
|
||||
for (auto& instance : mat.instances) {
|
||||
instance.offsets.instanceOffset = instanceData.size();
|
||||
instance.offsets.instanceOffset = (uint32)instanceData.size();
|
||||
MaterialOffsets offsets = instance.materialInstance->getMaterialOffsets();
|
||||
instance.offsets.textureOffset = offsets.textureOffset;
|
||||
instance.offsets.samplerOffset = offsets.samplerOffset;
|
||||
@@ -104,7 +104,7 @@ void VertexData::createDescriptors() {
|
||||
}
|
||||
}
|
||||
for (uint32 i = 0; i < transparentData.size(); ++i) {
|
||||
transparentData[i].offsets.instanceOffset = instanceData.size();
|
||||
transparentData[i].offsets.instanceOffset = (uint32)instanceData.size();
|
||||
cullingOffsets.add(transparentData[i].cullingOffset);
|
||||
instanceData.add(transparentData[i].instanceData);
|
||||
instanceMeshData.add(transparentData[i].meshData);
|
||||
@@ -139,17 +139,17 @@ void VertexData::createDescriptors() {
|
||||
void VertexData::loadMesh(MeshId id, Array<uint32> loadedIndices, Array<Meshlet> loadedMeshlets) {
|
||||
std::unique_lock l(vertexDataLock);
|
||||
for (auto&& chunk : loadedMeshlets | std::views::chunk(2048)) {
|
||||
uint32 meshletOffset = meshlets.size();
|
||||
uint32 meshletOffset = (uint32)meshlets.size();
|
||||
AABB meshAABB;
|
||||
uint32 numMeshlets = 0;
|
||||
for (auto&& m : chunk) {
|
||||
numMeshlets++;
|
||||
//...
|
||||
meshAABB = meshAABB.combine(m.boundingBox);
|
||||
uint32 vertexOffset = vertexIndices.size();
|
||||
uint32 vertexOffset = (uint32)vertexIndices.size();
|
||||
vertexIndices.resize(vertexOffset + m.numVertices);
|
||||
std::memcpy(vertexIndices.data() + vertexOffset, m.uniqueVertices, m.numVertices * sizeof(uint32));
|
||||
uint32 primitiveOffset = primitiveIndices.size();
|
||||
uint32 primitiveOffset = (uint32)primitiveIndices.size();
|
||||
primitiveIndices.resize(primitiveOffset + (m.numPrimitives * 3));
|
||||
std::memcpy(primitiveIndices.data() + primitiveOffset, m.primitiveLayout, m.numPrimitives * 3 * sizeof(uint8));
|
||||
meshlets.add(MeshletDescription{
|
||||
@@ -268,6 +268,8 @@ uint64 VertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer) {
|
||||
|
||||
List<VertexData*> vertexDataList;
|
||||
|
||||
void VertexData::addVertexDataInstance(VertexData* vertexData) { vertexDataList.add(vertexData); }
|
||||
|
||||
List<VertexData*> VertexData::getList() { return vertexDataList; }
|
||||
|
||||
VertexData* VertexData::findByTypeName(std::string name) {
|
||||
@@ -349,7 +351,7 @@ void VertexData::destroy() {
|
||||
}
|
||||
|
||||
uint32 VertexData::addCullingMapping(MeshId id) {
|
||||
uint32 result = meshletCount;
|
||||
uint32 result = (uint32)meshletCount;
|
||||
for (const auto& md : getMeshData(id)) {
|
||||
meshletCount += md.numMeshlets;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "Meshlet.h"
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
constexpr uint64 MAX_TEXCOORDS = 8;
|
||||
constexpr uint32 MAX_TEXCOORDS = 8;
|
||||
|
||||
namespace Seele {
|
||||
DECLARE_REF(MaterialInstance)
|
||||
@@ -64,7 +64,6 @@ class VertexData {
|
||||
uint64 getMeshVertexCount(MeshId id) { return meshVertexCounts[id]; }
|
||||
virtual void serializeMesh(MeshId id, ArchiveBuffer& buffer);
|
||||
virtual uint64 deserializeMesh(MeshId id, ArchiveBuffer& buffer);
|
||||
virtual void bindBuffers(Gfx::PRenderCommand command) = 0;
|
||||
virtual Gfx::PDescriptorLayout getVertexDataLayout() = 0;
|
||||
virtual Gfx::PDescriptorSet getVertexDataSet() = 0;
|
||||
virtual std::string getTypeName() const = 0;
|
||||
@@ -77,11 +76,10 @@ class VertexData {
|
||||
const Array<TransparentDraw>& getTransparentData() const { return transparentData; }
|
||||
const Array<Gfx::PBottomLevelAS>& getRayTracingData() const { return rayTracingScene; }
|
||||
const Array<MeshData>& getMeshData(MeshId id) const { return meshData[id]; }
|
||||
void registerBottomLevelAccelerationStructure(Gfx::PBottomLevelAS blas) {
|
||||
dataToBuild.add(blas);
|
||||
}
|
||||
uint64 getIndicesOffset(uint32 meshletIndex) { return meshlets[meshletIndex].indicesOffset; }
|
||||
void registerBottomLevelAccelerationStructure(Gfx::PBottomLevelAS blas) { dataToBuild.add(blas); }
|
||||
uint32 getIndicesOffset(uint32 meshletIndex) { return meshlets[meshletIndex].indicesOffset; }
|
||||
uint64 getNumInstances() const { return instanceData.size(); }
|
||||
static void addVertexDataInstance(VertexData* vertexData);
|
||||
static List<VertexData*> getList();
|
||||
static VertexData* findByTypeName(std::string name);
|
||||
virtual void init(Gfx::PGraphics graphics);
|
||||
@@ -110,6 +108,7 @@ class VertexData {
|
||||
uint32 indicesOffset = 0;
|
||||
};
|
||||
std::mutex materialDataLock;
|
||||
debug_resource vertexDataResource = {"VertexData"};
|
||||
Array<MaterialData> materialData;
|
||||
Array<TransparentDraw> transparentData;
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@ using namespace Seele::Vulkan;
|
||||
BufferAllocation::BufferAllocation(PGraphics graphics, const std::string& name, VkBufferCreateInfo bufferInfo,
|
||||
VmaAllocationCreateInfo allocInfo, Gfx::QueueType owner, uint64 alignment)
|
||||
: CommandBoundResource(graphics, name), size(bufferInfo.size), owner(owner) {
|
||||
if (bufferInfo.size == 0)
|
||||
return;
|
||||
VK_CHECK(vmaCreateBufferWithAlignment(graphics->getAllocator(), &bufferInfo, &allocInfo, alignment, &buffer, &allocation, &info));
|
||||
vmaGetAllocationMemoryProperties(graphics->getAllocator(), allocation, &properties);
|
||||
assert(!name.empty());
|
||||
@@ -102,7 +104,7 @@ void BufferAllocation::updateContents(uint64 regionOffset, uint64 regionSize, vo
|
||||
.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT,
|
||||
.usage = VMA_MEMORY_USAGE_AUTO,
|
||||
};
|
||||
OBufferAllocation staging = new BufferAllocation(graphics, "UpdateStaging", stagingInfo, stagingAlloc, Gfx::QueueType::GRAPHICS);
|
||||
OBufferAllocation staging = new BufferAllocation(graphics, fmt::format("{0}UpdateStaging", name), stagingInfo, stagingAlloc, Gfx::QueueType::GRAPHICS);
|
||||
|
||||
uint8* data;
|
||||
VK_CHECK(vmaMapMemory(graphics->getAllocator(), staging->allocation, (void**)&data));
|
||||
@@ -111,7 +113,7 @@ void BufferAllocation::updateContents(uint64 regionOffset, uint64 regionSize, vo
|
||||
vmaUnmapMemory(graphics->getAllocator(), staging->allocation);
|
||||
|
||||
Gfx::QueueType prevOwner = owner;
|
||||
// transferOwnership(Gfx::QueueType::TRANSFER);
|
||||
transferOwnership(Gfx::QueueType::TRANSFER);
|
||||
|
||||
PCommand cmd = graphics->getQueueCommands(Gfx::QueueType::GRAPHICS)->getCommands();
|
||||
VkBufferCopy copy = {
|
||||
@@ -125,7 +127,7 @@ void BufferAllocation::updateContents(uint64 regionOffset, uint64 regionSize, vo
|
||||
pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
|
||||
// transferOwnership(prevOwner);
|
||||
transferOwnership(prevOwner);
|
||||
graphics->getDestructionManager()->queueResourceForDestruction(std::move(staging));
|
||||
}
|
||||
|
||||
@@ -147,7 +149,7 @@ void BufferAllocation::readContents(uint64 regionOffset, uint64 regionSize, void
|
||||
OBufferAllocation staging = new BufferAllocation(graphics, "ReadStaging", stagingInfo, stagingAlloc, Gfx::QueueType::GRAPHICS);
|
||||
|
||||
Gfx::QueueType prevOwner = owner;
|
||||
// transferOwnership(Gfx::QueueType::TRANSFER);
|
||||
transferOwnership(Gfx::QueueType::TRANSFER);
|
||||
|
||||
PCommandPool pool = graphics->getQueueCommands(Gfx::QueueType::TRANSFER);
|
||||
PCommand cmd = pool->getCommands();
|
||||
@@ -164,7 +166,7 @@ void BufferAllocation::readContents(uint64 regionOffset, uint64 regionSize, void
|
||||
pool->submitCommands();
|
||||
cmd->getFence()->wait(1000000);
|
||||
|
||||
// transferOwnership(prevOwner);
|
||||
transferOwnership(prevOwner);
|
||||
|
||||
uint8* data;
|
||||
VK_CHECK(vmaMapMemory(graphics->getAllocator(), staging->allocation, (void**)&data));
|
||||
@@ -276,11 +278,11 @@ void Buffer::rotateBuffer(uint64 size, bool preserveContents) {
|
||||
return;
|
||||
}
|
||||
buffers.add(nullptr);
|
||||
createBuffer(size, buffers.size() - 1);
|
||||
createBuffer(size, (uint32)buffers.size() - 1);
|
||||
if (preserveContents) {
|
||||
copyBuffer(currentBuffer, buffers.size() - 1);
|
||||
}
|
||||
currentBuffer = buffers.size() - 1;
|
||||
currentBuffer = (uint32)buffers.size() - 1;
|
||||
}
|
||||
|
||||
void Buffer::createBuffer(uint64 size, uint32 destIndex) {
|
||||
@@ -437,6 +439,8 @@ void* ShaderBuffer::map() { return Vulkan::Buffer::map(); }
|
||||
void ShaderBuffer::unmap() { Vulkan::Buffer::unmap(); }
|
||||
|
||||
void ShaderBuffer::clear() {
|
||||
if (getAlloc() == nullptr)
|
||||
return;
|
||||
PCommand command = graphics->getQueueCommands(getAlloc()->owner)->getCommands();
|
||||
command->bindResource(PBufferAllocation(getAlloc()));
|
||||
vkCmdFillBuffer(command->getHandle(), Vulkan::Buffer::getHandle(), 0, VK_WHOLE_SIZE, 0);
|
||||
|
||||
@@ -18,7 +18,6 @@ class Command {
|
||||
Command(PGraphics graphics, PCommandPool pool);
|
||||
~Command();
|
||||
constexpr VkCommandBuffer getHandle() { return handle; }
|
||||
void reset();
|
||||
void begin();
|
||||
void end();
|
||||
void beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer);
|
||||
@@ -46,8 +45,6 @@ class Command {
|
||||
OFence fence;
|
||||
OSemaphore signalSemaphore;
|
||||
State state;
|
||||
VkViewport currentViewport;
|
||||
VkRect2D currentScissor;
|
||||
VkCommandBuffer handle;
|
||||
PRenderPass boundRenderPass;
|
||||
PFramebuffer boundFramebuffer;
|
||||
@@ -91,12 +88,12 @@ class RenderCommand : public Gfx::RenderCommand {
|
||||
virtual void traceRays(uint32 width, uint32 height, uint32 depth) override;
|
||||
|
||||
private:
|
||||
PGraphicsPipeline pipeline;
|
||||
PRayTracingPipeline rtPipeline;
|
||||
bool ready;
|
||||
PGraphicsPipeline pipeline = nullptr;
|
||||
PRayTracingPipeline rtPipeline = nullptr;
|
||||
bool ready = false;
|
||||
Array<PCommandBoundResource> boundResources;
|
||||
VkViewport currentViewport;
|
||||
VkRect2D currentScissor;
|
||||
VkViewport currentViewport = VkViewport();
|
||||
VkRect2D currentScissor = VkRect2D();
|
||||
PGraphics graphics;
|
||||
std::thread::id threadId;
|
||||
VkCommandBuffer handle;
|
||||
@@ -123,10 +120,8 @@ class ComputeCommand : public Gfx::ComputeCommand {
|
||||
|
||||
private:
|
||||
PComputePipeline pipeline;
|
||||
bool ready;
|
||||
bool ready = false;
|
||||
Array<PCommandBoundResource> boundResources;
|
||||
VkViewport currentViewport;
|
||||
VkRect2D currentScissor;
|
||||
PGraphics graphics;
|
||||
std::thread::id threadId;
|
||||
VkCommandBuffer handle;
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
VkBool32 Seele::Vulkan::debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData) {
|
||||
VkBool32 Seele::Vulkan::debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT, VkDebugUtilsMessageTypeFlagsEXT,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void*) {
|
||||
std::cerr << pCallbackData->pMessage << std::endl;
|
||||
return VK_FALSE;
|
||||
}
|
||||
|
||||
@@ -51,11 +51,11 @@ void DescriptorLayout::create() {
|
||||
constantsSize += gfxBinding.uniformLength;
|
||||
constantsStages |= gfxBinding.shaderStages;
|
||||
} else {
|
||||
mappings[gfxBinding.name] = {
|
||||
mappings[gfxBinding.name] = DescriptorMapping{
|
||||
.binding = (uint32)bindings.size(),
|
||||
.type = cast(gfxBinding.descriptorType),
|
||||
};
|
||||
bindings.add({
|
||||
bindings.add(VkDescriptorSetLayoutBinding{
|
||||
.binding = (uint32)bindings.size(),
|
||||
.descriptorType = cast(gfxBinding.descriptorType),
|
||||
.descriptorCount = gfxBinding.descriptorCount,
|
||||
@@ -97,11 +97,11 @@ DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout)
|
||||
perTypeSizes[binding.descriptorType] += 512;
|
||||
}
|
||||
Array<VkDescriptorPoolSize> poolSizes;
|
||||
for (const auto [type, num] : perTypeSizes) {
|
||||
VkDescriptorPoolSize size;
|
||||
size.descriptorCount = num;
|
||||
size.type = cast(type);
|
||||
poolSizes.add(size);
|
||||
for (const auto& [type, num] : perTypeSizes) {
|
||||
poolSizes.add(VkDescriptorPoolSize{
|
||||
.type = cast(type),
|
||||
.descriptorCount = num,
|
||||
});
|
||||
}
|
||||
VkDescriptorPoolCreateInfo createInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||
@@ -199,14 +199,14 @@ DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner)
|
||||
|
||||
DescriptorSet::~DescriptorSet() {}
|
||||
|
||||
void DescriptorSet::updateConstants(const std::string& name, uint32 offset, void* data) {
|
||||
std::memcpy(constantData.data() + owner->getLayout()->mappings[name].constantOffset, (char*)data + offset,
|
||||
owner->getLayout()->mappings[name].constantSize);
|
||||
void DescriptorSet::updateConstants(const std::string& mappingName, uint32 offset, void* data) {
|
||||
std::memcpy(constantData.data() + owner->getLayout()->mappings[mappingName].constantOffset, (char*)data + offset,
|
||||
owner->getLayout()->mappings[mappingName].constantSize);
|
||||
}
|
||||
|
||||
void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer shaderBuffer) {
|
||||
void DescriptorSet::updateBuffer(const std::string& mappingName, uint32 index, Gfx::PShaderBuffer shaderBuffer) {
|
||||
PShaderBuffer vulkanBuffer = shaderBuffer.cast<ShaderBuffer>();
|
||||
const auto& map = owner->getLayout()->mappings[name];
|
||||
const auto& map = owner->getLayout()->mappings[mappingName];
|
||||
uint32 binding = map.binding;
|
||||
if (boundResources[binding][index] == vulkanBuffer->getAlloc() || vulkanBuffer->getAlloc() == nullptr) {
|
||||
return;
|
||||
@@ -230,9 +230,9 @@ void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PSh
|
||||
boundResources[binding][index] = vulkanBuffer->getAlloc();
|
||||
}
|
||||
|
||||
void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer indexBuffer) {
|
||||
void DescriptorSet::updateBuffer(const std::string& mappingName, uint32 index, Gfx::PVertexBuffer indexBuffer) {
|
||||
PVertexBuffer vulkanBuffer = indexBuffer.cast<VertexBuffer>();
|
||||
const auto& map = owner->getLayout()->mappings[name];
|
||||
const auto& map = owner->getLayout()->mappings[mappingName];
|
||||
uint32 binding = map.binding;
|
||||
if (boundResources[binding][index] == vulkanBuffer->getAlloc() || vulkanBuffer->getAlloc() == nullptr) {
|
||||
return;
|
||||
@@ -257,9 +257,9 @@ void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PVe
|
||||
boundResources[binding][index] = vulkanBuffer->getAlloc();
|
||||
}
|
||||
|
||||
void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer indexBuffer) {
|
||||
void DescriptorSet::updateBuffer(const std::string& mappingName, uint32 index, Gfx::PIndexBuffer indexBuffer) {
|
||||
PIndexBuffer vulkanBuffer = indexBuffer.cast<IndexBuffer>();
|
||||
const auto& map = owner->getLayout()->mappings[name];
|
||||
const auto& map = owner->getLayout()->mappings[mappingName];
|
||||
uint32 binding = map.binding;
|
||||
if (boundResources[binding][index] == vulkanBuffer->getAlloc() || vulkanBuffer->getAlloc() == nullptr) {
|
||||
return;
|
||||
@@ -284,9 +284,9 @@ void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PIn
|
||||
boundResources[binding][index] = vulkanBuffer->getAlloc();
|
||||
}
|
||||
|
||||
void DescriptorSet::updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) {
|
||||
void DescriptorSet::updateSampler(const std::string& mappingName, uint32 index, Gfx::PSampler samplerState) {
|
||||
PSampler vulkanSampler = samplerState.cast<Sampler>();
|
||||
const auto& map = owner->getLayout()->mappings[name];
|
||||
const auto& map = owner->getLayout()->mappings[mappingName];
|
||||
uint32 binding = map.binding;
|
||||
if (boundResources[binding][index] == vulkanSampler->getHandle()) {
|
||||
return;
|
||||
@@ -312,9 +312,9 @@ void DescriptorSet::updateSampler(const std::string& name, uint32 index, Gfx::PS
|
||||
boundResources[binding][index] = vulkanSampler->getHandle();
|
||||
}
|
||||
|
||||
void DescriptorSet::updateTexture(const std::string& name, uint32 index, Gfx::PTexture2D texture) {
|
||||
void DescriptorSet::updateTexture(const std::string& mappingName, uint32 index, Gfx::PTexture texture) {
|
||||
TextureBase* vulkanTexture = texture.cast<TextureBase>().getHandle();
|
||||
const auto& map = owner->getLayout()->mappings[name];
|
||||
const auto& map = owner->getLayout()->mappings[mappingName];
|
||||
uint32 binding = map.binding;
|
||||
if (boundResources[binding][index] == vulkanTexture->getHandle()) {
|
||||
return;
|
||||
@@ -340,65 +340,9 @@ void DescriptorSet::updateTexture(const std::string& name, uint32 index, Gfx::PT
|
||||
boundResources[binding][index] = vulkanTexture->getHandle();
|
||||
}
|
||||
|
||||
void DescriptorSet::updateTexture(const std::string& name, uint32 index, Gfx::PTexture3D texture) {
|
||||
TextureBase* vulkanTexture = texture.cast<TextureBase>().getHandle();
|
||||
const auto& map = owner->getLayout()->mappings[name];
|
||||
uint32 binding = map.binding;
|
||||
if (boundResources[binding][index] == vulkanTexture->getHandle()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// It is assumed that the image is in the correct layout
|
||||
imageInfos.add(VkDescriptorImageInfo{
|
||||
.sampler = VK_NULL_HANDLE,
|
||||
.imageView = vulkanTexture->getView(),
|
||||
.imageLayout = cast(vulkanTexture->getLayout()),
|
||||
});
|
||||
writeDescriptors.add(VkWriteDescriptorSet{
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.pNext = nullptr,
|
||||
.dstSet = setHandle,
|
||||
.dstBinding = binding,
|
||||
.dstArrayElement = index,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = map.type,
|
||||
.pImageInfo = &imageInfos.back(),
|
||||
});
|
||||
|
||||
boundResources[binding][index] = vulkanTexture->getHandle();
|
||||
}
|
||||
|
||||
void DescriptorSet::updateTexture(const std::string& name, uint32 index, Gfx::PTextureCube texture) {
|
||||
TextureBase* vulkanTexture = texture.cast<TextureBase>().getHandle();
|
||||
const auto& map = owner->getLayout()->mappings[name];
|
||||
uint32 binding = map.binding;
|
||||
if (boundResources[binding][index] == vulkanTexture->getHandle()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// It is assumed that the image is in the correct layout
|
||||
imageInfos.add(VkDescriptorImageInfo{
|
||||
.sampler = VK_NULL_HANDLE,
|
||||
.imageView = vulkanTexture->getView(),
|
||||
.imageLayout = cast(vulkanTexture->getLayout()),
|
||||
});
|
||||
writeDescriptors.add(VkWriteDescriptorSet{
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.pNext = nullptr,
|
||||
.dstSet = setHandle,
|
||||
.dstBinding = binding,
|
||||
.dstArrayElement = index,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = map.type,
|
||||
.pImageInfo = &imageInfos.back(),
|
||||
});
|
||||
|
||||
boundResources[binding][index] = vulkanTexture->getHandle();
|
||||
}
|
||||
|
||||
void DescriptorSet::updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as) {
|
||||
void DescriptorSet::updateAccelerationStructure(const std::string& mappingName, uint32 index, Gfx::PTopLevelAS as) {
|
||||
auto tlas = as.cast<TopLevelAS>();
|
||||
uint32 binding = owner->getLayout()->mappings[name].binding;
|
||||
uint32 binding = owner->getLayout()->mappings[mappingName].binding;
|
||||
accelerationInfos.add(VkWriteDescriptorSetAccelerationStructureKHR{
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,
|
||||
.pNext = nullptr,
|
||||
@@ -418,8 +362,7 @@ void DescriptorSet::updateAccelerationStructure(const std::string& name, uint32
|
||||
|
||||
void DescriptorSet::writeChanges() {
|
||||
if (constantData.size() > 0) {
|
||||
if (constantsBuffer != nullptr)
|
||||
{
|
||||
if (constantsBuffer != nullptr) {
|
||||
graphics->getDestructionManager()->queueResourceForDestruction(std::move(constantsBuffer));
|
||||
}
|
||||
constantsBuffer = new BufferAllocation(graphics, owner->getLayout()->getName(),
|
||||
@@ -452,7 +395,7 @@ void DescriptorSet::writeChanges() {
|
||||
.pBufferInfo = &bufferInfos.back(),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (writeDescriptors.size() > 0) {
|
||||
if (isCurrentlyBound()) {
|
||||
std::cout << "Descriptor currently bound, allocate a new one instead" << std::endl;
|
||||
@@ -474,7 +417,7 @@ std::mutex layoutLock;
|
||||
Map<uint32, VkPipelineLayout> cachedLayouts;
|
||||
|
||||
void PipelineLayout::create() {
|
||||
for (auto [name, desc] : descriptorSetLayouts) {
|
||||
for (const auto& [_, desc] : descriptorSetLayouts) {
|
||||
PDescriptorLayout layout = desc.cast<DescriptorLayout>();
|
||||
layout->create();
|
||||
uint32 parameterIndex = parameterMapping[layout->getName()];
|
||||
|
||||
@@ -24,7 +24,7 @@ class DescriptorLayout : public Gfx::DescriptorLayout {
|
||||
private:
|
||||
PGraphics graphics;
|
||||
uint32 constantsSize = 0;
|
||||
VkShaderStageFlags constantsStages;
|
||||
VkShaderStageFlags constantsStages = 0;
|
||||
Array<VkDescriptorSetLayoutBinding> bindings;
|
||||
Map<std::string, DescriptorMapping> mappings;
|
||||
VkDescriptorSetLayout layoutHandle;
|
||||
@@ -64,9 +64,7 @@ class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource {
|
||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer indexBuffer) override;
|
||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer indexBuffer) override;
|
||||
virtual void updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) override;
|
||||
virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTexture2D texture) override;
|
||||
virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTexture3D texture) override;
|
||||
virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTextureCube texture) override;
|
||||
virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTexture texture) override;
|
||||
virtual void updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as) override;
|
||||
|
||||
constexpr VkDescriptorSet getHandle() const { return setHandle; }
|
||||
@@ -74,7 +72,6 @@ class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource {
|
||||
private:
|
||||
std::vector<uint8> constantData;
|
||||
OBufferAllocation constantsBuffer;
|
||||
VkShaderStageFlags constantsStageFlags;
|
||||
List<VkDescriptorImageInfo> imageInfos;
|
||||
List<VkDescriptorBufferInfo> bufferInfos;
|
||||
List<VkWriteDescriptorSetAccelerationStructureKHR> accelerationInfos;
|
||||
|
||||
@@ -16,40 +16,46 @@ Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::Render
|
||||
Array<VkImageView> attachments;
|
||||
uint32 width = 0;
|
||||
uint32 height = 0;
|
||||
uint32 layers = 0;
|
||||
for (auto inputAttachment : layout.inputAttachments) {
|
||||
PTexture2D vkInputAttachment = inputAttachment.getTexture().cast<Texture2D>();
|
||||
PTextureBase vkInputAttachment = inputAttachment.getTexture().cast<TextureBase>();
|
||||
attachments.add(vkInputAttachment->getView());
|
||||
description.inputAttachments[description.numInputAttachments++] = vkInputAttachment->getView();
|
||||
width = std::max(width, vkInputAttachment->getWidth());
|
||||
height = std::max(height, vkInputAttachment->getHeight());
|
||||
layers = std::max(layers, vkInputAttachment->getNumLayers());
|
||||
}
|
||||
for (auto colorAttachment : layout.colorAttachments) {
|
||||
PTexture2D vkColorAttachment = colorAttachment.getTexture().cast<Texture2D>();
|
||||
PTextureBase vkColorAttachment = colorAttachment.getTexture().cast<TextureBase>();
|
||||
attachments.add(vkColorAttachment->getView());
|
||||
description.colorAttachments[description.numColorAttachments++] = vkColorAttachment->getView();
|
||||
width = std::max(width, vkColorAttachment->getWidth());
|
||||
height = std::max(height, vkColorAttachment->getHeight());
|
||||
layers = std::max(layers, vkColorAttachment->getNumLayers());
|
||||
}
|
||||
for (auto resolveAttachment : layout.resolveAttachments) {
|
||||
PTexture2D vkResolveAttachment = resolveAttachment.getTexture().cast<Texture2D>();
|
||||
PTextureBase vkResolveAttachment = resolveAttachment.getTexture().cast<TextureBase>();
|
||||
attachments.add(vkResolveAttachment->getView());
|
||||
description.resolveAttachments[description.numResolveAttachments++] = vkResolveAttachment->getView();
|
||||
width = std::max(width, vkResolveAttachment->getWidth());
|
||||
height = std::max(height, vkResolveAttachment->getHeight());
|
||||
layers = std::max(layers, vkResolveAttachment->getNumLayers());
|
||||
}
|
||||
if (layout.depthAttachment.getTexture() != nullptr) {
|
||||
PTexture2D vkDepthAttachment = layout.depthAttachment.getTexture().cast<Texture2D>();
|
||||
PTextureBase vkDepthAttachment = layout.depthAttachment.getTexture().cast<TextureBase>();
|
||||
attachments.add(vkDepthAttachment->getView());
|
||||
description.depthAttachment = vkDepthAttachment->getView();
|
||||
width = std::max(width, vkDepthAttachment->getWidth());
|
||||
height = std::max(height, vkDepthAttachment->getHeight());
|
||||
layers = std::max(layers, vkDepthAttachment->getNumLayers());
|
||||
}
|
||||
if (layout.depthResolveAttachment.getTexture() != nullptr) {
|
||||
PTexture2D vkDepthAttachment = layout.depthResolveAttachment.getTexture().cast<Texture2D>();
|
||||
PTextureBase vkDepthAttachment = layout.depthResolveAttachment.getTexture().cast<TextureBase>();
|
||||
attachments.add(vkDepthAttachment->getView());
|
||||
description.depthResolveAttachment = vkDepthAttachment->getView();
|
||||
width = std::max(width, vkDepthAttachment->getWidth());
|
||||
height = std::max(height, vkDepthAttachment->getHeight());
|
||||
layers = std::max(layers, vkDepthAttachment->getNumLayers());
|
||||
}
|
||||
VkFramebufferCreateInfo createInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
||||
|
||||
@@ -172,8 +172,9 @@ Gfx::OViewport Graphics::createViewport(Gfx::PWindow owner, const ViewportCreate
|
||||
}
|
||||
|
||||
Gfx::ORenderPass Graphics::createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies,
|
||||
Gfx::PViewport renderArea, std::string name) {
|
||||
return new RenderPass(this, std::move(layout), std::move(dependencies), renderArea, name);
|
||||
URect renderArea, std::string name, Array<uint32> viewMasks,
|
||||
Array<uint32> correlationMasks) {
|
||||
return new RenderPass(this, std::move(layout), std::move(dependencies), renderArea, name, std::move(viewMasks), std::move(correlationMasks));
|
||||
}
|
||||
void Graphics::beginRenderPass(Gfx::PRenderPass renderPass) {
|
||||
PRenderPass rp = renderPass.cast<RenderPass>();
|
||||
@@ -321,7 +322,7 @@ Gfx::OPipelineStatisticsQuery Graphics::createPipelineStatisticsQuery(const std:
|
||||
return new PipelineStatisticsQuery(this, name);
|
||||
}
|
||||
|
||||
Gfx::OTimestampQuery Graphics::createTimestampQuery(uint64 numTimestamps, const std::string& name) {
|
||||
Gfx::OTimestampQuery Graphics::createTimestampQuery(uint64, const std::string& name) {
|
||||
return new TimestampQuery(this, name);
|
||||
}
|
||||
|
||||
@@ -446,7 +447,7 @@ Gfx::OTopLevelAS Graphics::createTopLevelAccelerationStructure(const Gfx::TopLev
|
||||
}
|
||||
|
||||
void Graphics::buildBottomLevelAccelerationStructures(Array<Gfx::PBottomLevelAS> data) {
|
||||
if (!supportRayTracing())
|
||||
if (!supportRayTracing() || data.empty())
|
||||
return;
|
||||
Gfx::PShaderBuffer verticesBuffer = StaticMeshVertexData::getInstance()->getPositionBuffer();
|
||||
Gfx::PIndexBuffer indexBuffer = StaticMeshVertexData::getInstance()->getIndexBuffer();
|
||||
@@ -457,9 +458,6 @@ void Graphics::buildBottomLevelAccelerationStructures(Array<Gfx::PBottomLevelAS>
|
||||
// For the sake of simplicity we won't stage the vertex data to the GPU memory
|
||||
|
||||
// Note that the buffer usage flags for buffers consumed by the bottom level acceleration structure require special flags
|
||||
const VkBufferUsageFlags buffer_usage_flags = VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR |
|
||||
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
|
||||
VkBufferCreateInfo transformBufferInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
@@ -593,7 +591,7 @@ void Graphics::buildBottomLevelAccelerationStructures(Array<Gfx::PBottomLevelAS>
|
||||
}
|
||||
|
||||
PCommand cmd = graphicsCommands->getCommands();
|
||||
vkCmdBuildAccelerationStructuresKHR(cmd->getHandle(), buildGeometries.size(), buildGeometries.data(), buildRangePointers.data());
|
||||
vkCmdBuildAccelerationStructuresKHR(cmd->getHandle(), (uint32)buildGeometries.size(), buildGeometries.data(), buildRangePointers.data());
|
||||
cmd->bindResource(PBufferAllocation(transformBuffer));
|
||||
destructionManager->queueResourceForDestruction(std::move(transformBuffer));
|
||||
for (auto& scratchAlloc : scratchBuffers) {
|
||||
@@ -827,6 +825,7 @@ void Graphics::pickPhysicalDevice() {
|
||||
.pNext = &features12,
|
||||
.storageBuffer16BitAccess = true,
|
||||
.uniformAndStorageBuffer16BitAccess = true,
|
||||
.multiview = true,
|
||||
};
|
||||
features = {
|
||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
|
||||
@@ -953,6 +952,7 @@ void Graphics::createDevice(GraphicsInitializer initializer) {
|
||||
initializer.deviceExtensions.add(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME);
|
||||
initializer.deviceExtensions.add(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME);
|
||||
}
|
||||
initializer.deviceExtensions.add(VK_KHR_MULTIVIEW_EXTENSION_NAME);
|
||||
#ifdef __APPLE__
|
||||
initializer.deviceExtensions.add("VK_KHR_portability_subset");
|
||||
#endif
|
||||
@@ -971,11 +971,11 @@ void Graphics::createDevice(GraphicsInitializer initializer) {
|
||||
transferQueue = 0;
|
||||
queues.add(new Queue(this, graphicsQueueInfo.familyIndex, graphicsQueueInfo.queueIndex));
|
||||
if (computeQueueInfo.familyIndex != -1) {
|
||||
computeQueue = queues.size();
|
||||
computeQueue = (uint32)queues.size();
|
||||
queues.add(new Queue(this, computeQueueInfo.familyIndex, computeQueueInfo.queueIndex));
|
||||
}
|
||||
if (transferQueueInfo.familyIndex != -1) {
|
||||
transferQueue = queues.size();
|
||||
transferQueue = (uint32)queues.size();
|
||||
queues.add(new Queue(this, transferQueueInfo.familyIndex, transferQueueInfo.queueIndex));
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,8 @@ class Graphics : public Gfx::Graphics {
|
||||
virtual Gfx::OViewport createViewport(Gfx::PWindow owner, const ViewportCreateInfo& createInfo) override;
|
||||
|
||||
virtual Gfx::ORenderPass createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies,
|
||||
Gfx::PViewport renderArea, std::string name) override;
|
||||
URect renderArea, std::string name, Array<uint32> viewMasks,
|
||||
Array<uint32> correlationMasks) override;
|
||||
virtual void beginRenderPass(Gfx::PRenderPass renderPass) override;
|
||||
virtual void endRenderPass() override;
|
||||
virtual void waitDeviceIdle() override;
|
||||
|
||||
@@ -11,23 +11,23 @@ using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
PipelineCache::PipelineCache(PGraphics graphics, const std::string& cacheFilePath) : graphics(graphics), cacheFile(cacheFilePath) {
|
||||
Array<uint8> cacheData;
|
||||
std::ifstream stream(cacheFilePath, std::ios::binary | std::ios::ate);
|
||||
VkPipelineCacheCreateInfo cacheCreateInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.initialDataSize = 0,
|
||||
};
|
||||
if (stream.good()) {
|
||||
Array<uint8> cacheData;
|
||||
uint32 fileSize = static_cast<uint32>(stream.tellg());
|
||||
cacheData.resize(fileSize);
|
||||
stream.seekg(0);
|
||||
stream.read((char*)cacheData.data(), fileSize);
|
||||
cacheCreateInfo.initialDataSize = fileSize;
|
||||
cacheCreateInfo.pInitialData = cacheData.data();
|
||||
std::cout << "Loaded " << fileSize << " bytes from pipeline cache" << std::endl;
|
||||
}
|
||||
VkPipelineCacheCreateInfo cacheCreateInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.initialDataSize = cacheData.size(),
|
||||
.pInitialData = cacheData.data(),
|
||||
};
|
||||
|
||||
VK_CHECK(vkCreatePipelineCache(graphics->getDevice(), &cacheCreateInfo, nullptr, &cache));
|
||||
}
|
||||
|
||||
@@ -508,7 +508,7 @@ PRayTracingPipeline PipelineCache::createPipeline(Gfx::RayTracingPipelineCreateI
|
||||
uint32 intersectionIndex = VK_SHADER_UNUSED_KHR;
|
||||
if (hitgroup.anyHitShader != nullptr) {
|
||||
auto anyHit = hitgroup.anyHitShader.cast<AnyHitShader>();
|
||||
anyHitIndex = shaderStages.size();
|
||||
anyHitIndex = (uint32)shaderStages.size();
|
||||
shaderStages.add(VkPipelineShaderStageCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
@@ -521,7 +521,7 @@ PRayTracingPipeline PipelineCache::createPipeline(Gfx::RayTracingPipelineCreateI
|
||||
}
|
||||
if (hitgroup.intersectionShader != nullptr) {
|
||||
auto intersect = hitgroup.intersectionShader.cast<IntersectionShader>();
|
||||
intersectionIndex = shaderGroups.size();
|
||||
intersectionIndex = (uint32)shaderGroups.size();
|
||||
shaderStages.add(VkPipelineShaderStageCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
@@ -592,7 +592,8 @@ PRayTracingPipeline PipelineCache::createPipeline(Gfx::RayTracingPipelineCreateI
|
||||
});
|
||||
}
|
||||
}
|
||||
uint32 hash = CRC::Calculate(shaderStages.data(), sizeof(VkPipelineShaderStageCreateInfo) * shaderStages.size(), CRC::CRC_32());
|
||||
uint32 hash = CRC::Calculate(shaderStages.data(), sizeof(VkPipelineShaderStageCreateInfo) * shaderStages.size(), CRC::CRC_32(),
|
||||
createInfo.pipelineLayout->getHash());
|
||||
hash = CRC::Calculate(shaderGroups.data(), sizeof(VkRayTracingShaderGroupCreateInfoKHR) * shaderGroups.size(), CRC::CRC_32(), hash);
|
||||
if (rayTracingPipelines.contains(hash)) {
|
||||
return rayTracingPipelines[hash];
|
||||
@@ -624,7 +625,7 @@ PRayTracingPipeline PipelineCache::createPipeline(Gfx::RayTracingPipelineCreateI
|
||||
const VkBufferUsageFlags sbtBufferUsage =
|
||||
VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
|
||||
const VmaMemoryUsage sbtMemoryUsage = VMA_MEMORY_USAGE_AUTO;
|
||||
|
||||
|
||||
uint64 rayGenStride = align<uint64>(handleSize + createInfo.rayGenGroup.parameters.size(), handleAlignment);
|
||||
uint64 hitStride = handleSize;
|
||||
for (const auto& h : createInfo.hitGroups) {
|
||||
@@ -674,7 +675,7 @@ PRayTracingPipeline PipelineCache::createPipeline(Gfx::RayTracingPipelineCreateI
|
||||
Gfx::QueueType::GRAPHICS, sbtAlignment);
|
||||
|
||||
Array<uint8> sbt(sbtSize);
|
||||
vkGetRayTracingShaderGroupHandlesKHR(graphics->getDevice(), pipelineHandle, 0, shaderGroups.size(), sbtSize, sbt.data());
|
||||
vkGetRayTracingShaderGroupHandlesKHR(graphics->getDevice(), pipelineHandle, 0, (uint32)shaderGroups.size(), sbtSize, sbt.data());
|
||||
|
||||
uint64 sbtOffset = 0;
|
||||
Array<uint8> rayGenSbt(rayGenStride);
|
||||
@@ -685,7 +686,6 @@ PRayTracingPipeline PipelineCache::createPipeline(Gfx::RayTracingPipelineCreateI
|
||||
rayGenBuffer->pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_SHADER_READ_BIT,
|
||||
VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR);
|
||||
|
||||
|
||||
Array<uint8> hitSbt(hitStride * createInfo.hitGroups.size());
|
||||
for (uint64 i = 0; i < createInfo.hitGroups.size(); ++i) {
|
||||
std::memcpy(hitSbt.data() + i * hitStride, sbt.data() + sbtOffset, handleSize);
|
||||
@@ -695,9 +695,8 @@ PRayTracingPipeline PipelineCache::createPipeline(Gfx::RayTracingPipelineCreateI
|
||||
}
|
||||
hitBuffer->updateContents(0, hitSbt.size(), hitSbt.data());
|
||||
hitBuffer->pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_SHADER_READ_BIT,
|
||||
VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR);
|
||||
VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR);
|
||||
|
||||
|
||||
Array<uint8> missSbt(missStride * createInfo.missGroups.size());
|
||||
for (uint64 i = 0; i < createInfo.missGroups.size(); ++i) {
|
||||
std::memcpy(missSbt.data() + i * missStride, sbt.data() + sbtOffset, handleSize);
|
||||
@@ -707,11 +706,11 @@ PRayTracingPipeline PipelineCache::createPipeline(Gfx::RayTracingPipelineCreateI
|
||||
}
|
||||
missBuffer->updateContents(0, missSbt.size(), missSbt.data());
|
||||
missBuffer->pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_SHADER_READ_BIT,
|
||||
VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR);
|
||||
VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR);
|
||||
|
||||
ORayTracingPipeline pipeline =
|
||||
new RayTracingPipeline(graphics, pipelineHandle, std::move(rayGenBuffer), rayGenStride, std::move(hitBuffer),
|
||||
hitStride, std::move(missBuffer), missStride, nullptr, 0, createInfo.pipelineLayout);
|
||||
new RayTracingPipeline(graphics, pipelineHandle, std::move(rayGenBuffer), rayGenStride, std::move(hitBuffer), hitStride,
|
||||
std::move(missBuffer), missStride, nullptr, 0, createInfo.pipelineLayout);
|
||||
PRayTracingPipeline handle = pipeline;
|
||||
rayTracingPipelines[hash] = std::move(pipeline);
|
||||
return handle;
|
||||
|
||||
@@ -23,8 +23,8 @@ class QueryPool {
|
||||
std::string name;
|
||||
VkQueryPipelineStatisticFlags flags;
|
||||
// ring buffer
|
||||
uint64 head = 0;
|
||||
uint64 tail = 0;
|
||||
uint32 head = 0;
|
||||
uint32 tail = 0;
|
||||
uint64 numAvailable;
|
||||
uint32 numQueries;
|
||||
uint32 resultsStride;
|
||||
|
||||
@@ -106,7 +106,7 @@ TopLevelAS::TopLevelAS(PGraphics graphics, const Gfx::TopLevelASCreateInfo& crea
|
||||
.pGeometries = &geometry,
|
||||
};
|
||||
|
||||
const uint32 primitiveCount = instances.size();
|
||||
const uint32 primitiveCount = (uint32)instances.size();
|
||||
|
||||
VkAccelerationStructureBuildSizesInfoKHR buildSizesInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR,
|
||||
|
||||
@@ -6,17 +6,16 @@
|
||||
#include "Resources.h"
|
||||
#include "Texture.h"
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Array<Gfx::SubPassDependency> _dependencies,
|
||||
Gfx::PViewport viewport, std::string name)
|
||||
RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Array<Gfx::SubPassDependency> _dependencies, URect viewport,
|
||||
std::string name, Array<uint32> viewMasks, Array<uint32> correlationMasks)
|
||||
: Gfx::RenderPass(std::move(_layout), std::move(_dependencies)), graphics(graphics) {
|
||||
renderArea.extent.width = viewport->getWidth();
|
||||
renderArea.extent.height = viewport->getHeight();
|
||||
renderArea.offset.x = viewport->getOffsetX();
|
||||
renderArea.offset.y = viewport->getOffsetY();
|
||||
renderArea.extent.width = viewport.size.x;
|
||||
renderArea.extent.height = viewport.size.y;
|
||||
renderArea.offset.x = viewport.offset.x;
|
||||
renderArea.offset.y = viewport.offset.y;
|
||||
subpassContents = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
|
||||
Array<VkAttachmentDescription2> attachments;
|
||||
Array<VkAttachmentReference2> inputRefs;
|
||||
@@ -167,6 +166,7 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Arra
|
||||
.pNext = layout.depthResolveAttachment.getTexture() != nullptr ? &depthResolve : nullptr,
|
||||
.flags = 0,
|
||||
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
.viewMask = viewMasks[0],
|
||||
.inputAttachmentCount = (uint32)inputRefs.size(),
|
||||
.pInputAttachments = inputRefs.data(),
|
||||
.colorAttachmentCount = (uint32)colorRefs.size(),
|
||||
@@ -197,8 +197,9 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Arra
|
||||
.pSubpasses = &subPassDesc,
|
||||
.dependencyCount = (uint32)dep.size(),
|
||||
.pDependencies = dep.data(),
|
||||
.correlatedViewMaskCount = (uint32)correlationMasks.size(),
|
||||
.pCorrelatedViewMasks = correlationMasks.data(),
|
||||
};
|
||||
|
||||
VK_CHECK(vkCreateRenderPass2(graphics->getDevice(), &info, nullptr, &renderPass));
|
||||
VkDebugUtilsObjectNameInfoEXT nameInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
||||
@@ -220,23 +221,23 @@ uint32 RenderPass::getFramebufferHash() {
|
||||
FramebufferDescription description;
|
||||
std::memset(&description, 0, sizeof(FramebufferDescription));
|
||||
for (auto& inputAttachment : layout.inputAttachments) {
|
||||
PTexture2D tex = inputAttachment.getTexture().cast<Texture2D>();
|
||||
PTextureBase tex = inputAttachment.getTexture().cast<TextureBase>();
|
||||
description.inputAttachments[description.numInputAttachments++] = tex->getView();
|
||||
}
|
||||
for (auto& colorAttachment : layout.colorAttachments) {
|
||||
PTexture2D tex = colorAttachment.getTexture().cast<Texture2D>();
|
||||
PTextureBase tex = colorAttachment.getTexture().cast<TextureBase>();
|
||||
description.colorAttachments[description.numColorAttachments++] = tex->getView();
|
||||
}
|
||||
for (auto& resolveAttachment : layout.resolveAttachments) {
|
||||
PTexture2D tex = resolveAttachment.getTexture().cast<Texture2D>();
|
||||
description.resolveAttachments[description.numResolveAttachments++] = tex->getView();
|
||||
PTextureBase tex = resolveAttachment.getTexture().cast<TextureBase>();
|
||||
description.resolveAttachments[description.numResolveAttachments++] = tex->getView();
|
||||
}
|
||||
if (layout.depthAttachment.getTexture() != nullptr) {
|
||||
PTexture2D tex = layout.depthAttachment.getTexture().cast<Texture2D>();
|
||||
PTextureBase tex = layout.depthAttachment.getTexture().cast<TextureBase>();
|
||||
description.depthAttachment = tex->getView();
|
||||
}
|
||||
if (layout.depthResolveAttachment.getTexture() != nullptr) {
|
||||
PTexture2D tex = layout.depthResolveAttachment.getTexture().cast<Texture2D>();
|
||||
PTextureBase tex = layout.depthResolveAttachment.getTexture().cast<TextureBase>();
|
||||
description.depthResolveAttachment = tex->getView();
|
||||
}
|
||||
return CRC::Calculate(&description, sizeof(FramebufferDescription), CRC::CRC_32());
|
||||
@@ -244,23 +245,23 @@ uint32 RenderPass::getFramebufferHash() {
|
||||
|
||||
void RenderPass::endRenderPass() {
|
||||
for (auto& inputAttachment : layout.inputAttachments) {
|
||||
PTexture2D tex = inputAttachment.getTexture().cast<Texture2D>();
|
||||
PTextureBase tex = inputAttachment.getTexture().cast<TextureBase>();
|
||||
tex->setLayout(inputAttachment.getFinalLayout());
|
||||
}
|
||||
for (auto& colorAttachment : layout.colorAttachments) {
|
||||
PTexture2D tex = colorAttachment.getTexture().cast<Texture2D>();
|
||||
PTextureBase tex = colorAttachment.getTexture().cast<TextureBase>();
|
||||
tex->setLayout(colorAttachment.getFinalLayout());
|
||||
}
|
||||
for (auto& resolveAttachment : layout.resolveAttachments) {
|
||||
PTexture2D tex = resolveAttachment.getTexture().cast<Texture2D>();
|
||||
PTextureBase tex = resolveAttachment.getTexture().cast<TextureBase>();
|
||||
tex->setLayout(resolveAttachment.getFinalLayout());
|
||||
}
|
||||
if (layout.depthAttachment.getTexture() != nullptr) {
|
||||
PTexture2D tex = layout.depthAttachment.getTexture().cast<Texture2D>();
|
||||
PTextureBase tex = layout.depthAttachment.getTexture().cast<TextureBase>();
|
||||
tex->setLayout(layout.depthAttachment.getFinalLayout());
|
||||
}
|
||||
if (layout.depthResolveAttachment.getTexture() != nullptr) {
|
||||
PTexture2D tex = layout.depthResolveAttachment.getTexture().cast<Texture2D>();
|
||||
PTextureBase tex = layout.depthResolveAttachment.getTexture().cast<TextureBase>();
|
||||
tex->setLayout(layout.depthResolveAttachment.getFinalLayout());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@ namespace Seele {
|
||||
namespace Vulkan {
|
||||
class RenderPass : public Gfx::RenderPass {
|
||||
public:
|
||||
RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, Gfx::PViewport viewport, std::string name);
|
||||
RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, URect viewport,
|
||||
std::string name, Array<uint32> viewMasks = {}, Array<uint32> correlationMasks = {});
|
||||
virtual ~RenderPass();
|
||||
uint32 getFramebufferHash();
|
||||
void endRenderPass();
|
||||
|
||||
@@ -34,7 +34,7 @@ void Semaphore::rotateSemaphore() {
|
||||
currentHandle = i;
|
||||
return;
|
||||
}
|
||||
currentHandle = handles.size();
|
||||
currentHandle = (uint32)handles.size();
|
||||
handles.add(new SemaphoreHandle(graphics, "Semaphore"));
|
||||
}
|
||||
|
||||
|
||||
@@ -29,10 +29,10 @@ VkImageAspectFlags getAspectFromFormat(Gfx::SeFormat format) {
|
||||
}
|
||||
|
||||
TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const TextureCreateInfo& createInfo, VkImage existingImage)
|
||||
: CommandBoundResource(graphics, createInfo.name), image(existingImage), owner(createInfo.sourceData.owner), width(createInfo.width),
|
||||
height(createInfo.height), depth(createInfo.depth), arrayCount(createInfo.elements), layerCount(createInfo.layers), mipLevels(1),
|
||||
samples(createInfo.samples), format(createInfo.format), usage(createInfo.usage),
|
||||
layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED), aspect(getAspectFromFormat(createInfo.format)), ownsImage(false) {
|
||||
: CommandBoundResource(graphics, createInfo.name), image(existingImage), imageView(VK_NULL_HANDLE), allocation(nullptr),
|
||||
owner(createInfo.sourceData.owner), width(createInfo.width), height(createInfo.height), depth(createInfo.depth),
|
||||
layerCount(createInfo.elements), mipLevels(1), samples(createInfo.samples), format(createInfo.format),
|
||||
usage(createInfo.usage), layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED), aspect(getAspectFromFormat(createInfo.format)), ownsImage(false) {
|
||||
if (createInfo.useMip) {
|
||||
mipLevels = static_cast<uint32_t>(std::floor(std::log2(std::max(width, height)))) + 1;
|
||||
}
|
||||
@@ -55,7 +55,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const
|
||||
case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
|
||||
type = VK_IMAGE_TYPE_2D;
|
||||
flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
|
||||
layerCount = 6 * arrayCount;
|
||||
layerCount = 6 * layerCount;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -76,7 +76,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const
|
||||
.depth = depth,
|
||||
},
|
||||
.mipLevels = mipLevels,
|
||||
.arrayLayers = arrayCount * layerCount,
|
||||
.arrayLayers = layerCount,
|
||||
.samples = (VkSampleCountFlagBits)samples,
|
||||
.tiling = VK_IMAGE_TILING_OPTIMAL,
|
||||
.usage = usage,
|
||||
@@ -95,7 +95,8 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const
|
||||
.pObjectName = name.c_str(),
|
||||
};
|
||||
vkSetDebugUtilsObjectNameEXT(graphics->getDevice(), &nameInfo);
|
||||
ownsImage = true;const DataSource& sourceData = createInfo.sourceData;
|
||||
ownsImage = true;
|
||||
const DataSource& sourceData = createInfo.sourceData;
|
||||
if (sourceData.size > 0) {
|
||||
changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
@@ -117,7 +118,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const
|
||||
vmaMapMemory(graphics->getAllocator(), stagingAlloc->allocation, &data);
|
||||
std::memcpy(data, sourceData.data, sourceData.size);
|
||||
vmaUnmapMemory(graphics->getAllocator(), stagingAlloc->allocation);
|
||||
|
||||
|
||||
PCommandPool commandPool = graphics->getQueueCommands(owner);
|
||||
VkBufferImageCopy region = {
|
||||
.bufferOffset = 0,
|
||||
@@ -128,7 +129,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.mipLevel = 0,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = arrayCount * layerCount,
|
||||
.layerCount = layerCount,
|
||||
},
|
||||
.imageOffset =
|
||||
{
|
||||
@@ -138,10 +139,10 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const
|
||||
},
|
||||
.imageExtent = {.width = width, .height = height, .depth = depth},
|
||||
};
|
||||
|
||||
vkCmdCopyBufferToImage(commandPool->getCommands()->getHandle(), stagingAlloc->buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
1, ®ion);
|
||||
|
||||
|
||||
vkCmdCopyBufferToImage(commandPool->getCommands()->getHandle(), stagingAlloc->buffer, image,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
|
||||
commandPool->getCommands()->bindResource(PBufferAllocation(stagingAlloc));
|
||||
generateMipmaps();
|
||||
// When loading a texture from a file, we will almost always use it as a texture map for fragment shaders
|
||||
@@ -150,7 +151,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const
|
||||
graphics->getDestructionManager()->queueResourceForDestruction(std::move(stagingAlloc));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VkImageViewCreateInfo viewInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
@@ -162,7 +163,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const
|
||||
{
|
||||
.aspectMask = aspect,
|
||||
.levelCount = mipLevels,
|
||||
.layerCount = layerCount * arrayCount,
|
||||
.layerCount = layerCount,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -194,7 +195,7 @@ void TextureHandle::pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlag
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = mipLevels,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = layerCount * arrayCount,
|
||||
.layerCount = layerCount,
|
||||
},
|
||||
};
|
||||
PCommand command = graphics->getQueueCommands(owner)->getCommands();
|
||||
@@ -222,7 +223,7 @@ void TextureHandle::transferOwnership(Gfx::QueueType newOwner) {
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = mipLevels,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = arrayCount,
|
||||
.layerCount = layerCount,
|
||||
},
|
||||
};
|
||||
PCommandPool sourcePool = graphics->getQueueCommands(owner);
|
||||
@@ -385,7 +386,10 @@ TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType, const Tex
|
||||
: handle(new TextureHandle(graphics, viewType, createInfo, existingImage)), graphics(graphics),
|
||||
initialOwner(createInfo.sourceData.owner) {}
|
||||
|
||||
TextureBase::~TextureBase() { graphics->getDestructionManager()->queueResourceForDestruction(std::move(handle)); }
|
||||
TextureBase::~TextureBase() {
|
||||
graphics->getDestructionManager()->queueResourceForDestruction(std::move(handle));
|
||||
handle = nullptr;
|
||||
}
|
||||
|
||||
void TextureBase::pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
|
||||
VkPipelineStageFlags dstStage) {
|
||||
|
||||
@@ -6,15 +6,13 @@
|
||||
#include "Resources.h"
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
|
||||
namespace Seele {
|
||||
namespace Vulkan {
|
||||
class TextureHandle : public CommandBoundResource {
|
||||
public:
|
||||
TextureHandle(PGraphics graphics, VkImageViewType viewType, const TextureCreateInfo& createInfo, VkImage existingImage);
|
||||
virtual ~TextureHandle();
|
||||
void pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
|
||||
VkPipelineStageFlags dstStage);
|
||||
void pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
|
||||
void transferOwnership(Gfx::QueueType newOwner);
|
||||
void changeLayout(Gfx::SeImageLayout newLayout, VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
|
||||
VkPipelineStageFlags dstStage);
|
||||
@@ -27,7 +25,6 @@ class TextureHandle : public CommandBoundResource {
|
||||
uint32 width;
|
||||
uint32 height;
|
||||
uint32 depth;
|
||||
uint32 arrayCount;
|
||||
uint32 layerCount;
|
||||
uint32 mipLevels;
|
||||
uint32 samples;
|
||||
@@ -37,15 +34,20 @@ class TextureHandle : public CommandBoundResource {
|
||||
VkImageAspectFlags aspect;
|
||||
uint8 ownsImage;
|
||||
};
|
||||
DECLARE_REF(TextureHandle)
|
||||
DEFINE_REF(TextureHandle)
|
||||
|
||||
DECLARE_REF(TextureBase)
|
||||
DECLARE_REF(Texture2D)
|
||||
DECLARE_REF(Texture3D)
|
||||
DECLARE_REF(TextureCube)
|
||||
class TextureBase {
|
||||
public:
|
||||
TextureBase(PGraphics graphics, VkImageViewType viewType, const TextureCreateInfo& createInfo,
|
||||
VkImage existingImage = VK_NULL_HANDLE);
|
||||
TextureBase(PGraphics graphics, VkImageViewType viewType, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
|
||||
virtual ~TextureBase();
|
||||
uint32 getWidth() const { return handle->width; }
|
||||
uint32 getHeight() const { return handle->height; }
|
||||
uint32 getDepth() const { return handle->depth; }
|
||||
uint32 getNumLayers() const { return handle->layerCount; }
|
||||
PTextureHandle getHandle() const { return handle; }
|
||||
VkImage getImage() const { return handle->image; };
|
||||
VkImageView getView() const { return handle->imageView; };
|
||||
@@ -58,13 +60,13 @@ class TextureBase {
|
||||
constexpr uint32 getMipLevels() const { return handle->mipLevels; }
|
||||
constexpr bool isDepthStencil() const { return handle->aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); }
|
||||
|
||||
void pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
|
||||
VkPipelineStageFlags dstStage);
|
||||
void pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
|
||||
void transferOwnership(Gfx::QueueType newOwner);
|
||||
void changeLayout(Gfx::SeImageLayout newLayout, VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
|
||||
VkPipelineStageFlags dstStage);
|
||||
void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer);
|
||||
void generateMipmaps();
|
||||
|
||||
protected:
|
||||
OTextureHandle handle;
|
||||
// Updates via reference
|
||||
|
||||
@@ -276,7 +276,6 @@ void Window::createSwapChain() {
|
||||
.width = extent.width,
|
||||
.height = extent.height,
|
||||
.depth = 1,
|
||||
.layers = 1,
|
||||
.elements = 1,
|
||||
.samples = 1,
|
||||
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||
|
||||
@@ -8,9 +8,13 @@ Window::Window() {}
|
||||
Window::~Window() {}
|
||||
|
||||
Viewport::Viewport(PWindow owner, const ViewportCreateInfo& viewportInfo)
|
||||
: sizeX(std::min(owner->getFramebufferWidth(), viewportInfo.dimensions.size.x)),
|
||||
sizeY(std::min(owner->getFramebufferHeight(), viewportInfo.dimensions.size.y)), offsetX(viewportInfo.dimensions.offset.x),
|
||||
offsetY(viewportInfo.dimensions.offset.y), fieldOfView(viewportInfo.fieldOfView), owner(owner) {}
|
||||
: sizeX(viewportInfo.dimensions.size.x), sizeY(viewportInfo.dimensions.size.y), offsetX(viewportInfo.dimensions.offset.x),
|
||||
offsetY(viewportInfo.dimensions.offset.y), fieldOfView(viewportInfo.fieldOfView), owner(owner) {
|
||||
if (owner != nullptr) {
|
||||
sizeX = std::min(owner->getFramebufferWidth(), sizeX);
|
||||
sizeY = std::min(owner->getFramebufferHeight(), sizeY);
|
||||
}
|
||||
}
|
||||
|
||||
Viewport::~Viewport() {}
|
||||
|
||||
|
||||
@@ -53,6 +53,12 @@ class Viewport {
|
||||
constexpr float getContentScaleX() const { return owner->getContentScaleX(); }
|
||||
constexpr float getContentScaleY() const { return owner->getContentScaleY(); }
|
||||
Matrix4 getProjectionMatrix() const;
|
||||
URect getRenderArea() const {
|
||||
return URect{
|
||||
.size = {sizeX, sizeY},
|
||||
.offset = {offsetX, offsetY},
|
||||
};
|
||||
}
|
||||
|
||||
protected:
|
||||
uint32 sizeX;
|
||||
|
||||
@@ -77,7 +77,7 @@ void Seele::beginCompilation(const ShaderCompilationInfo& info, SlangCompileTarg
|
||||
};
|
||||
|
||||
sessionDesc.compilerOptionEntries = option.data();
|
||||
sessionDesc.compilerOptionEntryCount = option.size();
|
||||
sessionDesc.compilerOptionEntryCount = (uint32)option.size();
|
||||
sessionDesc.defaultMatrixLayoutMode = SLANG_MATRIX_LAYOUT_COLUMN_MAJOR;
|
||||
Array<slang::PreprocessorMacroDesc> macros;
|
||||
for (const auto& [key, val] : info.defines) {
|
||||
@@ -139,11 +139,9 @@ void Seele::beginCompilation(const ShaderCompilationInfo& info, SlangCompileTarg
|
||||
|
||||
slang::ProgramLayout* signature = specializedComponent->getLayout(0, diagnostics.writeRef());
|
||||
CHECK_DIAGNOSTICS();
|
||||
std::cout << info.name << std::endl;
|
||||
for (size_t i = 0; i < signature->getParameterCount(); ++i) {
|
||||
for (uint32 i = 0; i < signature->getParameterCount(); ++i) {
|
||||
auto param = signature->getParameterByIndex(i);
|
||||
layout->addMapping(param->getName(), param->getBindingIndex());
|
||||
//std::cout << param->getName() << ": " << param->getBindingIndex() << std::endl;
|
||||
}
|
||||
|
||||
// workaround
|
||||
|
||||
@@ -99,21 +99,21 @@ void Material::updateFloatData(uint32 offset, uint32 numFloats, float* data) {
|
||||
}
|
||||
|
||||
uint32 Material::addTextures(uint32 numTextures) {
|
||||
uint32 textureOffset = textures.size();
|
||||
uint32 textureOffset = (uint32)textures.size();
|
||||
textures.resize(textures.size() + numTextures);
|
||||
assert(textures.size() < 512);
|
||||
return textureOffset;
|
||||
}
|
||||
|
||||
uint32 Material::addSamplers(uint32 numSamplers) {
|
||||
uint32 samplerOffset = samplers.size();
|
||||
uint32 samplerOffset = (uint32)samplers.size();
|
||||
samplers.resize(samplers.size() + numSamplers);
|
||||
assert(textures.size() < 512);
|
||||
return samplerOffset;
|
||||
}
|
||||
|
||||
uint32 Material::addFloats(uint32 numFloats) {
|
||||
uint32 floatOffset = floatData.size();
|
||||
uint32 floatOffset = (uint32)floatData.size();
|
||||
floatData.resize(floatData.size() + numFloats);
|
||||
return floatOffset;
|
||||
}
|
||||
@@ -158,8 +158,8 @@ void Material::load(ArchiveBuffer& buffer) {
|
||||
|
||||
void Material::compile() {
|
||||
std::ofstream codeStream("./shaders/generated/" + materialName + ".slang");
|
||||
codeStream << "import BRDF;\n";
|
||||
codeStream << "import MaterialParameter;\n";
|
||||
codeStream << "import LightEnv;\n";
|
||||
codeStream << "import Material;\n";
|
||||
codeStream << "struct Material{\n";
|
||||
codeStream << "\ttypedef " << brdf.profile << " BRDF;\n";
|
||||
|
||||
@@ -69,7 +69,7 @@ FloatParameter::FloatParameter(std::string name, float data, uint32 index) : Sha
|
||||
|
||||
FloatParameter::~FloatParameter() {}
|
||||
|
||||
void FloatParameter::updateDescriptorSet(uint32 textureOffset, uint32 samplerOffset, uint32 floatOffset) {
|
||||
void FloatParameter::updateDescriptorSet(uint32, uint32, uint32 floatOffset) {
|
||||
Material::updateFloatData(floatOffset + index, 1, &data);
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ VectorParameter::VectorParameter(std::string name, Vector data, uint32 index)
|
||||
|
||||
VectorParameter::~VectorParameter() {}
|
||||
|
||||
void VectorParameter::updateDescriptorSet(uint32 textureOffset, uint32 samplerOffset, uint32 floatOffset) {
|
||||
void VectorParameter::updateDescriptorSet(uint32, uint32, uint32 floatOffset) {
|
||||
Material::updateFloatData(floatOffset + index, 3, (float*) & data);
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ TextureParameter::TextureParameter(std::string name, PTextureAsset asset, uint32
|
||||
|
||||
TextureParameter::~TextureParameter() {}
|
||||
|
||||
void TextureParameter::updateDescriptorSet(uint32 textureOffset, uint32 samplerOffset, uint32 floatOffset) {
|
||||
void TextureParameter::updateDescriptorSet(uint32 textureOffset, uint32, uint32) {
|
||||
Material::updateTexture(textureOffset + index, data->getTexture());
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ SamplerParameter::SamplerParameter(std::string name, Gfx::OSampler sampler, uint
|
||||
|
||||
SamplerParameter::~SamplerParameter() {}
|
||||
|
||||
void SamplerParameter::updateDescriptorSet(uint32 textureOffset, uint32 samplerOffset, uint32 floatOffset) {
|
||||
void SamplerParameter::updateDescriptorSet(uint32, uint32 samplerOffset, uint32) {
|
||||
Material::updateSampler(samplerOffset + index, data);
|
||||
}
|
||||
|
||||
@@ -183,9 +183,9 @@ CombinedTextureParameter::CombinedTextureParameter(std::string name, PTextureAss
|
||||
|
||||
CombinedTextureParameter::~CombinedTextureParameter() {}
|
||||
|
||||
void CombinedTextureParameter::updateDescriptorSet(uint32 textureOffset, uint32 samplerOffset, uint32 floatOffset) { assert(false); }
|
||||
void CombinedTextureParameter::updateDescriptorSet(uint32 , uint32 , uint32 ) { assert(false); }
|
||||
|
||||
std::string CombinedTextureParameter::evaluate(Map<std::string, std::string>& varState) const { return ""; }
|
||||
std::string CombinedTextureParameter::evaluate(Map<std::string, std::string>&) const { return ""; }
|
||||
|
||||
void CombinedTextureParameter::save(ArchiveBuffer& buffer) const {
|
||||
ShaderParameter::save(buffer);
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "Math/Math.h"
|
||||
#include "MinimalEngine.h"
|
||||
|
||||
|
||||
namespace Seele {
|
||||
enum class ExpressionType {
|
||||
UNKNOWN,
|
||||
@@ -184,6 +183,9 @@ struct SwizzleExpression : public ShaderExpression {
|
||||
StaticArray<int32, 4> comp = {-1, -1, -1, -1};
|
||||
SwizzleExpression() {}
|
||||
SwizzleExpression(StaticArray<int32, 4> comp) : comp(std::move(comp)) {}
|
||||
SwizzleExpression(std::string key, std::string target, StaticArray<int32, 4> comp) : ShaderExpression(key) {
|
||||
inputs["target"].source = target;
|
||||
}
|
||||
virtual ~SwizzleExpression() {}
|
||||
virtual uint64 getIdentifier() const override { return IDENTIFIER; }
|
||||
virtual std::string evaluate(Map<std::string, std::string>& varState) const override;
|
||||
@@ -194,6 +196,11 @@ DEFINE_REF(SwizzleExpression)
|
||||
struct SampleExpression : public ShaderExpression {
|
||||
static constexpr uint64 IDENTIFIER = 0x16;
|
||||
SampleExpression() {}
|
||||
SampleExpression(std::string key, std::string texture, std::string sampler, std::string texCoords) : ShaderExpression(key) {
|
||||
inputs["texture"].source = texture;
|
||||
inputs["sampler"].source = sampler;
|
||||
inputs["texCoords"].source = texCoords;
|
||||
}
|
||||
virtual ~SampleExpression() {}
|
||||
virtual uint64 getIdentifier() const override { return IDENTIFIER; }
|
||||
virtual std::string evaluate(Map<std::string, std::string>& varState) const override;
|
||||
@@ -205,8 +212,6 @@ DEFINE_REF(SampleExpression)
|
||||
struct MaterialNode {
|
||||
std::string profile;
|
||||
Map<std::string, std::string> variables;
|
||||
MaterialNode() {}
|
||||
~MaterialNode() {}
|
||||
void save(ArchiveBuffer& buffer) const;
|
||||
void load(ArchiveBuffer& buffer);
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user