feat: add imgui texture inspector (Thanks claude)

This commit is contained in:
2026-10-11 01:34:49 +02:00
parent 95d1497169
commit 170af2a4e9
18 changed files with 692 additions and 18 deletions
+15
View File
@@ -11,6 +11,7 @@
#include <destrum/Graphics/GfxDevice.h>
#include <destrum/Graphics/Renderer.h>
#include <destrum/Graphics/Pipelines/ImguiPass.h>
#include <destrum/Graphics/ResourcesInspector.h>
#include <destrum/Input/InputManager.h>
@@ -41,6 +42,9 @@ public:
virtual void onWindowResize(int, int) {};
// Called inside the "Windows" menu of the main menu bar, add toggles for the game's own windows here
virtual void customWindowsMenu() {}
protected:
SDL_Window* window{nullptr};
AppParams m_params{};
@@ -72,6 +76,17 @@ protected:
float m_PhysicsTimeScale = 1.0f;
int m_PhysicsStepsLastFrame = 0;
struct DebugWindows {
bool stats{true};
bool physics{true};
bool inspector{true};
bool imageCache{false};
};
DebugWindows m_DebugWindows{};
ResourcesInspector m_ResourcesInspector;
void drawWindowsMenu();
void drawPhysicsPanel(float dt, float fixedDt, float accumulator);
};
@@ -1,8 +1,15 @@
#ifndef DESTRUM_IMGUI_PASS_H
#define DESTRUM_IMGUI_PASS_H
#include <array>
#include <utility>
#include <vector>
#include <vulkan/vulkan.h>
#include <SDL.h>
#include <imgui.h>
#include <destrum/Graphics/Swapchain.h>
class GfxDevice;
@@ -33,9 +40,19 @@ public:
[[nodiscard]] bool wantsMouse() const;
[[nodiscard]] bool wantsKeyboard() const;
// Wraps an image view for ImGui::Image in the frame that's being built. Call it every frame
// you draw the image, the descriptor set is freed again once the GPU is done with that frame.
// The image has to be in imageLayout by the time the UI gets rendered at the end of the frame.
[[nodiscard]] ImTextureID getFrameTexture(
VkImageView imageView,
VkImageLayout imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
private:
void initVulkanBackend();
void releaseTextures(std::vector<VkDescriptorSet>& textures);
void releaseAllTextures();
void transitionToColorAttachment(
VkCommandBuffer cmd,
VkImage image,
@@ -50,6 +67,17 @@ private:
VkDescriptorPool descriptorPool = VK_NULL_HANDLE;
VkFormat colorFormat = VK_FORMAT_UNDEFINED;
struct FrameTexture {
VkImageView imageView{VK_NULL_HANDLE};
VkImageLayout imageLayout{VK_IMAGE_LAYOUT_UNDEFINED};
VkDescriptorSet descriptorSet{VK_NULL_HANDLE};
};
// created while building the current UI, not submitted yet
std::vector<FrameTexture> pendingTextures;
// submitted with a frame, freed once that frame's fence has been waited on
std::array<std::vector<VkDescriptorSet>, FRAMES_IN_FLIGHT> inFlightTextures;
bool initialized = false;
bool frameBegun = false;
bool contextCreated = false;
@@ -53,6 +53,7 @@ public:
[[nodiscard]] ImageID getWhiteTextureID() const { return whiteImageId; }
[[nodiscard]] ImageID getErrorTextureID() const { return errorImageId; }
[[nodiscard]] ImageID getDefaultNormalTextureID() const { return defaultNormalImageId; }
BindlessSetManager& getBindlessSetManager();
VkDescriptorSetLayout getBindlessDescSetLayout() const;
@@ -62,6 +63,10 @@ public:
VkPipelineLayout layout,
VkPipelineBindPoint bindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS) const;
[[nodiscard]] bool isInitialized() const { return imageCache != nullptr && materialCache != nullptr; }
const ImageCache& images() const { return *imageCache; }
MeshCache& meshes() { return *meshCache; }
const MeshCache& meshes() const { return *meshCache; }
@@ -0,0 +1,35 @@
#ifndef RESOURCESINSPECTOR_H
#define RESOURCESINSPECTOR_H
#include <destrum/Graphics/ids.h>
struct GPUImage;
class ImguiPass;
class RenderResources;
// ImGui windows for looking into the render resource caches
class ResourcesInspector final
{
public:
void drawImageCacheWindow(bool* open, const RenderResources& resources, ImguiPass& imguiPass);
private:
struct PreviewInfo
{
bool previewable{false};
const char* reason{""};
};
[[nodiscard]] static PreviewInfo getPreviewInfo(const GPUImage& image);
void drawImagePreview(const GPUImage& image, float maxSize, ImguiPass& imguiPass) const;
void drawImageDetails(ImageID id, const RenderResources& resources) const;
[[nodiscard]] bool matchesFilter(ImageID id, const RenderResources& resources) const;
char filter[128]{};
float thumbnailSize{48.0f};
bool onlyPreviewable{false};
ImageID selectedImageId{NULL_IMAGE_ID};
};
#endif //RESOURCESINSPECTOR_H
+1 -1
View File
@@ -33,7 +33,7 @@ public:
void FixedUpdate(float dt);
void LateUpdate(float dt);
void Render(const RenderContext& ctx);
void RenderImgui();
void RenderImgui(bool* open = nullptr);
void CleanupDestroyedGameObjects();
void Unload();
+1 -1
View File
@@ -23,7 +23,7 @@ public:
void LateUpdate(float dt);
void Render(const RenderContext& ctx);
void RenderImgui();
void RenderImgui(bool* open = nullptr);
void HandleGameObjectDestroy();
void DestroyGameObjects();
+2 -1
View File
@@ -21,7 +21,8 @@ namespace ImGuiUtils {
std::string_view sceneName,
const std::vector<std::shared_ptr<GameObject>>& objects,
const std::vector<std::shared_ptr<GameObject>>& pendingAdditions,
ObjectId& selectedObjectId);
ObjectId& selectedObjectId,
bool* open = nullptr);
}
#endif // DESTRUM_IMGUIUTILS_H