Merge remote-tracking branch 'origin/main' into SP3-2-Physics

This commit is contained in:
Diren D Bharwani 2022-11-20 17:23:38 +08:00
commit 5871f32547
88 changed files with 2226 additions and 151 deletions

BIN
Assets/Fonts/SegoeUI.shfont Normal file

Binary file not shown.

View File

@ -0,0 +1,3 @@
Name: SegoeUI
ID: 176667660
Type: 10

BIN
Assets/Fonts/SegoeUI.ttf Normal file

Binary file not shown.

View File

@ -0,0 +1,8 @@
- VertexShader: 46580970
FragmentShader: 35983630
SubPass: G-Buffer Write
Properties:
data.color: {x: 1, y: 1, z: 1, w: 1}
data.textureIndex: 0
data.alpha: 0
data.beta: {x: 1, y: 1, z: 1}

View File

@ -0,0 +1,3 @@
Name: UIMat
ID: 129340704
Type: 7

104
Assets/Models/Quad.gltf Normal file
View File

@ -0,0 +1,104 @@
{
"asset" : {
"generator" : "Khronos glTF Blender I/O v3.3.27",
"version" : "2.0"
},
"scene" : 0,
"scenes" : [
{
"name" : "Scene",
"nodes" : [
0
]
}
],
"nodes" : [
{
"mesh" : 0,
"name" : "Quad"
}
],
"meshes" : [
{
"name" : "Plane",
"primitives" : [
{
"attributes" : {
"POSITION" : 0,
"NORMAL" : 1,
"TEXCOORD_0" : 2
},
"indices" : 3
}
]
}
],
"accessors" : [
{
"bufferView" : 0,
"componentType" : 5126,
"count" : 4,
"max" : [
0.5,
0.5,
3.774895063202166e-08
],
"min" : [
-0.5,
-0.5,
-3.774895063202166e-08
],
"type" : "VEC3"
},
{
"bufferView" : 1,
"componentType" : 5126,
"count" : 4,
"type" : "VEC3"
},
{
"bufferView" : 2,
"componentType" : 5126,
"count" : 4,
"type" : "VEC2"
},
{
"bufferView" : 3,
"componentType" : 5123,
"count" : 6,
"type" : "SCALAR"
}
],
"bufferViews" : [
{
"buffer" : 0,
"byteLength" : 48,
"byteOffset" : 0,
"target" : 34962
},
{
"buffer" : 0,
"byteLength" : 48,
"byteOffset" : 48,
"target" : 34962
},
{
"buffer" : 0,
"byteLength" : 32,
"byteOffset" : 96,
"target" : 34962
},
{
"buffer" : 0,
"byteLength" : 12,
"byteOffset" : 128,
"target" : 34963
}
],
"buffers" : [
{
"byteLength" : 140,
"uri" : "data:application/octet-stream;base64,AAAAvwAAAL9pISIzAAAAPwAAAL9pISIzAAAAvwAAAD9pISKzAAAAPwAAAD9pISKzAAAAAGkhojMAAIA/AAAAAGkhojMAAIA/AAAAAGkhojMAAIA/AAAAAGkhojMAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAAAAAEAAwAAAAMAAgA="
}
]
}

BIN
Assets/Models/Quad.shmodel Normal file

Binary file not shown.

View File

@ -0,0 +1,7 @@
Name: Quad
ID: 80501355
Type: 4
Sub Assets:
Name: Quad
ID: 141771688
Type: 8

View File

@ -15,6 +15,9 @@ layout(set = 2, binding = 0) uniform CameraData
{
vec4 position;
mat4 vpMat;
mat4 viewMat;
mat4 perspectiveMat;
mat4 orthoMat;
} cameraData;
void main()

View File

@ -34,7 +34,8 @@ layout(set = 2, binding = 0) uniform CameraData
vec4 position;
mat4 vpMat;
mat4 viewMat;
mat4 projMat;
mat4 perspectiveMat;
mat4 orthoMat;
} cameraData;
void main()

Binary file not shown.

View File

@ -0,0 +1,60 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
#extension GL_EXT_nonuniform_qualifier : require
struct MatPropData
{
vec4 color;
int textureIndex;
float alpha;
vec3 beta;
};
layout(location = 0) in struct
{
vec4 vertPos; // location 0
vec2 uv; // location = 1
vec4 normal; // location = 2
} In;
// material stuff
layout(location = 3) flat in struct
{
uint eid;
vec3 textColor;
} In2;
layout(set = 4, binding = 0) uniform sampler2D fontBitmap;
layout(location = 0) out vec4 color;
layout(location = 1) out uint outEntityID;
float median(float r, float g, float b)
{
return max(min(r, g), min(max(r, g), b));
}
void main()
{
vec3 msd = texture (fontBitmap, In.uv).rgb;
float sd = median (msd.r, msd.g, msd.b);
float screenPxDistance = 2 * (sd - 0.5f);
float opacity = clamp (screenPxDistance + 0.5f, 0.0f, 2.0f);
vec4 fragColor = vec4 (1.0f);
if (opacity > 0.02f && opacity < 1.9f)
{
fragColor = vec4(0.0f, 1.0f, 1.0f, 1.0f);
}
fragColor = mix(vec4(0.0f), vec4(In2.textColor, 1.0f), min (opacity, 1.0f));
color = fragColor;
outEntityID = In2.eid;
}

Binary file not shown.

View File

@ -0,0 +1,3 @@
Name: Text_FS
ID: 38024754
Type: 2

102
Assets/Shaders/Text_VS.glsl Normal file
View File

@ -0,0 +1,102 @@
#version 450
#extension GL_KHR_vulkan_glsl : enable
//#include "ShaderDescriptorDefinitions.glsl"
// vertex inputs
layout(location = 0) in vec4 positionalOffset;
layout(location = 1) in uint glyphIndex;
// between shader stages
layout(location = 0) out struct
{
vec4 vertPos; // location 0
vec2 uv; // location = 1
vec4 normal; // location = 2
} Out;
// material stuff
layout(location = 3) out struct
{
uint eid;
vec3 textColor;
} Out2;
// Camera data
layout(set = 2, binding = 0) uniform CameraData
{
vec4 position;
mat4 vpMat;
mat4 viewMat;
mat4 perspectiveMat;
mat4 orthoMat;
} cameraData;
// push constants
layout(std140, push_constant) uniform TestPushConstant
{
mat4 worldTransform;
uint eid;
vec3 textColor;
} testPushConstant;
// Descriptor sets
layout(std430, set = 4, binding = 1) buffer GlyphTransforms
{
mat4 matrices[];
} glyphTransforms;
vec2 CreateQuad(in uint vertexID)
{
uint b = 1 << vertexID;
return vec2 ((0x3 & b) != 0, (0x9 & b) != 0);
}
void main()
{
// write EID data to FS
Out2.eid = testPushConstant.eid;
// local variable for font index
uint fontIndex = glyphIndex;
// get font data
mat4 fontData = glyphTransforms.matrices[fontIndex];
// Generate UV coords and vertex positions
Out.uv = CreateQuad(gl_VertexIndex);
vec3 vertexPos = vec3(Out.uv, 1.0f);
// Get the local matrices
mat4 localModel = testPushConstant.worldTransform;
//mat4 uiScale = mat4(1.0f);
//uiScale[0][0] = cameraData.cameraRight / 20.49f;
//uiScale[1][1] = cameraData.cameraTop / 11.323f;
// transform the UV to atlas space to sample the font bitmap correctly
Out.uv = vec2(mat3(fontData) * vec3(Out.uv, 1.0f));
// Matrix to transform the quad from local to font space (for a font to be of correct size)
mat3 toFontSpace = mat3(1.0f);
toFontSpace[0][0] = fontData[3][0];
toFontSpace[1][1] = fontData[3][1];
toFontSpace[2][0] = positionalOffset.x;
toFontSpace[2][1] = positionalOffset.y;
mat4 PVMatrix = cameraData.vpMat;
// Initialize variables for use in FS
//characterIndex = gl_InstanceID;
// Transform the vertices to font space
vertexPos = toFontSpace * vertexPos;
Out2.textColor = testPushConstant.textColor;
// transform the vertex position to font space
gl_Position = PVMatrix * localModel * vec4(vertexPos, 1.0f);
}

Binary file not shown.

View File

@ -0,0 +1,3 @@
Name: Text_VS
ID: 39816727
Type: 2

View File

@ -0,0 +1,19 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
#extension GL_EXT_nonuniform_qualifier : require
layout (input_attachment_index = 0, set = 4, binding = 0) uniform subpassInput vec4 sceneTexture;
layout(location = 0) in struct
{
vec2 uv; // location = 0
} In;
layout(location = 0) out vec4 fragColor;
void main()
{
fragColor = vec4 (texture (sceneTexture, In.uv).rgb, 1.0f);
}

View File

@ -0,0 +1,21 @@
#version 450
#extension GL_KHR_vulkan_glsl : enable
layout(location = 0) out struct
{
vec2 uv; // location = 0
} Out;
vec2 CreateQuad(in uint vertexID)
{
uint b = 1 << vertexID;
return vec2 ((0x3 & b) != 0, (0x9 & b) != 0);
}
void main()
{
vec2 texCoord = CreateQuad (gl_VertexIndex);
vec2 vertexPos = texCoord - vec2(0.5f);
gl_Position = vec4 (vertexPos, 0.0f, 1.0f);
}

50
Assets/Shaders/UI_FS.glsl Normal file
View File

@ -0,0 +1,50 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
#extension GL_EXT_nonuniform_qualifier : require
struct MatPropData
{
vec4 color;
int textureIndex;
float alpha;
vec3 beta;
};
layout(location = 0) in struct
{
vec4 vertPos; // location 0
vec2 uv; // location = 1
vec4 normal; // location = 2
} In;
// material stuff
layout(location = 3) flat in struct
{
int materialIndex;
uint eid;
uint lightLayerIndex;
} In2;
layout (set = 0, binding = 1) uniform sampler2D textures[]; // for textures (global)
layout (std430, set = 3, binding = 0) buffer MaterialProperties // For materials
{
MatPropData data[];
} MatProp;
layout(location = 0) out vec4 position;
layout(location = 1) out uint outEntityID;
layout(location = 2) out uint lightLayerIndices;
layout(location = 3) out vec4 normals;
layout(location = 4) out vec4 albedo;
void main()
{
position = In.vertPos;
normals = In.normal;
albedo = vec4(1.0f);
outEntityID = In2.eid;
lightLayerIndices = In2.lightLayerIndex;
}

Binary file not shown.

View File

@ -0,0 +1,3 @@
Name: UI_FS
ID: 35983630
Type: 2

66
Assets/Shaders/UI_VS.glsl Normal file
View File

@ -0,0 +1,66 @@
#version 450
#extension GL_KHR_vulkan_glsl : enable
//#include "ShaderDescriptorDefinitions.glsl"
layout(location = 0) in vec3 aVertexPos;
layout(location = 1) in vec2 aUV;
layout(location = 2) in vec3 aNormal;
layout(location = 3) in vec3 aTangent;
layout(location = 4) in mat4 worldTransform;
layout(location = 8) in uvec2 integerData;
layout(location = 0) out struct
{
vec4 vertPos; // location 0
vec2 uv; // location = 1
vec4 normal; // location = 2
} Out;
// material stuff
layout(location = 3) out struct
{
int materialIndex;
uint eid;
uint lightLayerIndex;
} Out2;
layout(set = 2, binding = 0) uniform CameraData
{
vec4 position;
mat4 vpMat;
mat4 viewMat;
mat4 perspectiveMat;
mat4 orthoMat;
} cameraData;
void main()
{
Out2.materialIndex = gl_InstanceIndex;
Out2.eid = integerData[0];
Out2.lightLayerIndex = integerData[1];
// for transforming gBuffer position and normal data
mat4 modelViewMat = cameraData.viewMat * worldTransform;
// gBuffer position will be in view space
Out.vertPos = modelViewMat * vec4(aVertexPos, 1.0f);
// uvs for texturing in fragment shader
Out.uv = aUV;
mat3 transposeInv = mat3 (transpose(inverse(modelViewMat)));
// normals are also in view space
Out.normal.rgb = transposeInv * aNormal.rgb;
Out.normal.rgb = normalize (Out.normal.rgb);
// clip space for rendering
gl_Position = cameraData.orthoMat * worldTransform * vec4 (aVertexPos, 1.0f);
gl_Position.z += 0.1f; // HAX
// gl_Position = vec4 (aVertexPos, 1.0f);
}

Binary file not shown.

View File

@ -0,0 +1,3 @@
Name: UI_VS
ID: 46580970
Type: 2

View File

@ -6,7 +6,7 @@ echo ---------------------------------------------------
echo "SHADE DEPENDENCIES (Default - All in 10 Seconds)"
echo "A - All"
echo "B - VMA"
echo "C - msdf"
echo "C - FontCompiler"
echo "D - ModelCompiler"
echo "E - spdlog"
echo "F - reactphysics3d"
@ -28,7 +28,7 @@ set _e=%ERRORLEVEL%
if %_e%==1 goto VMA
if %_e%==2 goto VMA
if %_e%==3 goto MSDF
if %_e%==3 goto FontCompiler
if %_e%==4 goto ModelCompiler
if %_e%==5 goto spdlog
if %_e%==6 goto reactphysics3d
@ -47,12 +47,13 @@ if %_e%==16 goto fmod
echo -----------------------VMA----------------------------
rmdir "Dependencies/VMA" /S /Q
git clone https://github.com/SHADE-DP/VulkanMemoryAllocator.git "Dependencies/VMA"
if %_e%==2 (goto :done) else (goto :MSDF)
if %_e%==2 (goto :done) else (goto :FontCompiler)
:MSDF
echo -----------------------MSDF----------------------------
rmdir "Dependencies/msdf" /S /Q
git clone --recurse-submodules https://github.com/SHADE-DP/msdf-atlas-gen.git "Dependencies/msdf"
:FontCompiler
echo -----------------------FontCompiler----------------------------
rmdir "Dependencies/FontCompiler" /S /Q
git clone https://github.com/SHADE-DP/FontCompiler.git "Dependencies/FontCompiler"
git clone --recurse-submodules https://github.com/SHADE-DP/msdf-atlas-gen "Dependencies/FontCompiler/Dependencies/msdf"
if %_e%==3 (goto :done) else (goto :ModelCompiler)
:ModelCompiler

View File

@ -3,8 +3,9 @@ IncludeDir["ModelCompiler"] = "%{wks.location}\\Dependencies\\ModelCompiler"
IncludeDir["imgui"] = "%{wks.location}\\Dependencies\\imgui"
IncludeDir["imguizmo"] = "%{wks.location}\\Dependencies\\imguizmo"
IncludeDir["imnodes"] = "%{wks.location}\\Dependencies\\imnodes"
IncludeDir["msdf_atlas_gen"] = "%{wks.location}\\Dependencies\\msdf"
IncludeDir["msdfgen"] = "%{wks.location}\\Dependencies\\msdf\\msdfgen"
IncludeDir["FontCompiler"] = "%{wks.location}\\Dependencies\\FontCompiler"
IncludeDir["msdf_atlas_gen"] = "%{wks.location}\\Dependencies\\FontCompiler\\Dependencies\\msdf"
IncludeDir["msdfgen"] = "%{wks.location}\\Dependencies\\FontCompiler\\Dependencies\\msdf\\msdfgen"
IncludeDir["spdlog"] = "%{wks.location}\\Dependencies\\spdlog"
IncludeDir["tracy"] = "%{wks.location}\\Dependencies\\tracy"
IncludeDir["VMA"] = "%{wks.location}\\Dependencies\\VMA"

View File

@ -38,7 +38,9 @@ project "SHADE_Application"
"%{IncludeDir.spdlog}/include",
"%{IncludeDir.tinyddsloader}",
"%{IncludeDir.reactphysics3d}\\include",
"%{IncludeDir.yamlcpp}"
"%{IncludeDir.yamlcpp}",
"%{IncludeDir.msdf_atlas_gen}",
"%{IncludeDir.msdfgen}"
}
externalwarnings "Off"

View File

@ -80,6 +80,7 @@ namespace Sandbox
SHSystemManager::CreateSystem<SHCameraSystem>();
SHSystemManager::CreateSystem<SHUISystem>();
std::system("FontCompiler.exe ../../Assets/Fonts/SegoeUI.ttf");
SHSystemManager::CreateSystem<SHGraphicsSystem>();
SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
@ -140,7 +141,7 @@ namespace Sandbox
//SHComponentManager::CreateComponentSparseSet<SHCameraComponent>();
SHAssetManager::Load();
auto font = SHAssetManager::GetData<SHFontAsset>(176667660);
SHSystemManager::RegisterRoutine<SHAudioSystem, SHAudioSystem::AudioRoutine>();
@ -160,19 +161,24 @@ namespace Sandbox
void SBApplication::Update(void)
{
SHGraphicsSystem* graphicsSystem = SHADE::SHSystemManager::GetSystem<SHGraphicsSystem>();
#ifdef SHEDITOR
SHEditor* editor = SHADE::SHSystemManager::GetSystem<SHEditor>();
#endif
//TODO: Change true to window is open
while (!window.WindowShouldClose())
{
SHFrameRateController::UpdateFRC();
SHInputManager::UpdateInput(SHFrameRateController::GetRawDeltaTime());
SHSceneManager::UpdateSceneManager();
#ifdef SHEDITOR
if(editor->editorState == SHEditor::State::PLAY)
SHSceneManager::SceneUpdate(0.016f);
#endif
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f);
editor->PollPicking();
#endif
// TODO: Move into an Editor menu
static bool drawColliders = false;

View File

@ -13,6 +13,7 @@
#include "Physics/Interface/SHRigidBodyComponent.h"
#include "Physics/Interface/SHColliderComponent.h"
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
#include "Graphics/MiddleEnd/TextRendering/SHTextRendererComponent.h"
#include "Assets/SHAssetManager.h"
#include "Camera/SHCameraComponent.h"
@ -41,6 +42,19 @@ namespace Sandbox
void SBMainScene::Init()
{
sceneName = SHSerialization::DeserializeSceneFromFile(sceneAssetID);
/*-----------------------------------------------------------------------*/
/* TESTING CODE */
/*-----------------------------------------------------------------------*/
//testText = SHEntityManager::CreateEntity<SHTransformComponent, SHTextRendererComponent>(MAX_EID, "Test Text");
//auto gfxSystem =SHSystemManager::GetSystem<SHGraphicsSystem>();
//auto textComp = SHComponentManager::GetComponent<SHTextRendererComponent>(testText);
//textComp->SetFont(gfxSystem->GetFontLibrary().GetFonts()[0]);
/*-----------------------------------------------------------------------*/
/* TESTING CODE */
/*-----------------------------------------------------------------------*/
}
void SBMainScene::Update(float dt)

View File

@ -12,6 +12,8 @@ namespace Sandbox
EntityID testObj;
std::vector<EntityID> stressTestObjects;
EntityID testText;
public:
virtual void Load();
virtual void Init();

View File

@ -119,6 +119,7 @@ project "SHADE_Engine"
{
"xcopy /r /y /q \"%{IncludeDir.ModelCompiler}\\bin\\Debug\\assimp-vc142-mtd.dll\" \"$(OutDir)\"",
"xcopy /r /y /q \"%{IncludeDir.ModelCompiler}\\bin\\Debug\\ModelCompiler.exe\" \"$(OutDir)\"",
"xcopy /r /y /q \"%{IncludeDir.FontCompiler}\\bin\\Debug\\FontCompiler.exe\" \"$(OutDir)\"",
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodL.dll\" \"$(OutDir)\"",
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudioL.dll\" \"$(OutDir)\""
}
@ -128,6 +129,7 @@ project "SHADE_Engine"
{
"xcopy /r /y /q \"%{IncludeDir.ModelCompiler}\\bin\\Release\\assimp-vc142-mt.dll\" \"$(OutDir)\"",
"xcopy /r /y /q \"%{IncludeDir.ModelCompiler}\\bin\\Release\\ModelCompiler.exe\" \"$(OutDir)\"",
"xcopy /r /y /q \"%{IncludeDir.FontCompiler}\\bin\\Release\\FontCompiler.exe\" \"$(OutDir)\"",
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmod.dll\" \"$(OutDir)\"",
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudio.dll\" \"$(OutDir)\""
}

View File

@ -0,0 +1,47 @@
#pragma once
#include "SHAssetData.h"
#include "SH_API.h"
#include <vector>
#include <string>
#include "msdf-atlas-gen/msdf-atlas-gen.h"
#include "math/SHMatrix.h"
namespace SHADE
{
struct SH_API SHFontAsset : SHAssetData
{
using GlyphData = SHMatrix;
static constexpr uint32_t NUM_CHANNELS = 3;
static constexpr uint32_t BYTES_PER_CHANNEL = 3;
static constexpr uint8_t BASELINE_LEFT_MATRIX_INDEX_ROW = 3;
static constexpr uint8_t BASELINE_LEFT_MATRIX_INDEX_COL = 2;
static constexpr uint8_t BASELINE_BOTTOM_MATRIX_INDEX_ROW = 3;
static constexpr uint8_t BASELINE_BOTTOM_MATRIX_INDEX_COL = 3;
/*-----------------------------------------------------------------------*/
/* MEMBER VARIABLES */
/*-----------------------------------------------------------------------*/
//! Name of the shader file (without parent path)
std::string fontName;
//! Glyphs. Corresponds to the transformation container below.
std::vector<msdf_atlas::unicode_t> glyphs;
//! Data containing character and uv transformation data and other misc data
std::vector<GlyphData> glyphTransformations;
//! The actual data of the atlas to go into the binary. Was unique_ptr, vector easier to copy.
std::vector<unsigned char> bitmapData;
//! Width of the bitmap
uint32_t bitmapWidth;
//! Height of the bitmap
uint32_t bitmapHeight;
//! Font geometry required to get kerning from
msdf_atlas::FontGeometry fontGeometry;
};
}

View File

@ -0,0 +1,75 @@
#include "SHpch.h"
#include "SHFontLoader.h"
#include "Assets/Asset Types/SHFontAsset.h"
#include "Graphics/MiddleEnd/TextRendering/SHFreetypeInstance.h"
#include "msdf-atlas-gen/msdf-atlas-gen.h"
#include <fstream>
#include <sstream>
#include <string>
#include <algorithm>
namespace SHADE
{
SHADE::SHAssetData* SHFontLoader::Load(AssetPath path)
{
auto newFontAsset = new SHFontAsset();
std::ifstream file{ path.string(), std::ios::in | std::ios::binary };
if (!file.is_open())
{
SHLOG_ERROR("Unable to open compiled font file: {}", path.string());
return nullptr;
}
uint32_t numGlyphs = 0;
// read how many glyphs we have
file.read (reinterpret_cast<char*>(&numGlyphs), sizeof (uint32_t));
newFontAsset->glyphs.resize(numGlyphs);
newFontAsset->glyphTransformations.resize(numGlyphs);
for (uint32_t i = 0; i < numGlyphs; ++i)
{
// Read the data for the glyph
file.read(reinterpret_cast<char*>(&newFontAsset->glyphs[i]), sizeof(msdf_atlas::unicode_t));
}
for (uint32_t i = 0; i < numGlyphs; ++i)
{
// Read the data for the glyph transformations
file.read(reinterpret_cast<char*>(&newFontAsset->glyphTransformations[i]), sizeof(SHMatrix));
}
// read the width
file.read(reinterpret_cast<char*>(&newFontAsset->bitmapWidth), sizeof(SHFontAsset::bitmapWidth));
// read the height
file.read(reinterpret_cast<char*>(&newFontAsset->bitmapHeight), sizeof(SHFontAsset::bitmapHeight));
uint32_t bytesRequired = 0;
file.read(reinterpret_cast<char*>(&bytesRequired), sizeof(uint32_t));
// Read the bitmap
newFontAsset->bitmapData.resize(bytesRequired);
file.read(reinterpret_cast<char*>(newFontAsset->bitmapData.data()), bytesRequired);
file.close();
return newFontAsset;
}
void SHFontLoader::Write(SHAssetData const* data, AssetPath path)
{
/*
Stuff to write to binary file :
- Interleaved per character data
- codepoint (actual character)
- 4x4 Matrix data (stores UV transform + extra data)
- Actual atlas texture
*/
}
}

View File

@ -0,0 +1,24 @@
/*************************************************************************//**
* \file SHSFontLoader.h
* \author Loh Xiao Qi
* \date 23 10 2022
* \brief
*
* Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
* disclosure of this file or its contents without the prior written consent
* of DigiPen Institute of Technology is prohibited.
*****************************************************************************/
#pragma once
#include "Assets/Libraries/Loaders/SHAssetLoader.h"
namespace SHADE
{
struct SHFontLoader : SHAssetLoader
{
SHAssetData* Load(AssetPath path) override;
void Write(SHAssetData const* data, AssetPath path) override;
};
}

View File

@ -67,8 +67,9 @@ constexpr std::string_view ASSET_ROOT {"../../Assets"};
constexpr std::string_view BUILT_IN_ASSET_ROOT{ "../../Built_In" };
#endif
// COMPILER PATHS
// COMPILER EXE
constexpr std::string_view MODEL_COMPILER_EXE{ "ModelCompiler.exe" };
constexpr std::string_view FONT_COMPILER_EXE{ "FontCompiler.exe" };
// INTERNAL ASSET PATHS
constexpr std::string_view SCENE_FOLDER{ "/Scenes/" };
@ -81,14 +82,14 @@ constexpr std::string_view META_EXTENSION {".shmeta"};
constexpr std::string_view AUDIO_EXTENSION {".ogg"};
constexpr std::string_view AUDIO_WAV_EXTENSION {".wav"};
constexpr std::string_view SHADER_EXTENSION{ ".shshader" };
constexpr std::string_view SHADER_BUILT_IN_EXTENSION{".shshaderb"};
constexpr std::string_view SHADER_BUILT_IN_EXTENSION{ ".shshaderb" };
constexpr std::string_view FONT_EXTENSION{ ".shfont" };
constexpr std::string_view SCRIPT_EXTENSION {".cs"};
constexpr std::string_view SCENE_EXTENSION {".shade"};
constexpr std::string_view PREFAB_EXTENSION {".shprefab"};
constexpr std::string_view MATERIAL_EXTENSION {".shmat"};
constexpr std::string_view TEXTURE_EXTENSION {".shtex"};
constexpr std::string_view MODEL_EXTENSION{ ".shmodel" };
constexpr std::string_view FONT_EXTENSION{ ".shfont" };
constexpr std::string_view EXTENSIONS[] = {
AUDIO_EXTENSION,

View File

@ -20,6 +20,7 @@
#include "Libraries/Loaders/SHTextureLoader.h"
#include "Libraries/Loaders/SHShaderSourceLoader.h"
#include "Libraries/Loaders/SHTextBasedLoader.h"
#include "Libraries/Loaders/SHFontLoader.h"
//#include "Libraries/Compilers/SHMeshCompiler.h"
#include "Libraries/Compilers/SHTextureCompiler.h"
@ -392,7 +393,13 @@ namespace SHADE
auto const ext{ path.extension().string() };
if (ext == GLSL_EXTENSION.data())
{
newPath = SHShaderSourceCompiler::LoadAndCompileShader(path).value();
auto value { SHShaderSourceCompiler::LoadAndCompileShader(path) };
if (!value.has_value())
{
SHLOG_ERROR("Shader compile failed: {}", path.string());
return;
}
newPath = value.value();
}
else if (ext == GLTF_EXTENSION.data() || ext == FBX_EXTENSION.data())
{
@ -414,6 +421,16 @@ namespace SHADE
}
newPath = pathGen.value();
}
else if (ext == TTF_EXTENSION.data())
{
std::string command = FONT_COMPILER_EXE.data();
command += " " + path.string();
std::system(command.c_str());
std::string fontPath = path.string().substr(0, path.string().find_last_of('.'));
fontPath += FONT_EXTENSION;
newPath = fontPath;
}
else
{
SHLOG_WARNING("File Type compilation not yet Implemented: {}", path.string());
@ -466,6 +483,8 @@ namespace SHADE
loaders[static_cast<size_t>(AssetType::PREFAB)] = loaders[static_cast<size_t>(AssetType::SCENE)];
loaders[static_cast<size_t>(AssetType::MATERIAL)] = loaders[static_cast<size_t>(AssetType::SCENE)];
loaders[static_cast<size_t>(AssetType::MESH)] = nullptr;
loaders[static_cast<size_t>(AssetType::SCRIPT)] = nullptr;
loaders[static_cast<size_t>(AssetType::FONT)] = dynamic_cast<SHAssetLoader*>(new SHFontLoader());
}
/****************************************************************************

View File

@ -246,7 +246,7 @@ namespace SHADE
camera.orthoProjMatrix(2, 3) = -n / (f-n);
camera.orthoProjMatrix(3, 3) = 1.0f;
camera.orthoProjMatrix = SHMatrix::OrthographicRH(camera.GetWidth(), camera.GetHeight(), camera.GetNear(), camera.GetFar());
//camera.orthoProjMatrix = SHMatrix::OrthographicRH(camera.GetWidth(), camera.GetHeight(), camera.GetNear(), camera.GetFar());
//camera.projMatrix.Transpose();
camera.dirtyProj = false;

View File

@ -21,7 +21,7 @@ namespace SHADE
template<typename T>
static bool SetPayload(DragDropTag const& type, T* object, ImGuiCond const cond = 0)
{
ImGui::SetDragDropPayload(type.data(), static_cast<void*>(object), sizeof(T), cond);
hasDragDrop = ImGui::SetDragDropPayload(type.data(), static_cast<void*>(object), sizeof(T), cond);
hasDragDrop = true;
currentDragDropTag = type;

View File

@ -264,14 +264,19 @@ namespace SHADE
SHEditorWidgets::BeginPanel(std::format("{} Constraints", ICON_FA_LOCK).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
SHEditorWidgets::TextLabel("Freeze Position");
ImGui::PushID("FreezePos");
SHEditorWidgets::CheckBox("X", [component] {return component->GetFreezePositionX(); }, [component](bool const& value) {component->SetFreezePositionX(value); }, "Freeze Position - X"); ImGui::SameLine();
SHEditorWidgets::CheckBox("Y", [component] {return component->GetFreezePositionY(); }, [component](bool const& value) {component->SetFreezePositionY(value); }, "Freeze Position - Y"); ImGui::SameLine();
SHEditorWidgets::CheckBox("Z", [component] {return component->GetFreezePositionZ(); }, [component](bool const& value) {component->SetFreezePositionZ(value); }, "Freeze Position - Z");
ImGui::PopID();
SHEditorWidgets::TextLabel("Freeze Rotation");
ImGui::PushID("FreezeRot");
SHEditorWidgets::CheckBox("X", [component] {return component->GetFreezeRotationX(); }, [component](bool const& value) {component->SetFreezeRotationX(value); }, "Freeze Rotation - X"); ImGui::SameLine();
SHEditorWidgets::CheckBox("Y", [component] {return component->GetFreezeRotationY(); }, [component](bool const& value) {component->SetFreezeRotationY(value); }, "Freeze Rotation - Y"); ImGui::SameLine();
SHEditorWidgets::CheckBox("Z", [component] {return component->GetFreezeRotationZ(); }, [component](bool const& value) {component->SetFreezeRotationZ(value); }, "Freeze Rotation - Z");
ImGui::PopID();
SHEditorWidgets::EndPanel();
}

View File

@ -172,11 +172,20 @@ namespace SHADE
// Shader
bool shaderChanged = false;
const auto* SHADER_INFO = SHAssetManager::GetData<SHShaderAsset>(currentMatSpec->fragShader);
const std::string SHADER_NAME = SHADER_INFO ? SHADER_INFO->name : "Unknown Shader";
const auto* VERT_SHADER_INFO = SHAssetManager::GetData<SHShaderAsset>(currentMatSpec->vertexShader);
const std::string VERT_SHADER_NAME = VERT_SHADER_INFO ? VERT_SHADER_INFO->name : "Unknown Shader";
isDirty |= SHEditorWidgets::DragDropReadOnlyField<AssetID>
(
"Fragment Shader", SHADER_NAME.data(),
"Fragment Shader", VERT_SHADER_NAME.data(),
[this]() { return currentMatSpec->vertexShader; },
[this](const AssetID& id) { currentMatSpec->vertexShader = id; },
SHDragDrop::DRAG_RESOURCE
);
const auto* FRAG_SHADER_INFO = SHAssetManager::GetData<SHShaderAsset>(currentMatSpec->fragShader);
const std::string FRAG_SHADER_NAME = FRAG_SHADER_INFO ? FRAG_SHADER_INFO->name : "Unknown Shader";
isDirty |= SHEditorWidgets::DragDropReadOnlyField<AssetID>
(
"Fragment Shader", FRAG_SHADER_NAME.data(),
[this]() { return currentMatSpec->fragShader; },
[this](const AssetID& id) { currentMatSpec->fragShader = id; },
SHDragDrop::DRAG_RESOURCE

View File

@ -516,7 +516,7 @@ namespace SHADE
ImGui_ImplVulkan_DestroyFontUploadObjects();
renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer>& cmd)
renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer>& cmd, uint32_t frameIndex)
{
cmd->BeginLabeledSegment("ImGui Draw");
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer());

View File

@ -25,12 +25,9 @@ namespace SHADE
{
if (cmdBufferHdl && (bufferUsageFlags & vk::BufferUsageFlagBits::eTransferDst))
{
vk::BufferCopy copyRegion
{
.srcOffset = 0,
.dstOffset = 0,
.size = sizeStored,
};
vk::BufferCopy copyRegion{};
PrepareBufferCopy(copyRegion);
cmdBufferHdl->GetVkCommandBuffer().copyBuffer(stagingBuffer, vkBuffer, 1, &copyRegion);
}
}
@ -54,6 +51,13 @@ namespace SHADE
vmaFlushAllocation(vmaAllocator, alloc, srcOffset, dstOffset);
}
void SHVkBuffer::PrepareBufferCopy(vk::BufferCopy& bufferCopy) noexcept
{
bufferCopy.srcOffset = 0;
bufferCopy.dstOffset = 0;
bufferCopy.size = sizeStored;
}
vk::Buffer SHVkBuffer::GetVkBuffer(void) const noexcept
{
return vkBuffer;

View File

@ -106,6 +106,7 @@ namespace SHADE
void ResizeNoCopy (uint32_t newSize);
void ResizeReplace (uint32_t newSize, void* data, uint32_t srcSize);
void FlushAllocation (uint32_t srcOffset, uint32_t dstOffset) noexcept;
void PrepareBufferCopy (vk::BufferCopy& bufferCopy) noexcept;
/*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */

View File

@ -459,7 +459,7 @@ namespace SHADE
return SHVkInstance::GetResourceManager().Create<SHVkImage>(GetHandle(), &vmaAllocator, w, h, levels, format, usage, create);
}
Handle<SHVkImage> SHVkLogicalDevice::CreateImage(SHImageCreateParams const& imageDetails, unsigned char* data, uint32_t dataSize, std::span<uint32_t> inMipOffsets, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags) noexcept
Handle<SHVkImage> SHVkLogicalDevice::CreateImage(SHImageCreateParams const& imageDetails, unsigned char* data, uint32_t dataSize, std::vector<uint32_t> const& inMipOffsets, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags) noexcept
{
return SHVkInstance::GetResourceManager().Create<SHVkImage>(GetHandle(), &vmaAllocator, imageDetails, data, dataSize, inMipOffsets, memUsage, allocFlags);
}

View File

@ -162,7 +162,7 @@ namespace SHADE
SHImageCreateParams const& imageDetails,
unsigned char* data,
uint32_t dataSize,
std::span<uint32_t> inMipOffsets,
std::vector<uint32_t> const& inMipOffsets,
VmaMemoryUsage memUsage,
VmaAllocationCreateFlags allocFlags
) noexcept;

View File

@ -123,7 +123,7 @@ namespace SHADE
SHImageCreateParams const& imageDetails,
const unsigned char* data,
uint32_t dataSize,
std::span<uint32_t> inMipOffsets,
std::vector<uint32_t> const& inMipOffsets,
VmaMemoryUsage memUsage,
VmaAllocationCreateFlags allocFlags
) noexcept
@ -311,6 +311,22 @@ namespace SHADE
CreateFramebufferImage();
}
void SHVkImage::PrepareImageCopy(std::vector<vk::BufferImageCopy>& bufferImageCopy) noexcept
{
for (uint32_t i = 0; i < mipOffsets.size(); ++i)
{
bufferImageCopy[i].bufferOffset = mipOffsets[i];
bufferImageCopy[i].bufferRowLength = 0; // for padding
bufferImageCopy[i].bufferImageHeight = 0; // for padding
bufferImageCopy[i].imageSubresource.aspectMask = vk::ImageAspectFlagBits::eColor; // TODO: Need to change this to base it off image format.
bufferImageCopy[i].imageSubresource.mipLevel = i;
bufferImageCopy[i].imageSubresource.baseArrayLayer = 0; // TODO: Array textures not supported yet
bufferImageCopy[i].imageSubresource.layerCount = layerCount;
bufferImageCopy[i].imageOffset = vk::Offset3D{ 0,0,0 };
bufferImageCopy[i].imageExtent = vk::Extent3D{ width >> i, height >> i, 1 };
}
}
void SHVkImage::LinkWithExteriorImage(vk::Image inVkImage, vk::ImageType type, uint32_t inWidth, uint32_t inHeight, uint32_t inDepth, uint32_t layers, uint8_t levels, vk::Format format, vk::ImageUsageFlags flags) noexcept
{
vkImage = inVkImage;
@ -405,4 +421,9 @@ namespace SHADE
return height;
}
uint32_t SHVkImage::GetMipLevels(void) const noexcept
{
return mipLevelCount;
}
}

View File

@ -102,7 +102,7 @@ namespace SHADE
vk::Buffer stagingBuffer;
//! Mipmap offsets for initializing the vk::BufferImageCopy during transfer to GPU resource
std::span<uint32_t> mipOffsets;
std::vector<uint32_t> mipOffsets;
//! Handle to the device that creates these images
Handle<SHVkLogicalDevice> device;
@ -125,7 +125,7 @@ namespace SHADE
SHImageCreateParams const& imageDetails,
const unsigned char* data,
uint32_t dataSize,
std::span<uint32_t> inMipOffsets,
std::vector<uint32_t> const& inMipOffsets,
VmaMemoryUsage memUsage,
VmaAllocationCreateFlags allocFlags
) noexcept;
@ -142,6 +142,7 @@ namespace SHADE
void TransferToDeviceResource (Handle<SHVkCommandBuffer> cmdBufferHdl) noexcept;
void PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept;
void HandleResizeFramebufferImage(uint32_t newWidth, uint32_t newHeight) noexcept;
void PrepareImageCopy (std::vector<vk::BufferImageCopy>& bufferImageCopy) noexcept;
/*-----------------------------------------------------------------------*/
/* GETTERS AND SETTERS */
@ -153,6 +154,7 @@ namespace SHADE
vk::Format GetImageFormat (void) const noexcept;
uint32_t GetWidth (void) const noexcept;
uint32_t GetHeight (void) const noexcept;
uint32_t GetMipLevels (void) const noexcept;
};
}

View File

@ -28,6 +28,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
#include "Graphics/Descriptors/SHVkDescriptorPool.h"
#include "Scene/SHSceneManager.h"
#include "UI/SHUIComponent.h"
namespace SHADE
{
@ -309,7 +310,13 @@ namespace SHADE
{
if (SHSceneManager::CheckNodeAndComponentsActive<SHRenderable>(rendId))
{
transformData.emplace_back(transform->GetTRS());
auto uiComp = SHComponentManager::GetComponent_s<SHUIComponent>(rendId);
if (uiComp)
{
transformData.emplace_back(uiComp->GetMatrix());
}
else
transformData.emplace_back(transform->GetTRS());
}
else
{

View File

@ -97,6 +97,8 @@ namespace SHADE
Handle<SHVkDescriptorSetLayout> materialDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, { materialDataBinding });
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, materialDataPerInstanceLayout->GetVkHandle(), "[Descriptor Set Layout] Material Globals");
globalDescSetLayouts.push_back(staticGlobalLayout);
globalDescSetLayouts.push_back(dynamicGlobalLayout);
globalDescSetLayouts.push_back(cameraDataGlobalLayout);

View File

@ -90,7 +90,7 @@ namespace SHADE
auto const& RENDERERS = GFX_SYSTEM->GetDefaultViewport()->GetRenderers();
auto renderGraph = RENDERERS[SHGraphicsConstants::RenderGraphIndices::WORLD]->GetRenderGraph();
auto subPass = renderGraph->GetNode("Debug Draw")->GetSubpass("Debug Draw");
subPass->AddExteriorDrawCalls([this, GFX_SYSTEM](Handle<SHVkCommandBuffer>& cmdBuffer)
subPass->AddExteriorDrawCalls([this, GFX_SYSTEM](Handle<SHVkCommandBuffer>& cmdBuffer, uint32_t frameIndex)
{
// Get Current frame index
const uint32_t FRAME_IDX = GFX_SYSTEM->GetCurrentFrameIndex();
@ -106,7 +106,7 @@ namespace SHADE
}
});
auto subPassWithDepth = renderGraph->GetNode("Debug Draw with Depth")->GetSubpass("Debug Draw with Depth");
subPassWithDepth->AddExteriorDrawCalls([this, GFX_SYSTEM](Handle<SHVkCommandBuffer>& cmdBuffer)
subPassWithDepth->AddExteriorDrawCalls([this, GFX_SYSTEM](Handle<SHVkCommandBuffer>& cmdBuffer, uint32_t frameIndex)
{
// Get Current frame index
const uint32_t FRAME_IDX = GFX_SYSTEM->GetCurrentFrameIndex();

View File

@ -66,7 +66,9 @@ namespace SHADE
/***************************************************************************/
/*!
\brief
DescriptorSet Index for render graph resources.
DescriptorSet Index for render graph resources. Unlike the sets from
1 to 3 and 6, this set index does not have hard coded bindings and is
NOT part of the layouts included in the global data.
*/
/***************************************************************************/
static constexpr uint32_t RENDERGRAPH_RESOURCE = 4;
@ -75,13 +77,21 @@ namespace SHADE
\brief
DescriptorSet Index for render graph node compute resources. For data
that we wish to pass to compute shaders in the render graph, this is
the set to use. Unlike the sets from 1 to 3, this set index does not have
the set to use. Unlike the sets from 1 to 3 and 6, this set index does not have
hard coded bindings and is NOT part of the layouts included in the global
data.
*/
/***************************************************************************/
static constexpr uint32_t RENDERGRAPH_NODE_COMPUTE_RESOURCE = 5;
/***************************************************************************/
/*!
\brief
To store font data.
*/
/***************************************************************************/
static constexpr uint32_t FONT_DATA = 4;
};
struct DescriptorSetBindings
@ -107,7 +117,7 @@ namespace SHADE
/***************************************************************************/
/*!
\brief
DescriptorSet binding for combined image sampler data.
DescriptorSet binding for light data.
*/
/***************************************************************************/
@ -116,7 +126,7 @@ namespace SHADE
/***************************************************************************/
/*!
\brief
DescriptorSet binding for lights.
DescriptorSet binding for camera data.
*/
/***************************************************************************/
@ -130,6 +140,24 @@ namespace SHADE
/***************************************************************************/
static constexpr uint32_t BATCHED_PER_INST_DATA = 0;
/***************************************************************************/
/*!
\brief
Descriptor set binding for font bitmaps.
*/
/***************************************************************************/
static constexpr uint32_t FONT_BITMAP_DATA = 0;
/***************************************************************************/
/*!
\brief
Descriptor set binding for font matrix data.
*/
/***************************************************************************/
static constexpr uint32_t FONT_MATRIX_DATA = 1;
};
struct VertexBufferBindings
@ -177,6 +205,10 @@ namespace SHADE
/***************************************************************************/
static constexpr uint32_t INTEGER_DATA = 5;
static constexpr uint32_t CALCULATED_GLYPH_POSITION = 0;
static constexpr uint32_t GLYPH_INDEX = 1;
};
/*******************************************************************************/

View File

@ -42,6 +42,8 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/SHVkUtil.h"
#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h"
#include "../Meshes/SHPrimitiveGenerator.h"
#include "Graphics/MiddleEnd/TextRendering/SHFreetypeInstance.h"
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.h"
namespace SHADE
{
@ -115,14 +117,25 @@ namespace SHADE
// Create generic command buffer
graphicsCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
SHAssetManager::CompileAsset("../../Assets/Shaders/Text_VS.glsl", false);
SHAssetManager::CompileAsset("../../Assets/Shaders/Text_FS.glsl", false);
SHAssetManager::CompileAsset("../../Assets/Shaders/TestCube_VS.glsl", false);
SHAssetManager::CompileAsset("../../Assets/Shaders/UI_VS.glsl", false);
SHAssetManager::CompileAsset("../../Assets/Shaders/UI_FS.glsl", false);
SHAssetManager::CompileAsset("../../Assets/Models/Quad.gltf", false);
// Load Built In Shaders
static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT);
static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEFAULT);
static constexpr AssetID VS_DEBUG = 48002439; debugVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEBUG);
static constexpr AssetID FS_DEBUG = 36671027; debugFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEBUG);
static constexpr AssetID CS_COMPOSITE = 45072428; deferredCompositeShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(CS_COMPOSITE);
static constexpr AssetID SSAO = 38430899; ssaoShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(SSAO);
static constexpr AssetID SSAO_BLUR = 39760835; ssaoBlurShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(SSAO_BLUR);
static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT);
static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEFAULT);
static constexpr AssetID VS_DEBUG = 48002439; debugVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEBUG);
static constexpr AssetID FS_DEBUG = 36671027; debugFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEBUG);
static constexpr AssetID CS_COMPOSITE = 45072428; deferredCompositeShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(CS_COMPOSITE);
static constexpr AssetID SSAO = 38430899; ssaoShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(SSAO);
static constexpr AssetID SSAO_BLUR = 39760835; ssaoBlurShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(SSAO_BLUR);
static constexpr AssetID TEXT_VS = 39816727; textVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(TEXT_VS);
static constexpr AssetID TEXT_FS = 38024754; textFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(TEXT_FS);
static constexpr AssetID SEGOE_UI_FONT = 176667660; testFont = SHResourceManager::LoadOrGet<SHFont>(SEGOE_UI_FONT);
}
void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept
@ -149,6 +162,8 @@ namespace SHADE
worldCamera->SetLookAt(SHVec3(0.0f, 0.0f, 0.0f), SHVec3(0.0f, 0.0f, -2.0f), SHVec3(0.0f, 1.0f, 0.0f));
worldCamera->SetPerspective(90.0f, static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.0f, 100.0f);
worldCameraDirector = cameraSystem->CreateDirector();
// Create Default Viewport
worldViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast<float>(window->GetWindowSize().first), static_cast<float>(window->GetWindowSize().second), 0.0f, 1.0f));
@ -162,20 +177,21 @@ namespace SHADE
}
/*-----------------------------------------------------------------------*/
/* SCENE RENDER GRAPH RESOURCES */
/* WORLD RENDER GRAPH RESOURCES */
/*-----------------------------------------------------------------------*/
// Initialize world render graph
worldRenderGraph->Init("World Render Graph", device, swapchain);
worldRenderGraph->AddResource("Position", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
worldRenderGraph->AddResource("Normals", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
worldRenderGraph->Init("World Render Graph", device, swapchain, &resourceManager);
worldRenderGraph->AddResource("Position", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
worldRenderGraph->AddResource("Normals", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
//worldRenderGraph->AddResource("Tangents", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
worldRenderGraph->AddResource("Albedo", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
worldRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
worldRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
worldRenderGraph->AddResource("Light Layer Indices", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
worldRenderGraph->AddResource("SSAO", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
worldRenderGraph->AddResource("SSAO Blur", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
worldRenderGraph->AddResource("Albedo", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
worldRenderGraph->AddResource("Depth Buffer", { SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
worldRenderGraph->AddResource("Entity ID", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
worldRenderGraph->AddResource("Light Layer Indices", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
worldRenderGraph->AddResource("Scene", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, windowDims.first, windowDims.second);
worldRenderGraph->AddResource("SSAO", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
worldRenderGraph->AddResource("SSAO Blur", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
/*-----------------------------------------------------------------------*/
/* MAIN NODE */
@ -205,7 +221,7 @@ namespace SHADE
gBufferSubpass->AddColorOutput("Normals");
//gBufferSubpass->AddColorOutput("Tangents");
gBufferSubpass->AddColorOutput("Albedo");
gBufferSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL);
gBufferSubpass->AddDepthOutput("Depth Buffer", SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL);
/*-----------------------------------------------------------------------*/
/* SSAO PASS AND DATA INIT */
@ -250,25 +266,63 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
gBufferNode->AddNodeCompute("Deferred Composite", deferredCompositeShader, {"Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene"});
// Dummy Node
auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, { "Debug Draw" }); // no predecessors
auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass");
dummySubpass->AddInput("Scene");
{
//// Dummy Node to transition scene render graph resource
//auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, { "Debug Draw" }); // no predecessors
//auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass");
//dummySubpass->AddInput("Scene");
}
/*-----------------------------------------------------------------------*/
/* GENERATE RENDER GRAPH */
/* GENERATE WORLD RENDER GRAPH */
/*-----------------------------------------------------------------------*/
// Generate world render graph
worldRenderGraph->Generate();
/*-----------------------------------------------------------------------*/
/* SCREEN RENDER GRAPH */
/*-----------------------------------------------------------------------*/
// Initialize screen render graph
screenRenderGraph = resourceManager.Create<SHRenderGraph>();
screenRenderGraph->Init("Screen Render Graph", device, swapchain, &resourceManager);
screenRenderGraph->LinkNonOwningResource(worldRenderGraph, "Scene");
screenRenderGraph->LinkNonOwningResource(worldRenderGraph, "Entity ID");
screenRenderGraph->AddResource("Present", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second);
auto screenSpaceNode = screenRenderGraph->AddNode("Screen Space Pass", { "Scene", "Entity ID"}, {});
auto uiSubpass = screenSpaceNode->AddSubpass("UI");
uiSubpass->AddColorOutput("Scene");
uiSubpass->AddColorOutput("Entity ID");
uiSubpass->AddExteriorDrawCalls([=](Handle<SHVkCommandBuffer>& cmdBuffer, uint32_t frameIndex)
{
textRenderingSubSystem->Render(cmdBuffer, frameIndex);
});
{
// Dummy Node to transition scene render graph resource
auto dummyNode = screenRenderGraph->AddNode("Dummy Pass", { "Scene" }, { "Screen Space Pass" }); // no predecessors
auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass");
dummySubpass->AddInput("Scene");
}
//screenRenderGraph->AddRenderToSwapchainNode ("Scene", "Present", )
screenRenderGraph->Generate();
/*-----------------------------------------------------------------------*/
/* BIND RENDER GRAPH TO RENDERER */
/*-----------------------------------------------------------------------*/
// Add world renderer to default viewport
worldRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph);
worldRenderer->SetCamera(worldCamera);
worldRenderer->SetCameraDirector(worldCameraDirector);
// Add screen renderer to default viewport
screenRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], screenRenderGraph);
screenRenderer->SetCamera(screenCamera);
screenRenderer->SetCameraDirector(worldCameraDirector);
worldRenderer->SetCameraDirector(cameraSystem->CreateDirector());
// Create debug draw pipeline
debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass);
@ -315,6 +369,17 @@ namespace SHADE
lightingSubSystem = resourceManager.Create<SHLightingSubSystem>();
lightingSubSystem->Init(device, descPool);
textRenderingSubSystem = resourceManager.Create<SHTextRenderingSubSystem>();
// initialize the text renderer
auto uiNode = screenRenderGraph->GetNode("Screen Space Pass");
textRenderingSubSystem->Init(device, uiNode->GetRenderpass(), uiNode->GetSubpass("UI"), descPool, textVS, textFS, [=](Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex)
{
screenRenderer->BindDescSet(cmdBuffer, frameIndex);
});
SHFreetypeInstance::Init();
}
void SHGraphicsSystem::InitBuiltInResources(void)
@ -355,8 +420,8 @@ namespace SHADE
for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i)
renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0];
editorRenderGraph->Init("Editor Render Graph", device, swapchain);
editorRenderGraph->AddResource("Present", { SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second);
editorRenderGraph->Init("Editor Render Graph", device, swapchain, &resourceManager);
editorRenderGraph->AddResource("Present", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second);
auto imguiNode = editorRenderGraph->AddNode("ImGui Node", { "Present"}, {});
@ -385,6 +450,7 @@ namespace SHADE
void SHGraphicsSystem::Exit(void)
{
SHFreetypeInstance::Exit();
}
#pragma endregion INIT_EXIT
@ -454,6 +520,8 @@ namespace SHADE
#endif
}
textRenderingSubSystem->Run(frameIndex);
// For every viewport
for (int vpIndex = 0; vpIndex < static_cast<int>(viewports.size()); ++vpIndex)
{
@ -513,7 +581,7 @@ namespace SHADE
{
auto editorSystem = SHSystemManager::GetSystem<SHEditor>();
if (editorSystem->editorState != SHEditor::State::PLAY)
worldRenderer->UpdateDataAndBind(currentCmdBuffer, frameIndex, cameraSystem->GetEditorCamera()->GetViewMatrix(), cameraSystem->GetEditorCamera()->GetProjMatrix());
worldRenderer->UpdateDataAndBind(currentCmdBuffer, frameIndex, cameraSystem->GetEditorCamera()->GetViewMatrix(), cameraSystem->GetEditorCamera()->GetProjMatrix(), cameraSystem->GetEditorCamera()->GetOrthoMatrix());
else
renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex);
}
@ -761,7 +829,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
Handle<SHTexture> SHGraphicsSystem::AddTexture(const SHTextureAsset& texAsset)
{
const int MIPS = texAsset.mipOffsets.size();
const int MIPS = static_cast<int> (texAsset.mipOffsets.size());
auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams { .maxLod = static_cast<float>(MIPS) });
SET_VK_OBJ_NAME(device, vk::ObjectType::eSampler, sampler->GetVkSampler(), "[Sampler] Mips " + std::to_string(MIPS));
return texLibrary.Add(texAsset, sampler);
@ -769,7 +837,7 @@ namespace SHADE
SHADE::Handle<SHADE::SHTexture> SHGraphicsSystem::AddTexture(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector<uint32_t> mipOffsets)
{
const int MIPS = mipOffsets.size();
const int MIPS = static_cast<int> (mipOffsets.size());
auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams{ .maxLod = static_cast<float>(MIPS) });
SET_VK_OBJ_NAME(device, vk::ObjectType::eSampler, sampler->GetVkSampler(), "[Sampler] Mips " + std::to_string(MIPS));
return texLibrary.Add(pixelCount, pixelData, width, height, format, mipOffsets, sampler);
@ -798,6 +866,19 @@ namespace SHADE
return texLibrary.GetTextureHandle(textureId);
}
/*---------------------------------------------------------------------------------*/
/* Font Registration Functions */
/*---------------------------------------------------------------------------------*/
Handle<SHFont> SHGraphicsSystem::AddFont(SHFontAsset const& fontAsset) noexcept
{
return fontLibrary.AddFont(device, resourceManager, fontAsset);
}
void SHGraphicsSystem::BuildFonts(void) noexcept
{
fontLibrary.BuildFonts(device, graphicsQueue, graphicsCmdPool, descPool, textRenderingSubSystem->GetFontDataDescSetLayout(), resourceManager);
}
#pragma endregion ADD_REMOVE
#pragma region ROUTINES
@ -920,6 +1001,7 @@ namespace SHADE
#pragma region MISC
void SHGraphicsSystem::PrepareResize(uint32_t newWidth, uint32_t newHeight) noexcept
{
resizeWidth = newWidth;
@ -946,7 +1028,12 @@ namespace SHADE
renderContext.HandleResize();
worldRenderGraph->HandleResize(resizeWidth, resizeHeight);
#ifdef SHEDITOR
editorRenderGraph->HandleResize(windowDims.first, windowDims.second);
#endif
screenRenderGraph->HandleResize(resizeWidth, resizeHeight);
mousePickSystem->HandleResize();
postOffscreenRender->HandleResize();
@ -986,6 +1073,11 @@ namespace SHADE
return worldRenderGraph->GetNode(G_BUFFER_RENDER_GRAPH_NODE_NAME.data());
}
SHADE::SHFontLibrary const& SHGraphicsSystem::GetFontLibrary(void) const noexcept
{
return fontLibrary;
}
Handle<SHVkPipeline> SHGraphicsSystem::createDebugDrawPipeline(Handle<SHVkRenderpass> renderPass, Handle<SHSubpass> subpass)
{
auto pipelineLayout = resourceManager.Create<SHVkPipelineLayout>

View File

@ -32,6 +32,8 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h"
#include "Graphics/MiddleEnd/Lights/SHLightingSubSystem.h"
#include "Graphics/MiddleEnd/PostProcessing/SHSSAO.h"
#include "Camera/SHCameraDirector.h"
#include "Graphics/MiddleEnd/TextRendering/SHFontLibrary.h"
namespace SHADE
{
@ -54,6 +56,7 @@ namespace SHADE
class SHMaterial;
class SHMaterialInstance;
class SHMousePickSystem;
class SHTextRenderingSubSystem;
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
@ -326,6 +329,22 @@ namespace SHADE
*/
/***************************************************************************/
Handle<SHTexture> GetDefaultTexture() const noexcept { return defaultTexture; }
/***************************************************************************/
/*!
\brief
Adds a font into the font library.
\param fontAsset
Font asset to add.
\return
Handle to the new font.
*/
/***************************************************************************/
Handle<SHFont> AddFont (SHFontAsset const& fontAsset) noexcept;
void BuildFonts (void) noexcept;
void PrepareResize(uint32_t newWidth, uint32_t newHeight) noexcept;
void HandleResize(void) noexcept;
@ -355,6 +374,7 @@ namespace SHADE
Handle<SHVkPipeline> GetDebugDrawPipeline(void) const noexcept { return debugDrawPipeline; }
Handle<SHVkPipeline> GetDebugDrawDepthPipeline(void) const noexcept { return debugDrawDepthPipeline; }
uint32_t GetCurrentFrameIndex(void) const noexcept { return renderContext.GetCurrentFrame(); }
SHFontLibrary const& GetFontLibrary (void) const noexcept;
/*-----------------------------------------------------------------------------*/
/* Getters */
@ -391,6 +411,7 @@ namespace SHADE
SHResourceHub resourceManager;
SHMeshLibrary meshLibrary;
SHTextureLibrary texLibrary;
SHFontLibrary fontLibrary;
SHSamplerCache samplerCache;
SHMaterialInstanceCache materialInstanceCache;
@ -398,18 +419,20 @@ namespace SHADE
#ifdef SHEDITOR
Handle<SHViewport> editorViewport;
Handle<SHRenderer> editorRenderer;
Handle<SHRenderGraph> editorRenderGraph;
#endif
Handle<SHViewport> worldViewport; // Whole screen
std::vector<Handle<SHViewport>> viewports; // Additional viewports
std::vector<Handle<SHViewport>> viewports; // Additional viewports
// Temp renderers
// Renderers
Handle<SHRenderer> worldRenderer;
Handle<SHRenderer> screenRenderer;
// Temp Cameras
Handle<SHCamera> worldCamera;
Handle<SHCamera> screenCamera;
DirectorHandle worldCameraDirector;
// Built-In Shaders
Handle<SHVkShaderModule> defaultVertShader;
@ -419,7 +442,11 @@ namespace SHADE
Handle<SHVkShaderModule> deferredCompositeShader;
Handle<SHVkShaderModule> ssaoShader;
Handle<SHVkShaderModule> ssaoBlurShader;
Handle<SHVkShaderModule> textVS;
Handle<SHVkShaderModule> textFS;
// Fonts
Handle<SHFont> testFont;
// Built-In Materials
Handle<SHMaterial> defaultMaterial;
@ -434,11 +461,16 @@ namespace SHADE
// Render Graphs
Handle<SHRenderGraph> worldRenderGraph;
Handle<SHRenderGraph> screenRenderGraph;
#ifdef SHEDITOR
Handle<SHRenderGraph> editorRenderGraph;
#endif
// Sub systems
Handle<SHMousePickSystem> mousePickSystem;
Handle<SHPostOffscreenRenderSystem> postOffscreenRender;
Handle<SHLightingSubSystem> lightingSubSystem;
Handle<SHTextRenderingSubSystem> textRenderingSubSystem;
Handle<SHSSAO> ssaoStorage;
uint32_t resizeWidth = 1;

View File

@ -90,17 +90,22 @@ namespace SHADE
if (camera && cameraDirector)
{
//UpdateDataAndBind(cmdBuffer, frameIndex, SHMatrix::Transpose(cameraDirector->GetVPMatrix()));
UpdateDataAndBind(cmdBuffer, frameIndex, cameraDirector->GetViewMatrix(), cameraDirector->GetProjMatrix());
UpdateDataAndBind(cmdBuffer, frameIndex, cameraDirector->GetViewMatrix(), cameraDirector->GetProjMatrix(), cameraDirector->GetOrthoMatrix());
}
}
void SHRenderer::UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept
void SHRenderer::UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, SHMatrix const& viewMatrix, SHMatrix const& projMatrix, SHMatrix const& orthoMatrix) noexcept
{
SetViewProjectionMatrix(viewMatrix, projMatrix);
SetViewProjectionMatrix(viewMatrix, projMatrix, orthoMatrix);
//cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix();
cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex);
BindDescSet(cmdBuffer, frameIndex);
}
void SHRenderer::BindDescSet(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
{
std::array<uint32_t, 1> dynamicOffsets{ frameIndex * cameraDataAlignedSize };
cmdBuffer->BindDescriptorSet(cameraDescriptorSet, SH_PIPELINE_TYPE::GRAPHICS, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 });
@ -111,12 +116,13 @@ namespace SHADE
{
}
void SHRenderer::SetViewProjectionMatrix(SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept
void SHRenderer::SetViewProjectionMatrix(SHMatrix const& viewMatrix, SHMatrix const& projMatrix, SHMatrix const& orthoMatrix) noexcept
{
//cpuCameraData.viewProjectionMatrix = camera->GetViewMatrix() * camera->GetProjectionMatrix();
cpuCameraData.viewProjectionMatrix = SHMatrix::Transpose(projMatrix * viewMatrix);
cpuCameraData.viewMatrix = SHMatrix::Transpose(viewMatrix);
cpuCameraData.projectionMatrix = SHMatrix::Transpose(projMatrix);
cpuCameraData.orthoMatrix = SHMatrix::Transpose (orthoMatrix);
}
Handle<SHRenderGraph> SHRenderer::GetRenderGraph(void) const noexcept

View File

@ -48,6 +48,7 @@ namespace SHADE
SHMatrix viewProjectionMatrix;
SHMatrix viewMatrix;
SHMatrix projectionMatrix;
SHMatrix orthoMatrix;
};
/*---------------------------------------------------------------------------------*/
@ -63,6 +64,7 @@ namespace SHADE
/***********************************************************************************/
class SHRenderer
{
public:
/*-----------------------------------------------------------------------------*/
/* Constructor/Destructors */
@ -81,9 +83,10 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/
void Draw(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool) noexcept;
void UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
void UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept;
void UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, SHMatrix const& viewMatrix, SHMatrix const& projMatrix, SHMatrix const& orthoMatrix) noexcept;
void BindDescSet (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
void UpdateCameraDataToBuffer (void) noexcept;
void SetViewProjectionMatrix (SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept;
void SetViewProjectionMatrix (SHMatrix const& viewMatrix, SHMatrix const& projMatrix, SHMatrix const& orthoMatrix) noexcept;
/*-----------------------------------------------------------------------------*/
/* Setters and Getters */

View File

@ -423,9 +423,8 @@ namespace SHADE
/*!
\brief
Loops through every single light component and checks for dirty light
data. If light data is dirty, rewrite to the CPU container. We also want
to bind the descriptor set for the light data.
Loops through every single light component and writes light data to CPU
then GPU.
*/
/***************************************************************************/

View File

@ -76,7 +76,7 @@ namespace SHADE
};
uint32_t mipOffset = 0;
rotationVectorsImage = logicalDevice->CreateImage(imageDetails, reinterpret_cast<unsigned char*>( rotationVectors.data()), static_cast<uint32_t>(sizeof(rotationVectors)), {&mipOffset, 1}, VMA_MEMORY_USAGE_AUTO, {});
rotationVectorsImage = logicalDevice->CreateImage(imageDetails, reinterpret_cast<unsigned char*>(rotationVectors.data()), static_cast<uint32_t>(sizeof(rotationVectors)), { mipOffset }, VMA_MEMORY_USAGE_AUTO, {});
vk::ImageMemoryBarrier transferBarrier{};
rotationVectorsImage->PrepareImageTransitionInfo(vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal, transferBarrier);

View File

@ -0,0 +1,160 @@
#include "SHpch.h"
#include "SHFont.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
#include "Graphics/Buffers/SHVkBuffer.h"
#include "Graphics/Images/SHVkSampler.h"
namespace SHADE
{
/***************************************************************************/
/*!
\brief
Non-default ctor. Prepares objects in staging buffers with data from
SHFontAsset.
\param inLogicalDeviceHdl
Logical device required for vulkan object creation.
\param asset
Font asset to copy data from.
*/
/***************************************************************************/
SHFont::SHFont(Handle<SHVkLogicalDevice> inLogicalDeviceHdl, SHFontAsset const& asset) noexcept
{
/*-----------------------------------------------------------------------*/
/* PREPARE GPU DATA */
/*-----------------------------------------------------------------------*/
// assign device for convenient usage
logicalDevice = inLogicalDeviceHdl;
// Copy the font data
fontAsset = asset;
SHImageCreateParams imageParams
{
.imageType = vk::ImageType::e2D,
.width = fontAsset.bitmapWidth,
.height = fontAsset.bitmapHeight,
.depth = 1,
.levels = 1,
.arrayLayers = 1,
.imageFormat = vk::Format::eR8G8B8A8Unorm,
//.imageFormat = vk::Format::eR32Sfloat,
//.imageFormat = vk::Format::eR32G32B32Sfloat,
.usageFlags = vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst,
.createFlags = {}
};
uint32_t bytesRequired = asset.bitmapData.size();
uint32_t mipOffset = 0;
// Create the image
bitmapDataImage = logicalDevice->CreateImage(imageParams, fontAsset.bitmapData.data(), bytesRequired, { mipOffset }, VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO, {});
// Amount of data required to hold matrices for all glyphs
uint32_t glyphDataSize = fontAsset.glyphTransformations.size() * sizeof (SHMatrix);
// For indexing
for (uint32_t i = 0; i < fontAsset.glyphs.size(); ++i)
unicodeIndexing.emplace(fontAsset.glyphs[i], i);
// allocate GPU buffer for matrices
matrixDataBuffer = logicalDevice->CreateBuffer(glyphDataSize, fontAsset.glyphTransformations.data(), glyphDataSize, vk::BufferUsageFlagBits::eTransferDst | vk::BufferUsageFlagBits::eStorageBuffer, VMA_MEMORY_USAGE_AUTO, {});
sampler = logicalDevice->CreateSampler(SHVkSamplerParams{});
}
/***************************************************************************/
/*!
\brief
Transfers data from staging buffers to GPU. Does not issue any of the
barriers (we want this done outside).
\param commandBuffer
Command buffer used to
\return
*/
/***************************************************************************/
void SHFont::TransferToGPU(Handle<SHVkCommandBuffer> commandBuffer) noexcept
{
/*-----------------------------------------------------------------------*/
/* COMMANDS TO TRANSFER TO DEVICE MEMORY */
/*-----------------------------------------------------------------------*/
// Transfer to device memory
bitmapDataImage->TransferToDeviceResource(commandBuffer);
// Transfer to GPU buffer
matrixDataBuffer->TransferToDeviceResource(commandBuffer);
}
void SHFont::DoPostTransfer(Handle<SHVkDescriptorPool> descPool, Handle<SHVkDescriptorSetLayout> layout) noexcept
{
/*-----------------------------------------------------------------------*/
/* CREATE IMAGE VIEW */
/*-----------------------------------------------------------------------*/
// Create the image view to the device resource
SHImageViewDetails viewDetails
{
.viewType = vk::ImageViewType::e2D,
.format = bitmapDataImage->GetImageFormat(),
.imageAspectFlags = vk::ImageAspectFlagBits::eColor,
.baseMipLevel = 0,
.mipLevelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
};
bitmapDataImageView = bitmapDataImage->CreateImageView(logicalDevice, bitmapDataImage, viewDetails);
/*-----------------------------------------------------------------------*/
/* DESCRIPTORS */
/*-----------------------------------------------------------------------*/
// allocate desc set for the bitmap and matrix data
descSet = descPool->Allocate({ layout }, { 1 });
auto viewLayoutSampler = std::make_tuple(bitmapDataImageView, sampler, vk::ImageLayout::eShaderReadOnlyOptimal);
descSet->ModifyWriteDescImage(SHGraphicsConstants::DescriptorSetIndex::FONT_DATA, SHGraphicsConstants::DescriptorSetBindings::FONT_BITMAP_DATA, {&viewLayoutSampler, 1});
descSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::FONT_DATA,
SHGraphicsConstants::DescriptorSetBindings::FONT_MATRIX_DATA, { &matrixDataBuffer, 1 }, 0, fontAsset.glyphTransformations.size() * sizeof(SHMatrix));
// Bind image and buffer to desc set.
descSet->UpdateDescriptorSetImages(SHGraphicsConstants::DescriptorSetIndex::FONT_DATA, SHGraphicsConstants::DescriptorSetBindings::FONT_BITMAP_DATA);
descSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::FONT_DATA, SHGraphicsConstants::DescriptorSetBindings::FONT_MATRIX_DATA);
}
std::unordered_map<msdfgen::unicode_t, uint32_t> SHFont::GetUnicodeIndexing(void) const noexcept
{
return unicodeIndexing;
}
SHFontAsset const& SHFont::GetFontAsset(void) const noexcept
{
return fontAsset;
}
Handle<SHVkImage> SHFont::GetImage(void) const noexcept
{
return bitmapDataImage;
}
Handle<SHVkBuffer> SHFont::GetMatrixBuffer(void) const noexcept
{
return matrixDataBuffer;
}
Handle<SHVkDescriptorSetGroup> SHFont::GetDescriptorSet(void) const noexcept
{
return descSet;
}
}

View File

@ -0,0 +1,72 @@
#pragma once
#include "Resource/SHHandle.h"
#include "msdf-atlas-gen/msdf-atlas-gen.h"
#include "Assets/Asset Types/SHFontAsset.h"
namespace SHADE
{
class SHVkLogicalDevice;
class SHVkDescriptorPool;
class SHVkDescriptorSetGroup;
class SHVkDescriptorSetLayout;
class SHVkCommandBuffer;
class SHVkCommandPool;
class SHVkImage;
class SHVkImageView;
class SHVkBuffer;
class SHVkQueue;
class SHVkSampler;
class SHFont
{
private:
//! Device for creation and destruction
Handle<SHVkLogicalDevice> logicalDevice;
//! Font asset contains exactly what we need, so we'll use it
SHFontAsset fontAsset;
//! Device memory that stores bitmap data
Handle<SHVkImage> bitmapDataImage;
//! View to device memory
Handle<SHVkImageView> bitmapDataImageView;
//! Device memory that stores matrix data
Handle<SHVkBuffer> matrixDataBuffer;
//! Descriptor set required to store the bitmap AND matrix data for the UV and quad transformation
Handle<SHVkDescriptorSetGroup> descSet;
Handle<SHVkSampler> sampler;
//! Used for getting the correct indices into the matrix data buffer
std::unordered_map<msdfgen::unicode_t, uint32_t> unicodeIndexing;
////! To transition images for transfer ops
//vk::ImageMemoryBarrier preTransferBarrier;
////! To transition images for shader reads
//vk::ImageMemoryBarrier postTransferBarrier;
public:
/*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
SHFont (Handle<SHVkLogicalDevice> inLogicalDeviceHdl, SHFontAsset const& asset) noexcept;
void TransferToGPU (Handle<SHVkCommandBuffer> commandBuffer) noexcept;
void DoPostTransfer (Handle<SHVkDescriptorPool> descPool, Handle<SHVkDescriptorSetLayout> layout) noexcept;
/*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/
std::unordered_map<msdfgen::unicode_t, uint32_t> GetUnicodeIndexing (void) const noexcept;
SHFontAsset const& GetFontAsset (void) const noexcept;
Handle<SHVkImage> GetImage (void) const noexcept;
Handle<SHVkBuffer> GetMatrixBuffer (void) const noexcept;
Handle<SHVkDescriptorSetGroup> GetDescriptorSet (void) const noexcept;
};
}

View File

@ -0,0 +1,7 @@
#include "SHpch.h"
#include "SHFontAtlasData.h"
namespace SHADE
{
}

View File

@ -0,0 +1,7 @@
#pragma once
namespace SHADE
{
}

View File

@ -0,0 +1,108 @@
#include "SHpch.h"
#include "SHFontLibrary.h"
#include "Graphics/Images/SHVkImage.h"
#include "Graphics/Commands/SHVkCommandPool.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/Synchronization/SHVkFence.h"
#include "Graphics/Buffers/SHVkBuffer.h"
namespace SHADE
{
/***************************************************************************/
/*!
\brief
For adding fonts to the library
\param asset
The asset we want to create an SHFont from.
*/
/***************************************************************************/
Handle<SHFont> SHFontLibrary::AddFont(Handle<SHVkLogicalDevice> logicalDevice, SHResourceHub& resourceHub, SHFontAsset const& asset) noexcept
{
// Create new font
Handle<SHFont> newFont = resourceHub.Create<SHFont>(logicalDevice, asset);
// emplace new barriers and prepare them for transfer ops
preTransferBarriers.emplace_back();
postTransferBarriers.emplace_back();
newFont->GetImage()->PrepareImageTransitionInfo(vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal, preTransferBarriers[preTransferBarriers.size() - 1]);
newFont->GetImage()->PrepareImageTransitionInfo(vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal, postTransferBarriers[postTransferBarriers.size() - 1]);
unpreparedFonts.emplace_back (newFont);
return newFont;
}
/***************************************************************************/
/*!
\brief
Transfers staging buffer font memory to the GPU for optimized access.
\param cmdBuffer
Command buffer to record the transfer operations.
\param descPool
\return
*/
/***************************************************************************/
void SHFontLibrary::BuildFonts(Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkQueue> queue, Handle<SHVkCommandPool> cmdPool, Handle<SHVkDescriptorPool> descPool, Handle<SHVkDescriptorSetLayout> layout, SHResourceHub& resourceHub) noexcept
{
// create fence to wait on after transfer
Handle<SHVkFence> finishCopyFence = resourceHub.Create<SHVkFence>(logicalDevice);
finishCopyFence->Reset();
// allocate new command buffer
Handle<SHVkCommandBuffer> transferCommandBuffer = cmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
// Begin recording transfer ops
transferCommandBuffer->BeginRecording();
{
// Transition image to dst
transferCommandBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, {}, {}, preTransferBarriers);
// Transfer data from staging to image
for (auto& font : unpreparedFonts)
font->TransferToGPU(transferCommandBuffer);
// Transition dst to shader read
transferCommandBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eFragmentShader, {}, {}, {}, postTransferBarriers);
}
// End recording for transfer ops
transferCommandBuffer->EndRecording();
// Submit command buffer to queue
queue->SubmitCommandBuffer({transferCommandBuffer}, {}, {}, vk::PipelineStageFlagBits::eTransfer, finishCopyFence);
// wait for copy to finish
finishCopyFence->Wait(true, std::numeric_limits<uint32_t>::max());
// Prepare image views and desc sets
for (auto& font : unpreparedFonts)
font->DoPostTransfer(descPool, layout);
// Free the command buffer and fence
transferCommandBuffer.Free();
resourceHub.Free(finishCopyFence);
// Once unprepared fonts are now ready for use, push them into container
uint32_t i = static_cast<uint32_t> (unpreparedFonts.size());
std::copy (unpreparedFonts.begin(), unpreparedFonts.end(), std::back_inserter(fonts));
// All fonts have been prepared for GPU usage
unpreparedFonts.clear();
preTransferBarriers.clear();
postTransferBarriers.clear();
}
std::vector<Handle<SHFont>> const& SHFontLibrary::GetFonts(void) const noexcept
{
return fonts;
}
}

View File

@ -0,0 +1,36 @@
#pragma once
#include "SHFont.h"
#include <vector>
#include "Graphics/SHVulkanIncludes.h"
namespace SHADE
{
class SHVkLogicalDevice;
class SHVkDescriptorPool;
class SHVkCommandPool;
class SHVkCommandBuffer;
class SHVkQueue;
class SHVkDescriptorSetLayout;
class SH_API SHFontLibrary
{
private:
//! Handles to all the fonts usable in SHTextRendererComponents
std::vector<Handle<SHFont>> fonts;
//! Fonts that have yet to be properly prepared for usage
std::vector<Handle<SHFont>> unpreparedFonts;
//! For transitioning images for transfer operations
std::vector<vk::ImageMemoryBarrier> preTransferBarriers;
//! For transitioning images for shader reads
std::vector<vk::ImageMemoryBarrier> postTransferBarriers;
public:
Handle<SHFont> AddFont (Handle<SHVkLogicalDevice> logicalDevice, SHResourceHub& resourceHub, SHFontAsset const& asset) noexcept;
void BuildFonts (Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkQueue> queue, Handle<SHVkCommandPool> cmdPool, Handle<SHVkDescriptorPool> descPool, Handle<SHVkDescriptorSetLayout> layout, SHResourceHub& resourceHub) noexcept;
std::vector<Handle<SHFont>> const& GetFonts (void) const noexcept;
};
}

View File

@ -0,0 +1,27 @@
#include "SHpch.h"
#include "SHFreetypeInstance.h"
#include "msdf-atlas-gen/msdf-atlas-gen.h"
#include "msdfgen-ext.h"
namespace SHADE
{
msdfgen::FreetypeHandle* SHFreetypeInstance::freetypeHandle = nullptr;
void SHFreetypeInstance::Init(void) noexcept
{
// initialize freetype
freetypeHandle = msdfgen::initializeFreetype();
}
void SHFreetypeInstance::Exit(void) noexcept
{
msdfgen::deinitializeFreetype(freetypeHandle);
}
msdfgen::FreetypeHandle* SHFreetypeInstance::GetFreetypeHandle(void) noexcept
{
return freetypeHandle;
}
}

View File

@ -0,0 +1,23 @@
#pragma once
namespace msdfgen
{
class FreetypeHandle;
}
namespace SHADE
{
class SHFreetypeInstance
{
private:
//! Only need this to be initialized once
static msdfgen::FreetypeHandle* freetypeHandle;
public:
static void Init (void) noexcept;
static void Exit (void) noexcept;
static msdfgen::FreetypeHandle* GetFreetypeHandle(void) noexcept;
};
}

View File

@ -0,0 +1,79 @@
#include "SHpch.h"
#include "SHTextRendererComponent.h"
namespace SHADE
{
void SHTextRendererComponent::MakeDirty(void) noexcept
{
requiresRecompute = true;
}
void SHTextRendererComponent::Clean(void) noexcept
{
requiresRecompute = false;
}
/***************************************************************************/
/*!
\brief
On create the text has nothing.
*/
/***************************************************************************/
void SHTextRendererComponent::OnCreate(void)
{
text = "Text";
requiresRecompute = true;
// Default white color.
color = SHColour::WHITE;
}
void SHTextRendererComponent::OnDestroy(void)
{
}
/***************************************************************************/
/*!
\brief
Sets the text to be rendered.
\param newText
\return
*/
/***************************************************************************/
void SHTextRendererComponent::SetText(std::string_view newText) noexcept
{
text = newText;
MakeDirty();
}
void SHTextRendererComponent::SetFont(Handle<SHFont> font) noexcept
{
fontHandle = font;
}
/***************************************************************************/
/*!
\brief
Getter for the text required to render.
\return
*/
/***************************************************************************/
std::string const& SHTextRendererComponent::GetText(void) const noexcept
{
return text;
}
}

View File

@ -0,0 +1,61 @@
#pragma once
#include <string>
#include <string_view>
#include "ECS_Base/Components/SHComponent.h"
#include "Math/SHColour.h"
#include "Resource/SHHandle.h"
namespace SHADE
{
class SHFont;
class SHVkDescriptorSetGroup;
class SHVkBuffer;
class SH_API SHTextRendererComponent final : public SHComponent
{
public:
static constexpr uint32_t MAX_CHARACTERS = 500;
private:
using TextIndexingType = uint32_t;
private:
//! Text required to be rendered
std::string text;
//! Color of the text
SHColour color;
//! Requires to recompute the positions of each glyph/character
bool requiresRecompute;
//! Handle to the font used to render the text
Handle<SHFont> fontHandle;
//! We want to index into the buffer with matrices
Handle<SHVkBuffer> indexingDataBuffer;
//! character position data for each letter in the text
Handle<SHVkBuffer> charPositionDataBuffer;
void MakeDirty (void) noexcept;
void Clean (void) noexcept;
public:
void OnCreate(void) override final;
void OnDestroy(void) override final;
/*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/
void SetText (std::string_view newText) noexcept;
void SetFont (Handle<SHFont> font) noexcept;
std::string const& GetText (void) const noexcept;
friend class SHTextRenderingSubSystem;
};
}

View File

@ -0,0 +1,235 @@
#include "SHpch.h"
#include "SHTextRenderingSubSystem.h"
#include "Graphics/MiddleEnd/TextRendering/SHTextRendererComponent.h"
#include "ECS_Base/Managers/SHComponentManager.h"
#include "Math/Vector/SHVec4.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/MiddleEnd/TextRendering/SHFont.h"
#include "Graphics/Buffers/SHVkBuffer.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
#include "Graphics/Pipeline/SHVkPipeline.h"
#include "Graphics/SHVkUtil.h"
#include "Graphics/RenderGraph/SHSubpass.h"
#include "Math/Transform/SHTransformComponent.h"
namespace SHADE
{
void SHTextRenderingSubSystem::RecomputePositions(SHTextRendererComponent& textComp) noexcept
{
if (textComp.text.empty() || textComp.fontHandle)
return;
// Create the buffer
if (!textComp.indexingDataBuffer)
textComp.indexingDataBuffer = logicalDevice->CreateBuffer(SHTextRendererComponent::MAX_CHARACTERS * sizeof(uint32_t), nullptr, SHTextRendererComponent::MAX_CHARACTERS * sizeof(uint32_t), vk::BufferUsageFlagBits::eVertexBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT);
if (!textComp.charPositionDataBuffer)
textComp.indexingDataBuffer = logicalDevice->CreateBuffer(SHTextRendererComponent::MAX_CHARACTERS * sizeof(SHVec4), nullptr, SHTextRendererComponent::MAX_CHARACTERS * sizeof(SHVec4), vk::BufferUsageFlagBits::eVertexBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT);
// For indexing font transformation in the shader
std::vector <SHTextRendererComponent::TextIndexingType> indexingData;
// For placing glyphs correctly
std::vector <SHVec4> charPositionData;
// Baseline relative to entity with this component
SHVec4 baselineOrigin{ 0.0f, 0.0f, 0.0f, 1.0f };
// Number of characters in the string
uint32_t numChars = static_cast<uint32_t>(textComp.text.size());
// Get a ref to the transform indices
auto const& glyphTransformIndices = textComp.fontHandle->GetUnicodeIndexing();
// Get a ref to the glyph transformations
auto const& glyphTransforms = textComp.fontHandle->GetFontAsset().glyphTransformations;
bool dueNextLine = false;
// for every character
for (uint32_t i = 0; i < numChars; ++i)
{
SHTextRendererComponent::TextIndexingType index = glyphTransformIndices.at(textComp.text[i]);
// Copy baseline
SHVec4 characterPos = baselineOrigin;
// Get where to draw the glyph relative to the baseline
characterPos[0] += glyphTransforms[index].m[SHFontAsset::BASELINE_LEFT_MATRIX_INDEX_ROW][SHFontAsset::BASELINE_LEFT_MATRIX_INDEX_COL]; // Inside the matrix but not used in the shader so this value has no positional value
characterPos[1] += glyphTransforms[index].m[SHFontAsset::BASELINE_BOTTOM_MATRIX_INDEX_ROW][SHFontAsset::BASELINE_BOTTOM_MATRIX_INDEX_COL]; // Inside the matrix but not used in the shader so this value has no positional value
indexingData.push_back(index);
charPositionData.push_back(characterPos);
// if not the last character
if (i != numChars - 1)
{
// Get the advance and move the baseline
double advance = 0.0;
textComp.fontHandle->GetFontAsset().fontGeometry.getAdvance(advance, textComp.text[i], textComp.text[static_cast<uint64_t>(i) + 1]);
baselineOrigin[0] += static_cast<float>(advance);
//if (baselineOrigin[0] >= textComp.estimatedLineLength)
//{
// dueNextLine = true;
//}
}
//if (dueNextLine && textComp.renderedText[i] == ' ')
//{
// baselineOrigin[0] = 0.0f;
// baselineOrigin[1] -= textComp.lineSpacing;
// dueNextLine = false;
//}
}
textComp.indexingDataBuffer->WriteToMemory(indexingData.data(), static_cast<uint32_t>(indexingData.size()) * sizeof (SHTextRendererComponent::TextIndexingType),0, 0);
textComp.charPositionDataBuffer->WriteToMemory(charPositionData.data(), static_cast<uint32_t>(charPositionData.size()) * sizeof (SHVec4), 0, 0);
indexingData.clear();
charPositionData.clear();
}
void SHTextRenderingSubSystem::Init(Handle<SHVkLogicalDevice> device, Handle<SHVkRenderpass> compatibleRenderpass, Handle<SHSubpass> subpass, Handle<SHVkDescriptorPool> descPool, Handle<SHVkShaderModule> textVS, Handle<SHVkShaderModule> textFS, std::function<void(Handle<SHVkCommandBuffer>, uint32_t)> const& bindFunction) noexcept
{
SHComponentManager::CreateComponentSparseSet<SHTextRendererComponent>();
cameraDescSetBind = bindFunction;
logicalDevice = device;
// prepare pipeline layout params
SHPipelineLayoutParams plParams
{
.shaderModules = {textVS, textFS},
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts()
};
pipelineLayout = logicalDevice->CreatePipelineLayout(plParams);
// Create pipeline
pipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, compatibleRenderpass, subpass);
// vertex input state of the pipeline
SHVertexInputState vertexInputState;
// Configure vertex attributes
vertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_4D) }); // location = 0 (character position data)
vertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::UINT32_1D) }); // location = 1 (glyph index to index matrices)
// Set vertex state for new pipeline
pipeline->GetPipelineState().SetVertexInputState(vertexInputState);
SHColorBlendState colorBlendState{};
colorBlendState.logic_op_enable = VK_FALSE;
colorBlendState.logic_op = vk::LogicOp::eCopy;
auto const& subpassColorReferences = subpass->GetColorAttachmentReferences();
colorBlendState.attachments.reserve(static_cast<uint32_t>(subpassColorReferences.size()));
for (auto& att : subpassColorReferences)
{
colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState
{
.blendEnable = SHVkUtil::IsBlendCompatible(subpass->GetFormatFromAttachmentReference(att.attachment)) ? true : false,
.srcColorBlendFactor = vk::BlendFactor::eSrcAlpha,
.dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha,
.colorBlendOp = vk::BlendOp::eAdd,
.srcAlphaBlendFactor = vk::BlendFactor::eOne,
.dstAlphaBlendFactor = vk::BlendFactor::eZero,
.alphaBlendOp = vk::BlendOp::eAdd,
.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA,
}
);
}
pipeline->GetPipelineState().SetColorBlenState(colorBlendState);
// Construct pipeline
pipeline->ConstructPipeline();
SHVkDescriptorSetLayout::Binding fontBitmapBinding
{
.Type = vk::DescriptorType::eCombinedImageSampler,
.Stage = vk::ShaderStageFlagBits::eFragment,
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::FONT_BITMAP_DATA,
.DescriptorCount = 1,
};
SHVkDescriptorSetLayout::Binding fontMatrixBinding
{
.Type = vk::DescriptorType::eStorageBuffer,
.Stage = vk::ShaderStageFlagBits::eVertex,
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::FONT_MATRIX_DATA,
.DescriptorCount = 1,
};
fontDataDescSetLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::FONT_DATA, { fontBitmapBinding, fontMatrixBinding });
}
void SHTextRenderingSubSystem::Run(uint32_t frameIndex) noexcept
{
auto& textRendererComps = SHComponentManager::GetDense<SHTextRendererComponent>();
for (auto& comp : textRendererComps)
{
// If the component is dirty
if (comp.requiresRecompute)
{
RecomputePositions(comp);
comp.Clean();
}
}
}
void SHTextRenderingSubSystem::Render(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
{
auto& textRendererComps = SHComponentManager::GetDense<SHTextRendererComponent>();
for (auto& comp : textRendererComps)
{
auto* transform = SHComponentManager::GetComponent<SHTransformComponent>(comp.GetEID());
Handle<SHFont> fontHandle = comp.fontHandle;
if (fontHandle && transform)
{
// bind the pipeline
cmdBuffer->BindPipeline(pipeline);
// bind VBO (position and indices)
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::CALCULATED_GLYPH_POSITION, comp.charPositionDataBuffer, 0);
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::GLYPH_INDEX, comp.indexingDataBuffer, 0);
cameraDescSetBind(cmdBuffer, frameIndex);
// bind descriptors for font (matrices)
cmdBuffer->BindDescriptorSet(fontHandle->GetDescriptorSet(), SH_PIPELINE_TYPE::GRAPHICS, SHGraphicsConstants::DescriptorSetIndex::FONT_DATA, {});
cmdBuffer->SetPushConstantVariable("TestPushConstant.worldTransform", transform->GetTRS(), SH_PIPELINE_TYPE::GRAPHICS);
cmdBuffer->SetPushConstantVariable("TestPushConstant.eid", comp.GetEID(), SH_PIPELINE_TYPE::GRAPHICS);
cmdBuffer->SetPushConstantVariable("TestPushConstant.textColor", SHVec3 (1.0f, 1.0f, 1.0f), SH_PIPELINE_TYPE::GRAPHICS);
cmdBuffer->SubmitPushConstants(SH_PIPELINE_TYPE::GRAPHICS);
// call draw call
cmdBuffer->DrawArrays(4, comp.text.size(), 0, 0);
//glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, static_cast<GLsizei>(textComp.lastRenderedCharacterIndex) + 1);
}
}
}
void SHTextRenderingSubSystem::Exit(void) noexcept
{
}
Handle<SHVkDescriptorSetLayout> SHTextRenderingSubSystem::GetFontDataDescSetLayout(void) const noexcept
{
return fontDataDescSetLayout;
}
}

View File

@ -0,0 +1,65 @@
#pragma once
#include "Resource/SHHandle.h"
#include "Graphics/Pipeline/SHPipelineState.h"
#include "Math/SHMatrix.h"
#include "Math/Vector/SHVec3.h"
namespace SHADE
{
class SHVkLogicalDevice;
class SHVkDescriptorPool;
class SHVkDescriptorSetGroup;
class SHVkDescriptorSetLayout;
class SHVkBuffer;
class SHLightComponent;
class SHVkCommandBuffer;
class SHTextRendererComponent;
class SHVkPipeline;
class SHVkPipelineLayout;
class SHVkRenderpass;
class SHSubpass;
class SHVkShaderModule;
class SHTextRenderingSubSystem
{
private:
struct ShaderPushConstantData
{
SHMatrix worldTransform;
uint32_t eid;
SHVec3 textColor;
};
//! Logical device for creation and destruction
Handle<SHVkLogicalDevice> logicalDevice;
//! Pipeline for rendering the text
Handle<SHVkPipeline> pipeline;
//! Pipeline layout for the pipeline
Handle<SHVkPipelineLayout> pipelineLayout;
//! Descriptor set for font data access in shaders
Handle<SHVkDescriptorSetLayout> fontDataDescSetLayout;
//! Super temporary. Global descriptor set needs to be revamped along with
//! entire graphics system.
std::function<void(Handle<SHVkCommandBuffer>, uint32_t)> cameraDescSetBind;
private:
void RecomputePositions(SHTextRendererComponent& textComp) noexcept;
public:
void Init(Handle<SHVkLogicalDevice> device, Handle<SHVkRenderpass> compatibleRenderpass, Handle<SHSubpass> subpass, Handle<SHVkDescriptorPool> descPool, Handle<SHVkShaderModule> textVS, Handle<SHVkShaderModule> textFS, std::function<void(Handle<SHVkCommandBuffer>, uint32_t)> const& bindFunction) noexcept;
void Run(uint32_t frameIndex) noexcept;
void Render (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
void Exit(void) noexcept;
Handle<SHVkDescriptorSetLayout> GetFontDataDescSetLayout (void) const noexcept;
};
}

View File

@ -79,9 +79,9 @@ namespace SHADE
startOffset += pcInfo.size;
}
stageFlags |= shaderModule->GetShaderStageFlagBits();
}
stageFlags |= shaderModule->GetShaderStageFlagBits();
}
// After all the sizes of the push constant blocks have been added, record the size in the interface

View File

@ -3,7 +3,7 @@
namespace SHADE
{
// Used for attachment description creation for renderpass node
enum class SH_ATT_DESC_TYPE_FLAGS
enum class SH_RENDER_GRAPH_RESOURCE_FLAGS
{
COLOR = 0x01,
COLOR_PRESENT = 0x02,
@ -11,7 +11,8 @@ namespace SHADE
STENCIL = 0x08,
DEPTH_STENCIL = 0x10,
INPUT = 0x20,
STORAGE = 0x40
STORAGE = 0x40,
SHARED = 0x80 // if resource is meant to be used across render graphs, mark this flag
};
}

View File

@ -11,6 +11,9 @@
#include "SHAttachmentDescInitParams.h"
#include "SHRenderGraphStorage.h"
#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h"
#include "Tools/Utilities/SHUtilities.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
#include "Graphics/RenderGraph/SHRenderToSwapchainImageSystem.h"
namespace SHADE
{
@ -49,7 +52,7 @@ namespace SHADE
*/
/***************************************************************************/
void SHRenderGraph::AddResource(std::string resourceName, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, uint32_t w /*= static_cast<uint32_t>(-1)*/, uint32_t h /*= static_cast<uint32_t>(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageUsageFlagBits usageFlags/* = {}*/, vk::ImageCreateFlagBits createFlags /*= {}*/)
void SHRenderGraph::AddResource(std::string resourceName, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, uint32_t w /*= static_cast<uint32_t>(-1)*/, uint32_t h /*= static_cast<uint32_t>(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageUsageFlagBits usageFlags/* = {}*/, vk::ImageCreateFlagBits createFlags /*= {}*/)
{
// If we set to
if (w == static_cast<uint32_t>(-1) && h == static_cast<uint32_t>(-1))
@ -59,10 +62,41 @@ namespace SHADE
format = renderGraphStorage->swapchain->GetSurfaceFormatKHR().format;
}
auto resource = resourceManager->Create<SHRenderGraphResource>(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags);
auto resource = renderGraphStorage->resourceHub->Create<SHRenderGraphResource>(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags);
renderGraphStorage->graphResources->try_emplace(resourceName, resource);
}
void SHRenderGraph::LinkNonOwningResource(Handle<SHRenderGraph> resourceOrigin, std::string resourceName) noexcept
{
// resource to link
Handle<SHRenderGraphResource> resourceToLink = resourceOrigin->GetRenderGraphResource(resourceName);
if (!resourceToLink)
{
SHLOG_ERROR("Resource does not exist in render graph, cannot link resource.");
return;
}
// Get the final layout of the resource from the previous render graph
vk::ImageLayout finalLayout{vk::ImageLayout::eUndefined};
auto const& nodes = resourceOrigin->GetNodes();
for (auto& node : nodes)
{
if (vk::ImageLayout layout = resourceToLink->GetInfoTracker()->GetLayout(node, {}); layout != vk::ImageLayout::eUndefined)
finalLayout = layout;
for (auto& compute : node->nodeComputes)
{
if (vk::ImageLayout layout = resourceToLink->GetInfoTracker()->GetLayout(compute); layout != vk::ImageLayout::eUndefined)
finalLayout = layout;
}
}
renderGraphStorage->graphResources->try_emplace(resourceName, resourceToLink);
// add to this pool so that when we generate later, the attachment descriptions will make its initial layout the layout stored here
renderGraphStorage->nonOwningResourceInitialLayouts.emplace(resourceToLink.GetId().Raw, finalLayout);
}
/***************************************************************************/
/*!
@ -88,30 +122,59 @@ namespace SHADE
return;
}
// We first want to take all resources track their layout as undefined at the start of the node/renderpass
auto const resources = node->GetResources();
for (auto& resource : resources)
{
resource->GetInfoTracker()->TrackLayout(node, {}, vk::ImageLayout::eUndefined);
}
// attempt to get all final layouts for all resources
for (auto& subpass : node->subpasses)
{
for (auto& color : subpass->colorReferences)
{
// If final renderpass and attachment is a COLOR_PRESENT resource, make resource transition to present after last subpass
if (i == nodes.size() - 1 && (node->attResources[color.attachment]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)))
if (i == nodes.size() - 1 && (node->attResources[color.attachment]->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)))
resourceAttFinalLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR;
else
resourceAttFinalLayouts[color.attachment] = color.layout;
node->attResources[color.attachment]->infoTracker->TrackLayout(node, subpass, color.layout);
}
for (auto& depth : subpass->depthReferences)
{
resourceAttFinalLayouts[depth.attachment] = depth.layout;
node->attResources[depth.attachment]->infoTracker->TrackLayout(node, subpass, depth.layout);
}
for (auto& input : subpass->inputReferences)
{
resourceAttFinalLayouts[input.attachment] = input.layout;
node->attResources[input.attachment]->infoTracker->TrackLayout(node, subpass, input.layout);
}
}
for (uint32_t j = 0; j < node->attachmentDescriptions.size(); ++j)
{
auto& att = node->attachmentDescriptions[j];
att.initialLayout = vk::ImageLayout::eUndefined;
auto& resource = node->attResources[j];
// If resource is from another render graph, use the final layout it had when it was last used in that graph. This is initialized in LinkNonOwningResource.
// We also want to load the attachment, not "don't care".
if (resource->resourceTypeFlags & SHUtilities::ConvertEnum(SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED) &&
renderGraphStorage->nonOwningResourceInitialLayouts.contains(resource.GetId().Raw))
{
att.initialLayout = renderGraphStorage->nonOwningResourceInitialLayouts.at (resource.GetId().Raw);
att.loadOp = vk::AttachmentLoadOp::eLoad;
att.stencilLoadOp = vk::AttachmentLoadOp::eLoad;
}
else
att.initialLayout = vk::ImageLayout::eUndefined;
att.finalLayout = resourceAttFinalLayouts[j];
resource->GetInfoTracker()->TrackLayout(node, {}, att.finalLayout);
}
++i;
}
@ -146,12 +209,13 @@ namespace SHADE
attDesc.stencilLoadOp = vk::AttachmentLoadOp::eLoad;
attDesc.stencilStoreOp = vk::AttachmentStoreOp::eStore;
// TODO: Stencil load and store
// When an image is done being used in a renderpass, the image layout will end up being the finalLayout
// value of the attachment description. We want this to carry over to the next renderpass; specifically
// to have the initialLayout of the attachment description in the next renderpass match the finalLayout in the previous.
attDesc.initialLayout = predAttDesc.finalLayout;
// We also want to track it
predResource->GetInfoTracker()->TrackLayout(node, {}, attDesc.initialLayout);
}
}
}
@ -225,12 +289,12 @@ namespace SHADE
for (auto& inputAtt : subpass->inputReferences)
{
auto resource = node->attResources[inputAtt.attachment];
if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::INPUT))
if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT))
{
if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR) ||
resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT))
if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR) ||
resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT))
colorRead |= (1 << i);
else if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL))
else if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL))
depthRead |= (1 << i);
}
else
@ -323,6 +387,12 @@ namespace SHADE
}
}
void SHRenderGraph::ConfigureSubSystems(void) noexcept
{
if (renderToSwapchainImageSystem)
renderToSwapchainImageSystem->ConstructPipelines(renderGraphStorage->logicalDevice);
}
/***************************************************************************/
/*!
@ -354,17 +424,17 @@ namespace SHADE
*/
/***************************************************************************/
void SHRenderGraph::Init(std::string graphName, Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkSwapchain> swapchain) noexcept
void SHRenderGraph::Init(std::string graphName, Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkSwapchain> swapchain, SHResourceHub* resourceHub) noexcept
{
resourceManager = std::make_shared<SHResourceHub>();
//resourceHub = std::make_shared<SHResourceHub>();
renderGraphStorage = resourceManager->Create<SHRenderGraphStorage>();
renderGraphStorage->graphResources = resourceManager->Create<std::unordered_map<std::string, Handle<SHRenderGraphResource>>>();
renderGraphStorage = resourceHub->Create<SHRenderGraphStorage>();
renderGraphStorage->graphResources = resourceHub->Create<std::unordered_map<std::string, Handle<SHRenderGraphResource>>>();
renderGraphStorage->logicalDevice = logicalDevice;
renderGraphStorage->swapchain = swapchain;
renderGraphStorage->resourceManager = resourceManager;
renderGraphStorage->resourceHub = resourceHub;
renderGraphStorage->descriptorPool = logicalDevice->CreateDescriptorPools();
name = std::move(graphName);
@ -384,7 +454,6 @@ namespace SHADE
SHRenderGraph::SHRenderGraph(void) noexcept
: renderGraphStorage{}
, nodes{}
, resourceManager{nullptr}
{
}
@ -392,7 +461,6 @@ namespace SHADE
: renderGraphStorage{ rhs.renderGraphStorage }
, nodeIndexing{ std::move(rhs.nodeIndexing) }
, nodes{ std::move(rhs.nodes) }
, resourceManager{ std::move(rhs.resourceManager) }
, name { std::move(rhs.name) }
{
@ -406,7 +474,6 @@ namespace SHADE
renderGraphStorage = rhs.renderGraphStorage;
nodeIndexing = std::move(rhs.nodeIndexing);
nodes = std::move(rhs.nodes);
resourceManager = std::move(rhs.resourceManager);
name = std::move(rhs.name);
return *this;
@ -472,11 +539,38 @@ namespace SHADE
}
}
auto node = nodes.emplace_back(resourceManager->Create<SHRenderGraphNode>(nodeName, renderGraphStorage, std::move(descInitParams), std::move(predecessors)));
auto node = nodes.emplace_back(renderGraphStorage->resourceHub->Create<SHRenderGraphNode>(nodeName, renderGraphStorage, std::move(descInitParams), std::move(predecessors)));
nodeIndexing.emplace(std::move(nodeName), static_cast<uint32_t>(nodes.size()) - 1u);
return node;
}
void SHRenderGraph::AddRenderToSwapchainNode(std::string toSwapchainResource, std::string swapchainResource, std::initializer_list<std::string> predecessorNodes, std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> shaderModules) noexcept
{
for (auto& node : predecessorNodes)
{
if (!nodeIndexing.contains(node))
return;
}
if (renderGraphStorage->graphResources->contains(toSwapchainResource) && renderGraphStorage->graphResources->contains(swapchainResource))
{
auto newNode = AddNode("Render To Present", { ResourceInstruction (toSwapchainResource.c_str()), ResourceInstruction(swapchainResource.c_str()) }, predecessorNodes);
auto newSubpass = newNode->AddSubpass("Render");
newSubpass->AddColorOutput(swapchainResource);
newSubpass->AddInput(toSwapchainResource);
renderToSwapchainImageSystem = renderGraphStorage->resourceHub->Create<SHRenderToSwapchainImageSystem> (newNode, newSubpass, shaderModules);
newSubpass->AddExteriorDrawCalls([=](Handle<SHVkCommandBuffer>& cmdBuffer, uint32_t frameIndex)
{
cmdBuffer->BindPipeline(renderToSwapchainImageSystem->GetPipeline());
// draw a quad.
cmdBuffer->DrawIndexed(4, 0, 0);
});
}
}
/***************************************************************************/
/*!
@ -497,6 +591,7 @@ namespace SHADE
ConfigureSubpasses();
ConfigureRenderpasses();
ConfigureFramebuffers();
ConfigureSubSystems();
}
/***************************************************************************/
@ -539,7 +634,10 @@ namespace SHADE
{
// resize resources
for (auto& [name, resource] : *renderGraphStorage->graphResources)
resource->HandleResize(newWidth, newHeight);
{
if (!renderGraphStorage->nonOwningResourceInitialLayouts.contains (resource.GetId().Raw))
resource->HandleResize(newWidth, newHeight);
}
for (auto& node : nodes)
{
@ -556,6 +654,11 @@ namespace SHADE
}
std::vector<Handle<SHRenderGraphNode>> const& SHRenderGraph::GetNodes(void) const noexcept
{
return nodes;
}
Handle<SHRenderGraphResource> SHRenderGraph::GetRenderGraphResource(std::string const& resourceName) const noexcept
{
if (renderGraphStorage->graphResources->contains(resourceName))

View File

@ -32,6 +32,7 @@ namespace SHADE
class SHGraphicsGlobalData;
class SHVkDescriptorPool;
class SHRenderGraphStorage;
class SHRenderToSwapchainImageSystem;
class SH_API SHRenderGraph
{
@ -41,7 +42,7 @@ namespace SHADE
std::string resourceName;
bool dontClearOnLoad;
ResourceInstruction (char const* resourceName, bool dontClearOnLoad = false) noexcept;
ResourceInstruction(char const* resourceName, bool dontClearOnLoad = false) noexcept;
};
private:
@ -52,6 +53,7 @@ namespace SHADE
void ConfigureAttachmentDescriptions (void) noexcept;
void ConfigureSubpasses (void) noexcept;
void ConfigureRenderpasses (void) noexcept;
void ConfigureSubSystems (void) noexcept;
void ConfigureFramebuffers (void) noexcept;
/*-----------------------------------------------------------------------*/
@ -66,12 +68,12 @@ namespace SHADE
//! Render graph nodes
std::vector<Handle<SHRenderGraphNode>> nodes;
//! Resource library for graph handles
std::shared_ptr<SHResourceHub> resourceManager;
//! Name of the RenderGraph
std::string name;
//! For rendering onto the swapchain
Handle<SHRenderToSwapchainImageSystem> renderToSwapchainImageSystem;
public:
/*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */
@ -84,9 +86,11 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
void Init (std::string graphName, Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkSwapchain> swapchain) noexcept;
void AddResource(std::string resourceName, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {});
void Init (std::string graphName, Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkSwapchain> swapchain, SHResourceHub* resourceHub) noexcept;
void AddResource(std::string resourceName, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {});
void LinkNonOwningResource (Handle<SHRenderGraph> resourceOrigin, std::string resourceName) noexcept;
Handle<SHRenderGraphNode> AddNode (std::string nodeName, std::initializer_list<ResourceInstruction> resourceInstruction, std::initializer_list<std::string> predecessorNodes) noexcept;
void AddRenderToSwapchainNode (std::string toSwapchainResource, std::string swapchainResource, std::initializer_list<std::string> predecessorNodes, std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> shaderModules) noexcept;
void Generate (void) noexcept;
void CheckForNodeComputes (void) noexcept;
@ -97,9 +101,30 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/
Handle<SHRenderGraphNode> GetNode (std::string const& nodeName) const noexcept;
Handle<SHRenderGraphResource> GetRenderGraphResource (std::string const& resourceName) const noexcept;
Handle<SHRenderGraphNode> GetNode (std::string const& nodeName) const noexcept;
std::vector<Handle<SHRenderGraphNode>> const& GetNodes (void) const noexcept;
Handle<SHRenderGraphResource> GetRenderGraphResource (std::string const& resourceName) const noexcept;
};
}
#endif
/* Some notes here:
* - The graph wasn't implemented with the intention of it being this versatile.
* - Graphs weren't meant to share resources and hence the generating of the render graph doesn't account for it.
* However, because it was eventually necessary that some resources had to be shared and its contents carried over to
* other graphs, the functionality was implemented through a link function in SHRenderGraph.cpp to facilitate this linkage.
* This should ideally be replaced by an implementation more self-contained, perhaps through a higher level class like a canvas
* that manage the resources instead and can facilitate such linking of resources. Either that, or we allow only 1 render graph,
* but different matrices (SHRenderer) can be used in different nodes.
* - There are also way too many hash maps created for ease of access. This definitely can be cut down.
* -
*
*/

View File

@ -46,7 +46,7 @@ namespace SHADE
for (uint32_t j = 0; j < attResources.size(); ++j)
{
uint32_t imageViewIndex = (attResources[j]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? i : 0;
uint32_t imageViewIndex = (attResources[j]->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) ? i : 0;
imageViews[j] = attResources[j]->imageViews[imageViewIndex];
// We want the minimum dimensions for the framebuffer because the image attachments referenced cannot have dimensions smaller than the framebuffer's
@ -74,7 +74,7 @@ namespace SHADE
for (uint32_t j = 0; j < attResources.size(); ++j)
{
uint32_t imageViewIndex = (attResources[j]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? i : 0;
uint32_t imageViewIndex = (attResources[j]->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) ? i : 0;
imageViews[j] = attResources[j]->imageViews[imageViewIndex];
// We want the minimum dimensions for the framebuffer because the image attachments referenced cannot have dimensions smaller than the framebuffer's
@ -160,7 +160,7 @@ namespace SHADE
newDesc.format = attResources[i]->resourceFormat;
if (attResources[i]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT))
if (attResources[i]->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT))
containsSwapchainImage = true;
resourceAttachmentMapping->try_emplace(attResources[i].GetId().Raw, i);
@ -250,7 +250,7 @@ namespace SHADE
// Add subpass to container and create mapping for it
subpasses.emplace_back
(
graphStorage->resourceManager->Create<SHSubpass>
graphStorage->resourceHub->Create<SHSubpass>
(
subpassName,
graphStorage, GetHandle(), static_cast<uint32_t>(subpasses.size()),
@ -259,7 +259,7 @@ namespace SHADE
);
subpassIndexing.try_emplace(subpassName, static_cast<uint32_t>(subpasses.size()) - 1u);
Handle<SHSubpass> subpass = subpasses.back();
subpass->Init(*graphStorage->resourceManager);
subpass->Init(*graphStorage->resourceHub);
// Register the SuperBatch
batcher.RegisterSuperBatch(subpass->GetSuperBatch());
@ -279,10 +279,18 @@ namespace SHADE
nodeComputeResources.push_back(resource);
}
// need to use for tracking resources
std::vector<Handle<SHRenderGraphResource>> temp (nodeComputeResources);
// Create the subpass compute with the resources
auto nodeCompute = graphStorage->resourceManager->Create<SHRenderGraphNodeCompute>(std::move(nodeName), graphStorage, computeShaderModule, std::move(nodeComputeResources), std::move (dynamicBufferBindings), nodeComputes.empty());
auto nodeCompute = graphStorage->resourceHub->Create<SHRenderGraphNodeCompute>(std::move(nodeName), graphStorage, computeShaderModule, std::move(nodeComputeResources), std::move (dynamicBufferBindings), nodeComputes.empty());
nodeComputes.push_back(nodeCompute);
for (auto& resource : temp)
{
resource->GetInfoTracker()->TrackLayout(nodeCompute);
}
return nodeCompute;
}
@ -405,4 +413,9 @@ namespace SHADE
return {};
}
std::vector<Handle<SHRenderGraphResource>> const& SHRenderGraphNode::GetResources(void) const noexcept
{
return attResources;
}
}

View File

@ -117,6 +117,7 @@ namespace SHADE
Handle<SHVkRenderpass> GetRenderpass(void) const noexcept;
Handle<SHSubpass> GetSubpass(std::string_view subpassName) const noexcept;
Handle<SHRenderGraphResource> GetResource (uint32_t resourceIndex) const noexcept;
std::vector<Handle<SHRenderGraphResource>> const& GetResources (void) const noexcept;
friend class SHRenderGraph;
};

View File

@ -45,6 +45,7 @@ namespace SHADE
// save the resources
resources = std::move (subpassComputeResources);
//Get the descriptor set layouts required to allocate. We only want the ones for allocate because
//global descriptors are already bound in the main system.
auto const& graphResourceLayout = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsPipeline()[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE];
@ -65,7 +66,7 @@ namespace SHADE
if (layouts.size() == SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE + 1)
{
// create compute resources
computeResource = graphStorage->resourceManager->Create<ComputeResource>();
computeResource = graphStorage->resourceHub->Create<ComputeResource>();
auto computeResourceLayout = layouts[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE];
computeResource->descSet = graphStorage->descriptorPool->Allocate({ computeResourceLayout }, { 1 });
#ifdef _DEBUG
@ -119,7 +120,7 @@ namespace SHADE
// loop through bindings and write descriptor sets
for (auto& binding : pipelineDescSetLayouts->GetBindings())
{
uint32_t imageIndex = (resources[i]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? frameIndex : 0;
uint32_t imageIndex = (resources[i]->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) ? frameIndex : 0;
SHVkDescriptorSetGroup::viewSamplerLayout vsl = std::make_tuple(resources[i]->GetImageView(imageIndex), Handle<SHVkSampler>{}, vk::ImageLayout::eGeneral);
graphResourceDescSets[frameIndex]->ModifyWriteDescImage(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint, { &vsl, 1 });
@ -154,7 +155,7 @@ namespace SHADE
.newLayout = vk::ImageLayout::eGeneral,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = resource->GetImage((resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? i : 0)->GetVkImage(),
.image = resource->GetImage((resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) ? i : 0)->GetVkImage(),
.subresourceRange = vk::ImageSubresourceRange
{
.aspectMask = resource->imageAspectFlags,

View File

@ -6,9 +6,41 @@
#include "Graphics/Buffers/SHVkBuffer.h"
#include "Graphics/SHVkUtil.h"
#include "SHRenderGraphStorage.h"
#include "Graphics/RenderGraph/SHSubpass.h"
#include "Graphics/RenderGraph/SHRenderGraphNode.h"
namespace SHADE
{
void SHRenderGraphResource::InfoTracker::TrackLayout(Handle<SHRenderGraphNode> node, Handle<SHSubpass> subpass, vk::ImageLayout layout) noexcept
{
NodeSubpassPair nodeSubpassPair = std::pair(node, subpass);
layoutTracker[std::hash<NodeSubpassPair>{}(nodeSubpassPair)] = layout;
}
void SHRenderGraphResource::InfoTracker::TrackLayout(Handle<SHRenderGraphNodeCompute> compute) noexcept
{
computeTracker.emplace (compute.GetId().Raw);
}
vk::ImageLayout SHRenderGraphResource::InfoTracker::GetLayout(Handle<SHRenderGraphNode> node, Handle<SHSubpass> subpass) const noexcept
{
NodeSubpassPair nodeSubpassPair = std::pair(node, subpass);
std::size_t hashedValue = std::hash<NodeSubpassPair>{}(nodeSubpassPair);
if (layoutTracker.contains(hashedValue))
return layoutTracker.at(hashedValue);
else
return vk::ImageLayout::eUndefined;
}
vk::ImageLayout SHRenderGraphResource::InfoTracker::GetLayout(Handle<SHRenderGraphNodeCompute> compute) const noexcept
{
if (computeTracker.contains (compute.GetId().Raw))
return vk::ImageLayout::eGeneral;
else
return vk::ImageLayout::eUndefined;
}
/***************************************************************************/
/*!
@ -46,7 +78,7 @@ namespace SHADE
*/
/***************************************************************************/
SHRenderGraphResource::SHRenderGraphResource(Handle<SHRenderGraphStorage> renderGraphStorage, std::string const& name, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept
SHRenderGraphResource::SHRenderGraphResource(Handle<SHRenderGraphStorage> renderGraphStorage, std::string const& name, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept
: graphStorage{renderGraphStorage}
, resourceTypeFlags{ }
, resourceFormat{ format }
@ -58,9 +90,9 @@ namespace SHADE
, resourceName{ name }
{
// If the resource type is an arbitrary image and not swapchain image
if (typeFlags.size() == 1 && *typeFlags.begin() == SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)
if (typeFlags.size() == 1 && *typeFlags.begin() == SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)
{
resourceTypeFlags |= static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT);
resourceTypeFlags |= static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT);
// Prepare image view details
SHImageViewDetails viewDetails
@ -98,30 +130,30 @@ namespace SHADE
// Check the resource type and set image usage flags and image aspect flags accordingly
switch (type)
{
case SH_ATT_DESC_TYPE_FLAGS::COLOR:
case SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR:
usage |= vk::ImageUsageFlagBits::eColorAttachment;
imageAspectFlags |= vk::ImageAspectFlagBits::eColor;
break;
case SH_ATT_DESC_TYPE_FLAGS::DEPTH:
case SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH:
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
imageAspectFlags |= vk::ImageAspectFlagBits::eDepth;
break;
case SH_ATT_DESC_TYPE_FLAGS::STENCIL:
case SH_RENDER_GRAPH_RESOURCE_FLAGS::STENCIL:
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
imageAspectFlags |= vk::ImageAspectFlagBits::eStencil;
break;
case SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL:
case SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL:
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
imageAspectFlags |= vk::ImageAspectFlagBits::eStencil | vk::ImageAspectFlagBits::eDepth;
break;
case SH_ATT_DESC_TYPE_FLAGS::INPUT:
case SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT:
usage |= vk::ImageUsageFlagBits::eInputAttachment;
usage |= vk::ImageUsageFlagBits::eSampled;
break;
case SH_ATT_DESC_TYPE_FLAGS::STORAGE:
case SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE:
usage |= vk::ImageUsageFlagBits::eStorage;
break;
case SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT:
case SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT:
{
SHLOG_ERROR ("COLOR_PRESENT cannot be with other resource type flags. ");
return;
@ -151,6 +183,8 @@ namespace SHADE
imageViews.push_back(imageView);
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eImageView, imageView->GetImageView(), "[Image View] " + resourceName);
}
infoTracker = renderGraphStorage->resourceHub->Create<InfoTracker>();
}
/***************************************************************************/
@ -175,6 +209,7 @@ namespace SHADE
, mipLevels{ rhs.mipLevels }
, imageAspectFlags{ rhs.imageAspectFlags }
, graphStorage{rhs.graphStorage}
, infoTracker {std::move (rhs.infoTracker)}
{
}
@ -207,6 +242,7 @@ namespace SHADE
mipLevels = rhs.mipLevels;
imageAspectFlags = rhs.imageAspectFlags;
graphStorage = rhs.graphStorage;
infoTracker = std::move(infoTracker);
return *this;
}
@ -229,7 +265,7 @@ namespace SHADE
width = newWidth;
height = newHeight;
if ((resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) == 0)
if ((resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) == 0)
{
// prepare image view details
SHImageViewDetails viewDetails
@ -347,4 +383,9 @@ namespace SHADE
return resourceName;
}
SHADE::Handle<SHADE::SHRenderGraphResource::InfoTracker> SHRenderGraphResource::GetInfoTracker(void) const noexcept
{
return infoTracker;
}
}

View File

@ -6,6 +6,7 @@
#include "Resource/SHHandle.h"
#include "Graphics/SHVulkanIncludes.h"
#include "SH_API.h"
#include <unordered_set>
namespace SHADE
{
@ -16,11 +17,41 @@ namespace SHADE
class SHVkCommandBuffer;
class SHVkBuffer;
class SHRenderGraphStorage;
class SHRenderGraphNode;
class SHSubpass;
class SHRenderGraphNodeCompute;
static constexpr uint32_t NON_SWAPCHAIN_RESOURCE_INDEX = 0;
class SH_API SHRenderGraphResource
{
public:
// For keeping track of resources as it gets passed down the pipeline (between multiple render graphs)
class InfoTracker
{
private:
using NodeSubpassPair = std::pair<Handle<SHRenderGraphNode>, Handle<SHSubpass>>;
//! key here is the render graph node and subpass name combined, value is the layout of the resource at that node and subpass
std::unordered_map<std::size_t, vk::ImageLayout> layoutTracker;
//! if a resource is involved in a compute process, record it here
std::unordered_set<uint64_t> computeTracker;
public:
/*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
void TrackLayout (Handle<SHRenderGraphNode> node, Handle<SHSubpass> subpass, vk::ImageLayout layout) noexcept;
void TrackLayout (Handle<SHRenderGraphNodeCompute> compute) noexcept;
/*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/
vk::ImageLayout GetLayout(Handle<SHRenderGraphNode> node, Handle<SHSubpass> subpass) const noexcept;
vk::ImageLayout GetLayout(Handle<SHRenderGraphNodeCompute> compute) const noexcept;
};
private:
/*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER VARIABLES */
@ -62,12 +93,14 @@ namespace SHADE
//! usage flags
vk::ImageUsageFlags usage = {};
//! For tracking resource states in stages of the render graphs
Handle<InfoTracker> infoTracker;
public:
/*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/
SHRenderGraphResource(Handle<SHRenderGraphStorage> renderGraphStorage, std::string const& name, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept;
SHRenderGraphResource(Handle<SHRenderGraphStorage> renderGraphStorage, std::string const& name, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept;
SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept;
SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept;
~SHRenderGraphResource(void) noexcept;
@ -89,6 +122,7 @@ namespace SHADE
Handle<SHVkImage> GetImage (uint32_t index = NON_SWAPCHAIN_RESOURCE_INDEX) const noexcept;
uint8_t GetMipLevels (void) const noexcept;
std::string GetName (void) const noexcept;
Handle<InfoTracker> GetInfoTracker (void) const noexcept;
friend class SHRenderGraphNode;
friend class SHRenderGraph;

View File

@ -20,7 +20,7 @@ namespace SHADE
Handle<SHVkSwapchain> swapchain;
//! Resource manager for creation of objects
std::shared_ptr<SHResourceHub> resourceManager;
SHResourceHub* resourceHub;
//! Descriptor pool for the descriptor sets to be created in the subpasses
Handle<SHVkDescriptorPool> descriptorPool;
@ -28,6 +28,10 @@ namespace SHADE
//! For accessing resources anywhere in the graph
Handle<std::unordered_map<std::string, Handle<SHRenderGraphResource>>> graphResources;
//! HACK: Because there's no interface to specify a dependency between graphs, this will help attachment descriptions
//! use the correct layout, when a resource is shared between graphs
std::unordered_map<uint64_t, vk::ImageLayout> nonOwningResourceInitialLayouts{};
//SHRenderGraphStorage(void) noexcept;
//SHRenderGraphStorage(SHRenderGraphStorage&& rhs) noexcept;
//SHRenderGraphStorage& operator=(SHRenderGraphStorage&& rhs) noexcept;

View File

@ -0,0 +1,44 @@
#include "SHpch.h"
#include "SHRenderToSwapchainImageSystem.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
#include "Graphics/RenderGraph/SHRenderGraphNode.h"
namespace SHADE
{
SHRenderToSwapchainImageSystem::SHRenderToSwapchainImageSystem(Handle<SHRenderGraphNode> node, Handle<SHSubpass> subpass, std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> shaders) noexcept
: renderGraphNode {node}
, subpass{subpass}
, shaderModules{shaders}
, pipeline{}
, pipelineLayout{}
{
}
void SHRenderToSwapchainImageSystem::ConstructPipelines(Handle<SHVkLogicalDevice> logicalDevice) noexcept
{
auto pipelineLayout = logicalDevice->CreatePipelineLayout(SHPipelineLayoutParams
{
.shaderModules = {shaderModules.first, shaderModules.second},
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts(),
});
auto newPipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderGraphNode->GetRenderpass(), subpass);
SHInputAssemblyState inputAssembly{};
inputAssembly.topology = vk::PrimitiveTopology::eTriangleFan;
newPipeline->GetPipelineState().SetInputAssemblyState(inputAssembly);
newPipeline->ConstructPipeline();
}
Handle<SHVkPipeline> SHRenderToSwapchainImageSystem::GetPipeline(void) const noexcept
{
return pipeline;
}
}

View File

@ -0,0 +1,43 @@
#pragma once
#include "Resource/SHHandle.h"
#include <utility>
namespace SHADE
{
class SHVkPipeline;
class SHVkPipelineLayout;
class SHVkShaderModule;
class SHRenderGraphNode;
class SHSubpass;
class SHVkLogicalDevice;
class SHSubpass;
class SHRenderToSwapchainImageSystem
{
private:
//! Render Graph node to get the renderpass from to initialize the pipeline
Handle<SHRenderGraphNode> renderGraphNode;
//! Subpass to initialize the pipeline with
Handle<SHSubpass> subpass;
//! Shader module required to render the quad on screen
std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> shaderModules;
//! pipeline required to draw the image
Handle<SHVkPipeline> pipeline;
//! Pipeline layout of the pipeline
Handle<SHVkPipelineLayout> pipelineLayout;
public:
SHRenderToSwapchainImageSystem (Handle<SHRenderGraphNode> node, Handle<SHSubpass> subpass, std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> shaders) noexcept;
void ConstructPipelines (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
Handle<SHVkPipeline> GetPipeline (void) const noexcept;
};
}

View File

@ -148,18 +148,18 @@ namespace SHADE
*/
/***************************************************************************/
void SHSubpass::AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE_FLAGS attachmentDescriptionType) noexcept
void SHSubpass::AddDepthOutput(std::string resourceToReference, SH_RENDER_GRAPH_RESOURCE_FLAGS attachmentDescriptionType) noexcept
{
vk::ImageLayout imageLayout;
switch (attachmentDescriptionType)
{
case SH_ATT_DESC_TYPE_FLAGS::DEPTH:
case SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH:
imageLayout = vk::ImageLayout::eDepthAttachmentOptimal;
break;
case SH_ATT_DESC_TYPE_FLAGS::STENCIL:
case SH_RENDER_GRAPH_RESOURCE_FLAGS::STENCIL:
imageLayout = vk::ImageLayout::eStencilAttachmentOptimal;
break;
case SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL:
case SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL:
imageLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
break;
default:
@ -211,7 +211,7 @@ namespace SHADE
// Draw all the exterior draw calls
for (auto& drawCall : exteriorDrawCalls)
{
drawCall(commandBuffer);
drawCall(commandBuffer, frameIndex);
}
commandBuffer->EndLabeledSegment();
}
@ -221,7 +221,7 @@ namespace SHADE
UpdateWriteDescriptors();
}
void SHSubpass::AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&)> const& newDrawCall) noexcept
void SHSubpass::AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&, uint32_t)> const& newDrawCall) noexcept
{
exteriorDrawCalls.push_back(newDrawCall);
}
@ -315,7 +315,7 @@ namespace SHADE
auto resource = graphStorage->graphResources->at(inputNames[binding.BindPoint]);
// If resource is swapchain image, get the correct image, if not just get 0.
uint32_t viewIndex = (resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? i : 0;
uint32_t viewIndex = (resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) ? i : 0;
// layout is GENERAL if image is meant to be used as storage image, if not use SHADER_READ_ONLY_OPTINAL
vk::ImageLayout descriptorLayout = (binding.Type == vk::DescriptorType::eStorageImage) ? vk::ImageLayout::eGeneral : vk::ImageLayout::eShaderReadOnlyOptimal;

View File

@ -76,7 +76,7 @@ namespace SHADE
//! after we draw everything from the batch. Because of this, these draw calls
//! are always the last things drawn, so DO NOT USE THIS FUNCTIONALITY FOR ANYTHING
//! COMPLEX.
std::vector<std::function<void(Handle<SHVkCommandBuffer>&)>> exteriorDrawCalls;
std::vector<std::function<void(Handle<SHVkCommandBuffer>&, uint32_t)>> exteriorDrawCalls;
/// For identifying subpasses
std::string name;
@ -95,11 +95,11 @@ namespace SHADE
// Preparation functions
void AddColorOutput(std::string resourceToReference) noexcept;
void AddGeneralColorOutput(std::string resourceToReference) noexcept;
void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE_FLAGS attachmentDescriptionType = SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL) noexcept;
void AddDepthOutput(std::string resourceToReference, SH_RENDER_GRAPH_RESOURCE_FLAGS attachmentDescriptionType = SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL) noexcept;
void AddGeneralDepthOutput(std::string resourceToReference) noexcept;
void AddInput(std::string resourceToReference) noexcept;
void AddGeneralInput (std::string resourceToReference) noexcept;
void AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&)> const& newDrawCall) noexcept;
void AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&, uint32_t)> const& newDrawCall) noexcept;
// Runtime functions
void Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;

View File

@ -25,7 +25,8 @@ namespace SHADE
std::unordered_map<std::type_index, std::function<void(AssetID)>> SHResourceManager::typedFreeFuncMap;
std::vector<AssetID> SHResourceManager::loadedAssetData;
bool SHResourceManager::textureChanged = false;
bool SHResourceManager::meshChanged = false;
bool SHResourceManager::meshChanged = false;
bool SHResourceManager::fontChanged = false;
/*-----------------------------------------------------------------------------------*/
/* Function Definitions */
@ -76,6 +77,11 @@ namespace SHADE
gfxSystem->BuildTextures();
textureChanged = false;
}
if (fontChanged)
{
gfxSystem->BuildFonts();
fontChanged = false;
}
// Free CPU Resources
for (auto assetId : loadedAssetData)

View File

@ -26,6 +26,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
#include "Assets/Asset Types/SHMaterialAsset.h"
#include "Graphics/MiddleEnd/TextRendering/SHFont.h"
namespace SHADE
{
@ -47,8 +48,8 @@ namespace SHADE
template<> struct SHResourceLoader<SHVkShaderModule> { using AssetType = SHShaderAsset; };
template<> struct SHResourceLoader<SHMaterialSpec> { using AssetType = SHMaterialAsset; };
template<> struct SHResourceLoader<SHMaterial> { using AssetType = SHMaterialSpec; };
/// <summary>
template<> struct SHResourceLoader<SHFont> { using AssetType = SHFontAsset; };
/// <summary>
/// Static class responsible for loading and caching runtime resources from their
/// serialised Asset IDs.
/// </summary>
@ -178,6 +179,7 @@ namespace SHADE
// Dirty Flags
static bool meshChanged;
static bool textureChanged;
static bool fontChanged;
/*---------------------------------------------------------------------------------*/
/* Helper Functions */

View File

@ -39,6 +39,7 @@ namespace SHADE
!std::is_same_v<ResourceType, SHTexture> &&
!std::is_same_v<ResourceType, SHVkShaderModule> &&
!std::is_same_v<ResourceType, SHMaterialSpec> &&
!std::is_same_v<ResourceType, SHFont> &&
!std::is_same_v<ResourceType, SHMaterial>
)
{
@ -337,5 +338,12 @@ namespace SHADE
return matHandle;
}
else if constexpr (std::is_same_v<ResourceType, SHFont>)
{
loadedAssetData.emplace_back(assetId);
fontChanged = true;
return gfxSystem->AddFont(assetData);
}
}
}

View File

@ -25,10 +25,11 @@ workspace "SHADE"
include "SHADE_CSharp"
group "Dependencies"
include "Dependencies/msdf"
include "Dependencies/FontCompiler/Dependencies/msdf"
include "Dependencies/imgui"
--include "Dependencies/tracy"
include "Dependencies/yamlcpp"
include "Dependencies/reactphysics3d"
include "Dependencies/ModelCompiler"
include "Dependencies/FontCompiler"
group ""