From d30b6d401114b529a725fe6746f28f15da76869a Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Sat, 18 Dec 2021 21:43:15 -0600 Subject: [PATCH] Implement active box using new draw item on draw layers --- scwx-qt/gl/color.frag | 9 + scwx-qt/gl/color.vert | 13 + scwx-qt/scwx-qt.cmake | 14 +- scwx-qt/scwx-qt.qrc | 2 + scwx-qt/source/scwx/qt/gl/draw/draw_item.cpp | 33 +++ scwx-qt/source/scwx/qt/gl/draw/draw_item.hpp | 39 +++ scwx-qt/source/scwx/qt/gl/draw/rectangle.cpp | 286 +++++++++++++++++++ scwx-qt/source/scwx/qt/gl/draw/rectangle.hpp | 48 ++++ scwx-qt/source/scwx/qt/map/draw_layer.cpp | 98 +++++++ scwx-qt/source/scwx/qt/map/draw_layer.hpp | 34 +++ scwx-qt/source/scwx/qt/map/map_widget.cpp | 2 +- scwx-qt/source/scwx/qt/map/overlay_layer.cpp | 65 +++-- scwx-qt/source/scwx/qt/map/overlay_layer.hpp | 4 +- 13 files changed, 610 insertions(+), 37 deletions(-) create mode 100644 scwx-qt/gl/color.frag create mode 100644 scwx-qt/gl/color.vert create mode 100644 scwx-qt/source/scwx/qt/gl/draw/draw_item.cpp create mode 100644 scwx-qt/source/scwx/qt/gl/draw/draw_item.hpp create mode 100644 scwx-qt/source/scwx/qt/gl/draw/rectangle.cpp create mode 100644 scwx-qt/source/scwx/qt/gl/draw/rectangle.hpp create mode 100644 scwx-qt/source/scwx/qt/map/draw_layer.cpp create mode 100644 scwx-qt/source/scwx/qt/map/draw_layer.hpp diff --git a/scwx-qt/gl/color.frag b/scwx-qt/gl/color.frag new file mode 100644 index 00000000..003c6c8d --- /dev/null +++ b/scwx-qt/gl/color.frag @@ -0,0 +1,9 @@ +#version 330 core +in vec4 color; + +layout (location = 0) out vec4 fragColor; + +void main() +{ + fragColor = color; +} diff --git a/scwx-qt/gl/color.vert b/scwx-qt/gl/color.vert new file mode 100644 index 00000000..5c8d1ff7 --- /dev/null +++ b/scwx-qt/gl/color.vert @@ -0,0 +1,13 @@ +#version 330 core +layout (location = 0) in vec3 aVertex; +layout (location = 1) in vec4 aColor; + +uniform mat4 uMVPMatrix; + +out vec4 color; + +void main() +{ + gl_Position = uMVPMatrix * vec4(aVertex, 1.0f); + color = aColor; +} diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake index 3bb34c5d..1568eeef 100644 --- a/scwx-qt/scwx-qt.cmake +++ b/scwx-qt/scwx-qt.cmake @@ -58,6 +58,10 @@ set(HDR_GL source/scwx/qt/gl/gl.hpp source/scwx/qt/gl/text_shader.hpp) set(SRC_GL source/scwx/qt/gl/shader_program.cpp source/scwx/qt/gl/text_shader.cpp) +set(HDR_GL_DRAW source/scwx/qt/gl/draw/draw_item.hpp + source/scwx/qt/gl/draw/rectangle.hpp) +set(SRC_GL_DRAW source/scwx/qt/gl/draw/draw_item.cpp + source/scwx/qt/gl/draw/rectangle.cpp) set(HDR_MANAGER source/scwx/qt/manager/radar_product_manager.hpp source/scwx/qt/manager/resource_manager.hpp source/scwx/qt/manager/settings_manager.hpp) @@ -65,6 +69,7 @@ set(SRC_MANAGER source/scwx/qt/manager/radar_product_manager.cpp source/scwx/qt/manager/resource_manager.cpp source/scwx/qt/manager/settings_manager.cpp) set(HDR_MAP source/scwx/qt/map/color_table_layer.hpp + source/scwx/qt/map/draw_layer.hpp source/scwx/qt/map/generic_layer.hpp source/scwx/qt/map/layer_wrapper.hpp source/scwx/qt/map/map_context.hpp @@ -74,6 +79,7 @@ set(HDR_MAP source/scwx/qt/map/color_table_layer.hpp source/scwx/qt/map/radar_product_layer.hpp source/scwx/qt/map/radar_range_layer.hpp) set(SRC_MAP source/scwx/qt/map/color_table_layer.cpp + source/scwx/qt/map/draw_layer.cpp source/scwx/qt/map/generic_layer.cpp source/scwx/qt/map/layer_wrapper.cpp source/scwx/qt/map/map_widget.cpp @@ -101,7 +107,9 @@ set(SRC_VIEW source/scwx/qt/view/level2_product_view.cpp set(RESOURCE_FILES scwx-qt.qrc) -set(SHADER_FILES gl/overlay.frag +set(SHADER_FILES gl/color.frag + gl/color.vert + gl/overlay.frag gl/overlay.vert gl/radar.frag gl/radar.vert @@ -116,6 +124,8 @@ set(PROJECT_SOURCES ${HDR_MAIN} ${SRC_MAIN} ${HDR_GL} ${SRC_GL} + ${HDR_GL_DRAW} + ${SRC_GL_DRAW} ${HDR_MANAGER} ${SRC_MANAGER} ${UI_MAIN} @@ -138,6 +148,8 @@ source_group("Header Files\\main" FILES ${HDR_MAIN}) source_group("Source Files\\main" FILES ${SRC_MAIN}) source_group("Header Files\\gl" FILES ${HDR_GL}) source_group("Source Files\\gl" FILES ${SRC_GL}) +source_group("Header Files\\gl\\draw" FILES ${HDR_GL_DRAW}) +source_group("Source Files\\gl\\draw" FILES ${SRC_GL_DRAW}) source_group("Header Files\\manager" FILES ${HDR_MANAGER}) source_group("Source Files\\manager" FILES ${SRC_MANAGER}) source_group("UI Files\\main" FILES ${UI_MAIN}) diff --git a/scwx-qt/scwx-qt.qrc b/scwx-qt/scwx-qt.qrc index 1009008d..7cc85108 100644 --- a/scwx-qt/scwx-qt.qrc +++ b/scwx-qt/scwx-qt.qrc @@ -1,5 +1,7 @@ + gl/color.frag + gl/color.vert gl/overlay.frag gl/overlay.vert gl/radar.frag diff --git a/scwx-qt/source/scwx/qt/gl/draw/draw_item.cpp b/scwx-qt/source/scwx/qt/gl/draw/draw_item.cpp new file mode 100644 index 00000000..83c9d951 --- /dev/null +++ b/scwx-qt/source/scwx/qt/gl/draw/draw_item.cpp @@ -0,0 +1,33 @@ +#include + +#include + +namespace scwx +{ +namespace qt +{ +namespace gl +{ +namespace draw +{ + +static const std::string logPrefix_ = "[scwx::qt::gl::draw::draw_item] "; + +class DrawItemImpl +{ +public: + explicit DrawItemImpl() {} + + ~DrawItemImpl() {} +}; + +DrawItem::DrawItem() : p(std::make_unique()) {} +DrawItem::~DrawItem() = default; + +DrawItem::DrawItem(DrawItem&&) noexcept = default; +DrawItem& DrawItem::operator=(DrawItem&&) noexcept = default; + +} // namespace draw +} // namespace gl +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/gl/draw/draw_item.hpp b/scwx-qt/source/scwx/qt/gl/draw/draw_item.hpp new file mode 100644 index 00000000..09e98092 --- /dev/null +++ b/scwx-qt/source/scwx/qt/gl/draw/draw_item.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include + +namespace scwx +{ +namespace qt +{ +namespace gl +{ +namespace draw +{ + +class DrawItemImpl; + +class DrawItem +{ +public: + explicit DrawItem(); + ~DrawItem(); + + DrawItem(const DrawItem&) = delete; + DrawItem& operator=(const DrawItem&) = delete; + + DrawItem(DrawItem&&) noexcept; + DrawItem& operator=(DrawItem&&) noexcept; + + virtual void Initialize() = 0; + virtual void Render() = 0; + virtual void Deinitialize() = 0; + +private: + std::unique_ptr p; +}; + +} // namespace draw +} // namespace gl +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/gl/draw/rectangle.cpp b/scwx-qt/source/scwx/qt/gl/draw/rectangle.cpp new file mode 100644 index 00000000..2c00b8a5 --- /dev/null +++ b/scwx-qt/source/scwx/qt/gl/draw/rectangle.cpp @@ -0,0 +1,286 @@ +#include + +#include + +#include + +namespace scwx +{ +namespace qt +{ +namespace gl +{ +namespace draw +{ + +static const std::string logPrefix_ = "[scwx::qt::gl::draw::rectangle] "; + +static constexpr size_t NUM_RECTANGLES = 5; +static constexpr size_t NUM_TRIANGLES = NUM_RECTANGLES * 2; +static constexpr size_t VERTICES_PER_TRIANGLE = 3; +static constexpr size_t VERTICES_PER_RECTANGLE = VERTICES_PER_TRIANGLE * 2; +static constexpr size_t POINTS_PER_VERTEX = 7; +static constexpr size_t BUFFER_LENGTH = + NUM_TRIANGLES * VERTICES_PER_TRIANGLE * POINTS_PER_VERTEX; + +class RectangleImpl +{ +public: + explicit RectangleImpl(OpenGLFunctions& gl) : + gl_ {gl}, + dirty_ {false}, + visible_ {true}, + x_ {0.0f}, + y_ {0.0f}, + z_ {0.0f}, + width_ {0.0f}, + height_ {0.0f}, + borderColor_ {0, 0, 0, 0}, + borderWidth_ {0.0f}, + fillColor_ {std::nullopt}, + vao_ {GL_INVALID_INDEX}, + vbo_ {GL_INVALID_INDEX} + { + } + + ~RectangleImpl() {} + + OpenGLFunctions& gl_; + + bool dirty_; + + bool visible_; + float x_; + float y_; + float z_; + float width_; + float height_; + + float borderWidth_; + boost::gil::rgba8_pixel_t borderColor_; + + std::optional fillColor_; + + GLuint vao_; + GLuint vbo_; + + void Update(); +}; + +Rectangle::Rectangle(OpenGLFunctions& gl) : + DrawItem(), p(std::make_unique(gl)) +{ +} +Rectangle::~Rectangle() = default; + +Rectangle::Rectangle(Rectangle&&) noexcept = default; +Rectangle& Rectangle::operator=(Rectangle&&) noexcept = default; + +void Rectangle::Initialize() +{ + gl::OpenGLFunctions& gl = p->gl_; + + gl.glGenVertexArrays(1, &p->vao_); + gl.glGenBuffers(1, &p->vbo_); + + gl.glBindVertexArray(p->vao_); + gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_); + gl.glBufferData( + GL_ARRAY_BUFFER, sizeof(float) * BUFFER_LENGTH, nullptr, GL_DYNAMIC_DRAW); + + gl.glVertexAttribPointer(0, + 3, + GL_FLOAT, + GL_FALSE, + POINTS_PER_VERTEX * sizeof(float), + static_cast(0)); + gl.glEnableVertexAttribArray(0); + + gl.glVertexAttribPointer(1, + 4, + GL_FLOAT, + GL_FALSE, + POINTS_PER_VERTEX * sizeof(float), + reinterpret_cast(3 * sizeof(float))); + gl.glEnableVertexAttribArray(1); + + p->dirty_ = true; +} + +void Rectangle::Render() +{ + if (p->visible_) + { + gl::OpenGLFunctions& gl = p->gl_; + + gl.glBindVertexArray(p->vao_); + gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_); + + p->Update(); + + if (p->fillColor_.has_value()) + { + // Draw fill + gl.glDrawArrays(GL_TRIANGLES, 24, 6); + } + + if (p->borderWidth_ > 0.0f) + { + // Draw border + gl.glDrawArrays(GL_TRIANGLES, 0, 24); + } + } +} + +void Rectangle::Deinitialize() +{ + gl::OpenGLFunctions& gl = p->gl_; + + gl.glDeleteVertexArrays(1, &p->vao_); + gl.glDeleteBuffers(1, &p->vbo_); +} + +void Rectangle::SetBorder(float width, boost::gil::rgba8_pixel_t color) +{ + if (p->borderWidth_ != width || p->borderColor_ != color) + { + p->borderWidth_ = width; + p->borderColor_ = color; + p->dirty_ = true; + } +} + +void Rectangle::SetFill(boost::gil::rgba8_pixel_t color) +{ + if (p->fillColor_ != color) + { + p->fillColor_ = color; + p->dirty_ = true; + } +} + +void Rectangle::SetPosition(float x, float y) +{ + if (p->x_ != x || p->y_ != y) + { + p->x_ = x; + p->y_ = y; + p->dirty_ = true; + } +} + +void Rectangle::SetSize(float width, float height) +{ + if (p->width_ != width || p->height_ != height) + { + p->width_ = width; + p->height_ = height; + p->dirty_ = true; + } +} + +void Rectangle::SetVisible(bool visible) +{ + p->visible_ = visible; +} + +void RectangleImpl::Update() +{ + if (dirty_) + { + gl::OpenGLFunctions& gl = gl_; + + const float lox = x_; + const float rox = x_ + width_; + const float boy = y_; + const float toy = y_ + height_; + + const float lix = lox + borderWidth_; + const float rix = rox - borderWidth_; + + const float biy = boy + borderWidth_; + const float tiy = toy - borderWidth_; + + const float bc0 = borderColor_[0] / 255.0f; + const float bc1 = borderColor_[1] / 255.0f; + const float bc2 = borderColor_[2] / 255.0f; + const float bc3 = borderColor_[3] / 255.0f; + + float fc0 = 0.0f; + float fc1 = 0.0f; + float fc2 = 0.0f; + float fc3 = 0.0f; + + if (fillColor_.has_value()) + { + boost::gil::rgba8_pixel_t& fc = fillColor_.value(); + + fc0 = fc[0] / 255.0f; + fc1 = fc[1] / 255.0f; + fc2 = fc[2] / 255.0f; + fc3 = fc[3] / 255.0f; + } + + const float buffer[NUM_RECTANGLES][VERTICES_PER_RECTANGLE] + [POINTS_PER_VERTEX] = // + { // + + // Left Border + { + {lox, boy, z_, bc0, bc1, bc2, bc3}, // BL + {lox, toy, z_, bc0, bc1, bc2, bc3}, // TL + {lix, boy, z_, bc0, bc1, bc2, bc3}, // BR + {lix, boy, z_, bc0, bc1, bc2, bc3}, // BR + {lix, toy, z_, bc0, bc1, bc2, bc3}, // TR + {lox, toy, z_, bc0, bc1, bc2, bc3} // TL + }, + // Right Border + { + {rox, boy, z_, bc0, bc1, bc2, bc3}, // BR + {rox, toy, z_, bc0, bc1, bc2, bc3}, // TR + {rix, boy, z_, bc0, bc1, bc2, bc3}, // BL + {rix, boy, z_, bc0, bc1, bc2, bc3}, // BL + {rix, toy, z_, bc0, bc1, bc2, bc3}, // TL + {rox, toy, z_, bc0, bc1, bc2, bc3} // TR + }, + // Top Border + { + {lox, toy, z_, bc0, bc1, bc2, bc3}, // TL + {rox, toy, z_, bc0, bc1, bc2, bc3}, // TR + {rox, tiy, z_, bc0, bc1, bc2, bc3}, // BR + {rox, tiy, z_, bc0, bc1, bc2, bc3}, // BR + {lox, tiy, z_, bc0, bc1, bc2, bc3}, // BL + {lox, toy, z_, bc0, bc1, bc2, bc3} // TL + }, + // Bottom Border + { + {lox, boy, z_, bc0, bc1, bc2, bc3}, // BL + {rox, boy, z_, bc0, bc1, bc2, bc3}, // BR + {rox, biy, z_, bc0, bc1, bc2, bc3}, // TR + {rox, biy, z_, bc0, bc1, bc2, bc3}, // TR + {lox, biy, z_, bc0, bc1, bc2, bc3}, // TL + {lox, boy, z_, bc0, bc1, bc2, bc3} // BL + }, + // Fill + { + {lox, toy, z_, fc0, fc1, fc2, fc3}, // TL + {rox, toy, z_, fc0, fc1, fc2, fc3}, // TR + {rox, boy, z_, fc0, fc1, fc2, fc3}, // BR + {rox, boy, z_, fc0, fc1, fc2, fc3}, // BR + {lox, boy, z_, fc0, fc1, fc2, fc3}, // BL + {lox, toy, z_, fc0, fc1, fc2, fc3} // TL + }}; + + gl.glBufferData(GL_ARRAY_BUFFER, + sizeof(float) * BUFFER_LENGTH, + buffer, + GL_DYNAMIC_DRAW); + + dirty_ = false; + } +} + +} // namespace draw +} // namespace gl +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/gl/draw/rectangle.hpp b/scwx-qt/source/scwx/qt/gl/draw/rectangle.hpp new file mode 100644 index 00000000..02ca7a91 --- /dev/null +++ b/scwx-qt/source/scwx/qt/gl/draw/rectangle.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include +#include + +#include + +namespace scwx +{ +namespace qt +{ +namespace gl +{ +namespace draw +{ + +class RectangleImpl; + +class Rectangle : public DrawItem +{ +public: + explicit Rectangle(OpenGLFunctions& gl); + ~Rectangle(); + + Rectangle(const Rectangle&) = delete; + Rectangle& operator=(const Rectangle&) = delete; + + Rectangle(Rectangle&&) noexcept; + Rectangle& operator=(Rectangle&&) noexcept; + + void Initialize() override; + void Render() override; + void Deinitialize() override; + + void SetBorder(float width, boost::gil::rgba8_pixel_t color); + void SetFill(boost::gil::rgba8_pixel_t color); + void SetPosition(float x, float y); + void SetSize(float width, float height); + void SetVisible(bool visible); + +private: + std::unique_ptr p; +}; + +} // namespace draw +} // namespace gl +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/map/draw_layer.cpp b/scwx-qt/source/scwx/qt/map/draw_layer.cpp new file mode 100644 index 00000000..6fb68970 --- /dev/null +++ b/scwx-qt/source/scwx/qt/map/draw_layer.cpp @@ -0,0 +1,98 @@ +#include +#include + +#include +#include +#include +#include + +namespace scwx +{ +namespace qt +{ +namespace map +{ + +static const std::string logPrefix_ = "[scwx::qt::map::draw_layer] "; + +class DrawLayerImpl +{ +public: + explicit DrawLayerImpl(std::shared_ptr context) : + shaderProgram_ {context->gl_}, uMVPMatrixLocation_(GL_INVALID_INDEX) + { + } + + ~DrawLayerImpl() {} + + gl::ShaderProgram shaderProgram_; + GLint uMVPMatrixLocation_; + + std::vector> drawList_; +}; + +DrawLayer::DrawLayer(std::shared_ptr context) : + GenericLayer(context), p(std::make_unique(context)) +{ +} +DrawLayer::~DrawLayer() = default; + +void DrawLayer::Initialize() +{ + gl::OpenGLFunctions& gl = context()->gl_; + + p->shaderProgram_.Load(":/gl/color.vert", ":/gl/color.frag"); + + p->uMVPMatrixLocation_ = + gl.glGetUniformLocation(p->shaderProgram_.id(), "uMVPMatrix"); + if (p->uMVPMatrixLocation_ == -1) + { + BOOST_LOG_TRIVIAL(warning) << logPrefix_ << "Could not find uMVPMatrix"; + } + + p->shaderProgram_.Use(); + + for (auto item : p->drawList_) + { + item->Initialize(); + } +} + +void DrawLayer::Render(const QMapbox::CustomLayerRenderParameters& params) +{ + gl::OpenGLFunctions& gl = context()->gl_; + + p->shaderProgram_.Use(); + + glm::mat4 projection = glm::ortho(0.0f, + static_cast(params.width), + 0.0f, + static_cast(params.height), + -10.0f, + 10.0f); + + gl.glUniformMatrix4fv( + p->uMVPMatrixLocation_, 1, GL_FALSE, glm::value_ptr(projection)); + + for (auto item : p->drawList_) + { + item->Render(); + } +} + +void DrawLayer::Deinitialize() +{ + for (auto item : p->drawList_) + { + item->Deinitialize(); + } +} + +void DrawLayer::AddDrawItem(std::shared_ptr drawItem) +{ + p->drawList_.push_back(drawItem); +} + +} // namespace map +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/map/draw_layer.hpp b/scwx-qt/source/scwx/qt/map/draw_layer.hpp new file mode 100644 index 00000000..29fdbf11 --- /dev/null +++ b/scwx-qt/source/scwx/qt/map/draw_layer.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include +#include + +namespace scwx +{ +namespace qt +{ +namespace map +{ + +class DrawLayerImpl; + +class DrawLayer : public GenericLayer +{ +public: + explicit DrawLayer(std::shared_ptr context); + virtual ~DrawLayer(); + + virtual void Initialize(); + virtual void Render(const QMapbox::CustomLayerRenderParameters&); + virtual void Deinitialize(); + +protected: + void AddDrawItem(std::shared_ptr drawItem); + +private: + std::unique_ptr p; +}; + +} // namespace map +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/map/map_widget.cpp b/scwx-qt/source/scwx/qt/map/map_widget.cpp index 0bad5ae5..c7d577e0 100644 --- a/scwx-qt/source/scwx/qt/map/map_widget.cpp +++ b/scwx-qt/source/scwx/qt/map/map_widget.cpp @@ -304,8 +304,8 @@ void MapWidget::AddLayers() p->map_->addCustomLayer("radar", std::move(pHost), before); RadarRangeLayer::Add( p->map_, p->context_->radarProductView_->range(), before); - p->map_->addCustomLayer("overlay", std::move(pOverlayHost)); p->map_->addCustomLayer("colorTable", std::move(pColorTableHost)); + p->map_->addCustomLayer("overlay", std::move(pOverlayHost)); } void MapWidget::keyPressEvent(QKeyEvent* ev) diff --git a/scwx-qt/source/scwx/qt/map/overlay_layer.cpp b/scwx-qt/source/scwx/qt/map/overlay_layer.cpp index d46b3685..16c95859 100644 --- a/scwx-qt/source/scwx/qt/map/overlay_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/overlay_layer.cpp @@ -1,9 +1,10 @@ // Enable chrono formatters #ifndef __cpp_lib_format -#define __cpp_lib_format 202110L +# define __cpp_lib_format 202110L #endif #include +#include #include #include #include @@ -42,6 +43,8 @@ public: vbo_ {GL_INVALID_INDEX}, vao_ {GL_INVALID_INDEX}, texture_ {GL_INVALID_INDEX}, + activeBoxOuter_ {std::make_shared(context->gl_)}, + activeBoxInner_ {std::make_shared(context->gl_)}, sweepTimeString_ {}, sweepTimeNeedsUpdate_ {true} { @@ -54,24 +57,34 @@ public: gl::ShaderProgram shaderProgram_; GLint uMVPMatrixLocation_; GLint uColorLocation_; - std::array vbo_; + GLuint vbo_; GLuint vao_; GLuint texture_; + std::shared_ptr activeBoxOuter_; + std::shared_ptr activeBoxInner_; + std::string sweepTimeString_; bool sweepTimeNeedsUpdate_; }; OverlayLayer::OverlayLayer(std::shared_ptr context) : - GenericLayer(context), p(std::make_unique(context)) + DrawLayer(context), p(std::make_unique(context)) { + AddDrawItem(p->activeBoxOuter_); + AddDrawItem(p->activeBoxInner_); + + p->activeBoxInner_->SetPosition(1.0f, 1.0f); } + OverlayLayer::~OverlayLayer() = default; void OverlayLayer::Initialize() { BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Initialize()"; + DrawLayer::Initialize(); + gl::OpenGLFunctions& gl = context()->gl_; p->textShader_.Initialize(); @@ -104,20 +117,12 @@ void OverlayLayer::Initialize() gl.glGenVertexArrays(1, &p->vao_); // Generate vertex buffer objects - gl.glGenBuffers(static_cast(p->vbo_.size()), p->vbo_.data()); + gl.glGenBuffers(1, &p->vbo_); gl.glBindVertexArray(p->vao_); - // Active box (dynamic sized) - gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); - gl.glBufferData( - GL_ARRAY_BUFFER, sizeof(float) * 5 * 2, nullptr, GL_DYNAMIC_DRAW); - - gl.glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, static_cast(0)); - gl.glEnableVertexAttribArray(0); - // Upper right panel (dynamic sized) - gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); + gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_); gl.glBufferData( GL_ARRAY_BUFFER, sizeof(float) * 6 * 2, nullptr, GL_DYNAMIC_DRAW); @@ -164,25 +169,15 @@ void OverlayLayer::Render(const QMapbox::CustomLayerRenderParameters& params) gl.glUniformMatrix4fv( p->uMVPMatrixLocation_, 1, GL_FALSE, glm::value_ptr(projection)); + // Active Box + p->activeBoxOuter_->SetVisible(context()->settings_.isActive_); + p->activeBoxInner_->SetVisible(context()->settings_.isActive_); if (context()->settings_.isActive_) { - const float vertexLX = 1.0f; - const float vertexRX = static_cast(params.width) - 1.0f; - const float vertexTY = static_cast(params.height) - 1.0f; - const float vertexBY = 1.0f; - const float vertices[5][2] = {{vertexLX, vertexTY}, // TL - {vertexLX, vertexBY}, // BL - {vertexRX, vertexBY}, // BR - {vertexRX, vertexTY}, // TR - {vertexLX, vertexTY}}; // TL - - // Draw vertices - gl.glBindVertexArray(p->vao_); - gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); - gl.glVertexAttribPointer( - 0, 2, GL_FLOAT, GL_FALSE, 0, static_cast(0)); - gl.glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); - gl.glDrawArrays(GL_LINE_STRIP, 0, 5); + p->activeBoxOuter_->SetSize(params.width, params.height); + p->activeBoxOuter_->SetBorder(1.0f, {0, 0, 0, 255}); + p->activeBoxInner_->SetSize(params.width - 2.0f, params.height - 2.0f); + p->activeBoxInner_->SetBorder(1.0f, {255, 255, 255, 255}); } if (p->sweepTimeString_.length() > 0) @@ -207,7 +202,7 @@ void OverlayLayer::Render(const QMapbox::CustomLayerRenderParameters& params) // Draw vertices gl.glBindVertexArray(p->vao_); - gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); + gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_); gl.glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 0, static_cast(0)); gl.glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); @@ -225,6 +220,8 @@ void OverlayLayer::Render(const QMapbox::CustomLayerRenderParameters& params) gl::TextAlign::Right); } + DrawLayer::Render(params); + SCWX_GL_CHECK_ERROR(); } @@ -232,16 +229,18 @@ void OverlayLayer::Deinitialize() { BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Deinitialize()"; + DrawLayer::Deinitialize(); + gl::OpenGLFunctions& gl = context()->gl_; gl.glDeleteVertexArrays(1, &p->vao_); - gl.glDeleteBuffers(static_cast(p->vbo_.size()), p->vbo_.data()); + gl.glDeleteBuffers(1, &p->vbo_); gl.glDeleteTextures(1, &p->texture_); p->uMVPMatrixLocation_ = GL_INVALID_INDEX; p->uColorLocation_ = GL_INVALID_INDEX; p->vao_ = GL_INVALID_INDEX; - p->vbo_ = {GL_INVALID_INDEX}; + p->vbo_ = GL_INVALID_INDEX; p->texture_ = GL_INVALID_INDEX; disconnect(context()->radarProductView_.get(), diff --git a/scwx-qt/source/scwx/qt/map/overlay_layer.hpp b/scwx-qt/source/scwx/qt/map/overlay_layer.hpp index 263d106f..a8110971 100644 --- a/scwx-qt/source/scwx/qt/map/overlay_layer.hpp +++ b/scwx-qt/source/scwx/qt/map/overlay_layer.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include namespace scwx { @@ -11,7 +11,7 @@ namespace map class OverlayLayerImpl; -class OverlayLayer : public GenericLayer +class OverlayLayer : public DrawLayer { public: explicit OverlayLayer(std::shared_ptr context);