Starting framework for static mesh rendering

This commit is contained in:
Dynamitos
2024-05-08 10:51:59 +02:00
parent af7d624d06
commit 46a2713729
31 changed files with 645 additions and 320 deletions
+4 -4
View File
@@ -26,12 +26,12 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target
{ {
result += pLightEnv.directionalLights[i].illuminate(lightingParams, brdf); result += pLightEnv.directionalLights[i].illuminate(lightingParams, brdf);
} }
for(uint i = 0; i < lightCount; ++i) for(uint i = 0; i < pLightEnv.numPointLights; ++i)
{ {
uint lightIndex = pLightCullingData.lightIndexList[startOffset + i]; //uint lightIndex = pLightCullingData.lightIndexList[startOffset + i];
result += pLightEnv.pointLights[lightIndex].illuminate(lightingParams, brdf); result += pLightEnv.pointLights[i].illuminate(lightingParams, brdf);
} }
result += brdf.evaluateAmbient(); //result += brdf.evaluateAmbient();
// gamma correction // gamma correction
result = result / (result + float3(1.0)); result = result / (result + float3(1.0));
result = pow(result, float3(1.0/2.2)); result = pow(result, float3(1.0/2.2));
+43
View File
@@ -0,0 +1,43 @@
import Common;
import BRDF;
import Scene;
import VertexData;
import MaterialParameter;
struct PrimitiveAttributes
{
uint cull: SV_CullPrimitive;
};
[numthreads(MESH_GROUP_SIZE, 1, 1)]
[outputtopology("triangle")]
[shader("mesh")]
void meshMain(
in uint threadID: SV_GroupIndex,
in uint groupID: SV_GroupID,
out vertices FragmentParameter vertices[MAX_VERTICES],
out indices uint3 indices[MAX_PRIMITIVES]
){
MeshletDescription m = pScene.meshletInfos[groupID];
SetMeshOutputCounts(m.vertexCount, m.primitiveCount);
for(uint i = threadID; i < MAX_PRIMITIVES; i += MESH_GROUP_SIZE)
{
uint p = min(i, m.primitiveCount - 1);
{
uint local_idx0 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 0];
uint local_idx1 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 1];
uint local_idx2 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 2];
indices[p] = uint3(local_idx0, local_idx1, local_idx2);
}
}
for(uint i = threadID; i < MAX_VERTICES; i+=MESH_GROUP_SIZE)
{
uint v = min(i, m.vertexCount - 1);
{
uint vertexIndex = pScene.vertexIndices[m.vertexOffset + v];
VertexAttributes attr = pVertexData.getAttributes(md.indicesOffset + vertexIndex);
vertices[v] = attr.getParameter(float4x4(1.0));
}
}
}
+7 -2
View File
@@ -58,11 +58,16 @@ float4 screenToView(float4 screen)
return clipToView(clip); return clipToView(clip);
} }
float4 screenToModel(float4x4 inverseTransform, float4 screen) float4 screenToWorld(float4 screen)
{ {
float4 view = screenToView(screen); float4 view = screenToView(screen);
float4 world = viewToWorld(view); return viewToWorld(view);
}
float4 screenToModel(float4x4 inverseTransform, float4 screen)
{
float4 world = screenToWorld(screen);
return worldToModel(inverseTransform, world); return worldToModel(inverseTransform, world);
} }
+3 -1
View File
@@ -69,6 +69,7 @@ void MeshLoader::loadTextures(const aiScene* scene, const std::filesystem::path&
texPath = (meshDirectory / texPath).replace_extension("png"); texPath = (meshDirectory / texPath).replace_extension("png");
if (tex->mHeight == 0) if (tex->mHeight == 0)
{ {
std::cout << "Dumping texture " << texPath << std::endl;
// already compressed, just dump it to the disk // already compressed, just dump it to the disk
std::ofstream file(texPath, std::ios::binary); std::ofstream file(texPath, std::ios::binary);
file.write((const char*)tex->pcData, tex->mWidth); file.write((const char*)tex->pcData, tex->mWidth);
@@ -76,6 +77,7 @@ void MeshLoader::loadTextures(const aiScene* scene, const std::filesystem::path&
} }
else else
{ {
std::cout << "Writing extracted png " << texPath << std::endl;
// recompress data so that the TextureLoader can read it // recompress data so that the TextureLoader can read it
unsigned char* texData = new unsigned char[tex->mWidth * tex->mHeight * 4]; unsigned char* texData = new unsigned char[tex->mWidth * tex->mHeight * 4];
convertAssimpARGB(texData, tex->pcData, tex->mWidth * tex->mHeight); convertAssimpARGB(texData, tex->pcData, tex->mWidth * tex->mHeight);
@@ -412,8 +414,8 @@ void MeshLoader::loadMaterials(const aiScene* scene, const Array<PTextureAsset>&
case aiShadingMode_Toon: case aiShadingMode_Toon:
brdf.profile = "CelShading"; brdf.profile = "CelShading";
break; break;
case aiShadingMode_CookTorrance:
default: default:
case aiShadingMode_CookTorrance:
brdf.profile = "CookTorrance"; brdf.profile = "CookTorrance";
brdf.variables["roughness"] = outputRoughness; brdf.variables["roughness"] = outputRoughness;
brdf.variables["metallic"] = outputMetallic; brdf.variables["metallic"] = outputMetallic;
+6 -1
View File
@@ -61,7 +61,12 @@ void TextureLoader::import(TextureImportArgs args, PTextureAsset textureAsset)
auto ktxFile = args.filePath; auto ktxFile = args.filePath;
ktxFile.replace_extension("ktx"); ktxFile.replace_extension("ktx");
std::stringstream ss; std::stringstream ss;
ss << "toktx --encode etc1s " << ktxFile << " " << args.filePath; ss << "toktx --encode etc1s ";
if (args.type == TextureImportType::TEXTURE_NORMAL)
{
ss << "--normal_mode ";
}
ss << ktxFile << " " << args.filePath;
system(ss.str().c_str()); system(ss.str().c_str());
args.filePath = ktxFile; args.filePath = ktxFile;
} }
+1 -4
View File
@@ -58,15 +58,12 @@ int main() {
AssetImporter::importMesh(MeshImportArgs{ AssetImporter::importMesh(MeshImportArgs{
.filePath = sourcePath / "import/models/cube.fbx", .filePath = sourcePath / "import/models/cube.fbx",
}); });
//AssetImporter::importMesh(MeshImportArgs{
// .filePath = sourcePath / "import/models/Arissa.fbx",
// });
AssetImporter::importMesh(MeshImportArgs{ AssetImporter::importMesh(MeshImportArgs{
.filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.glb", .filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.glb",
.importPath = "Whitechapel" .importPath = "Whitechapel"
}); });
//AssetImporter::importMesh(MeshImportArgs{ //AssetImporter::importMesh(MeshImportArgs{
// .filePath = sourcePath / "import/models/Volvo S90/Volvo S90.fbx", // .filePath = sourcePath / "import/models/Volvo S90/Volvo S90.blend",
// .importPath = "Volvo", // .importPath = "Volvo",
// }); // });
WindowCreateInfo mainWindowInfo; WindowCreateInfo mainWindowInfo;
+2
View File
@@ -14,6 +14,8 @@ struct KeyboardInput
float mouseY; float mouseY;
float deltaX; float deltaX;
float deltaY; float deltaY;
float scrollX;
float scrollY;
}; };
} // namespace Component } // namespace Component
} // namespace Seele } // namespace Seele
+1
View File
@@ -8,6 +8,7 @@ namespace Component
struct Mesh struct Mesh
{ {
PMeshAsset asset; PMeshAsset asset;
bool isStatic = true;
}; };
} // namespace Component } // namespace Component
} // namespace Seele } // namespace Seele
+4 -4
View File
@@ -14,8 +14,8 @@ public:
virtual ~RenderCommand(); virtual ~RenderCommand();
virtual void setViewport(Gfx::PViewport viewport) = 0; virtual void setViewport(Gfx::PViewport viewport) = 0;
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) = 0; virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) = 0;
virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0; virtual void bindDescriptor(Gfx::PDescriptorSet set, Array<uint32> dynamicOffsets = {}) = 0;
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) = 0; virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets, Array<uint32> dynamicOffsets = {}) = 0;
virtual void bindVertexBuffer(const Array<PVertexBuffer>& buffer) = 0; virtual void bindVertexBuffer(const Array<PVertexBuffer>& buffer) = 0;
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) = 0; virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) = 0;
virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) = 0; virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) = 0;
@@ -31,8 +31,8 @@ public:
ComputeCommand(); ComputeCommand();
virtual ~ComputeCommand(); virtual ~ComputeCommand();
virtual void bindPipeline(Gfx::PComputePipeline pipeline) = 0; virtual void bindPipeline(Gfx::PComputePipeline pipeline) = 0;
virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0; virtual void bindDescriptor(Gfx::PDescriptorSet set, Array<uint32> dynamicOffsets = {}) = 0;
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) = 0; virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets, Array<uint32> dynamicOffsets = {}) = 0;
virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) = 0; virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) = 0;
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) = 0; virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) = 0;
std::string name; std::string name;
+1 -1
View File
@@ -24,7 +24,7 @@ struct GraphicsInitializer
: applicationName("SeeleEngine") : applicationName("SeeleEngine")
, engineName("SeeleEngine") , engineName("SeeleEngine")
, windowLayoutFile(nullptr) , windowLayoutFile(nullptr)
, layers{} , layers{"VK_LAYER_LUNARG_monitor"}
, instanceExtensions{} , instanceExtensions{}
, deviceExtensions{"VK_KHR_swapchain"} , deviceExtensions{"VK_KHR_swapchain"}
, windowHandle(nullptr) , windowHandle(nullptr)
+160 -72
View File
@@ -12,12 +12,12 @@
#include "Material/MaterialInstance.h" #include "Material/MaterialInstance.h"
#include "Graphics/Descriptor.h" #include "Graphics/Descriptor.h"
#include "Graphics/Command.h" #include "Graphics/Command.h"
#include "Graphics/StaticMeshVertexData.h"
using namespace Seele; using namespace Seele;
BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) BasePass::BasePass(Gfx::PGraphics graphics, PScene scene)
: RenderPass(graphics, scene) : RenderPass(graphics, scene)
, descriptorSets(6)
{ {
} }
@@ -56,85 +56,77 @@ void BasePass::render()
opaqueCulling->writeChanges(); opaqueCulling->writeChanges();
transparentCulling->writeChanges(); transparentCulling->writeChanges();
Gfx::ShaderPermutation permutation;
if (graphics->supportMeshShading())
{
permutation.setTaskFile("MeshletBasePass");
permutation.setMeshFile("MeshletBasePass");
}
else
{
permutation.setVertexFile("LegacyBasePass");
}
permutation.setFragmentFile("BasePass");
graphics->beginRenderPass(renderPass); graphics->beginRenderPass(renderPass);
Array<Gfx::ORenderCommand> commands; Array<Gfx::ORenderCommand> commands;
for (VertexData* vertexData : VertexData::getList()) // Static Meshes
{ {
permutation.setVertexData(vertexData->getTypeName()); Gfx::ShaderPermutation permutation;
const auto& materials = vertexData->getMaterialData(); if (graphics->supportMeshShading())
for (const auto& [_, materialData] : materials)
{ {
// Create Pipeline(Material, VertexData) permutation.setTaskFile("StaticMeshletPass");
// Descriptors: permutation.setMeshFile("StaticMeshletPass");
// ViewData => global, static }
// VertexData => per meshtype else
// SceneData => per material instance {
// LightEnv => provided by scene permutation.setVertexFile("StaticLegacyPass");
// Material => per material }
// LightCulling => calculated by pass permutation.setFragmentFile("BasePass");
permutation.setMaterial(materialData.material->getName()); StaticMeshVertexData* vd = StaticMeshVertexData::getInstance();
Gfx::PermutationId id(permutation); permutation.setVertexData(vd->getTypeName());
for (const auto& [_, mappings] : vd->getStaticMeshes())
{
for (const auto& mapping : mappings)
{
permutation.setMaterial(mapping.material->getBaseMaterial()->getName());
Gfx::PermutationId id(permutation);
Gfx::ORenderCommand command = graphics->createRenderCommand("BaseRender"); Gfx::ORenderCommand command = graphics->createRenderCommand("BaseRender");
command->setViewport(viewport); command->setViewport(viewport);
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id); const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
assert(collection != nullptr); assert(collection != nullptr);
if (graphics->supportMeshShading())
{
Gfx::MeshPipelineCreateInfo pipelineInfo;
pipelineInfo.taskShader = collection->taskShader;
pipelineInfo.meshShader = collection->meshShader;
pipelineInfo.fragmentShader = collection->fragmentShader;
pipelineInfo.pipelineLayout = collection->pipelineLayout;
pipelineInfo.renderPass = renderPass;
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL;
pipelineInfo.multisampleState.samples = viewport->getSamples();
pipelineInfo.colorBlend.attachmentCount = 1;
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
}
else
{
Gfx::LegacyPipelineCreateInfo pipelineInfo;
pipelineInfo.vertexShader = collection->vertexShader;
pipelineInfo.fragmentShader = collection->fragmentShader;
pipelineInfo.pipelineLayout = collection->pipelineLayout;
pipelineInfo.renderPass = renderPass;
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL;
pipelineInfo.multisampleState.samples = viewport->getSamples();
pipelineInfo.colorBlend.attachmentCount = 1;
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
}
command->bindDescriptor(vertexData->getVertexDataSet());
command->bindDescriptor(viewParamsSet);
command->bindDescriptor(scene->getLightEnvironment()->getDescriptorSet());
command->bindDescriptor(opaqueCulling);
for (const auto& [_, instance] : materialData.instances)
{
command->bindDescriptor(instance.materialInstance->getDescriptorSet());
command->bindDescriptor(instance.descriptorSet);
if (graphics->supportMeshShading()) if (graphics->supportMeshShading())
{ {
command->drawMesh(instance.meshes.size(), 1, 1); Gfx::MeshPipelineCreateInfo pipelineInfo;
pipelineInfo.taskShader = collection->taskShader;
pipelineInfo.meshShader = collection->meshShader;
pipelineInfo.fragmentShader = collection->fragmentShader;
pipelineInfo.pipelineLayout = collection->pipelineLayout;
pipelineInfo.renderPass = renderPass;
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL;
pipelineInfo.multisampleState.samples = viewport->getSamples();
pipelineInfo.colorBlend.attachmentCount = 1;
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
} }
else else
{ {
command->bindIndexBuffer(vertexData->getIndexBuffer()); Gfx::LegacyPipelineCreateInfo pipelineInfo;
pipelineInfo.vertexShader = collection->vertexShader;
pipelineInfo.fragmentShader = collection->fragmentShader;
pipelineInfo.pipelineLayout = collection->pipelineLayout;
pipelineInfo.renderPass = renderPass;
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL;
pipelineInfo.multisampleState.samples = viewport->getSamples();
pipelineInfo.colorBlend.attachmentCount = 1;
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
}
command->bindDescriptor(vd->getVertexDataSet());
command->bindDescriptor(viewParamsSet);
command->bindDescriptor(scene->getLightEnvironment()->getDescriptorSet());
command->bindDescriptor(opaqueCulling);
command->bindDescriptor(mapping.material->getDescriptorSet());
command->bindDescriptor(vd->getInstanceDataSet(), {0, 0});
if (graphics->supportMeshShading())
{
command->drawMesh(vd->getMeshData(mapping.mapped).size(), 1, 1);
}
else
{
command->bindIndexBuffer(vd->getIndexBuffer());
uint32 instanceOffset = 0; uint32 instanceOffset = 0;
for (const auto& [instance, meshData] : instance.meshes) for (const auto& meshData : vd->getMeshData(mapping.mapped))
{ {
if (meshData.numIndices > 0) if (meshData.numIndices > 0)
{ {
@@ -143,10 +135,104 @@ void BasePass::render()
instanceOffset++; instanceOffset++;
} }
} }
commands.add(std::move(command));
} }
commands.add(std::move(command));
} }
} }
// Others
{
Gfx::ShaderPermutation permutation;
if (graphics->supportMeshShading())
{
permutation.setTaskFile("MeshletPass");
permutation.setMeshFile("MeshletPass");
}
else
{
permutation.setVertexFile("LegacyPass");
}
permutation.setFragmentFile("BasePass");
for (VertexData* vertexData : VertexData::getList())
{
permutation.setVertexData(vertexData->getTypeName());
const auto& materials = vertexData->getMaterialData();
for (const auto& [_, materialData] : materials)
{
// Create Pipeline(Material, VertexData)
// Descriptors:
// ViewData => global, static
// VertexData => per meshtype
// SceneData => per material instance
// LightEnv => provided by scene
// Material => per material
// LightCulling => calculated by pass
permutation.setMaterial(materialData.material->getName());
Gfx::PermutationId id(permutation);
Gfx::ORenderCommand command = graphics->createRenderCommand("BaseRender");
command->setViewport(viewport);
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
assert(collection != nullptr);
if (graphics->supportMeshShading())
{
Gfx::MeshPipelineCreateInfo pipelineInfo;
pipelineInfo.taskShader = collection->taskShader;
pipelineInfo.meshShader = collection->meshShader;
pipelineInfo.fragmentShader = collection->fragmentShader;
pipelineInfo.pipelineLayout = collection->pipelineLayout;
pipelineInfo.renderPass = renderPass;
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL;
pipelineInfo.multisampleState.samples = viewport->getSamples();
pipelineInfo.colorBlend.attachmentCount = 1;
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
}
else
{
Gfx::LegacyPipelineCreateInfo pipelineInfo;
pipelineInfo.vertexShader = collection->vertexShader;
pipelineInfo.fragmentShader = collection->fragmentShader;
pipelineInfo.pipelineLayout = collection->pipelineLayout;
pipelineInfo.renderPass = renderPass;
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL;
pipelineInfo.multisampleState.samples = viewport->getSamples();
pipelineInfo.colorBlend.attachmentCount = 1;
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
}
command->bindDescriptor(vertexData->getVertexDataSet());
command->bindDescriptor(viewParamsSet);
command->bindDescriptor(scene->getLightEnvironment()->getDescriptorSet());
command->bindDescriptor(opaqueCulling);
for (const auto& [_, instance] : materialData.instances)
{
command->bindDescriptor(instance.materialInstance->getDescriptorSet());
command->bindDescriptor(vertexData->getInstanceDataSet(), {instance.descriptorOffset, instance.descriptorOffset});
if (graphics->supportMeshShading())
{
command->drawMesh(vertexData->getMeshData(instance.meshId).size(), 1, 1);
}
else
{
command->bindIndexBuffer(vertexData->getIndexBuffer());
uint32 instanceOffset = 0;
for (const auto& meshData : vertexData->getMeshData(instance.meshId))
{
if (meshData.numIndices > 0)
{
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset);
}
instanceOffset++;
}
}
}
commands.add(std::move(command));
}
}
}
graphics->executeCommands(std::move(commands)); graphics->executeCommands(std::move(commands));
graphics->endRenderPass(); graphics->endRenderPass();
} }
@@ -177,18 +263,20 @@ void BasePass::publishOutputs()
if (graphics->supportMeshShading()) if (graphics->supportMeshShading())
{ {
graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "BasePass", "MeshletBasePass", true, true, "BasePass", true, true, "MeshletBasePass"); graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "BasePass", "MeshletPass", true, true, "BasePass", true, true, "MeshBasePass");
graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "StaticBasePass", "StaticMeshletPass", true, true, "BasePass", true, true, "StaticMeshletPass");
} }
else else
{ {
graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "BasePass", "LegacyBasePass", true, true, "BasePass"); graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "BasePass", "LegacyPass", true, true, "BasePass");
graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "StaticBasePass", "StaticLegacyPass", true, true, "BasePass");
} }
} }
void BasePass::createRenderPass() void BasePass::createRenderPass()
{ {
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH"); depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
depthAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR); depthAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD);
depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL); depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{ Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
+1 -14
View File
@@ -17,7 +17,6 @@ public:
virtual void endFrame() override; virtual void endFrame() override;
virtual void publishOutputs() override; virtual void publishOutputs() override;
virtual void createRenderPass() override; virtual void createRenderPass() override;
static void modifyRenderPassMacros(Map<const char*, const char*>& defines);
private: private:
Gfx::RenderTargetAttachment colorAttachment; Gfx::RenderTargetAttachment colorAttachment;
Gfx::RenderTargetAttachment depthAttachment; Gfx::RenderTargetAttachment depthAttachment;
@@ -28,22 +27,10 @@ private:
Gfx::PDescriptorSet opaqueCulling; Gfx::PDescriptorSet opaqueCulling;
Gfx::PDescriptorSet transparentCulling; Gfx::PDescriptorSet transparentCulling;
Array<Gfx::PDescriptorSet> descriptorSets; //Array<Gfx::PDescriptorSet> descriptorSets;
PCameraActor source; PCameraActor source;
Gfx::OPipelineLayout basePassLayout; Gfx::OPipelineLayout basePassLayout;
// Set 0: viewParameter, provided by renderpass
static constexpr uint32 INDEX_VIEW_PARAMS = 0;
// Set 1: vertex buffers, provided by vertexdata
static constexpr uint32 INDEX_VERTEX_DATA = 1;
// Set 2: instance data, provided by vertexdata
static constexpr uint32 INDEX_SCENE_DATA = 2;
// Set 3: light environment, provided by lightenv
static constexpr uint32 INDEX_LIGHT_ENV = 3;
// Set 4: material data, generated from material
static constexpr uint32 INDEX_MATERIAL = 4;
// Set 5: light culling data
Gfx::ODescriptorLayout lightCullingLayout; Gfx::ODescriptorLayout lightCullingLayout;
static constexpr uint32 INDEX_LIGHT_CULLING = 5;
}; };
DEFINE_REF(BasePass) DEFINE_REF(BasePass)
} // namespace Seele } // namespace Seele
@@ -15,6 +15,10 @@ target_sources(Engine
RenderPass.cpp RenderPass.cpp
SkyboxRenderPass.h SkyboxRenderPass.h
SkyboxRenderPass.cpp SkyboxRenderPass.cpp
StaticDepthPrepass.h
StaticDepthPrepass.cpp
StaticBasePass.h
StaticBasePass.cpp
TextPass.h TextPass.h
TextPass.cpp TextPass.cpp
UIPass.h UIPass.h
@@ -31,5 +35,7 @@ target_sources(Engine
RenderGraphResources.h RenderGraphResources.h
RenderPass.h RenderPass.h
SkyboxRenderPass.h SkyboxRenderPass.h
StaticDepthPrepass.h
StaticBasePass.h
TextPass.h TextPass.h
UIPass.h) UIPass.h)
+73 -117
View File
@@ -9,22 +9,22 @@
#include "Math/Vector.h" #include "Math/Vector.h"
#include "RenderGraph.h" #include "RenderGraph.h"
#include "Graphics/Command.h" #include "Graphics/Command.h"
#include "Graphics/StaticMeshVertexData.h"
using namespace Seele; using namespace Seele;
DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene) DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene)
: RenderPass(graphics, scene) : RenderPass(graphics, scene)
, descriptorSets(3)
{ {
depthPrepassLayout = graphics->createPipelineLayout("DepthPrepassLayout"); depthPrepassLayout = graphics->createPipelineLayout("DepthPrepassLayout");
depthPrepassLayout->addDescriptorLayout(viewParamsLayout); depthPrepassLayout->addDescriptorLayout(viewParamsLayout);
if (graphics->supportMeshShading()) if (graphics->supportMeshShading())
{ {
graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "MeshletBasePass", false, false, "", true, true, "MeshletBasePass"); graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "MeshletPass", false, false, "", true, true, "MeshletPass");
} }
else else
{ {
graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "LegacyBasePass"); graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "LegacyPass");
} }
} }
@@ -35,95 +35,99 @@ DepthPrepass::~DepthPrepass()
void DepthPrepass::beginFrame(const Component::Camera& cam) void DepthPrepass::beginFrame(const Component::Camera& cam)
{ {
RenderPass::beginFrame(cam); RenderPass::beginFrame(cam);
descriptorSets[INDEX_VIEW_PARAMS] = viewParamsSet;
} }
void DepthPrepass::render() void DepthPrepass::render()
{ {
Gfx::ShaderPermutation permutation;
if(graphics->supportMeshShading())
{
permutation.setTaskFile("MeshletBasePass");
permutation.setMeshFile("MeshletBasePass");
}
else
{
permutation.setVertexFile("LegacyBasePass");
}
graphics->beginRenderPass(renderPass); graphics->beginRenderPass(renderPass);
Array<Gfx::ORenderCommand> commands; Array<Gfx::ORenderCommand> commands;
for (VertexData* vertexData : VertexData::getList())
// Others
{ {
permutation.setVertexData(vertexData->getTypeName()); Gfx::ShaderPermutation permutation;
const auto& materials = vertexData->getMaterialData(); if (graphics->supportMeshShading())
for (const auto& [_, materialData] : materials)
{ {
// Create Pipeline(Material, VertexData) permutation.setTaskFile("MeshletPass");
// Descriptors: permutation.setMeshFile("MeshletPass");
// ViewData => global, static }
// Material => per material else
// VertexData => per meshtype {
// SceneData => per material instance permutation.setVertexFile("LegacyPass");
Gfx::PermutationId id(permutation); }
for (VertexData* vertexData : VertexData::getList())
Gfx::ORenderCommand command = graphics->createRenderCommand("DepthRender"); {
command->setViewport(viewport); permutation.setVertexData(vertexData->getTypeName());
const auto& materials = vertexData->getMaterialData();
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id); for (const auto& [_, materialData] : materials)
assert(collection != nullptr);
if(graphics->supportMeshShading())
{ {
Gfx::MeshPipelineCreateInfo pipelineInfo; // Create Pipeline(VertexData)
pipelineInfo.taskShader = collection->taskShader; // Descriptors:
pipelineInfo.meshShader = collection->meshShader; // ViewData => global, static
pipelineInfo.fragmentShader = collection->fragmentShader; // VertexData => per meshtype
pipelineInfo.pipelineLayout = collection->pipelineLayout; // SceneData => per material instance
pipelineInfo.renderPass = renderPass; permutation.setMaterial(materialData.material->getName());
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER; Gfx::PermutationId id(permutation);
pipelineInfo.multisampleState.samples = viewport->getSamples();
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
}
else
{
Gfx::LegacyPipelineCreateInfo pipelineInfo;
pipelineInfo.vertexShader = collection->vertexShader;
pipelineInfo.fragmentShader = collection->fragmentShader;
pipelineInfo.pipelineLayout = collection->pipelineLayout;
pipelineInfo.renderPass = renderPass;
//pipelineInfo.depthStencilState.depthWriteEnable = false;
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER;
pipelineInfo.multisampleState.samples = viewport->getSamples();
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
}
descriptorSets[INDEX_VERTEX_DATA] = vertexData->getVertexDataSet(); Gfx::ORenderCommand command = graphics->createRenderCommand("BaseRender");
for (const auto& [_, instance] : materialData.instances) command->setViewport(viewport);
{
//descriptorSets[INDEX_MATERIAL] = instance.materialInstance->getDescriptorSet(); const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
descriptorSets[INDEX_SCENE_DATA] = instance.descriptorSet; assert(collection != nullptr);
command->bindDescriptor(descriptorSets);
if (graphics->supportMeshShading()) if (graphics->supportMeshShading())
{ {
command->drawMesh(instance.meshes.size(), 1, 1); Gfx::MeshPipelineCreateInfo pipelineInfo;
pipelineInfo.taskShader = collection->taskShader;
pipelineInfo.meshShader = collection->meshShader;
pipelineInfo.fragmentShader = collection->fragmentShader;
pipelineInfo.pipelineLayout = collection->pipelineLayout;
pipelineInfo.renderPass = renderPass;
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER;
pipelineInfo.multisampleState.samples = viewport->getSamples();
pipelineInfo.colorBlend.attachmentCount = 1;
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
} }
else else
{ {
command->bindIndexBuffer(vertexData->getIndexBuffer()); Gfx::LegacyPipelineCreateInfo pipelineInfo;
uint32 instanceOffset = 0; pipelineInfo.vertexShader = collection->vertexShader;
for (const auto& [_, meshData] : instance.meshes) pipelineInfo.fragmentShader = collection->fragmentShader;
pipelineInfo.pipelineLayout = collection->pipelineLayout;
pipelineInfo.renderPass = renderPass;
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER;
pipelineInfo.multisampleState.samples = viewport->getSamples();
pipelineInfo.colorBlend.attachmentCount = 1;
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
}
command->bindDescriptor(vertexData->getVertexDataSet());
command->bindDescriptor(viewParamsSet);
for (const auto& [_, instance] : materialData.instances)
{
command->bindDescriptor(vertexData->getInstanceDataSet(), { instance.descriptorOffset, instance.descriptorOffset });
if (graphics->supportMeshShading())
{ {
if (meshData.numIndices > 0) command->drawMesh(vertexData->getMeshData(instance.meshId).size(), 1, 1);
}
else
{
command->bindIndexBuffer(vertexData->getIndexBuffer());
uint32 instanceOffset = 0;
for (const auto& meshData : vertexData->getMeshData(instance.meshId))
{ {
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset++); if (meshData.numIndices > 0)
{
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset);
}
instanceOffset++;
} }
} }
} }
commands.add(std::move(command));
} }
commands.add(std::move(command));
} }
} }
graphics->executeCommands(std::move(commands)); graphics->executeCommands(std::move(commands));
graphics->endRenderPass(); graphics->endRenderPass();
} }
@@ -134,56 +138,8 @@ void DepthPrepass::endFrame()
void DepthPrepass::publishOutputs() void DepthPrepass::publishOutputs()
{ {
// If we render to a part of an image, the depth buffer itself must
// still match the size of the whole image or their coordinate systems go out of sync
TextureCreateInfo depthBufferInfo = {
.format = Gfx::SE_FORMAT_D32_SFLOAT,
.width = viewport->getOwner()->getFramebufferWidth(),
.height = viewport->getOwner()->getFramebufferHeight(),
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
};
depthBuffer = graphics->createTexture2D(depthBufferInfo);
depthAttachment =
Gfx::RenderTargetAttachment(depthBuffer,
Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_GENERAL,
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
resources->registerRenderPassOutput("DEPTHPREPASS_DEPTH", depthAttachment);
} }
void DepthPrepass::createRenderPass() void DepthPrepass::createRenderPass()
{
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
.depthAttachment = depthAttachment,
};
Array<Gfx::SubPassDependency> dependency = {
{
.srcSubpass = ~0U,
.dstSubpass = 0,
.srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
.dstStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
.srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
},
{
.srcSubpass = 0,
.dstSubpass = ~0U,
.srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
.dstStage = Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
.srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.dstAccess = Gfx::SE_ACCESS_SHADER_READ_BIT,
},
{
.srcSubpass = 0,
.dstSubpass = ~0U,
.srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
.dstStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
.srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
}
};
renderPass = graphics->createRenderPass(std::move(layout), dependency, viewport);
}
void DepthPrepass::modifyRenderPassMacros(Map<const char*, const char*>&)
{ {
} }
@@ -16,20 +16,10 @@ public:
virtual void endFrame() override; virtual void endFrame() override;
virtual void publishOutputs() override; virtual void publishOutputs() override;
virtual void createRenderPass() override; virtual void createRenderPass() override;
static void modifyRenderPassMacros(Map<const char*, const char*>& defines);
private: private:
Gfx::RenderTargetAttachment depthAttachment; Gfx::RenderTargetAttachment depthAttachment;
Gfx::OTexture2D depthBuffer; Gfx::OTexture2D depthBuffer;
Array<Gfx::PDescriptorSet> descriptorSets;
Gfx::OPipelineLayout depthPrepassLayout; Gfx::OPipelineLayout depthPrepassLayout;
// Set 0: viewParameter
static constexpr uint32 INDEX_VIEW_PARAMS = 0;
// Set 0: vertices, from VertexData
constexpr static uint32 INDEX_VERTEX_DATA = 1;
// Set 2: mesh data, either index buffer or meshlet data
constexpr static uint32 INDEX_SCENE_DATA = 2;
Gfx::ODescriptorLayout sceneDataLayout; Gfx::ODescriptorLayout sceneDataLayout;
}; };
DEFINE_REF(DepthPrepass) DEFINE_REF(DepthPrepass)
@@ -20,7 +20,6 @@ public:
virtual void endFrame() override; virtual void endFrame() override;
virtual void publishOutputs() override; virtual void publishOutputs() override;
virtual void createRenderPass() override; virtual void createRenderPass() override;
static void modifyRenderPassMacros(Map<const char*, const char*>& defines);
private: private:
void setupFrustums(); void setupFrustums();
static constexpr uint32 BLOCK_SIZE = 32; static constexpr uint32 BLOCK_SIZE = 32;
@@ -0,0 +1,165 @@
#include "StaticDepthPrepass.h"
#include "Graphics/StaticMeshVertexData.h"
#include "Graphics/Shader.h"
using namespace Seele;
StaticDepthPrepass::StaticDepthPrepass(Gfx::PGraphics graphics, PScene scene)
: RenderPass(graphics, scene)
{
depthPrepassLayout = graphics->createPipelineLayout("DepthPrepassLayout");
depthPrepassLayout->addDescriptorLayout(viewParamsLayout);
if (graphics->supportMeshShading())
{
graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "MeshletPass", false, false, "", true, true, "MeshletPass");
}
else
{
graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "LegacyPass");
}
}
StaticDepthPrepass::~StaticDepthPrepass()
{
}
void StaticDepthPrepass::beginFrame(const Component::Camera& cam)
{
RenderPass::beginFrame(cam);
}
void StaticDepthPrepass::render()
{
// Static Meshes
{
Gfx::ShaderPermutation permutation;
if (graphics->supportMeshShading())
{
permutation.setTaskFile("StaticMeshletPass");
permutation.setMeshFile("StaticMeshletPass");
}
else
{
permutation.setVertexFile("LegacyPass");
}
StaticMeshVertexData* vd = StaticMeshVertexData::getInstance();
permutation.setVertexData(vd->getTypeName());
for (const auto& [_, mappings] : vd->)
{
permutation.setMaterial(mapping.material->getBaseMaterial()->getName());
Gfx::PermutationId id(permutation);
Gfx::ORenderCommand command = graphics->createRenderCommand("DepthRender");
command->setViewport(viewport);
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
assert(collection != nullptr);
if (graphics->supportMeshShading())
{
Gfx::MeshPipelineCreateInfo pipelineInfo;
pipelineInfo.taskShader = collection->taskShader;
pipelineInfo.meshShader = collection->meshShader;
pipelineInfo.fragmentShader = collection->fragmentShader;
pipelineInfo.pipelineLayout = collection->pipelineLayout;
pipelineInfo.renderPass = renderPass;
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL;
pipelineInfo.multisampleState.samples = viewport->getSamples();
pipelineInfo.colorBlend.attachmentCount = 1;
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
}
else
{
Gfx::LegacyPipelineCreateInfo pipelineInfo;
pipelineInfo.vertexShader = collection->vertexShader;
pipelineInfo.fragmentShader = collection->fragmentShader;
pipelineInfo.pipelineLayout = collection->pipelineLayout;
pipelineInfo.renderPass = renderPass;
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL;
pipelineInfo.multisampleState.samples = viewport->getSamples();
pipelineInfo.colorBlend.attachmentCount = 1;
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
}
command->bindDescriptor(viewParamsSet);
command->bindDescriptor(vd->getVertexDataSet());
command->bindDescriptor(vd->getInstanceDataSet(), { 0, 0 });
if (graphics->supportMeshShading())
{
command->drawMesh(vd->getMeshData(mapping.mapped).size(), 1, 1);
}
else
{
command->bindIndexBuffer(vd->getIndexBuffer());
uint32 instanceOffset = 0;
for (const auto& meshData : vd->getMeshData(mapping.mapped))
{
if (meshData.numIndices > 0)
{
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset);
}
instanceOffset++;
}
}
commands.add(std::move(command));
}
}
}
}
void StaticDepthPrepass::endFrame()
{
}
void StaticDepthPrepass::publishOutputs()
{
// If we render to a part of an image, the depth buffer itself must
// still match the size of the whole image or their coordinate systems go out of sync
TextureCreateInfo depthBufferInfo = {
.format = Gfx::SE_FORMAT_D32_SFLOAT,
.width = viewport->getOwner()->getFramebufferWidth(),
.height = viewport->getOwner()->getFramebufferHeight(),
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
};
depthBuffer = graphics->createTexture2D(depthBufferInfo);
depthAttachment =
Gfx::RenderTargetAttachment(depthBuffer,
Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_GENERAL,
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
resources->registerRenderPassOutput("DEPTHPREPASS_DEPTH", depthAttachment);
}
void StaticDepthPrepass::createRenderPass()
{
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
.depthAttachment = depthAttachment,
};
Array<Gfx::SubPassDependency> dependency = {
{
.srcSubpass = ~0U,
.dstSubpass = 0,
.srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
.dstStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
.srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
},
{
.srcSubpass = 0,
.dstSubpass = ~0U,
.srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
.dstStage = Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
.srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.dstAccess = Gfx::SE_ACCESS_SHADER_READ_BIT,
},
{
.srcSubpass = 0,
.dstSubpass = ~0U,
.srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
.dstStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
.srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
}
};
renderPass = graphics->createRenderPass(std::move(layout), dependency, viewport);
}
@@ -0,0 +1,24 @@
#pragma once
#include "RenderPass.h"
namespace Seele
{
class StaticDepthPrepass : public RenderPass
{
public:
StaticDepthPrepass(Gfx::PGraphics graphics, PScene scene);
StaticDepthPrepass(StaticDepthPrepass&&) = default;
StaticDepthPrepass& operator=(StaticDepthPrepass&&) = default;
virtual ~StaticDepthPrepass();
virtual void beginFrame(const Component::Camera& cam) override;
virtual void render() override;
virtual void endFrame() override;
virtual void publishOutputs() override;
virtual void createRenderPass() override;
private:
Gfx::RenderTargetAttachment depthAttachment;
Gfx::OTexture2D depthBuffer;
Gfx::OPipelineLayout depthPrepassLayout;
Gfx::ODescriptorLayout sceneDataLayout;
};
}
@@ -1,6 +1,7 @@
#include "StaticMeshVertexData.h" #include "StaticMeshVertexData.h"
#include "Graphics.h" #include "Graphics.h"
#include "Graphics/Enums.h" #include "Graphics/Enums.h"
#include "Mesh.h"
using namespace Seele; using namespace Seele;
@@ -192,6 +193,43 @@ Gfx::PDescriptorSet StaticMeshVertexData::getVertexDataSet()
return descriptorSet; return descriptorSet;
} }
void StaticMeshVertexData::registerStaticMesh(entt::entity id, const Array<OMesh>& meshes, const Component::Transform& transform)
{
std::unique_lock l(vertexDataLock);
std::unique_lock l2(mutex);
for (auto& mesh : meshes)
{
uint64 numVertices = meshVertexCounts[mesh->id];
uint64 offset = meshOffsets[mesh->id];
MeshId mapped = VertexData::allocateVertexData(numVertices);
Array<Vector> pos(numVertices);
Matrix4 matrix = transform.toMatrix();
for (uint64 i = 0; i < numVertices; ++i)
{
pos[i] = matrix * Vector4(positionData[offset + i], 1);
}
loadPositions(mapped, pos);
Array<Vector2> tex(numVertices);
for (size_t i = 0; i < MAX_TEXCOORDS; ++i)
{
std::memcpy(tex.data(), texCoordsData[i].data() + offset, numVertices * sizeof(Vector2));
loadTexCoords(mapped, i, tex);
}
Array<Vector> aux(numVertices);
std::memcpy(aux.data(), normalData.data() + offset, numVertices * sizeof(Vector));
loadNormals(mapped, aux);
std::memcpy(aux.data(), biTangentData.data() + offset, numVertices * sizeof(Vector));
loadBiTangents(mapped, aux);
std::memcpy(aux.data(), colorData.data() + offset, numVertices * sizeof(Vector));
loadColors(mapped, aux);
staticMeshes[id].add(StaticMeshMapping{
.original = mesh->id,
.mapped = mapped,
.material = mesh->referencedMaterial->getHandle(),
});
}
}
void StaticMeshVertexData::resizeBuffers() void StaticMeshVertexData::resizeBuffers()
{ {
ShaderBufferCreateInfo createInfo = { ShaderBufferCreateInfo createInfo = {
@@ -3,12 +3,19 @@
#include "Graphics/Command.h" #include "Graphics/Command.h"
#include "Math/Vector.h" #include "Math/Vector.h"
#include "VertexData.h" #include "VertexData.h"
#include "entt/entt.hpp"
namespace Seele namespace Seele
{ {
class StaticMeshVertexData : public VertexData class StaticMeshVertexData : public VertexData
{ {
public: public:
struct StaticMeshMapping
{
MeshId original;
MeshId mapped;
PMaterialInstance material;
};
StaticMeshVertexData(); StaticMeshVertexData();
virtual ~StaticMeshVertexData(); virtual ~StaticMeshVertexData();
static StaticMeshVertexData* getInstance(); static StaticMeshVertexData* getInstance();
@@ -26,9 +33,12 @@ public:
virtual Gfx::PDescriptorLayout getVertexDataLayout() override; virtual Gfx::PDescriptorLayout getVertexDataLayout() override;
virtual Gfx::PDescriptorSet getVertexDataSet() override; virtual Gfx::PDescriptorSet getVertexDataSet() override;
virtual std::string getTypeName() const override { return "StaticMeshVertexData"; } virtual std::string getTypeName() const override { return "StaticMeshVertexData"; }
void registerStaticMesh(const Array<OMesh>& meshes, const Component::Transform& transform);
private: private:
virtual void resizeBuffers() override; virtual void resizeBuffers() override;
virtual void updateBuffers() override; virtual void updateBuffers() override;
Array<MeshletDescription> staticMeshlets;
std::mutex mutex; std::mutex mutex;
Gfx::OShaderBuffer positions; Gfx::OShaderBuffer positions;
Array<Vector> positionData; Array<Vector> positionData;
+55 -63
View File
@@ -36,16 +36,18 @@ void VertexData::updateMesh(PMesh mesh, Component::Transform& transform)
MaterialData& matData = materialData[mat->getName()]; MaterialData& matData = materialData[mat->getName()];
matData.material = mat; matData.material = mat;
MaterialInstanceData& matInstanceData = matData.instances[referencedInstance->getId()]; MaterialInstanceData& matInstanceData = matData.instances[referencedInstance->getId()];
matInstanceData.descriptorOffset = instanceData.size();
matInstanceData.numMeshes = 0;
matInstanceData.meshId = mesh->id;
for (const auto& data : meshData[mesh->id]) for (const auto& data : meshData[mesh->id])
{ {
Matrix4 transformMatrix = transform.toMatrix() * mesh->transform; Matrix4 transformMatrix = transform.toMatrix() * mesh->transform;
matInstanceData.meshes.add(MeshInstanceData{ instanceData.add(InstanceData {
.instance = InstanceData { .transformMatrix = transformMatrix,
.transformMatrix = transformMatrix, .inverseTransformMatrix = glm::inverse(transformMatrix),
.inverseTransformMatrix = glm::inverse(transformMatrix), });
}, instanceMeshData.add(data);
.data = data, matInstanceData.numMeshes++;
});
for (size_t i = 0; i < 0; ++i) for (size_t i = 0; i < 0; ++i)
{ {
auto bounding = meshlets[data.meshletOffset + i].bounding; auto bounding = meshlets[data.meshletOffset + i].bounding;
@@ -94,58 +96,45 @@ void VertexData::createDescriptors()
{ {
std::unique_lock l(materialDataLock); std::unique_lock l(materialDataLock);
instanceDataLayout->reset(); instanceDataLayout->reset();
for (const auto& [_, mat] : materialData) instanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
{ .sourceData = {
for (auto& [_, matInst] : mat.instances) .size = sizeof(InstanceData) * instanceData.size(),
{ .data = (uint8*)instanceData.data(),
Array<InstanceData> instanceData; },
Array<MeshData> meshes; .numElements = instanceData.size(),
for (auto& inst : matInst.meshes) .dynamic = false,
{ .name = "InstanceBuffer"
meshes.add(inst.data); });
instanceData.add(inst.instance); instanceBuffer->pipelineBarrier(
} Gfx::SE_ACCESS_TRANSFER_WRITE_BIT,
matInst.instanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
.sourceData = { Gfx::SE_ACCESS_MEMORY_READ_BIT,
.size = sizeof(InstanceData) * instanceData.size(), Gfx::SE_PIPELINE_STAGE_VERTEX_SHADER_BIT
.data = (uint8*)instanceData.data(), );
}, descriptorSet = instanceDataLayout->allocateDescriptorSet();
.numElements = instanceData.size(),
.dynamic = false, instanceMeshDataBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.name = "InstanceBuffer" .sourceData = {
}); .size = sizeof(MeshData) * instanceMeshData.size(),
matInst.instanceBuffer->pipelineBarrier( .data = (uint8*)instanceMeshData.data(),
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, },
Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, .numElements = instanceMeshData.size(),
Gfx::SE_ACCESS_MEMORY_READ_BIT, .dynamic = false,
Gfx::SE_PIPELINE_STAGE_VERTEX_SHADER_BIT .name = "MeshDataBuffer"
); });
matInst.descriptorSet = instanceDataLayout->allocateDescriptorSet(); instanceMeshDataBuffer->pipelineBarrier(
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT,
matInst.meshDataBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
.sourceData = { Gfx::SE_ACCESS_MEMORY_READ_BIT,
.size = sizeof(MeshData) * meshes.size(), Gfx::SE_PIPELINE_STAGE_VERTEX_SHADER_BIT
.data = (uint8*)meshes.data(), );
}, descriptorSet->updateBuffer(0, instanceBuffer);
.numElements = meshes.size(), descriptorSet->updateBuffer(1, instanceMeshDataBuffer);
.dynamic = false, descriptorSet->updateBuffer(2, meshletBuffer);
.name = "MeshDataBuffer" descriptorSet->updateBuffer(3, primitiveIndicesBuffer);
}); descriptorSet->updateBuffer(4, vertexIndicesBuffer);
matInst.meshDataBuffer->pipelineBarrier(
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, descriptorSet->writeChanges();
Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
Gfx::SE_ACCESS_MEMORY_READ_BIT,
Gfx::SE_PIPELINE_STAGE_VERTEX_SHADER_BIT
);
matInst.descriptorSet->updateBuffer(0, matInst.instanceBuffer);
matInst.descriptorSet->updateBuffer(1, matInst.meshDataBuffer);
matInst.descriptorSet->updateBuffer(2, meshletBuffer);
matInst.descriptorSet->updateBuffer(3, primitiveIndicesBuffer);
matInst.descriptorSet->updateBuffer(4, vertexIndicesBuffer);
matInst.descriptorSet->writeChanges();
}
}
} }
void VertexData::loadMesh(MeshId id, Array<uint32> loadedIndices, Array<Meshlet> loadedMeshlets) void VertexData::loadMesh(MeshId id, Array<uint32> loadedIndices, Array<Meshlet> loadedMeshlets)
@@ -264,7 +253,7 @@ List<VertexData*> VertexData::getList()
return vertexDataList; return vertexDataList;
} }
VertexData* Seele::VertexData::findByTypeName(std::string name) VertexData* VertexData::findByTypeName(std::string name)
{ {
for (auto vd : vertexDataList) for (auto vd : vertexDataList)
{ {
@@ -276,15 +265,16 @@ VertexData* Seele::VertexData::findByTypeName(std::string name)
return nullptr; return nullptr;
} }
void Seele::VertexData::init(Gfx::PGraphics _graphics) void VertexData::init(Gfx::PGraphics _graphics)
{ {
graphics = _graphics; graphics = _graphics;
verticesAllocated = NUM_DEFAULT_ELEMENTS; verticesAllocated = NUM_DEFAULT_ELEMENTS;
instanceDataLayout = graphics->createDescriptorLayout("pScene"); instanceDataLayout = graphics->createDescriptorLayout("pScene");
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,});
// instanceData
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,});
// meshData // meshData
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,}); instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,});
// meshletData // meshletData
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 2, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 2, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
// primitiveIndices // primitiveIndices
@@ -299,6 +289,8 @@ void Seele::VertexData::init(Gfx::PGraphics _graphics)
void VertexData::destroy() void VertexData::destroy()
{ {
instanceBuffer = nullptr;
instanceMeshDataBuffer = nullptr;
instanceDataLayout = nullptr; instanceDataLayout = nullptr;
meshletBuffer = nullptr; meshletBuffer = nullptr;
vertexIndicesBuffer = nullptr; vertexIndicesBuffer = nullptr;
+14 -13
View File
@@ -43,18 +43,12 @@ public:
uint32 indicesOffset = 0; uint32 indicesOffset = 0;
uint32 pad0[3]; uint32 pad0[3];
}; };
struct MeshInstanceData
{
InstanceData instance;
MeshData data;
};
struct MaterialInstanceData struct MaterialInstanceData
{ {
PMaterialInstance materialInstance; PMaterialInstance materialInstance;
Gfx::OShaderBuffer instanceBuffer; uint32 descriptorOffset;
Gfx::OShaderBuffer meshDataBuffer; uint64 numMeshes;
Gfx::PDescriptorSet descriptorSet; MeshId meshId;
Array<MeshInstanceData> meshes;
}; };
struct MaterialData struct MaterialData
{ {
@@ -76,6 +70,7 @@ public:
virtual std::string getTypeName() const = 0; virtual std::string getTypeName() const = 0;
Gfx::PIndexBuffer getIndexBuffer() { return indexBuffer; } Gfx::PIndexBuffer getIndexBuffer() { return indexBuffer; }
Gfx::PDescriptorLayout getInstanceDataLayout() { return instanceDataLayout; } Gfx::PDescriptorLayout getInstanceDataLayout() { return instanceDataLayout; }
Gfx::PDescriptorSet getInstanceDataSet() { return descriptorSet; }
const Map<std::string, MaterialData>& getMaterialData() const { return materialData; } const Map<std::string, MaterialData>& getMaterialData() const { return materialData; }
const Array<MeshData>& getMeshData(MeshId id) { return meshData[id]; } const Array<MeshData>& getMeshData(MeshId id) { return meshData[id]; }
static List<VertexData*> getList(); static List<VertexData*> getList();
@@ -89,10 +84,10 @@ protected:
struct MeshletDescription struct MeshletDescription
{ {
AABB bounding; AABB bounding;
uint32_t vertexCount; uint32 vertexCount;
uint32_t primitiveCount; uint32 primitiveCount;
uint32_t vertexOffset; uint32 vertexOffset;
uint32_t primitiveOffset; uint32 primitiveOffset;
Vector color; Vector color;
float pad; float pad;
}; };
@@ -114,6 +109,12 @@ protected:
Gfx::OShaderBuffer primitiveIndicesBuffer; Gfx::OShaderBuffer primitiveIndicesBuffer;
// for legacy pipeline // for legacy pipeline
Gfx::OIndexBuffer indexBuffer; Gfx::OIndexBuffer indexBuffer;
// Material data
Array<InstanceData> instanceData;
Gfx::OShaderBuffer instanceBuffer;
Array<MeshData> instanceMeshData;
Gfx::OShaderBuffer instanceMeshDataBuffer;
Gfx::PDescriptorSet descriptorSet;
uint64 idCounter; uint64 idCounter;
uint64 head; uint64 head;
uint64 verticesAllocated; uint64 verticesAllocated;
+8 -8
View File
@@ -270,7 +270,7 @@ void RenderCommand::bindPipeline(Gfx::PGraphicsPipeline gfxPipeline)
pipeline = gfxPipeline.cast<GraphicsPipeline>(); pipeline = gfxPipeline.cast<GraphicsPipeline>();
pipeline->bind(handle); pipeline->bind(handle);
} }
void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet) void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint32> dynamicOffsets)
{ {
assert(threadId == std::this_thread::get_id()); assert(threadId == std::this_thread::get_id());
auto descriptor = descriptorSet.cast<DescriptorSet>(); auto descriptor = descriptorSet.cast<DescriptorSet>();
@@ -279,9 +279,9 @@ void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet)
descriptor->bind(); descriptor->bind();
VkDescriptorSet setHandle = descriptor->getHandle(); VkDescriptorSet setHandle = descriptor->getHandle();
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), pipeline->getPipelineLayout()->findParameter(descriptorSet->getName()), 1, &setHandle, 0, nullptr); vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), pipeline->getPipelineLayout()->findParameter(descriptorSet->getName()), 1, &setHandle, dynamicOffsets.size(), dynamicOffsets.data());
} }
void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets) void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets, Array<uint32> dynamicOffsets)
{ {
assert(threadId == std::this_thread::get_id()); assert(threadId == std::this_thread::get_id());
VkDescriptorSet* sets = new VkDescriptorSet[descriptorSets.size()]; VkDescriptorSet* sets = new VkDescriptorSet[descriptorSets.size()];
@@ -294,7 +294,7 @@ void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorS
boundDescriptors.add(descriptorSet.getHandle()); boundDescriptors.add(descriptorSet.getHandle());
sets[pipeline->getPipelineLayout()->findParameter(descriptorSet->getName())] = descriptorSet->getHandle(); sets[pipeline->getPipelineLayout()->findParameter(descriptorSet->getName())] = descriptorSet->getHandle();
} }
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), 0, (uint32)descriptorSets.size(), sets, 0, nullptr); vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), 0, (uint32)descriptorSets.size(), sets, dynamicOffsets.size(), dynamicOffsets.data());
delete[] sets; delete[] sets;
} }
void RenderCommand::bindVertexBuffer(const Array<Gfx::PVertexBuffer>& streams) void RenderCommand::bindVertexBuffer(const Array<Gfx::PVertexBuffer>& streams)
@@ -407,7 +407,7 @@ void ComputeCommand::bindPipeline(Gfx::PComputePipeline computePipeline)
pipeline->bind(handle); pipeline->bind(handle);
} }
void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet) void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint32> dynamicOffsets)
{ {
assert(threadId == std::this_thread::get_id()); assert(threadId == std::this_thread::get_id());
auto descriptor = descriptorSet.cast<DescriptorSet>(); auto descriptor = descriptorSet.cast<DescriptorSet>();
@@ -416,10 +416,10 @@ void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet)
descriptor->bind(); descriptor->bind();
VkDescriptorSet setHandle = descriptor->getHandle(); VkDescriptorSet setHandle = descriptor->getHandle();
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->getLayout(), pipeline->getPipelineLayout()->findParameter(descriptorSet->getName()), 1, &setHandle, 0, nullptr); vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->getLayout(), pipeline->getPipelineLayout()->findParameter(descriptorSet->getName()), 1, &setHandle, dynamicOffsets.size(), dynamicOffsets.data());
} }
void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets) void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets, Array<uint32> dynamicOffsets)
{ {
assert(threadId == std::this_thread::get_id()); assert(threadId == std::this_thread::get_id());
VkDescriptorSet* sets = new VkDescriptorSet[descriptorSets.size()]; VkDescriptorSet* sets = new VkDescriptorSet[descriptorSets.size()];
@@ -433,7 +433,7 @@ void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptor
boundDescriptors.add(descriptorSet.getHandle()); boundDescriptors.add(descriptorSet.getHandle());
sets[pipeline->getPipelineLayout()->findParameter(descriptorSet->getName())] = descriptorSet->getHandle(); sets[pipeline->getPipelineLayout()->findParameter(descriptorSet->getName())] = descriptorSet->getHandle();
} }
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->getLayout(), 0, (uint32)descriptorSets.size(), sets, 0, nullptr); vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->getLayout(), 0, (uint32)descriptorSets.size(), sets, dynamicOffsets.size(), dynamicOffsets.data());
delete[] sets; delete[] sets;
} }
+4 -4
View File
@@ -72,8 +72,8 @@ public:
bool isReady(); bool isReady();
virtual void setViewport(Gfx::PViewport viewport) override; virtual void setViewport(Gfx::PViewport viewport) override;
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override; virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override;
virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet) override; virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint32> dynamicOffsets) override;
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets) override; virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets, Array<uint32> dynamicOffsets) override;
virtual void bindVertexBuffer(const Array<Gfx::PVertexBuffer>& buffers) override; virtual void bindVertexBuffer(const Array<Gfx::PVertexBuffer>& buffers) override;
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override; virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override;
virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size,
@@ -107,8 +107,8 @@ public:
void reset(); void reset();
bool isReady(); bool isReady();
virtual void bindPipeline(Gfx::PComputePipeline pipeline) override; virtual void bindPipeline(Gfx::PComputePipeline pipeline) override;
virtual void bindDescriptor(Gfx::PDescriptorSet set) override; virtual void bindDescriptor(Gfx::PDescriptorSet set, Array<uint32> dynamicOffsets) override;
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) override; virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets, Array<uint32> dynamicOffsets) override;
virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size,
const void* data) override; const void* data) override;
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) override; virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) override;
+10
View File
@@ -22,10 +22,14 @@ void KeyboardInput::update(Component::KeyboardInput& input)
input.mouseY = mouseY; input.mouseY = mouseY;
input.mouse1 = mouse1; input.mouse1 = mouse1;
input.mouse2 = mouse2; input.mouse2 = mouse2;
input.scrollX = scrollX;
input.scrollY = scrollY;
deltaX = mouseX - lastMouseX; deltaX = mouseX - lastMouseX;
deltaY = mouseY - lastMouseY; deltaY = mouseY - lastMouseY;
lastMouseX = mouseX; lastMouseX = mouseX;
lastMouseY = mouseY; lastMouseY = mouseY;
scrollX = 0;
scrollY = 0;
} }
void KeyboardInput::keyCallback(KeyCode code, InputAction action, KeyModifier) void KeyboardInput::keyCallback(KeyCode code, InputAction action, KeyModifier)
@@ -50,3 +54,9 @@ void KeyboardInput::mouseButtonCallback(MouseButton button, InputAction action,
mouse2 = action != InputAction::RELEASE; mouse2 = action != InputAction::RELEASE;
} }
} }
void KeyboardInput::scrollCallback(double xScroll, double yScroll)
{
scrollX = xScroll;
scrollY = yScroll;
}
+3
View File
@@ -15,6 +15,7 @@ public:
void keyCallback(KeyCode code, InputAction action, KeyModifier modifier); void keyCallback(KeyCode code, InputAction action, KeyModifier modifier);
void mouseCallback(double xPos, double yPos); void mouseCallback(double xPos, double yPos);
void mouseButtonCallback(MouseButton button, InputAction action, KeyModifier modifier); void mouseButtonCallback(MouseButton button, InputAction action, KeyModifier modifier);
void scrollCallback(double xScroll, double yScroll);
private: private:
Seele::StaticArray<bool, (size_t)KeyCode::KEY_LAST> keys; Seele::StaticArray<bool, (size_t)KeyCode::KEY_LAST> keys;
bool mouse1 = false; bool mouse1 = false;
@@ -25,6 +26,8 @@ private:
float mouseY = 0; float mouseY = 0;
float deltaX = 0; float deltaX = 0;
float deltaY = 0; float deltaY = 0;
float scrollX = 0;
float scrollY = 0;
}; };
DEFINE_REF(KeyboardInput) DEFINE_REF(KeyboardInput)
} }
+2 -1
View File
@@ -108,8 +108,9 @@ void GameView::mouseButtonCallback(MouseButton button, InputAction action, KeyMo
keyboardSystem->mouseButtonCallback(button, action, modifier); keyboardSystem->mouseButtonCallback(button, action, modifier);
} }
void GameView::scrollCallback(double, double) void GameView::scrollCallback(double xScroll, double yScroll)
{ {
keyboardSystem->scrollCallback(xScroll, yScroll);
} }
void GameView::fileCallback(int, const char**) void GameView::fileCallback(int, const char**)