Starting framework for static mesh rendering
This commit is contained in:
@@ -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));
|
||||||
|
|||||||
@@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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{
|
||||||
|
|||||||
@@ -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)
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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**)
|
||||||
|
|||||||
Reference in New Issue
Block a user