From 4f9b62536278e65975b8a3267ddc506bc8f978ab Mon Sep 17 00:00:00 2001 From: Thomas Choquet Date: Sat, 7 Mar 2026 14:43:24 +0900 Subject: [PATCH 1/5] add suport for imgui texture id --- examples/imgui_usage/CMakeLists.txt | 17 ++++- examples/imgui_usage/imgui_usage.cpp | 70 ++++++++++++++++--- examples/imgui_usage/resources/MyImage01.jpg | Bin 0 -> 20123 bytes include/Graphics/CommandBuffer.hpp | 2 + include/Graphics/Texture.hpp | 12 ++++ src/Metal/MetalCommandBuffer.hpp | 2 + src/Metal/MetalCommandBuffer.mm | 7 ++ src/Metal/MetalTexture.hpp | 6 ++ src/Vulkan/VulkanCommandBuffer.cpp | 30 ++++++++ src/Vulkan/VulkanCommandBuffer.hpp | 4 ++ src/Vulkan/VulkanTexture.cpp | 25 +++++++ src/Vulkan/VulkanTexture.hpp | 10 +++ 12 files changed, 173 insertions(+), 12 deletions(-) create mode 100644 examples/imgui_usage/resources/MyImage01.jpg diff --git a/examples/imgui_usage/CMakeLists.txt b/examples/imgui_usage/CMakeLists.txt index 1edb4241..d3109c1e 100644 --- a/examples/imgui_usage/CMakeLists.txt +++ b/examples/imgui_usage/CMakeLists.txt @@ -53,6 +53,20 @@ if (imgui_SOURCE_DIR) set_target_properties(imgui PROPERTIES FOLDER "dependencies") endif() +## STB_IMAGE ############################################################### + +FetchContent_Declare(stb_image + GIT_REPOSITORY https://github.com/Thomas-Chqt/stb_image.git + GIT_TAG a09b799a2ba95c14f511493db4ea59811b2fcc97 + GIT_SHALLOW 1 + GIT_PROGRESS TRUE + FIND_PACKAGE_ARGS +) +FetchContent_MakeAvailable(stb_image) +if (stb_image_SOURCE_DIR) + set_target_properties(stb_image PROPERTIES FOLDER "dependencies") +endif() + ################################################################## add_executable(imgui_usage) @@ -86,9 +100,10 @@ target_include_directories(imgui_usage PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}") if(CMAKE_GENERATOR STREQUAL "Xcode") target_compile_definitions(imgui_usage PRIVATE "__XCODE__") endif() +target_compile_definitions(imgui_usage PRIVATE "RESOURCE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/resources\"") target_compile_definitions(imgui_usage PRIVATE "GLFW_INCLUDE_NONE") -target_link_libraries(imgui_usage PRIVATE Graphics imgui) +target_link_libraries(imgui_usage PRIVATE Graphics imgui stb_image) if(APPLE AND NOT CMAKE_GENERATOR STREQUAL "Xcode") set(CODESIGN_IDENTITY "-" CACHE STRING "Codesigning identity for imgui_usage") diff --git a/examples/imgui_usage/imgui_usage.cpp b/examples/imgui_usage/imgui_usage.cpp index 3a48db4b..11de12e7 100644 --- a/examples/imgui_usage/imgui_usage.cpp +++ b/examples/imgui_usage/imgui_usage.cpp @@ -12,13 +12,16 @@ #include "Graphics/Framebuffer.hpp" #include "Graphics/Instance.hpp" #include "Graphics/Device.hpp" +#include "Graphics/Sampler.hpp" #include "Graphics/Surface.hpp" #include "Graphics/Enums.hpp" #include "Graphics/Swapchain.hpp" -#include "imgui.h" +#include "Graphics/Texture.hpp" #include +#include #include +#include #include #include @@ -99,6 +102,41 @@ class Application m_commandBufferPools.at(i) = m_device->newCommandBufferPool(); } + int width = 0; + int height = 0; + stbi_uc* textureBytes = stbi_load(RESOURCE_DIR"/MyImage01.jpg", &width, &height, nullptr, STBI_rgb_alpha); + assert(textureBytes); + + m_texture = m_device->newTexture(gfx::Texture::Descriptor{ + .type = gfx::TextureType::texture2d, + .width = static_cast(width), + .height = static_cast(height), + .pixelFormat = gfx::PixelFormat::RGBA8Unorm, + .usages = gfx::TextureUsage::copyDestination | gfx::TextureUsage::shaderRead, + .storageMode = gfx::ResourceStorageMode::deviceLocal + }); + assert(m_texture); + + std::shared_ptr stagingBuffer = m_device->newBuffer(gfx::Buffer::Descriptor{ + .size = static_cast(width) * static_cast(height) * pixelFormatSize(gfx::PixelFormat::RGBA8Unorm), + .usages = gfx::BufferUsage::copySource, + .storageMode = gfx::ResourceStorageMode::hostVisible + }); + assert(stagingBuffer); + + auto* bufferData = stagingBuffer->content(); + std::memcpy(bufferData, textureBytes, stagingBuffer->size()); + + stbi_image_free(textureBytes); + + std::shared_ptr commandBuffer = m_commandBufferPools.at(m_frameIdx)->get(); + commandBuffer->beginBlitPass(); + { + commandBuffer->copyBufferToTexture(stagingBuffer, 0, m_texture, 0); + } + commandBuffer->endBlitPass(); + m_device->submitCommandBuffers(commandBuffer); + ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); @@ -116,6 +154,8 @@ class Application } m_device->imguiInit({gfx::PixelFormat::BGRA8Unorm}); + + m_texture->initImTextureId(m_device->newSampler(gfx::Sampler::Descriptor{})); } void loop() @@ -144,16 +184,19 @@ class Application if (m_lastCommandBuffers.at(m_frameIdx) != nullptr) { m_device->waitCommandBuffer(*m_lastCommandBuffers.at(m_frameIdx)); - m_lastCommandBuffers.at(m_frameIdx).reset(); m_commandBufferPools.at(m_frameIdx)->reset(); } m_device->imguiNewFrame(); ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); { - static bool showDemoWindow = true; - ImGui::ShowDemoWindow(&showDemoWindow); + ImGui::ShowDemoWindow(); + + ImGui::Begin("texture"); + ImGui::Image(*m_texture->imTextureId(), ImVec2((float)m_texture->width(), (float)m_texture->height())); + ImGui::End(); } ImGui::Render(); @@ -177,19 +220,17 @@ class Application commandBuffer->beginRenderPass(framebuffer); { + commandBuffer->addSampledTexture(m_texture); commandBuffer->imGuiRenderDrawData(ImGui::GetDrawData()); } commandBuffer->endRenderPass(); commandBuffer->presentDrawable(drawable); - m_lastCommandBuffers.at(m_frameIdx) = commandBuffer; m_device->submitCommandBuffers(commandBuffer); + m_lastCommandBuffers.at(m_frameIdx) = commandBuffer.get(); - if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable) - { - ImGui::UpdatePlatformWindows(); - ImGui::RenderPlatformWindowsDefault(); - } + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); m_frameIdx = (m_frameIdx + 1) % maxFrameInFlight; } @@ -197,8 +238,13 @@ class Application void clean() { + m_texture.reset(); + m_device->waitIdle(); + for (auto& pool : m_commandBufferPools) + pool->reset(); m_device->imguiShutdown(); + ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext(); glfwDestroyWindow(m_window); @@ -212,9 +258,11 @@ class Application std::unique_ptr m_device; std::unique_ptr m_swapchain; + std::shared_ptr m_texture; + uint8_t m_frameIdx = 0; std::array, maxFrameInFlight> m_commandBufferPools; - std::array, maxFrameInFlight> m_lastCommandBuffers = {}; + std::array m_lastCommandBuffers = {}; }; int main() diff --git a/examples/imgui_usage/resources/MyImage01.jpg b/examples/imgui_usage/resources/MyImage01.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ac02db2c233c5bbadfac75361443426a17f48b71 GIT binary patch literal 20123 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 z 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 YpaFmh!Qh&DDQt{#d8xgPBL>g^*$(e%lK=n! literal 0 HcmV?d00001 diff --git a/include/Graphics/CommandBuffer.hpp b/include/Graphics/CommandBuffer.hpp index c91dbcc0..d977af3c 100644 --- a/include/Graphics/CommandBuffer.hpp +++ b/include/Graphics/CommandBuffer.hpp @@ -62,6 +62,8 @@ class CommandBuffer virtual void presentDrawable(const std::shared_ptr&) = 0; + virtual void addSampledTexture(const std::shared_ptr&) = 0; // for imgui + virtual ~CommandBuffer() = default; protected: diff --git a/include/Graphics/Texture.hpp b/include/Graphics/Texture.hpp index ce9c070e..c2209409 100644 --- a/include/Graphics/Texture.hpp +++ b/include/Graphics/Texture.hpp @@ -11,8 +11,15 @@ #define TEXTURE_HPP #include "Graphics/Enums.hpp" +#include "Graphics/Sampler.hpp" #include +#include +#include + +#if defined (GFX_IMGUI_ENABLED) +using ImTextureID = uint64_t; +#endif namespace gfx { @@ -41,6 +48,11 @@ class Texture virtual TextureUsages usages() const = 0; virtual ResourceStorageMode storageMode() const = 0; +#if defined (GFX_IMGUI_ENABLED) + virtual void initImTextureId(const std::shared_ptr&) = 0; + virtual std::optional imTextureId() const = 0; +#endif + virtual ~Texture() = default; protected: diff --git a/src/Metal/MetalCommandBuffer.hpp b/src/Metal/MetalCommandBuffer.hpp index 901d1990..7ff01db7 100644 --- a/src/Metal/MetalCommandBuffer.hpp +++ b/src/Metal/MetalCommandBuffer.hpp @@ -68,6 +68,8 @@ class MetalCommandBuffer : public CommandBuffer void presentDrawable(const std::shared_ptr&) override; + void addSampledTexture(const std::shared_ptr&) override; + inline id mtlCommandBuffer() const { return m_mtlCommandBuffer; } inline id commandEncoder() const { return m_commandEncoder; } diff --git a/src/Metal/MetalCommandBuffer.mm b/src/Metal/MetalCommandBuffer.mm index f2cab9b5..4a8729d1 100644 --- a/src/Metal/MetalCommandBuffer.mm +++ b/src/Metal/MetalCommandBuffer.mm @@ -19,6 +19,7 @@ #include "Metal/MetalBuffer.hpp" #include "Metal/MetalSampler.hpp" #include "Metal/MetalTexture.hpp" +#include #if defined(GFX_IMGUI_ENABLED) # include "Metal/imgui_impl_metal.h" #endif @@ -267,6 +268,12 @@ [m_mtlCommandBuffer presentDrawable:drawable->mtlDrawable()]; }} +void MetalCommandBuffer::addSampledTexture(const std::shared_ptr& aTexture) +{ + auto texture = std::dynamic_pointer_cast(aTexture); + m_usedTextures.insert(texture); +} + MetalCommandBuffer& MetalCommandBuffer::operator = (MetalCommandBuffer&& other) noexcept { @autoreleasepool { if (this != &other) diff --git a/src/Metal/MetalTexture.hpp b/src/Metal/MetalTexture.hpp index 27c85221..81fb1df8 100644 --- a/src/Metal/MetalTexture.hpp +++ b/src/Metal/MetalTexture.hpp @@ -14,6 +14,7 @@ #include "Graphics/Texture.hpp" #include "Metal/MetalBuffer.hpp" +#include #if !defined(__OBJC__) #error this file can only by used in objective c @@ -41,6 +42,11 @@ class MetalTexture : public Texture inline TextureUsages usages() const override { return m_usages; }; inline ResourceStorageMode storageMode() const override { return m_storageMode; }; +#if defined (GFX_IMGUI_ENABLED) + inline void initImTextureId(const std::shared_ptr&) override {} // no-op + inline std::optional imTextureId() const override { return std::bit_cast((__bridge void*)m_mtlTexture); } +#endif + inline id mtltexture() const { return m_mtlTexture; } inline void setMtlTexture(const id& t) { m_mtlTexture = t; } diff --git a/src/Vulkan/VulkanCommandBuffer.cpp b/src/Vulkan/VulkanCommandBuffer.cpp index 2fa236cf..d3222b9d 100644 --- a/src/Vulkan/VulkanCommandBuffer.cpp +++ b/src/Vulkan/VulkanCommandBuffer.cpp @@ -20,6 +20,7 @@ #include "Vulkan/VulkanSampler.hpp" #include "Vulkan/VulkanTexture.hpp" #include "Vulkan/VulkanEnums.hpp" +#include #if defined(GFX_IMGUI_ENABLED) # include "Vulkan/imgui_impl_vulkan.h" #endif @@ -539,4 +540,33 @@ void VulkanCommandBuffer::presentDrawable(const std::shared_ptr& aDraw m_presentedDrawables.insert(drawable); } +void VulkanCommandBuffer::addSampledTexture(const std::shared_ptr& aTexture) +{ + auto texture = std::dynamic_pointer_cast(aTexture); + std::vector imageMemoryBarriers; + + ImageSyncRequest syncReq{}; + syncReq.stageMask = vk::PipelineStageFlagBits2::eFragmentShader; + syncReq.accessMask = vk::AccessFlagBits2::eShaderRead; + syncReq.layout = vk::ImageLayout::eShaderReadOnlyOptimal; + syncReq.preserveContent = true; + + auto it = m_imageFinalSyncStates.find(texture); + if (it != m_imageFinalSyncStates.end()) { + auto barrier = syncImage(it->second, syncReq); // will update the final sync state + if (barrier.has_value()) { + barrier->setImage(texture->vkImage()); + barrier->setSubresourceRange(texture->subresourceRange()); + imageMemoryBarriers.push_back(*barrier); + } + } else { + auto [it1, res1] = m_imageSyncRequests.insert(std::make_pair(texture, syncReq)); + assert(res1); + (void)res1; + auto [it2, res2] = m_imageFinalSyncStates.insert(std::make_pair(texture, imageStateAfterSync(syncReq))); + assert(res2); + (void)res2; + } +} + } diff --git a/src/Vulkan/VulkanCommandBuffer.hpp b/src/Vulkan/VulkanCommandBuffer.hpp index 8dbcc3c8..4a122d70 100644 --- a/src/Vulkan/VulkanCommandBuffer.hpp +++ b/src/Vulkan/VulkanCommandBuffer.hpp @@ -16,12 +16,14 @@ #include "Graphics/Buffer.hpp" #include "Graphics/ParameterBlock.hpp" +#include "Graphics/Texture.hpp" #include "Vulkan/VulkanBuffer.hpp" #include "Vulkan/VulkanGraphicsPipeline.hpp" #include "Vulkan/VulkanSampler.hpp" #include "Vulkan/VulkanTexture.hpp" #include "Vulkan/VulkanDrawable.hpp" #include "Vulkan/VulkanParameterBlock.hpp" +#include namespace gfx { @@ -64,6 +66,8 @@ class VulkanCommandBuffer : public CommandBuffer void presentDrawable(const std::shared_ptr&) override; + void addSampledTexture(const std::shared_ptr&) override; // for imgui + const vk::CommandBuffer& vkCommandBuffer() const { return m_vkCommandBuffer; } diff --git a/src/Vulkan/VulkanTexture.cpp b/src/Vulkan/VulkanTexture.cpp index c06fc5a9..ecd63669 100644 --- a/src/Vulkan/VulkanTexture.cpp +++ b/src/Vulkan/VulkanTexture.cpp @@ -9,8 +9,18 @@ #include "Vulkan/VulkanTexture.hpp" #include "Graphics/Enums.hpp" +#include "Graphics/Texture.hpp" #include "Vulkan/VulkanDevice.hpp" #include "Vulkan/VulkanEnums.hpp" +#include "Vulkan/VulkanSampler.hpp" + +#include +#include +#include + +#if defined (GFX_IMGUI_ENABLED) +#include "imgui_impl_vulkan.h" +#endif namespace gfx { @@ -98,8 +108,23 @@ VulkanTexture::VulkanTexture(const VulkanDevice* device, const Texture::Descript m_vkImageView = m_device->vkDevice().createImageView(imageViewCreateInfo); } +#if defined (GFX_IMGUI_ENABLED) +void VulkanTexture::initImTextureId(const std::shared_ptr& sampler) +{ + auto vulkanSampler = std::dynamic_pointer_cast(sampler); + assert(vulkanSampler); + + m_imTextureIdSampler = vulkanSampler; + if (m_imTextureId.has_value()) + ImGui_ImplVulkan_RemoveTexture(std::bit_cast(*m_imTextureId)); + m_imTextureId = std::bit_cast(ImGui_ImplVulkan_AddTexture(m_imTextureIdSampler->vkSampler(), m_vkImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)); +} +#endif + VulkanTexture::~VulkanTexture() { + if (m_imTextureId.has_value()) + ImGui_ImplVulkan_RemoveTexture(std::bit_cast(*m_imTextureId)); m_device->vkDevice().destroyImageView(m_vkImageView); if (m_allocation != VK_NULL_HANDLE) vmaDestroyImage(m_device->allocator(), m_vkImage, m_allocation); diff --git a/src/Vulkan/VulkanTexture.hpp b/src/Vulkan/VulkanTexture.hpp index a1a2d142..ab842ad5 100644 --- a/src/Vulkan/VulkanTexture.hpp +++ b/src/Vulkan/VulkanTexture.hpp @@ -12,8 +12,10 @@ #include "Graphics/Texture.hpp" #include "Graphics/Enums.hpp" +#include "Graphics/Sampler.hpp" #include "Vulkan/Sync.hpp" +#include "Vulkan/VulkanSampler.hpp" namespace gfx { @@ -37,6 +39,11 @@ class VulkanTexture : public Texture inline TextureUsages usages() const override { return m_usages; }; inline ResourceStorageMode storageMode() const override { return m_storageMode; }; +#if defined (GFX_IMGUI_ENABLED) + void initImTextureId(const std::shared_ptr&) override; + inline std::optional imTextureId() const override { return m_imTextureId; } +#endif + inline const vk::Image& vkImage() const { return m_vkImage; } inline const vk::ImageSubresourceRange& subresourceRange() const { return m_subresourceRange; } @@ -63,6 +70,9 @@ class VulkanTexture : public Texture ImageSyncState m_syncState; + std::optional m_imTextureId; + std::shared_ptr m_imTextureIdSampler; + public: VulkanTexture& operator=(const VulkanTexture&) = delete; VulkanTexture& operator=(VulkanTexture&&) = delete; From 7f12cb778f2ac5235de090c33362ff28e5161809 Mon Sep 17 00:00:00 2001 From: Thomas Choquet Date: Sat, 7 Mar 2026 14:54:23 +0900 Subject: [PATCH 2/5] fix build without imgui --- src/Vulkan/VulkanTexture.cpp | 2 ++ src/Vulkan/VulkanTexture.hpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/Vulkan/VulkanTexture.cpp b/src/Vulkan/VulkanTexture.cpp index ecd63669..ce5febf0 100644 --- a/src/Vulkan/VulkanTexture.cpp +++ b/src/Vulkan/VulkanTexture.cpp @@ -123,8 +123,10 @@ void VulkanTexture::initImTextureId(const std::shared_ptr& sampler) VulkanTexture::~VulkanTexture() { +#if defined (GFX_IMGUI_ENABLED) if (m_imTextureId.has_value()) ImGui_ImplVulkan_RemoveTexture(std::bit_cast(*m_imTextureId)); +#endif m_device->vkDevice().destroyImageView(m_vkImageView); if (m_allocation != VK_NULL_HANDLE) vmaDestroyImage(m_device->allocator(), m_vkImage, m_allocation); diff --git a/src/Vulkan/VulkanTexture.hpp b/src/Vulkan/VulkanTexture.hpp index ab842ad5..c0734035 100644 --- a/src/Vulkan/VulkanTexture.hpp +++ b/src/Vulkan/VulkanTexture.hpp @@ -70,7 +70,9 @@ class VulkanTexture : public Texture ImageSyncState m_syncState; +#if defined (GFX_IMGUI_ENABLED) std::optional m_imTextureId; +#endif std::shared_ptr m_imTextureIdSampler; public: From fa99b120602c3c71428bf7b79beeb92be46a4296 Mon Sep 17 00:00:00 2001 From: Thomas Choquet Date: Sat, 7 Mar 2026 15:01:52 +0900 Subject: [PATCH 3/5] use uint64 for imgui texture id --- include/Graphics/Texture.hpp | 6 +----- src/Metal/MetalTexture.hpp | 2 +- src/Vulkan/VulkanTexture.cpp | 2 +- src/Vulkan/VulkanTexture.hpp | 5 +++-- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/include/Graphics/Texture.hpp b/include/Graphics/Texture.hpp index c2209409..11101619 100644 --- a/include/Graphics/Texture.hpp +++ b/include/Graphics/Texture.hpp @@ -17,10 +17,6 @@ #include #include -#if defined (GFX_IMGUI_ENABLED) -using ImTextureID = uint64_t; -#endif - namespace gfx { @@ -50,7 +46,7 @@ class Texture #if defined (GFX_IMGUI_ENABLED) virtual void initImTextureId(const std::shared_ptr&) = 0; - virtual std::optional imTextureId() const = 0; + virtual std::optional imTextureId() const = 0; #endif virtual ~Texture() = default; diff --git a/src/Metal/MetalTexture.hpp b/src/Metal/MetalTexture.hpp index 81fb1df8..6884fe13 100644 --- a/src/Metal/MetalTexture.hpp +++ b/src/Metal/MetalTexture.hpp @@ -44,7 +44,7 @@ class MetalTexture : public Texture #if defined (GFX_IMGUI_ENABLED) inline void initImTextureId(const std::shared_ptr&) override {} // no-op - inline std::optional imTextureId() const override { return std::bit_cast((__bridge void*)m_mtlTexture); } + inline std::optional imTextureId() const override { return std::bit_cast((__bridge void*)m_mtlTexture); } #endif inline id mtltexture() const { return m_mtlTexture; } diff --git a/src/Vulkan/VulkanTexture.cpp b/src/Vulkan/VulkanTexture.cpp index ce5febf0..b0bb051c 100644 --- a/src/Vulkan/VulkanTexture.cpp +++ b/src/Vulkan/VulkanTexture.cpp @@ -117,7 +117,7 @@ void VulkanTexture::initImTextureId(const std::shared_ptr& sampler) m_imTextureIdSampler = vulkanSampler; if (m_imTextureId.has_value()) ImGui_ImplVulkan_RemoveTexture(std::bit_cast(*m_imTextureId)); - m_imTextureId = std::bit_cast(ImGui_ImplVulkan_AddTexture(m_imTextureIdSampler->vkSampler(), m_vkImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)); + m_imTextureId = std::bit_cast(ImGui_ImplVulkan_AddTexture(m_imTextureIdSampler->vkSampler(), m_vkImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)); } #endif diff --git a/src/Vulkan/VulkanTexture.hpp b/src/Vulkan/VulkanTexture.hpp index c0734035..defaa032 100644 --- a/src/Vulkan/VulkanTexture.hpp +++ b/src/Vulkan/VulkanTexture.hpp @@ -16,6 +16,7 @@ #include "Vulkan/Sync.hpp" #include "Vulkan/VulkanSampler.hpp" +#include namespace gfx { @@ -41,7 +42,7 @@ class VulkanTexture : public Texture #if defined (GFX_IMGUI_ENABLED) void initImTextureId(const std::shared_ptr&) override; - inline std::optional imTextureId() const override { return m_imTextureId; } + inline std::optional imTextureId() const override { return m_imTextureId; } #endif inline const vk::Image& vkImage() const { return m_vkImage; } @@ -71,7 +72,7 @@ class VulkanTexture : public Texture ImageSyncState m_syncState; #if defined (GFX_IMGUI_ENABLED) - std::optional m_imTextureId; + std::optional m_imTextureId; #endif std::shared_ptr m_imTextureIdSampler; From 3d87c671bd1d59417dd3633200a69644460f1616 Mon Sep 17 00:00:00 2001 From: Thomas Choquet Date: Sat, 7 Mar 2026 15:10:10 +0900 Subject: [PATCH 4/5] include cstring in imgui_usage.cpp --- examples/imgui_usage/imgui_usage.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/imgui_usage/imgui_usage.cpp b/examples/imgui_usage/imgui_usage.cpp index 11de12e7..b6f6d249 100644 --- a/examples/imgui_usage/imgui_usage.cpp +++ b/examples/imgui_usage/imgui_usage.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #if __XCODE__ #include From 6db8727f2b3c86f4cf30409bd26036284bdffffb Mon Sep 17 00:00:00 2001 From: Thomas Choquet Date: Sat, 7 Mar 2026 15:47:53 +0900 Subject: [PATCH 5/5] automatically create sampler for imgui texture id --- examples/imgui_usage/imgui_usage.cpp | 4 ++-- include/Graphics/Texture.hpp | 4 +--- src/Metal/MetalTexture.hpp | 3 +-- src/Vulkan/VulkanTexture.cpp | 10 ++++------ src/Vulkan/VulkanTexture.hpp | 3 +-- 5 files changed, 9 insertions(+), 15 deletions(-) diff --git a/examples/imgui_usage/imgui_usage.cpp b/examples/imgui_usage/imgui_usage.cpp index b6f6d249..36facbed 100644 --- a/examples/imgui_usage/imgui_usage.cpp +++ b/examples/imgui_usage/imgui_usage.cpp @@ -12,7 +12,6 @@ #include "Graphics/Framebuffer.hpp" #include "Graphics/Instance.hpp" #include "Graphics/Device.hpp" -#include "Graphics/Sampler.hpp" #include "Graphics/Surface.hpp" #include "Graphics/Enums.hpp" #include "Graphics/Swapchain.hpp" @@ -156,7 +155,6 @@ class Application m_device->imguiInit({gfx::PixelFormat::BGRA8Unorm}); - m_texture->initImTextureId(m_device->newSampler(gfx::Sampler::Descriptor{})); } void loop() @@ -196,6 +194,8 @@ class Application ImGui::ShowDemoWindow(); ImGui::Begin("texture"); + if (m_texture->imTextureId().has_value() == false) + m_texture->initImTextureId(); ImGui::Image(*m_texture->imTextureId(), ImVec2((float)m_texture->width(), (float)m_texture->height())); ImGui::End(); } diff --git a/include/Graphics/Texture.hpp b/include/Graphics/Texture.hpp index 11101619..5145d1fe 100644 --- a/include/Graphics/Texture.hpp +++ b/include/Graphics/Texture.hpp @@ -11,10 +11,8 @@ #define TEXTURE_HPP #include "Graphics/Enums.hpp" -#include "Graphics/Sampler.hpp" #include -#include #include namespace gfx @@ -45,7 +43,7 @@ class Texture virtual ResourceStorageMode storageMode() const = 0; #if defined (GFX_IMGUI_ENABLED) - virtual void initImTextureId(const std::shared_ptr&) = 0; + virtual void initImTextureId() = 0; virtual std::optional imTextureId() const = 0; #endif diff --git a/src/Metal/MetalTexture.hpp b/src/Metal/MetalTexture.hpp index 6884fe13..342578c7 100644 --- a/src/Metal/MetalTexture.hpp +++ b/src/Metal/MetalTexture.hpp @@ -14,7 +14,6 @@ #include "Graphics/Texture.hpp" #include "Metal/MetalBuffer.hpp" -#include #if !defined(__OBJC__) #error this file can only by used in objective c @@ -43,7 +42,7 @@ class MetalTexture : public Texture inline ResourceStorageMode storageMode() const override { return m_storageMode; }; #if defined (GFX_IMGUI_ENABLED) - inline void initImTextureId(const std::shared_ptr&) override {} // no-op + inline void initImTextureId() override {} // no-op inline std::optional imTextureId() const override { return std::bit_cast((__bridge void*)m_mtlTexture); } #endif diff --git a/src/Vulkan/VulkanTexture.cpp b/src/Vulkan/VulkanTexture.cpp index b0bb051c..b6f42a46 100644 --- a/src/Vulkan/VulkanTexture.cpp +++ b/src/Vulkan/VulkanTexture.cpp @@ -9,15 +9,12 @@ #include "Vulkan/VulkanTexture.hpp" #include "Graphics/Enums.hpp" +#include "Graphics/Sampler.hpp" #include "Graphics/Texture.hpp" #include "Vulkan/VulkanDevice.hpp" #include "Vulkan/VulkanEnums.hpp" #include "Vulkan/VulkanSampler.hpp" -#include -#include -#include - #if defined (GFX_IMGUI_ENABLED) #include "imgui_impl_vulkan.h" #endif @@ -109,9 +106,10 @@ VulkanTexture::VulkanTexture(const VulkanDevice* device, const Texture::Descript } #if defined (GFX_IMGUI_ENABLED) -void VulkanTexture::initImTextureId(const std::shared_ptr& sampler) +void VulkanTexture::initImTextureId() { - auto vulkanSampler = std::dynamic_pointer_cast(sampler); + std::shared_ptr aSampler = m_device->newSampler(Sampler::Descriptor{}); + auto vulkanSampler = std::dynamic_pointer_cast(aSampler); assert(vulkanSampler); m_imTextureIdSampler = vulkanSampler; diff --git a/src/Vulkan/VulkanTexture.hpp b/src/Vulkan/VulkanTexture.hpp index defaa032..080b446d 100644 --- a/src/Vulkan/VulkanTexture.hpp +++ b/src/Vulkan/VulkanTexture.hpp @@ -16,7 +16,6 @@ #include "Vulkan/Sync.hpp" #include "Vulkan/VulkanSampler.hpp" -#include namespace gfx { @@ -41,7 +40,7 @@ class VulkanTexture : public Texture inline ResourceStorageMode storageMode() const override { return m_storageMode; }; #if defined (GFX_IMGUI_ENABLED) - void initImTextureId(const std::shared_ptr&) override; + void initImTextureId() override; inline std::optional imTextureId() const override { return m_imTextureId; } #endif