feat: add click to select

This commit is contained in:
2026-10-23 20:53:56 +02:00
parent f055bdcbf1
commit f7e7c56392
20 changed files with 385 additions and 20 deletions
+4
View File
@@ -123,12 +123,16 @@ private:
void drawDockSpace();
void drawViewportWindow();
void applyViewportResize();
void requestSelectionPick();
void applySelectionPick();
[[nodiscard]] bool canPickInViewport() const { return usesEditorViewport() && (!playing || paused); }
ViewportRect viewportRect{};
glm::ivec2 viewportDesiredSize{0};
bool viewportHovered{false};
bool viewportFocused{false};
bool viewportMouseClaimed{false};
bool pickSelectsParent{false};
void drawPlayControls();
void applyPlayModeToggle();
@@ -22,7 +22,7 @@ struct GPUInstanceData {
glm::mat4 transform;
VkDeviceAddress vertexBuffer;
std::uint32_t materialId;
std::uint32_t padding;
std::uint32_t objectId;
};
static_assert(sizeof(GPUInstanceData) == 80);
@@ -39,6 +39,11 @@ public:
VkDeviceSize offset = 0,
VkDeviceSize size = VK_WHOLE_SIZE) const;
void invalidateAllocation(
const GPUBuffer& buffer,
VkDeviceSize offset = 0,
VkDeviceSize size = VK_WHOLE_SIZE) const;
[[nodiscard]] VkDeviceAddress getBufferAddress(const GPUBuffer& buffer) const;
private:
@@ -26,6 +26,8 @@ struct MeshDrawCommand {
// skinned meshes only
const SkinnedMesh* skinnedMesh{nullptr};
std::uint32_t jointMatricesStartIndex{0};
std::uint32_t objectId{0};
};
#endif //MESHDRAWCOMMAND_H
@@ -24,7 +24,8 @@ public:
GfxDevice& gfxDevice,
RenderResources& resources,
VkFormat drawImageFormat,
VkFormat depthImageFormat);
VkFormat depthImageFormat,
VkFormat selectionImageFormat);
void drawDepthPrepass(
VkCommandBuffer cmd,
@@ -32,7 +33,8 @@ public:
const RenderResources& resources,
const GPUBuffer& sceneDataBuffer,
const IndirectDrawList& drawList,
const IndirectDrawList::View& view);
const IndirectDrawList::View& view,
bool writeObjectIds);
void draw(
VkCommandBuffer cmd,
@@ -71,6 +73,7 @@ private:
VkPipelineLayout m_pipelineLayout{VK_NULL_HANDLE};
std::unique_ptr<Pipeline> m_pipeline;
std::unique_ptr<Pipeline> m_depthPrepassPipeline;
std::unique_ptr<Pipeline> m_selectionPrepassPipeline;
bool m_renderWireframe{false};
};
+40 -3
View File
@@ -2,6 +2,7 @@
#define RENDERER_H
#include <glm/mat4x4.hpp>
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#include <destrum/Graphics/Camera.h>
@@ -21,6 +22,7 @@
#include <array>
#include <memory>
#include <optional>
#include <utility>
#include <vector>
#include <destrum/Graphics/Pipelines/SkinningPipeline.h>
@@ -58,9 +60,9 @@ public:
void draw(VkCommandBuffer cmd, GfxDevice& gfxDevice, const Camera& camera, const SceneData& sceneData);
void cleanup(GfxDevice& gfxDevice);
void drawMesh(MeshID id, const glm::mat4& transform, MaterialID materialId);
void drawMesh(MeshID id, const glm::mat4& transform, MaterialID materialId, std::uint32_t objectId = 0);
void drawSkinnedMesh(MeshID id, const glm::mat4& transform, MaterialID materialId, SkinnedMesh* skinnedMesh,
std::size_t jointMatricesStartIndex);
std::size_t jointMatricesStartIndex, std::uint32_t objectId = 0);
void submitLight(const Light& light);
const GPUImage& getDrawImage() const;
@@ -101,6 +103,31 @@ public:
return renderLightHeatmap;
}
void setRenderSelectionView(bool selectionView)
{
renderSelectionView = selectionView;
}
bool getRenderSelectionView() const
{
return renderSelectionView;
}
void setSelectionPassEnabled(bool enabled)
{
selectionPassEnabled = enabled;
}
void requestSelectionPick(const glm::ivec2& pixel)
{
requestedPick = pixel;
}
[[nodiscard]] std::optional<std::uint32_t> takeSelectionPick()
{
return std::exchange(pickResult, std::nullopt);
}
void setShadowDistance(float distance)
{
shadowMapPipeline->setShadowDistance(distance);
@@ -126,6 +153,7 @@ public:
private:
void createDrawImage(GfxDevice& gfxDevice, const glm::ivec2& drawImageSize, bool firstCreate);
void uploadLights(const Camera& camera);
void recordSelectionPick(VkCommandBuffer cmd, std::uint32_t frameIndex);
[[nodiscard]] std::uint32_t assignShadowIndex(const Light& light, const Frustum& cameraFrustum);
RenderResources* resources = nullptr;
@@ -142,9 +170,18 @@ private:
VkFormat drawImageFormat{VK_FORMAT_R16G16B16A16_SFLOAT};
VkFormat depthImageFormat{VK_FORMAT_D32_SFLOAT};
VkFormat selectionImageFormat{VK_FORMAT_R32_UINT};
ImageID drawImageId{NULL_IMAGE_ID};
ImageID depthImageId{NULL_IMAGE_ID};
ImageID selectionImageId{NULL_IMAGE_ID};
std::array<GPUBuffer, FRAMES_IN_FLIGHT> pickBuffers{};
std::array<bool, FRAMES_IN_FLIGHT> pickPending{};
std::optional<glm::ivec2> requestedPick;
std::optional<std::uint32_t> pickResult;
bool selectionPassEnabled{false};
bool renderSelectionView{false};
VkSampleCountFlagBits samples{VK_SAMPLE_COUNT_1_BIT};
@@ -173,7 +210,7 @@ private:
std::uint32_t shadowMapId;
float shadowNormalOffset;
std::uint32_t padding;
std::uint32_t debugSelectionView;
glm::mat4 lightViewProj;
std::uint32_t spotShadowAtlasId;