From 3b851b0c6a80eb0afc8d67863ea5f2b50f2ec1c8 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Tue, 17 Sep 2024 09:45:56 +0200 Subject: [PATCH] Publish GlTexture in the API --- src/immvision/gl_texture.h | 49 +++++++ src/immvision/immvision.h | 1 + src/immvision/internal/cv/colormap.cpp | 16 +-- .../internal/drawing/image_drawing.cpp | 4 +- .../internal/drawing/image_drawing.h | 4 +- .../internal/drawing/internal_icons.cpp | 8 +- src/immvision/internal/gl/gl_texture.cpp | 30 +++-- src/immvision/internal/gl/gl_texture.h | 34 ----- src/immvision/internal/image.cpp | 2 +- src/immvision/internal/image_cache.cpp | 4 +- src/immvision/internal/image_cache.h | 4 +- .../internal/imgui/image_widgets.cpp | 8 +- src/immvision/internal/imgui/image_widgets.h | 4 +- src/immvision/internal/inspector.cpp | 4 +- src_all_in_one/immvision/immvision.cpp | 127 ++++++++++-------- src_all_in_one/immvision/immvision.h | 55 +++++++- 16 files changed, 221 insertions(+), 133 deletions(-) create mode 100644 src/immvision/gl_texture.h delete mode 100644 src/immvision/internal/gl/gl_texture.h diff --git a/src/immvision/gl_texture.h b/src/immvision/gl_texture.h new file mode 100644 index 0000000..7f973e6 --- /dev/null +++ b/src/immvision/gl_texture.h @@ -0,0 +1,49 @@ +#pragma once +#include "imgui.h" +#include + + +namespace ImmVision +{ + // GlTexture contains an OpenGL texture which can be created or updated from a cv::Mat (C++), or numpy array (Python) + struct GlTexture + { + // + // Constructors + // + + // Create an empty texture + GlTexture(); + // Create a texture from an image (cv::Mat in C++, numpy array in Python) + GlTexture(const cv::Mat& image, bool isColorOrderBGR); + // The destructor will delete the texture from the GPU + ~GlTexture(); + + // GlTextureCv is non copiable (since it holds a reference to a texture stored on the GPU), + // but it is movable. + GlTexture(const GlTexture& ) = delete; + GlTexture& operator=(const GlTexture& ) = delete; + GlTexture(GlTexture&& other) noexcept = default; + GlTexture& operator=(GlTexture&& other) noexcept = default; + + + // + // Methods + // + + // Update the texture from a new image (cv::Mat in C++, numpy array in Python). + void UpdateFromImage(const cv::Mat& image, bool isColorOrderBGR); + // Returns the size as ImVec2 + ImVec2 SizeImVec2() const; + + + // + // Members + // + + // OpenGL texture ID on the GPU + ImTextureID TextureId; + // Image size in pixels + cv::Size Size; + }; +} // namespace ImmVision diff --git a/src/immvision/immvision.h b/src/immvision/immvision.h index 61b50ff..5c9be95 100644 --- a/src/immvision/immvision.h +++ b/src/immvision/immvision.h @@ -1,2 +1,3 @@ #include "immvision/image.h" #include "immvision/inspector.h" +#include "immvision/gl_texture.h" diff --git a/src/immvision/internal/cv/colormap.cpp b/src/immvision/internal/cv/colormap.cpp index 6e208cd..2ce15ec 100644 --- a/src/immvision/internal/cv/colormap.cpp +++ b/src/immvision/internal/cv/colormap.cpp @@ -4,7 +4,7 @@ #include "immvision/internal/misc/tinycolormap.hpp" #include "immvision/internal/misc/magic_enum.hpp" #include "immvision/internal/misc/math_utils.h" -#include "immvision/internal/gl/gl_texture.h" +#include "immvision/gl_texture.h" #include "immvision/imgui_imm.h" #include "imgui.h" #include "imgui_internal.h" @@ -23,18 +23,18 @@ namespace ImmVision { ImVec2 size_(size); if (size.x == 0.f) - size_ = texture.mImageSize; - ImGui::Image(texture.mImTextureId, size_); + size_ = texture.SizeImVec2(); + ImGui::Image(texture.TextureId, size_); } bool GlTexture_DrawButton(const GlTexture& texture, const ImVec2& size) { ImVec2 size_(size); if (size.x == 0.f) - size_ = texture.mImageSize; + size_ = texture.SizeImVec2(); char id[64]; snprintf(id, 64, "##%p", &texture); - return ImGui::ImageButton(id, texture.mImTextureId, size_); + return ImGui::ImageButton(id, texture.TextureId, size_); } } @@ -143,7 +143,7 @@ namespace ImmVision } - static insertion_order_map> sColormapsTexturesCache; + static insertion_order_map> sColormapsTexturesCache; void FillTextureCache() @@ -154,7 +154,7 @@ namespace ImmVision for (const auto& k: images.insertion_order_keys()) { cv::Mat& m = images.get(k); - auto texture = std::make_unique(m, true); + auto texture = std::make_unique(m, true); sColormapsTexturesCache.insert(k, std::move(texture)); } } @@ -169,7 +169,7 @@ namespace ImmVision if (cache.empty()) { for (const auto& k: sColormapsTexturesCache.insertion_order_keys()) - cache.insert(k, sColormapsTexturesCache.get(k)->mImTextureId); + cache.insert(k, sColormapsTexturesCache.get(k)->TextureId); } return cache; } diff --git a/src/immvision/internal/drawing/image_drawing.cpp b/src/immvision/internal/drawing/image_drawing.cpp index adf33f2..29febcb 100644 --- a/src/immvision/internal/drawing/image_drawing.cpp +++ b/src/immvision/internal/drawing/image_drawing.cpp @@ -164,7 +164,7 @@ namespace ImmVision const cv::Mat& image, cv::Mat& in_out_rgba_image_cache, bool shall_refresh_rgba, - GlTextureCv* outTexture + GlTexture* outTexture ) { if (image.empty()) @@ -301,7 +301,7 @@ namespace ImmVision // // Blit // - outTexture->BlitMat(finalImage, false); + outTexture->UpdateFromImage(finalImage, false); } bool HasColormapParam(const ImageParams ¶ms) diff --git a/src/immvision/internal/drawing/image_drawing.h b/src/immvision/internal/drawing/image_drawing.h index 6dd42a2..403eab3 100644 --- a/src/immvision/internal/drawing/image_drawing.h +++ b/src/immvision/internal/drawing/image_drawing.h @@ -1,6 +1,6 @@ #pragma once #include "immvision/image.h" -#include "immvision/internal/gl/gl_texture.h" +#include "immvision/gl_texture.h" #include namespace ImmVision @@ -21,7 +21,7 @@ namespace ImmVision const cv::Mat& image, cv::Mat& in_out_rgba_image_cache, bool shall_refresh_rgba, - GlTextureCv* outTexture + GlTexture* outTexture ); bool HasColormapParam(const ImageParams& params); diff --git a/src/immvision/internal/drawing/internal_icons.cpp b/src/immvision/internal/drawing/internal_icons.cpp index 54cf789..170ef97 100644 --- a/src/immvision/internal/drawing/internal_icons.cpp +++ b/src/immvision/internal/drawing/internal_icons.cpp @@ -1,6 +1,6 @@ #include "immvision/internal/drawing/internal_icons.h" #include "immvision/internal/cv/cv_drawing_utils.h" -#include "immvision/internal/gl/gl_texture.h" +#include "immvision/gl_texture.h" #include "immvision/image.h" #include "immvision/imgui_imm.h" #include @@ -228,7 +228,7 @@ namespace ImmVision } - static std::map> sIconsTextureCache; + static std::map> sIconsTextureCache; //static cv::Size gIconSize(20, 20); cv::Size IconSize() @@ -253,10 +253,10 @@ namespace ImmVision cv::Mat resized = m; cv::resize(m, resized, cv::Size(IconSize().width * 2, IconSize().height * 2), 0., 0., cv::INTER_AREA); - auto texture = std::make_unique(resized, true); + auto texture = std::make_unique(resized, true); sIconsTextureCache[iconType] = std::move(texture); } - return sIconsTextureCache[iconType]->mImTextureId; + return sIconsTextureCache[iconType]->TextureId; } bool IconButton(IconType iconType, bool disabled) diff --git a/src/immvision/internal/gl/gl_texture.cpp b/src/immvision/internal/gl/gl_texture.cpp index b35107e..27d9f4c 100644 --- a/src/immvision/internal/gl/gl_texture.cpp +++ b/src/immvision/internal/gl/gl_texture.cpp @@ -1,5 +1,4 @@ -#include "immvision/internal/gl/gl_texture.h" - +#include "immvision/gl_texture.h" #include "immvision/internal/cv/cv_drawing_utils.h" #include "immvision/internal/gl/gl_provider.h" @@ -9,29 +8,32 @@ namespace ImmVision GlTexture::GlTexture() { ImTextureID textureId_Gl = ImmVision_GlProvider::GenTexture(); - this->mImTextureId = textureId_Gl; + this->TextureId = textureId_Gl; } GlTexture::~GlTexture() { - ImmVision_GlProvider::DeleteTexture(mImTextureId); + ImmVision_GlProvider::DeleteTexture(TextureId); } - // - // ImageTextureCv - // - GlTextureCv::GlTextureCv(const cv::Mat& mat, bool isBgrOrder) : GlTextureCv() + GlTexture::GlTexture(const cv::Mat& image, bool isColorOrderBGR) : GlTexture() { - BlitMat(mat, isBgrOrder); + UpdateFromImage(image, isColorOrderBGR); } - void GlTextureCv::BlitMat(const cv::Mat& mat, bool isBgrOrder) + void GlTexture::UpdateFromImage(const cv::Mat& image, bool isColorOrderBGR) { - if (mat.empty()) + if (image.empty()) return; - cv::Mat mat_rgba = CvDrawingUtils::converted_to_rgba_image(mat, isBgrOrder); + cv::Mat mat_rgba = CvDrawingUtils::converted_to_rgba_image(image, isColorOrderBGR); - ImmVision_GlProvider::Blit_RGBA_Buffer(mat_rgba.data, mat_rgba.cols, mat_rgba.rows, mImTextureId); - this->mImageSize = ImVec2((float)mat_rgba.cols, (float) mat_rgba.rows); + ImmVision_GlProvider::Blit_RGBA_Buffer(mat_rgba.data, mat_rgba.cols, mat_rgba.rows, TextureId); + this->Size = mat_rgba.size(); } + + ImVec2 GlTexture::SizeImVec2() const + { + return {(float)Size.width, (float)Size.height}; + } + } // namespace ImmVision diff --git a/src/immvision/internal/gl/gl_texture.h b/src/immvision/internal/gl/gl_texture.h deleted file mode 100644 index 7480e33..0000000 --- a/src/immvision/internal/gl/gl_texture.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once -#include "imgui.h" -#include -#include - -namespace ImmVision -{ - /// GlTexture holds a OpenGL Texture (created via glGenTextures) - /// You can blit (i.e transfer) image buffer onto it. - /// The linked OpenGL texture lifetime is linked to this. - /// GlTexture is not copiable (since it holds a reference to a texture stored on the GPU) - struct GlTexture - { - GlTexture(); - virtual ~GlTexture(); - - // non copiable - GlTexture(const GlTexture& ) = delete; - GlTexture& operator=(const GlTexture& ) = delete; - - // members - ImVec2 mImageSize; - ImTextureID mImTextureId; - }; - - struct GlTextureCv : public GlTexture - { - GlTextureCv() = default; - GlTextureCv(const cv::Mat& mat, bool isBgrOrder); - ~GlTextureCv() override = default; - - void BlitMat(const cv::Mat& mat, bool isBgrOrder); - }; -} // namespace ImmVision diff --git a/src/immvision/internal/image.cpp b/src/immvision/internal/image.cpp index 098c56e..38a66d8 100644 --- a/src/immvision/internal/image.cpp +++ b/src/immvision/internal/image.cpp @@ -465,7 +465,7 @@ namespace ImmVision // // Lambda / Show image // - auto fnShowImage = [¶ms](const GlTextureCv& glTexture) -> MouseInformation + auto fnShowImage = [¶ms](const GlTexture& glTexture) -> MouseInformation { bool disableDragWindow = params->PanWithMouse; cv::Point2d mouseLocation = ImageWidgets::DisplayTexture_TrackMouse( diff --git a/src/immvision/internal/image_cache.cpp b/src/immvision/internal/image_cache.cpp index 848ac44..7cc403b 100644 --- a/src/immvision/internal/image_cache.cpp +++ b/src/immvision/internal/image_cache.cpp @@ -94,7 +94,7 @@ namespace ImmVision { mCacheImages.AddKey(key); isNewEntry = true; - mCacheImages.Get(key).GlTexture = std::make_unique(); + mCacheImages.Get(key).GlTexture = std::make_unique(); } return isNewEntry; } @@ -137,7 +137,7 @@ namespace ImmVision bool fullRefresh = ( userRefresh || isNewEntry - || (cachedImage.GlTexture->mImageSize.x == 0.f) + || (cachedImage.GlTexture->Size.empty()) || ShallRefreshRgbaCache(oldParams, *params)); if (fullRefresh) { diff --git a/src/immvision/internal/image_cache.h b/src/immvision/internal/image_cache.h index 81063da..2b3e636 100644 --- a/src/immvision/internal/image_cache.h +++ b/src/immvision/internal/image_cache.h @@ -1,6 +1,6 @@ #pragma once #include "immvision/image.h" -#include "immvision/internal/gl/gl_texture.h" +#include "immvision/gl_texture.h" #include "immvision/internal/gl/short_lived_cache.h" @@ -31,7 +31,7 @@ namespace ImmVision // These caches are heavy and will be destroyed // if not used (after about 5 seconds) cv::Mat ImageRgbaCache; // Image with applied colormap, alpha grid & paper background - std::unique_ptr GlTexture; + std::unique_ptr GlTexture; }; // returns true if new entry diff --git a/src/immvision/internal/imgui/image_widgets.cpp b/src/immvision/internal/imgui/image_widgets.cpp index a7cd09c..b6d7b1e 100644 --- a/src/immvision/internal/imgui/image_widgets.cpp +++ b/src/immvision/internal/imgui/image_widgets.cpp @@ -11,17 +11,17 @@ namespace ImmVision { ImVec2 size_(size); if (size.x == 0.f) - size_ = texture.mImageSize; + size_ = texture.SizeImVec2(); ImVec2 imageTl = ImGui::GetCursorScreenPos(); ImVec2 imageBr(imageTl.x + size.x, imageTl.y + size.y); std::stringstream id; - id << "##" << texture.mImTextureId; + id << "##" << texture.TextureId; if (disableDragWindow) ImGui::InvisibleButton(id.str().c_str(), size); else ImGui::Dummy(size); - ImGui::GetWindowDrawList()->AddImage(texture.mImTextureId, imageTl, imageBr); + ImGui::GetWindowDrawList()->AddImage(texture.TextureId, imageTl, imageBr); } float FontSizeRatio() @@ -30,7 +30,7 @@ namespace ImmVision return r; } - cv::Point2d DisplayTexture_TrackMouse(const GlTextureCv& texture, ImVec2 displaySize, bool disableDragWindow) + cv::Point2d DisplayTexture_TrackMouse(const GlTexture& texture, ImVec2 displaySize, bool disableDragWindow) { ImVec2 imageTopLeft = ImGui::GetCursorScreenPos(); GlTexture_Draw_DisableDragWindow(texture, displaySize, disableDragWindow); diff --git a/src/immvision/internal/imgui/image_widgets.h b/src/immvision/internal/imgui/image_widgets.h index b2a0213..01648b3 100644 --- a/src/immvision/internal/imgui/image_widgets.h +++ b/src/immvision/internal/imgui/image_widgets.h @@ -1,5 +1,5 @@ #pragma once -#include "immvision/internal/gl/gl_texture.h" +#include "immvision/gl_texture.h" #include "immvision/image.h" #include "imgui.h" #include @@ -8,7 +8,7 @@ namespace ImmVision { namespace ImageWidgets { - cv::Point2d DisplayTexture_TrackMouse(const GlTextureCv& texture, ImVec2 displaySize, bool disableDragWindow); + cv::Point2d DisplayTexture_TrackMouse(const GlTexture& texture, ImVec2 displaySize, bool disableDragWindow); void ShowImageInfo(const cv::Mat &image, double zoomFactor); void ShowPixelColorWidget(const cv::Mat &image, cv::Point pt, const ImageParams& params); diff --git a/src/immvision/internal/inspector.cpp b/src/immvision/internal/inspector.cpp index 46d31e9..f9c86f0 100644 --- a/src/immvision/internal/inspector.cpp +++ b/src/immvision/internal/inspector.cpp @@ -98,11 +98,11 @@ namespace ImmVision if (ImGui::Selectable(id_selectable.c_str(), is_selected, 0, itemSize)) s_Inspector_CurrentIndex = i; - float imageRatio = cacheImage.GlTexture->mImageSize.x / cacheImage.GlTexture->mImageSize.y; + float imageRatio = cacheImage.GlTexture->SizeImVec2().x / cacheImage.GlTexture->SizeImVec2().y; ImVec2 image_tl(pos.x, pos.y + ImGui::GetTextLineHeight()); ImVec2 image_br(pos.x + imageRatio * imageHeight, image_tl.y + imageHeight); - ImGui::GetWindowDrawList()->AddImage(cacheImage.GlTexture->mImTextureId, image_tl, image_br); + ImGui::GetWindowDrawList()->AddImage(cacheImage.GlTexture->TextureId, image_tl, image_br); ImGui::PopID(); } diff --git a/src_all_in_one/immvision/immvision.cpp b/src_all_in_one/immvision/immvision.cpp index 101cfb7..18d559e 100644 --- a/src_all_in_one/immvision/immvision.cpp +++ b/src_all_in_one/immvision/immvision.cpp @@ -4473,37 +4473,52 @@ namespace ImmVision ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// src/immvision/internal/gl/gl_texture.h included by src/immvision/internal/cv/colormap.cpp// +// src/immvision/gl_texture.h included by src/immvision/internal/cv/colormap.cpp // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#include + namespace ImmVision { - /// GlTexture holds a OpenGL Texture (created via glGenTextures) - /// You can blit (i.e transfer) image buffer onto it. - /// The linked OpenGL texture lifetime is linked to this. - /// GlTexture is not copiable (since it holds a reference to a texture stored on the GPU) + // GlTexture contains an OpenGL texture which can be created or updated from a cv::Mat (C++), or numpy array (Python) struct GlTexture { + // + // Constructors + // + + // Create an empty texture GlTexture(); - virtual ~GlTexture(); + // Create a texture from an image (cv::Mat in C++, numpy array in Python) + GlTexture(const cv::Mat& image, bool isColorOrderBGR); + // The destructor will delete the texture from the GPU + ~GlTexture(); - // non copiable + // GlTextureCv is non copiable (since it holds a reference to a texture stored on the GPU), + // but it is movable. GlTexture(const GlTexture& ) = delete; GlTexture& operator=(const GlTexture& ) = delete; + GlTexture(GlTexture&& other) noexcept = default; + GlTexture& operator=(GlTexture&& other) noexcept = default; - // members - ImVec2 mImageSize; - ImTextureID mImTextureId; - }; - struct GlTextureCv : public GlTexture - { - GlTextureCv() = default; - GlTextureCv(const cv::Mat& mat, bool isBgrOrder); - ~GlTextureCv() override = default; + // + // Methods + // + + // Update the texture from a new image (cv::Mat in C++, numpy array in Python). + void UpdateFromImage(const cv::Mat& image, bool isColorOrderBGR); + // Returns the size as ImVec2 + ImVec2 SizeImVec2() const; - void BlitMat(const cv::Mat& mat, bool isBgrOrder); + + // + // Members + // + + // OpenGL texture ID on the GPU + ImTextureID TextureId; + // Image size in pixels + cv::Size Size; }; } // namespace ImmVision @@ -4585,18 +4600,18 @@ namespace ImmVision { ImVec2 size_(size); if (size.x == 0.f) - size_ = texture.mImageSize; - ImGui::Image(texture.mImTextureId, size_); + size_ = texture.SizeImVec2(); + ImGui::Image(texture.TextureId, size_); } bool GlTexture_DrawButton(const GlTexture& texture, const ImVec2& size) { ImVec2 size_(size); if (size.x == 0.f) - size_ = texture.mImageSize; + size_ = texture.SizeImVec2(); char id[64]; snprintf(id, 64, "##%p", &texture); - return ImGui::ImageButton(id, texture.mImTextureId, size_); + return ImGui::ImageButton(id, texture.TextureId, size_); } } @@ -4705,7 +4720,7 @@ namespace ImmVision } - static insertion_order_map> sColormapsTexturesCache; + static insertion_order_map> sColormapsTexturesCache; void FillTextureCache() @@ -4716,7 +4731,7 @@ namespace ImmVision for (const auto& k: images.insertion_order_keys()) { cv::Mat& m = images.get(k); - auto texture = std::make_unique(m, true); + auto texture = std::make_unique(m, true); sColormapsTexturesCache.insert(k, std::move(texture)); } } @@ -4731,7 +4746,7 @@ namespace ImmVision if (cache.empty()) { for (const auto& k: sColormapsTexturesCache.insertion_order_keys()) - cache.insert(k, sColormapsTexturesCache.get(k)->mImTextureId); + cache.insert(k, sColormapsTexturesCache.get(k)->TextureId); } return cache; } @@ -6350,7 +6365,7 @@ namespace ImmVision const cv::Mat& image, cv::Mat& in_out_rgba_image_cache, bool shall_refresh_rgba, - GlTextureCv* outTexture + GlTexture* outTexture ); bool HasColormapParam(const ImageParams& params); @@ -6520,7 +6535,7 @@ namespace ImmVision const cv::Mat& image, cv::Mat& in_out_rgba_image_cache, bool shall_refresh_rgba, - GlTextureCv* outTexture + GlTexture* outTexture ) { if (image.empty()) @@ -6657,7 +6672,7 @@ namespace ImmVision // // Blit // - outTexture->BlitMat(finalImage, false); + outTexture->UpdateFromImage(finalImage, false); } bool HasColormapParam(const ImageParams ¶ms) @@ -6951,7 +6966,7 @@ namespace ImmVision } - static std::map> sIconsTextureCache; + static std::map> sIconsTextureCache; //static cv::Size gIconSize(20, 20); cv::Size IconSize() @@ -6976,10 +6991,10 @@ namespace ImmVision cv::Mat resized = m; cv::resize(m, resized, cv::Size(IconSize().width * 2, IconSize().height * 2), 0., 0., cv::INTER_AREA); - auto texture = std::make_unique(resized, true); + auto texture = std::make_unique(resized, true); sIconsTextureCache[iconType] = std::move(texture); } - return sIconsTextureCache[iconType]->mImTextureId; + return sIconsTextureCache[iconType]->TextureId; } bool IconButton(IconType iconType, bool disabled) @@ -7206,37 +7221,39 @@ namespace ImmVision_GlProvider ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - namespace ImmVision { GlTexture::GlTexture() { ImTextureID textureId_Gl = ImmVision_GlProvider::GenTexture(); - this->mImTextureId = textureId_Gl; + this->TextureId = textureId_Gl; } GlTexture::~GlTexture() { - ImmVision_GlProvider::DeleteTexture(mImTextureId); + ImmVision_GlProvider::DeleteTexture(TextureId); } - // - // ImageTextureCv - // - GlTextureCv::GlTextureCv(const cv::Mat& mat, bool isBgrOrder) : GlTextureCv() + GlTexture::GlTexture(const cv::Mat& image, bool isColorOrderBGR) : GlTexture() { - BlitMat(mat, isBgrOrder); + UpdateFromImage(image, isColorOrderBGR); } - void GlTextureCv::BlitMat(const cv::Mat& mat, bool isBgrOrder) + void GlTexture::UpdateFromImage(const cv::Mat& image, bool isColorOrderBGR) { - if (mat.empty()) + if (image.empty()) return; - cv::Mat mat_rgba = CvDrawingUtils::converted_to_rgba_image(mat, isBgrOrder); + cv::Mat mat_rgba = CvDrawingUtils::converted_to_rgba_image(image, isColorOrderBGR); - ImmVision_GlProvider::Blit_RGBA_Buffer(mat_rgba.data, mat_rgba.cols, mat_rgba.rows, mImTextureId); - this->mImageSize = ImVec2((float)mat_rgba.cols, (float) mat_rgba.rows); + ImmVision_GlProvider::Blit_RGBA_Buffer(mat_rgba.data, mat_rgba.cols, mat_rgba.rows, TextureId); + this->Size = mat_rgba.size(); } + + ImVec2 GlTexture::SizeImVec2() const + { + return {(float)Size.width, (float)Size.height}; + } + } // namespace ImmVision @@ -9321,7 +9338,7 @@ namespace ImmVision { namespace ImageWidgets { - cv::Point2d DisplayTexture_TrackMouse(const GlTextureCv& texture, ImVec2 displaySize, bool disableDragWindow); + cv::Point2d DisplayTexture_TrackMouse(const GlTexture& texture, ImVec2 displaySize, bool disableDragWindow); void ShowImageInfo(const cv::Mat &image, double zoomFactor); void ShowPixelColorWidget(const cv::Mat &image, cv::Point pt, const ImageParams& params); @@ -9368,7 +9385,7 @@ namespace ImmVision // These caches are heavy and will be destroyed // if not used (after about 5 seconds) cv::Mat ImageRgbaCache; // Image with applied colormap, alpha grid & paper background - std::unique_ptr GlTexture; + std::unique_ptr GlTexture; }; // returns true if new entry @@ -9898,7 +9915,7 @@ namespace ImmVision // // Lambda / Show image // - auto fnShowImage = [¶ms](const GlTextureCv& glTexture) -> MouseInformation + auto fnShowImage = [¶ms](const GlTexture& glTexture) -> MouseInformation { bool disableDragWindow = params->PanWithMouse; cv::Point2d mouseLocation = ImageWidgets::DisplayTexture_TrackMouse( @@ -10334,7 +10351,7 @@ namespace ImmVision { mCacheImages.AddKey(key); isNewEntry = true; - mCacheImages.Get(key).GlTexture = std::make_unique(); + mCacheImages.Get(key).GlTexture = std::make_unique(); } return isNewEntry; } @@ -10377,7 +10394,7 @@ namespace ImmVision bool fullRefresh = ( userRefresh || isNewEntry - || (cachedImage.GlTexture->mImageSize.x == 0.f) + || (cachedImage.GlTexture->Size.empty()) || ShallRefreshRgbaCache(oldParams, *params)); if (fullRefresh) { @@ -10728,17 +10745,17 @@ namespace ImmVision { ImVec2 size_(size); if (size.x == 0.f) - size_ = texture.mImageSize; + size_ = texture.SizeImVec2(); ImVec2 imageTl = ImGui::GetCursorScreenPos(); ImVec2 imageBr(imageTl.x + size.x, imageTl.y + size.y); std::stringstream id; - id << "##" << texture.mImTextureId; + id << "##" << texture.TextureId; if (disableDragWindow) ImGui::InvisibleButton(id.str().c_str(), size); else ImGui::Dummy(size); - ImGui::GetWindowDrawList()->AddImage(texture.mImTextureId, imageTl, imageBr); + ImGui::GetWindowDrawList()->AddImage(texture.TextureId, imageTl, imageBr); } float FontSizeRatio() @@ -10747,7 +10764,7 @@ namespace ImmVision return r; } - cv::Point2d DisplayTexture_TrackMouse(const GlTextureCv& texture, ImVec2 displaySize, bool disableDragWindow) + cv::Point2d DisplayTexture_TrackMouse(const GlTexture& texture, ImVec2 displaySize, bool disableDragWindow) { ImVec2 imageTopLeft = ImGui::GetCursorScreenPos(); GlTexture_Draw_DisableDragWindow(texture, displaySize, disableDragWindow); @@ -11654,11 +11671,11 @@ namespace ImmVision if (ImGui::Selectable(id_selectable.c_str(), is_selected, 0, itemSize)) s_Inspector_CurrentIndex = i; - float imageRatio = cacheImage.GlTexture->mImageSize.x / cacheImage.GlTexture->mImageSize.y; + float imageRatio = cacheImage.GlTexture->SizeImVec2().x / cacheImage.GlTexture->SizeImVec2().y; ImVec2 image_tl(pos.x, pos.y + ImGui::GetTextLineHeight()); ImVec2 image_br(pos.x + imageRatio * imageHeight, image_tl.y + imageHeight); - ImGui::GetWindowDrawList()->AddImage(cacheImage.GlTexture->mImTextureId, image_tl, image_br); + ImGui::GetWindowDrawList()->AddImage(cacheImage.GlTexture->TextureId, image_tl, image_br); ImGui::PopID(); } diff --git a/src_all_in_one/immvision/immvision.h b/src_all_in_one/immvision/immvision.h index d8d598e..09d1811 100644 --- a/src_all_in_one/immvision/immvision.h +++ b/src_all_in_one/immvision/immvision.h @@ -381,4 +381,57 @@ namespace ImmVision IMMVISION_API void Inspector_ClearImages(); -} // namespace ImmVision \ No newline at end of file +} // namespace ImmVision +////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// src/immvision/immvision.h continued // +////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// src/immvision/gl_texture.h included by src/immvision/immvision.h // +////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +namespace ImmVision +{ + // GlTexture contains an OpenGL texture which can be created or updated from a cv::Mat (C++), or numpy array (Python) + struct GlTexture + { + // + // Constructors + // + + // Create an empty texture + GlTexture(); + // Create a texture from an image (cv::Mat in C++, numpy array in Python) + GlTexture(const cv::Mat& image, bool isColorOrderBGR); + // The destructor will delete the texture from the GPU + ~GlTexture(); + + // GlTextureCv is non copiable (since it holds a reference to a texture stored on the GPU), + // but it is movable. + GlTexture(const GlTexture& ) = delete; + GlTexture& operator=(const GlTexture& ) = delete; + GlTexture(GlTexture&& other) noexcept = default; + GlTexture& operator=(GlTexture&& other) noexcept = default; + + + // + // Methods + // + + // Update the texture from a new image (cv::Mat in C++, numpy array in Python). + void UpdateFromImage(const cv::Mat& image, bool isColorOrderBGR); + // Returns the size as ImVec2 + ImVec2 SizeImVec2() const; + + + // + // Members + // + + // OpenGL texture ID on the GPU + ImTextureID TextureId; + // Image size in pixels + cv::Size Size; + }; +} // namespace ImmVision