From 565734217bf39cef3208c241cd7f0c39916d6f9e Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Sat, 19 Aug 2023 22:52:38 -0500 Subject: [PATCH] Update placefile icon texture coordinates when the texture atlas changes --- scwx-qt/source/scwx/qt/gl/draw/draw_item.cpp | 11 +++++++ scwx-qt/source/scwx/qt/gl/draw/draw_item.hpp | 7 +++-- .../scwx/qt/gl/draw/placefile_icons.cpp | 31 ++++++++++++------- .../scwx/qt/gl/draw/placefile_icons.hpp | 3 +- scwx-qt/source/scwx/qt/gl/gl_context.cpp | 5 +++ scwx-qt/source/scwx/qt/gl/gl_context.hpp | 2 ++ scwx-qt/source/scwx/qt/map/draw_layer.cpp | 12 ++++++- 7 files changed, 55 insertions(+), 16 deletions(-) diff --git a/scwx-qt/source/scwx/qt/gl/draw/draw_item.cpp b/scwx-qt/source/scwx/qt/gl/draw/draw_item.cpp index 1cc558a5..bbbe155b 100644 --- a/scwx-qt/source/scwx/qt/gl/draw/draw_item.cpp +++ b/scwx-qt/source/scwx/qt/gl/draw/draw_item.cpp @@ -41,6 +41,17 @@ DrawItem::~DrawItem() = default; DrawItem::DrawItem(DrawItem&&) noexcept = default; DrawItem& DrawItem::operator=(DrawItem&&) noexcept = default; +void DrawItem::Render( + const QMapLibreGL::CustomLayerRenderParameters& /* params */) +{ +} + +void DrawItem::Render(const QMapLibreGL::CustomLayerRenderParameters& params, + bool /* textureAtlasChanged */) +{ + Render(params); +} + void DrawItem::UseDefaultProjection( const QMapLibreGL::CustomLayerRenderParameters& params, GLint uMVPMatrixLocation) diff --git a/scwx-qt/source/scwx/qt/gl/draw/draw_item.hpp b/scwx-qt/source/scwx/qt/gl/draw/draw_item.hpp index dbacb008..4c3b7140 100644 --- a/scwx-qt/source/scwx/qt/gl/draw/draw_item.hpp +++ b/scwx-qt/source/scwx/qt/gl/draw/draw_item.hpp @@ -28,9 +28,10 @@ public: DrawItem& operator=(DrawItem&&) noexcept; virtual void Initialize() = 0; - virtual void - Render(const QMapLibreGL::CustomLayerRenderParameters& params) = 0; - virtual void Deinitialize() = 0; + virtual void Render(const QMapLibreGL::CustomLayerRenderParameters& params); + virtual void Render(const QMapLibreGL::CustomLayerRenderParameters& params, + bool textureAtlasChanged); + virtual void Deinitialize() = 0; protected: void diff --git a/scwx-qt/source/scwx/qt/gl/draw/placefile_icons.cpp b/scwx-qt/source/scwx/qt/gl/draw/placefile_icons.cpp index 14bde0d9..11d844c7 100644 --- a/scwx-qt/source/scwx/qt/gl/draw/placefile_icons.cpp +++ b/scwx-qt/source/scwx/qt/gl/draw/placefile_icons.cpp @@ -37,8 +37,6 @@ struct PlacefileIconInfo auto baseUrl = QUrl::fromUserInput(QString::fromStdString(baseUrlString)); auto relativeUrl = QUrl(QString::fromStdString(iconFile->filename_)); resolvedUrl_ = baseUrl.resolved(relativeUrl).toString().toStdString(); - - UpdateTextureInfo(); } void UpdateTextureInfo(); @@ -78,10 +76,9 @@ public: std::mutex iconMutex_; - boost::unordered_flat_map + boost::unordered_flat_map currentIconFiles_ {}; - boost::unordered_flat_map - newIconFiles_ {}; + boost::unordered_flat_map newIconFiles_ {}; std::vector> currentIconList_ {}; @@ -103,7 +100,7 @@ public: GLsizei numVertices_; void UpdateBuffers(); - void Update(); + void Update(bool textureAtlasChanged); }; PlacefileIcons::PlacefileIcons(std::shared_ptr context) : @@ -203,7 +200,8 @@ void PlacefileIcons::Initialize() } void PlacefileIcons::Render( - const QMapLibreGL::CustomLayerRenderParameters& params) + const QMapLibreGL::CustomLayerRenderParameters& params, + bool textureAtlasChanged) { std::unique_lock lock {p->iconMutex_}; @@ -213,7 +211,7 @@ void PlacefileIcons::Render( gl.glBindVertexArray(p->vao_); - p->Update(); + p->Update(textureAtlasChanged); p->shaderProgram_->Use(); UseRotationProjection(params, p->uMVPMatrixLocation_); UseMapProjection( @@ -329,8 +327,6 @@ void PlacefileIcons::FinishIcons() p->newIconList_.clear(); p->newIconFiles_.clear(); - p->UpdateBuffers(); - // Mark the draw item dirty p->dirty_ = true; } @@ -434,8 +430,21 @@ void PlacefileIcons::Impl::UpdateBuffers() dirty_ = true; } -void PlacefileIcons::Impl::Update() +void PlacefileIcons::Impl::Update(bool textureAtlasChanged) { + // If the texture atlas has changed + if (textureAtlasChanged) + { + // Update texture coordinates + for (auto& iconFile : currentIconFiles_) + { + iconFile.second.UpdateTextureInfo(); + } + + // Update OpenGL buffer data + UpdateBuffers(); + } + if (dirty_) { gl::OpenGLFunctions& gl = context_->gl(); diff --git a/scwx-qt/source/scwx/qt/gl/draw/placefile_icons.hpp b/scwx-qt/source/scwx/qt/gl/draw/placefile_icons.hpp index 3abc4086..08069ac5 100644 --- a/scwx-qt/source/scwx/qt/gl/draw/placefile_icons.hpp +++ b/scwx-qt/source/scwx/qt/gl/draw/placefile_icons.hpp @@ -30,7 +30,8 @@ public: void set_thresholded(bool thresholded); void Initialize() override; - void Render(const QMapLibreGL::CustomLayerRenderParameters& params) override; + void Render(const QMapLibreGL::CustomLayerRenderParameters& params, + bool textureAtlasChanged) override; void Deinitialize() override; /** diff --git a/scwx-qt/source/scwx/qt/gl/gl_context.cpp b/scwx-qt/source/scwx/qt/gl/gl_context.cpp index 2b996c54..64e2df46 100644 --- a/scwx-qt/source/scwx/qt/gl/gl_context.cpp +++ b/scwx-qt/source/scwx/qt/gl/gl_context.cpp @@ -52,6 +52,11 @@ gl::OpenGLFunctions& GlContext::gl() return p->gl_; } +std::uint64_t GlContext::texture_buffer_count() const +{ + return p->textureBufferCount_; +} + std::shared_ptr GlContext::GetShaderProgram(const std::string& vertexPath, const std::string& fragmentPath) diff --git a/scwx-qt/source/scwx/qt/gl/gl_context.hpp b/scwx-qt/source/scwx/qt/gl/gl_context.hpp index 5c53de59..b09ff403 100644 --- a/scwx-qt/source/scwx/qt/gl/gl_context.hpp +++ b/scwx-qt/source/scwx/qt/gl/gl_context.hpp @@ -24,6 +24,8 @@ public: gl::OpenGLFunctions& gl(); + std::uint64_t texture_buffer_count() const; + std::shared_ptr GetShaderProgram(const std::string& vertexPath, const std::string& fragmentPath); diff --git a/scwx-qt/source/scwx/qt/map/draw_layer.cpp b/scwx-qt/source/scwx/qt/map/draw_layer.cpp index 91c823e3..097f7a40 100644 --- a/scwx-qt/source/scwx/qt/map/draw_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/draw_layer.cpp @@ -24,6 +24,8 @@ public: std::shared_ptr context_; std::vector> drawList_; GLuint textureAtlas_; + + std::uint64_t textureAtlasBuildCount_ {}; }; DrawLayer::DrawLayer(std::shared_ptr context) : @@ -47,13 +49,21 @@ void DrawLayer::Render(const QMapLibreGL::CustomLayerRenderParameters& params) gl::OpenGLFunctions& gl = p->context_->gl(); p->textureAtlas_ = p->context_->GetTextureAtlas(); + // Determine if the texture atlas changed since last render + std::uint64_t newTextureAtlasBuildCount = + p->context_->texture_buffer_count(); + bool textureAtlasChanged = + newTextureAtlasBuildCount != p->textureAtlasBuildCount_; + gl.glActiveTexture(GL_TEXTURE0); gl.glBindTexture(GL_TEXTURE_2D, p->textureAtlas_); for (auto& item : p->drawList_) { - item->Render(params); + item->Render(params, textureAtlasChanged); } + + p->textureAtlasBuildCount_ = newTextureAtlasBuildCount; } void DrawLayer::Deinitialize()