Program Listing for File MeshDrawRecorder.ixx#
↰ Return to documentation for file (Src/GraphicsEngineVulkan/renderer/MeshDrawRecorder.ixx)
module;
#include <optional>
#include <cstdint>
#include <glm/glm.hpp>
#include <vulkan/vulkan.hpp>
#include "renderer/pushConstants/PushConstantRasterizer.hpp"
export module kataglyphis.vulkan.mesh_draw_recorder;
import kataglyphis.vulkan.scene;
import kataglyphis.vulkan.frustum;
import kataglyphis.vulkan.mesh;
export namespace Kataglyphis::VulkanRendererInternals {
struct MeshDrawStats
{
unsigned int drawn;
unsigned int considered;
};
template<typename PerModelSetup, typename CullPredicate, typename PerMeshSetup>
MeshDrawStats walkSceneMeshes(vk::CommandBuffer commandBuffer,
Kataglyphis::Scene *scene,
PerModelSetup &&onModel,
CullPredicate &&shouldCull,
PerMeshSetup &&onMesh)
{
MeshDrawStats stats{ 0, 0 };
// object descriptions are flattened one-per-mesh across all models
// (Scene::add_model), so objectIndex is the running FLAT mesh index, not
// the model index. It advances for every mesh - culled ones included -
// to stay aligned with that buffer.
uint32_t flat_mesh_index = 0;
for (uint32_t m = 0; m < scene->getModelCount(); m++) {
const glm::mat4 model_matrix = scene->getModelMatrix(m);
onModel(model_matrix);
for (unsigned int k = 0; k < scene->getMeshCount(m); k++) {
const uint32_t object_index = flat_mesh_index++;
++stats.considered;
// Unreachable with a null mesh: m/k come from getModelCount()/
// getMeshCount(m), so findMesh() always resolves here. Kept as a
// fallback rather than an assert so behaviour matches the former
// per-accessor calls byte-for-byte.
Mesh *mesh = scene->findMesh(m, k);
static const AABB unknownBounds{ glm::vec3(1.0F), glm::vec3(-1.0F) };
const AABB &meshBounds = mesh != nullptr ? mesh->getBounds() : unknownBounds;
if (shouldCull(transformAABB(model_matrix, meshBounds))) { continue; }
onMesh(model_matrix, object_index, mesh);
const vk::Buffer vertex_buffer = mesh != nullptr ? mesh->getVertexBuffer() : vk::Buffer{};
const vk::DeviceSize offset = 0;
commandBuffer.bindVertexBuffers(0, 1, &vertex_buffer, &offset);
commandBuffer.bindIndexBuffer(
mesh != nullptr ? mesh->getIndexBuffer() : vk::Buffer{}, 0, vk::IndexType::eUint32);
commandBuffer.drawIndexed(mesh != nullptr ? mesh->getIndexCount() : 0, 1, 0, 0, 0);
++stats.drawn;
}
}
return stats;
}
MeshDrawStats recordSceneMeshDraws(vk::CommandBuffer commandBuffer,
vk::PipelineLayout pipelineLayout,
vk::ShaderStageFlags pushConstantStages,
Kataglyphis::Scene *scene,
const std::optional<FrustumPlanes> &cameraFrustum,
PushConstantRasterizer &pushConstant);
}// namespace Kataglyphis::VulkanRendererInternals