Create shader programs through map context in order to cache programs through re-initialization

This commit is contained in:
Dan Paulat 2022-10-02 23:16:35 -05:00
parent 32e8ca72a0
commit a45e996872
10 changed files with 324 additions and 144 deletions

View file

@ -73,6 +73,7 @@ set(SRC_MAP source/scwx/qt/map/color_table_layer.cpp
source/scwx/qt/map/draw_layer.cpp source/scwx/qt/map/draw_layer.cpp
source/scwx/qt/map/generic_layer.cpp source/scwx/qt/map/generic_layer.cpp
source/scwx/qt/map/layer_wrapper.cpp source/scwx/qt/map/layer_wrapper.cpp
source/scwx/qt/map/map_context.cpp
source/scwx/qt/map/map_widget.cpp source/scwx/qt/map/map_widget.cpp
source/scwx/qt/map/overlay_layer.cpp source/scwx/qt/map/overlay_layer.cpp
source/scwx/qt/map/radar_product_layer.cpp source/scwx/qt/map/radar_product_layer.cpp

View file

@ -1,4 +1,5 @@
#include <scwx/qt/gl/text_shader.hpp> #include <scwx/qt/gl/text_shader.hpp>
#include <scwx/qt/gl/shader_program.hpp>
#include <scwx/util/logger.hpp> #include <scwx/util/logger.hpp>
#pragma warning(push, 0) #pragma warning(push, 0)
@ -18,41 +19,46 @@ static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
class TextShaderImpl class TextShaderImpl
{ {
public: public:
explicit TextShaderImpl(OpenGLFunctions& gl) : explicit TextShaderImpl(std::shared_ptr<map::MapContext> context) :
gl_ {gl}, projectionLocation_(GL_INVALID_INDEX) context_ {context},
shaderProgram_ {nullptr},
projectionLocation_(GL_INVALID_INDEX)
{ {
} }
~TextShaderImpl() {} ~TextShaderImpl() {}
OpenGLFunctions& gl_; std::shared_ptr<map::MapContext> context_;
std::shared_ptr<ShaderProgram> shaderProgram_;
GLint projectionLocation_; GLint projectionLocation_;
}; };
TextShader::TextShader(OpenGLFunctions& gl) : TextShader::TextShader(std::shared_ptr<map::MapContext> context) :
ShaderProgram(gl), p(std::make_unique<TextShaderImpl>(gl)) p(std::make_unique<TextShaderImpl>(context))
{ {
} }
TextShader::~TextShader() = default; TextShader::~TextShader() = default;
TextShader::TextShader(TextShader&&) noexcept = default; TextShader::TextShader(TextShader&&) noexcept = default;
TextShader& TextShader::operator=(TextShader&&) noexcept = default; TextShader& TextShader::operator=(TextShader&&) noexcept = default;
bool TextShader::Initialize() bool TextShader::Initialize()
{ {
OpenGLFunctions& gl = p->gl_; OpenGLFunctions& gl = p->context_->gl();
// Load and configure shader // Load and configure shader
bool success = Load(":/gl/text.vert", ":/gl/text.frag"); p->shaderProgram_ =
p->context_->GetShaderProgram(":/gl/text.vert", ":/gl/text.frag");
p->projectionLocation_ = gl.glGetUniformLocation(id(), "projection"); p->projectionLocation_ =
gl.glGetUniformLocation(p->shaderProgram_->id(), "projection");
if (p->projectionLocation_ == -1) if (p->projectionLocation_ == -1)
{ {
logger_->warn("Could not find projection"); logger_->warn("Could not find projection");
} }
return success; return true;
} }
void TextShader::RenderText(const std::string& text, void TextShader::RenderText(const std::string& text,
@ -65,9 +71,9 @@ void TextShader::RenderText(const std::string& text,
GLuint textureId, GLuint textureId,
TextAlign align) TextAlign align)
{ {
OpenGLFunctions& gl = p->gl_; OpenGLFunctions& gl = p->context_->gl();
Use(); p->shaderProgram_->Use();
gl.glEnable(GL_BLEND); gl.glEnable(GL_BLEND);
gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -103,7 +109,7 @@ void TextShader::RenderText(const std::string& text,
void TextShader::SetProjection(const glm::mat4& projection) void TextShader::SetProjection(const glm::mat4& projection)
{ {
p->gl_.glUniformMatrix4fv( p->context_->gl().glUniformMatrix4fv(
p->projectionLocation_, 1, GL_FALSE, glm::value_ptr(projection)); p->projectionLocation_, 1, GL_FALSE, glm::value_ptr(projection));
} }

View file

@ -1,6 +1,6 @@
#pragma once #pragma once
#include <scwx/qt/gl/shader_program.hpp> #include <scwx/qt/map/map_context.hpp>
#include <scwx/qt/util/font.hpp> #include <scwx/qt/util/font.hpp>
#include <memory> #include <memory>
@ -24,13 +24,13 @@ enum class TextAlign
class TextShaderImpl; class TextShaderImpl;
class TextShader : public ShaderProgram class TextShader
{ {
public: public:
explicit TextShader(OpenGLFunctions& gl); explicit TextShader(std::shared_ptr<map::MapContext> context);
~TextShader(); ~TextShader();
TextShader(const TextShader&) = delete; TextShader(const TextShader&) = delete;
TextShader& operator=(const TextShader&) = delete; TextShader& operator=(const TextShader&) = delete;
TextShader(TextShader&&) noexcept; TextShader(TextShader&&) noexcept;

View file

@ -21,7 +21,7 @@ class ColorTableLayerImpl
{ {
public: public:
explicit ColorTableLayerImpl(std::shared_ptr<MapContext> context) : explicit ColorTableLayerImpl(std::shared_ptr<MapContext> context) :
shaderProgram_(context->gl_), shaderProgram_(nullptr),
uMVPMatrixLocation_(GL_INVALID_INDEX), uMVPMatrixLocation_(GL_INVALID_INDEX),
vbo_ {GL_INVALID_INDEX}, vbo_ {GL_INVALID_INDEX},
vao_ {GL_INVALID_INDEX}, vao_ {GL_INVALID_INDEX},
@ -31,7 +31,8 @@ public:
} }
~ColorTableLayerImpl() = default; ~ColorTableLayerImpl() = default;
gl::ShaderProgram shaderProgram_; std::shared_ptr<gl::ShaderProgram> shaderProgram_;
GLint uMVPMatrixLocation_; GLint uMVPMatrixLocation_;
std::array<GLuint, 2> vbo_; std::array<GLuint, 2> vbo_;
GLuint vao_; GLuint vao_;
@ -52,13 +53,14 @@ void ColorTableLayer::Initialize()
{ {
logger_->debug("Initialize()"); logger_->debug("Initialize()");
gl::OpenGLFunctions& gl = context()->gl_; gl::OpenGLFunctions& gl = context()->gl();
// Load and configure overlay shader // Load and configure overlay shader
p->shaderProgram_.Load(":/gl/texture1d.vert", ":/gl/texture1d.frag"); p->shaderProgram_ =
context()->GetShaderProgram(":/gl/texture1d.vert", ":/gl/texture1d.frag");
p->uMVPMatrixLocation_ = p->uMVPMatrixLocation_ =
gl.glGetUniformLocation(p->shaderProgram_.id(), "uMVPMatrix"); gl.glGetUniformLocation(p->shaderProgram_->id(), "uMVPMatrix");
if (p->uMVPMatrixLocation_ == -1) if (p->uMVPMatrixLocation_ == -1)
{ {
logger_->warn("Could not find uMVPMatrix"); logger_->warn("Could not find uMVPMatrix");
@ -66,7 +68,7 @@ void ColorTableLayer::Initialize()
gl.glGenTextures(1, &p->texture_); gl.glGenTextures(1, &p->texture_);
p->shaderProgram_.Use(); p->shaderProgram_->Use();
// Generate a vertex array object // Generate a vertex array object
gl.glGenVertexArrays(1, &p->vao_); gl.glGenVertexArrays(1, &p->vao_);
@ -99,7 +101,7 @@ void ColorTableLayer::Initialize()
gl.glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, static_cast<void*>(0)); gl.glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, static_cast<void*>(0));
gl.glEnableVertexAttribArray(1); gl.glEnableVertexAttribArray(1);
connect(context()->radarProductView_.get(), connect(context()->radar_product_view().get(),
&view::RadarProductView::ColorTableUpdated, &view::RadarProductView::ColorTableUpdated,
this, this,
[=]() { p->colorTableNeedsUpdate_ = true; }); [=]() { p->colorTableNeedsUpdate_ = true; });
@ -107,10 +109,11 @@ void ColorTableLayer::Initialize()
void ColorTableLayer::Render(const QMapbox::CustomLayerRenderParameters& params) void ColorTableLayer::Render(const QMapbox::CustomLayerRenderParameters& params)
{ {
gl::OpenGLFunctions& gl = context()->gl_; gl::OpenGLFunctions& gl = context()->gl();
auto radarProductView = context()->radar_product_view();
if (context()->radarProductView_ == nullptr || if (context()->radar_product_view() == nullptr ||
!context()->radarProductView_->IsInitialized()) !context()->radar_product_view()->IsInitialized())
{ {
// Defer rendering until view is initialized // Defer rendering until view is initialized
return; return;
@ -121,14 +124,14 @@ void ColorTableLayer::Render(const QMapbox::CustomLayerRenderParameters& params)
0.0f, 0.0f,
static_cast<float>(params.height)); static_cast<float>(params.height));
p->shaderProgram_.Use(); p->shaderProgram_->Use();
gl.glUniformMatrix4fv( gl.glUniformMatrix4fv(
p->uMVPMatrixLocation_, 1, GL_FALSE, glm::value_ptr(projection)); p->uMVPMatrixLocation_, 1, GL_FALSE, glm::value_ptr(projection));
if (p->colorTableNeedsUpdate_) if (p->colorTableNeedsUpdate_)
{ {
p->colorTable_ = context()->radarProductView_->color_table(); p->colorTable_ = radarProductView->color_table();
gl.glActiveTexture(GL_TEXTURE0); gl.glActiveTexture(GL_TEXTURE0);
gl.glBindTexture(GL_TEXTURE_1D, p->texture_); gl.glBindTexture(GL_TEXTURE_1D, p->texture_);
@ -145,9 +148,8 @@ void ColorTableLayer::Render(const QMapbox::CustomLayerRenderParameters& params)
gl.glGenerateMipmap(GL_TEXTURE_1D); gl.glGenerateMipmap(GL_TEXTURE_1D);
} }
if (p->colorTable_.size() > 0 && if (p->colorTable_.size() > 0 && radarProductView->sweep_time() !=
context()->radarProductView_->sweep_time() != std::chrono::system_clock::time_point())
std::chrono::system_clock::time_point())
{ {
// Color table panel vertices // Color table panel vertices
const float vertexLX = 0.0f; const float vertexLX = 0.0f;
@ -176,7 +178,7 @@ void ColorTableLayer::Deinitialize()
{ {
logger_->debug("Deinitialize()"); logger_->debug("Deinitialize()");
gl::OpenGLFunctions& gl = context()->gl_; gl::OpenGLFunctions& gl = context()->gl();
gl.glDeleteVertexArrays(1, &p->vao_); gl.glDeleteVertexArrays(1, &p->vao_);
gl.glDeleteBuffers(2, p->vbo_.data()); gl.glDeleteBuffers(2, p->vbo_.data());

View file

@ -22,14 +22,15 @@ class DrawLayerImpl
{ {
public: public:
explicit DrawLayerImpl(std::shared_ptr<MapContext> context) : explicit DrawLayerImpl(std::shared_ptr<MapContext> context) :
shaderProgram_ {context->gl_}, uMVPMatrixLocation_(GL_INVALID_INDEX) shaderProgram_ {nullptr}, uMVPMatrixLocation_(GL_INVALID_INDEX)
{ {
} }
~DrawLayerImpl() {} ~DrawLayerImpl() {}
gl::ShaderProgram shaderProgram_; std::shared_ptr<gl::ShaderProgram> shaderProgram_;
GLint uMVPMatrixLocation_;
GLint uMVPMatrixLocation_;
std::vector<std::shared_ptr<gl::draw::DrawItem>> drawList_; std::vector<std::shared_ptr<gl::draw::DrawItem>> drawList_;
}; };
@ -42,20 +43,21 @@ DrawLayer::~DrawLayer() = default;
void DrawLayer::Initialize() void DrawLayer::Initialize()
{ {
gl::OpenGLFunctions& gl = context()->gl_; gl::OpenGLFunctions& gl = context()->gl();
p->shaderProgram_.Load(":/gl/color.vert", ":/gl/color.frag"); p->shaderProgram_ =
context()->GetShaderProgram(":/gl/color.vert", ":/gl/color.frag");
p->uMVPMatrixLocation_ = p->uMVPMatrixLocation_ =
gl.glGetUniformLocation(p->shaderProgram_.id(), "uMVPMatrix"); gl.glGetUniformLocation(p->shaderProgram_->id(), "uMVPMatrix");
if (p->uMVPMatrixLocation_ == -1) if (p->uMVPMatrixLocation_ == -1)
{ {
logger_->warn("Could not find uMVPMatrix"); logger_->warn("Could not find uMVPMatrix");
} }
p->shaderProgram_.Use(); p->shaderProgram_->Use();
for (auto item : p->drawList_) for (auto& item : p->drawList_)
{ {
item->Initialize(); item->Initialize();
} }
@ -63,9 +65,9 @@ void DrawLayer::Initialize()
void DrawLayer::Render(const QMapbox::CustomLayerRenderParameters& params) void DrawLayer::Render(const QMapbox::CustomLayerRenderParameters& params)
{ {
gl::OpenGLFunctions& gl = context()->gl_; gl::OpenGLFunctions& gl = context()->gl();
p->shaderProgram_.Use(); p->shaderProgram_->Use();
glm::mat4 projection = glm::ortho(0.0f, glm::mat4 projection = glm::ortho(0.0f,
static_cast<float>(params.width), static_cast<float>(params.width),
@ -75,7 +77,7 @@ void DrawLayer::Render(const QMapbox::CustomLayerRenderParameters& params)
gl.glUniformMatrix4fv( gl.glUniformMatrix4fv(
p->uMVPMatrixLocation_, 1, GL_FALSE, glm::value_ptr(projection)); p->uMVPMatrixLocation_, 1, GL_FALSE, glm::value_ptr(projection));
for (auto item : p->drawList_) for (auto& item : p->drawList_)
{ {
item->Render(); item->Render();
} }
@ -83,7 +85,7 @@ void DrawLayer::Render(const QMapbox::CustomLayerRenderParameters& params)
void DrawLayer::Deinitialize() void DrawLayer::Deinitialize()
{ {
for (auto item : p->drawList_) for (auto& item : p->drawList_)
{ {
item->Deinitialize(); item->Deinitialize();
} }

View file

@ -0,0 +1,131 @@
#include <scwx/qt/map/map_context.hpp>
#include <scwx/util/hash.hpp>
namespace scwx
{
namespace qt
{
namespace map
{
class MapContext::Impl
{
public:
explicit Impl(std::shared_ptr<view::RadarProductView> radarProductView) :
gl_ {},
settings_ {},
radarProductView_ {radarProductView},
radarProductGroup_ {common::RadarProductGroup::Unknown},
radarProduct_ {"???"},
radarProductCode_ {0},
shaderProgramMap_ {},
shaderProgramMutex_ {}
{
}
~Impl() {}
gl::OpenGLFunctions gl_;
MapSettings settings_;
std::shared_ptr<view::RadarProductView> radarProductView_;
common::RadarProductGroup radarProductGroup_;
std::string radarProduct_;
int16_t radarProductCode_;
std::unordered_map<std::pair<std::string, std::string>,
std::shared_ptr<gl::ShaderProgram>,
util::hash<std::pair<std::string, std::string>>>
shaderProgramMap_;
std::mutex shaderProgramMutex_;
};
MapContext::MapContext(
std::shared_ptr<view::RadarProductView> radarProductView) :
p(std::make_unique<Impl>(radarProductView))
{
}
MapContext::~MapContext() = default;
MapContext::MapContext(MapContext&&) noexcept = default;
MapContext& MapContext::operator=(MapContext&&) noexcept = default;
gl::OpenGLFunctions& MapContext::gl()
{
return p->gl_;
}
MapSettings& MapContext::settings()
{
return p->settings_;
}
std::shared_ptr<view::RadarProductView> MapContext::radar_product_view() const
{
return p->radarProductView_;
}
common::RadarProductGroup MapContext::radar_product_group() const
{
return p->radarProductGroup_;
}
std::string MapContext::radar_product() const
{
return p->radarProduct_;
}
int16_t MapContext::radar_product_code() const
{
return p->radarProductCode_;
}
void MapContext::set_radar_product_view(
std::shared_ptr<view::RadarProductView> radarProductView)
{
p->radarProductView_ = radarProductView;
}
void MapContext::set_radar_product_group(
common::RadarProductGroup radarProductGroup)
{
p->radarProductGroup_ = radarProductGroup;
}
void MapContext::set_radar_product(const std::string& radarProduct)
{
p->radarProduct_ = radarProduct;
}
void MapContext::set_radar_product_code(int16_t radarProductCode)
{
p->radarProductCode_ = radarProductCode;
}
std::shared_ptr<gl::ShaderProgram>
MapContext::GetShaderProgram(const std::string& vertexPath,
const std::string& fragmentPath)
{
const std::pair<std::string, std::string> key {vertexPath, fragmentPath};
std::shared_ptr<gl::ShaderProgram> shaderProgram;
std::unique_lock lock(p->shaderProgramMutex_);
auto it = p->shaderProgramMap_.find(key);
if (it == p->shaderProgramMap_.end())
{
shaderProgram = std::make_shared<gl::ShaderProgram>(p->gl_);
shaderProgram->Load(vertexPath, fragmentPath);
p->shaderProgramMap_[key] = shaderProgram;
}
else
{
shaderProgram = it->second;
}
return shaderProgram;
}
} // namespace map
} // namespace qt
} // namespace scwx

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <scwx/qt/gl/gl.hpp> #include <scwx/qt/gl/gl.hpp>
#include <scwx/qt/gl/shader_program.hpp>
#include <scwx/qt/map/map_settings.hpp> #include <scwx/qt/map/map_settings.hpp>
#include <scwx/qt/view/radar_product_view.hpp> #include <scwx/qt/view/radar_product_view.hpp>
@ -11,32 +12,40 @@ namespace qt
namespace map namespace map
{ {
struct MapContext class MapContext
{ {
public:
explicit MapContext( explicit MapContext(
std::shared_ptr<view::RadarProductView> radarProductView = nullptr) : std::shared_ptr<view::RadarProductView> radarProductView = nullptr);
gl_ {}, ~MapContext();
settings_ {},
radarProductView_ {radarProductView},
radarProductGroup_ {common::RadarProductGroup::Unknown},
radarProduct_ {"???"},
radarProductCode_ {0}
{
}
~MapContext() = default;
MapContext(const MapContext&) = delete; MapContext(const MapContext&) = delete;
MapContext& operator=(const MapContext&) = delete; MapContext& operator=(const MapContext&) = delete;
MapContext(MapContext&&) noexcept = default; MapContext(MapContext&&) noexcept;
MapContext& operator=(MapContext&&) noexcept = default; MapContext& operator=(MapContext&&) noexcept;
gl::OpenGLFunctions gl_; gl::OpenGLFunctions& gl();
MapSettings settings_; MapSettings& settings();
std::shared_ptr<view::RadarProductView> radarProductView_; std::shared_ptr<view::RadarProductView> radar_product_view() const;
common::RadarProductGroup radarProductGroup_; common::RadarProductGroup radar_product_group() const;
std::string radarProduct_; std::string radar_product() const;
int16_t radarProductCode_; int16_t radar_product_code() const;
void set_radar_product_view(
std::shared_ptr<view::RadarProductView> radarProductView);
void set_radar_product_group(common::RadarProductGroup radarProductGroup);
void set_radar_product(const std::string& radarProduct);
void set_radar_product_code(int16_t radarProductCode);
std::shared_ptr<gl::ShaderProgram>
GetShaderProgram(const std::string& vertexPath,
const std::string& fragmentPath);
private:
class Impl;
std::unique_ptr<Impl> p;
}; };
} // namespace map } // namespace map

View file

@ -153,9 +153,11 @@ common::Level3ProductCategoryMap MapWidget::GetAvailableLevel3Categories()
float MapWidget::GetElevation() const float MapWidget::GetElevation() const
{ {
if (p->context_->radarProductView_ != nullptr) auto radarProductView = p->context_->radar_product_view();
if (radarProductView != nullptr)
{ {
return p->context_->radarProductView_->elevation(); return radarProductView->elevation();
} }
else else
{ {
@ -165,9 +167,11 @@ float MapWidget::GetElevation() const
std::vector<float> MapWidget::GetElevationCuts() const std::vector<float> MapWidget::GetElevationCuts() const
{ {
if (p->context_->radarProductView_ != nullptr) auto radarProductView = p->context_->radar_product_view();
if (radarProductView != nullptr)
{ {
return p->context_->radarProductView_->GetElevationCuts(); return radarProductView->GetElevationCuts();
} }
else else
{ {
@ -182,10 +186,12 @@ MapWidgetImpl::GetLevel2ProductOrDefault(const std::string& productName) const
if (level2Product == common::Level2Product::Unknown) if (level2Product == common::Level2Product::Unknown)
{ {
if (context_->radarProductView_ != nullptr) auto radarProductView = context_->radar_product_view();
if (radarProductView != nullptr)
{ {
level2Product = common::GetLevel2Product( level2Product =
context_->radarProductView_->GetRadarProductName()); common::GetLevel2Product(radarProductView->GetRadarProductName());
} }
} }
@ -218,9 +224,11 @@ std::vector<std::string> MapWidget::GetLevel3Products()
common::RadarProductGroup MapWidget::GetRadarProductGroup() const common::RadarProductGroup MapWidget::GetRadarProductGroup() const
{ {
if (p->context_->radarProductView_ != nullptr) auto radarProductView = p->context_->radar_product_view();
if (radarProductView != nullptr)
{ {
return p->context_->radarProductView_->GetRadarProductGroup(); return radarProductView->GetRadarProductGroup();
} }
else else
{ {
@ -230,10 +238,11 @@ common::RadarProductGroup MapWidget::GetRadarProductGroup() const
std::string MapWidget::GetRadarProductName() const std::string MapWidget::GetRadarProductName() const
{ {
auto radarProductView = p->context_->radar_product_view();
if (p->context_->radarProductView_ != nullptr) if (radarProductView != nullptr)
{ {
return p->context_->radarProductView_->GetRadarProductName(); return radarProductView->GetRadarProductName();
} }
else else
{ {
@ -255,9 +264,11 @@ std::shared_ptr<config::RadarSite> MapWidget::GetRadarSite() const
uint16_t MapWidget::GetVcp() const uint16_t MapWidget::GetVcp() const
{ {
if (p->context_->radarProductView_ != nullptr) auto radarProductView = p->context_->radar_product_view();
if (radarProductView != nullptr)
{ {
return p->context_->radarProductView_->vcp(); return radarProductView->vcp();
} }
else else
{ {
@ -267,10 +278,12 @@ uint16_t MapWidget::GetVcp() const
void MapWidget::SelectElevation(float elevation) void MapWidget::SelectElevation(float elevation)
{ {
if (p->context_->radarProductView_ != nullptr) auto radarProductView = p->context_->radar_product_view();
if (radarProductView != nullptr)
{ {
p->context_->radarProductView_->SelectElevation(elevation); radarProductView->SelectElevation(elevation);
p->context_->radarProductView_->Update(); radarProductView->Update();
} }
} }
@ -280,8 +293,7 @@ void MapWidget::SelectRadarProduct(common::RadarProductGroup group,
{ {
bool radarProductViewCreated = false; bool radarProductViewCreated = false;
std::shared_ptr<view::RadarProductView>& radarProductView = auto radarProductView = p->context_->radar_product_view();
p->context_->radarProductView_;
std::string productName {product}; std::string productName {product};
@ -304,12 +316,13 @@ void MapWidget::SelectRadarProduct(common::RadarProductGroup group,
(radarProductView->GetRadarProductGroup() == (radarProductView->GetRadarProductGroup() ==
common::RadarProductGroup::Level2 && common::RadarProductGroup::Level2 &&
radarProductView->GetRadarProductName() != productName) || radarProductView->GetRadarProductName() != productName) ||
p->context_->radarProductCode_ != productCode) p->context_->radar_product_code() != productCode)
{ {
p->RadarProductViewDisconnect(); p->RadarProductViewDisconnect();
radarProductView = view::RadarProductViewFactory::Create( radarProductView = view::RadarProductViewFactory::Create(
group, productName, productCode, p->radarProductManager_); group, productName, productCode, p->radarProductManager_);
p->context_->set_radar_product_view(radarProductView);
p->RadarProductViewConnect(); p->RadarProductViewConnect();
@ -320,9 +333,9 @@ void MapWidget::SelectRadarProduct(common::RadarProductGroup group,
radarProductView->SelectProduct(productName); radarProductView->SelectProduct(productName);
} }
p->context_->radarProductGroup_ = group; p->context_->set_radar_product_group(group);
p->context_->radarProduct_ = productName; p->context_->set_radar_product(productName);
p->context_->radarProductCode_ = productCode; p->context_->set_radar_product_code(productCode);
if (radarProductView != nullptr) if (radarProductView != nullptr)
{ {
@ -372,7 +385,7 @@ void MapWidget::SelectRadarProduct(
void MapWidget::SetActive(bool isActive) void MapWidget::SetActive(bool isActive)
{ {
p->context_->settings_.isActive_ = isActive; p->context_->settings().isActive_ = isActive;
update(); update();
} }
@ -382,11 +395,13 @@ void MapWidget::SetAutoRefresh(bool enabled)
{ {
p->autoRefreshEnabled_ = enabled; p->autoRefreshEnabled_ = enabled;
if (p->autoRefreshEnabled_ && p->context_->radarProductView_ != nullptr) auto radarProductView = p->context_->radar_product_view();
if (p->autoRefreshEnabled_ && radarProductView != nullptr)
{ {
p->radarProductManager_->EnableRefresh( p->radarProductManager_->EnableRefresh(
p->context_->radarProductView_->GetRadarProductGroup(), radarProductView->GetRadarProductGroup(),
p->context_->radarProductView_->GetRadarProductName(), radarProductView->GetRadarProductName(),
true); true);
} }
} }
@ -430,7 +445,9 @@ void MapWidget::AddLayers()
} }
p->layerList_.clear(); p->layerList_.clear();
if (p->context_->radarProductView_ != nullptr) auto radarProductView = p->context_->radar_product_view();
if (radarProductView != nullptr)
{ {
p->radarProductLayer_ = std::make_shared<RadarProductLayer>(p->context_); p->radarProductLayer_ = std::make_shared<RadarProductLayer>(p->context_);
p->colorTableLayer_ = std::make_shared<ColorTableLayer>(p->context_); p->colorTableLayer_ = std::make_shared<ColorTableLayer>(p->context_);
@ -453,7 +470,7 @@ void MapWidget::AddLayers()
p->AddLayer("radar", p->radarProductLayer_, before); p->AddLayer("radar", p->radarProductLayer_, before);
RadarRangeLayer::Add(p->map_, RadarRangeLayer::Add(p->map_,
p->context_->radarProductView_->range(), radarProductView->range(),
{radarSite->latitude(), radarSite->longitude()}); {radarSite->latitude(), radarSite->longitude()});
p->AddLayer("colorTable", p->colorTableLayer_); p->AddLayer("colorTable", p->colorTableLayer_);
} }
@ -572,7 +589,7 @@ void MapWidget::initializeGL()
logger_->debug("initializeGL()"); logger_->debug("initializeGL()");
makeCurrent(); makeCurrent();
p->context_->gl_.initializeOpenGLFunctions(); p->context_->gl().initializeOpenGLFunctions();
p->map_.reset(new QMapboxGL(nullptr, p->settings_, size(), pixelRatio())); p->map_.reset(new QMapboxGL(nullptr, p->settings_, size(), pixelRatio()));
connect(p->map_.get(), connect(p->map_.get(),
@ -637,9 +654,10 @@ void MapWidgetImpl::RadarProductManagerConnect()
const std::string& product, const std::string& product,
std::chrono::system_clock::time_point latestTime) std::chrono::system_clock::time_point latestTime)
{ {
if (autoRefreshEnabled_ && context_->radarProductGroup_ == group && if (autoRefreshEnabled_ &&
context_->radar_product_group() == group &&
(group == common::RadarProductGroup::Level2 || (group == common::RadarProductGroup::Level2 ||
context_->radarProduct_ == product)) context_->radar_product() == product))
{ {
// Create file request // Create file request
std::shared_ptr<request::NexradFileRequest> request = std::shared_ptr<request::NexradFileRequest> request =
@ -698,16 +716,18 @@ void MapWidgetImpl::InitializeNewRadarProductView(
util::async( util::async(
[=]() [=]()
{ {
auto radarProductView = context_->radar_product_view();
std::string colorTableFile = std::string colorTableFile =
manager::SettingsManager::palette_settings()->palette(colorPalette); manager::SettingsManager::palette_settings()->palette(colorPalette);
if (!colorTableFile.empty()) if (!colorTableFile.empty())
{ {
std::shared_ptr<common::ColorTable> colorTable = std::shared_ptr<common::ColorTable> colorTable =
common::ColorTable::Load(colorTableFile); common::ColorTable::Load(colorTableFile);
context_->radarProductView_->LoadColorTable(colorTable); radarProductView->LoadColorTable(colorTable);
} }
context_->radarProductView_->Initialize(); radarProductView->Initialize();
}); });
if (map_ != nullptr) if (map_ != nullptr)
@ -718,26 +738,28 @@ void MapWidgetImpl::InitializeNewRadarProductView(
void MapWidgetImpl::RadarProductViewConnect() void MapWidgetImpl::RadarProductViewConnect()
{ {
if (context_->radarProductView_ != nullptr) auto radarProductView = context_->radar_product_view();
if (radarProductView != nullptr)
{ {
connect( connect(
context_->radarProductView_.get(), radarProductView.get(),
&view::RadarProductView::ColorTableUpdated, &view::RadarProductView::ColorTableUpdated,
this, this,
[&]() { widget_->update(); }, [&]() { widget_->update(); },
Qt::QueuedConnection); Qt::QueuedConnection);
connect( connect(
context_->radarProductView_.get(), radarProductView.get(),
&view::RadarProductView::SweepComputed, &view::RadarProductView::SweepComputed,
this, this,
[&]() [=]()
{ {
std::shared_ptr<config::RadarSite> radarSite = std::shared_ptr<config::RadarSite> radarSite =
radarProductManager_->radar_site(); radarProductManager_->radar_site();
RadarRangeLayer::Update( RadarRangeLayer::Update(
map_, map_,
context_->radarProductView_->range(), radarProductView->range(),
{radarSite->latitude(), radarSite->longitude()}); {radarSite->latitude(), radarSite->longitude()});
widget_->update(); widget_->update();
emit widget_->RadarSweepUpdated(); emit widget_->RadarSweepUpdated();
@ -748,13 +770,15 @@ void MapWidgetImpl::RadarProductViewConnect()
void MapWidgetImpl::RadarProductViewDisconnect() void MapWidgetImpl::RadarProductViewDisconnect()
{ {
if (context_->radarProductView_ != nullptr) auto radarProductView = context_->radar_product_view();
if (radarProductView != nullptr)
{ {
disconnect(context_->radarProductView_.get(), disconnect(radarProductView.get(),
&view::RadarProductView::ColorTableUpdated, &view::RadarProductView::ColorTableUpdated,
this, this,
nullptr); nullptr);
disconnect(context_->radarProductView_.get(), disconnect(radarProductView.get(),
&view::RadarProductView::SweepComputed, &view::RadarProductView::SweepComputed,
this, this,
nullptr); nullptr);

View file

@ -34,12 +34,12 @@ class OverlayLayerImpl
{ {
public: public:
explicit OverlayLayerImpl(std::shared_ptr<MapContext> context) : explicit OverlayLayerImpl(std::shared_ptr<MapContext> context) :
textShader_(context->gl_), textShader_(context),
font_(util::Font::Create(":/res/fonts/din1451alt.ttf")), font_(util::Font::Create(":/res/fonts/din1451alt.ttf")),
texture_ {GL_INVALID_INDEX}, texture_ {GL_INVALID_INDEX},
activeBoxOuter_ {std::make_shared<gl::draw::Rectangle>(context->gl_)}, activeBoxOuter_ {std::make_shared<gl::draw::Rectangle>(context->gl())},
activeBoxInner_ {std::make_shared<gl::draw::Rectangle>(context->gl_)}, activeBoxInner_ {std::make_shared<gl::draw::Rectangle>(context->gl())},
timeBox_ {std::make_shared<gl::draw::Rectangle>(context->gl_)}, timeBox_ {std::make_shared<gl::draw::Rectangle>(context->gl())},
sweepTimeString_ {}, sweepTimeString_ {},
sweepTimeNeedsUpdate_ {true} sweepTimeNeedsUpdate_ {true}
{ {
@ -81,7 +81,8 @@ void OverlayLayer::Initialize()
DrawLayer::Initialize(); DrawLayer::Initialize();
gl::OpenGLFunctions& gl = context()->gl_; gl::OpenGLFunctions& gl = context()->gl();
auto radarProductView = context()->radar_product_view();
p->textShader_.Initialize(); p->textShader_.Initialize();
@ -90,9 +91,9 @@ void OverlayLayer::Initialize()
p->texture_ = p->font_->GenerateTexture(gl); p->texture_ = p->font_->GenerateTexture(gl);
} }
if (context()->radarProductView_ != nullptr) if (radarProductView != nullptr)
{ {
connect(context()->radarProductView_.get(), connect(radarProductView.get(),
&view::RadarProductView::SweepComputed, &view::RadarProductView::SweepComputed,
this, this,
&OverlayLayer::UpdateSweepTimeNextFrame); &OverlayLayer::UpdateSweepTimeNextFrame);
@ -103,14 +104,14 @@ void OverlayLayer::Render(const QMapbox::CustomLayerRenderParameters& params)
{ {
constexpr float fontSize = 16.0f; constexpr float fontSize = 16.0f;
gl::OpenGLFunctions& gl = context()->gl_; gl::OpenGLFunctions& gl = context()->gl();
auto radarProductView = context()->radar_product_view();
auto& settings = context()->settings();
if (p->sweepTimeNeedsUpdate_ && context()->radarProductView_ != nullptr) if (p->sweepTimeNeedsUpdate_ && radarProductView != nullptr)
{ {
p->sweepTimeString_ = p->sweepTimeString_ = scwx::util::TimeString(
scwx::util::TimeString(context()->radarProductView_->sweep_time(), radarProductView->sweep_time(), std::chrono::current_zone(), false);
std::chrono::current_zone(),
false);
p->sweepTimeNeedsUpdate_ = false; p->sweepTimeNeedsUpdate_ = false;
} }
@ -120,9 +121,9 @@ void OverlayLayer::Render(const QMapbox::CustomLayerRenderParameters& params)
static_cast<float>(params.height)); static_cast<float>(params.height));
// Active Box // Active Box
p->activeBoxOuter_->SetVisible(context()->settings_.isActive_); p->activeBoxOuter_->SetVisible(settings.isActive_);
p->activeBoxInner_->SetVisible(context()->settings_.isActive_); p->activeBoxInner_->SetVisible(settings.isActive_);
if (context()->settings_.isActive_) if (settings.isActive_)
{ {
p->activeBoxOuter_->SetSize(params.width, params.height); p->activeBoxOuter_->SetSize(params.width, params.height);
p->activeBoxInner_->SetSize(params.width - 2.0f, params.height - 2.0f); p->activeBoxInner_->SetSize(params.width - 2.0f, params.height - 2.0f);
@ -164,15 +165,16 @@ void OverlayLayer::Deinitialize()
DrawLayer::Deinitialize(); DrawLayer::Deinitialize();
gl::OpenGLFunctions& gl = context()->gl_; gl::OpenGLFunctions& gl = context()->gl();
auto radarProductView = context()->radar_product_view();
gl.glDeleteTextures(1, &p->texture_); gl.glDeleteTextures(1, &p->texture_);
p->texture_ = GL_INVALID_INDEX; p->texture_ = GL_INVALID_INDEX;
if (context()->radarProductView_ != nullptr) if (radarProductView != nullptr)
{ {
disconnect(context()->radarProductView_.get(), disconnect(radarProductView.get(),
&view::RadarProductView::SweepComputed, &view::RadarProductView::SweepComputed,
this, this,
&OverlayLayer::UpdateSweepTimeNextFrame); &OverlayLayer::UpdateSweepTimeNextFrame);

View file

@ -33,7 +33,7 @@ class RadarProductLayerImpl
{ {
public: public:
explicit RadarProductLayerImpl(std::shared_ptr<MapContext> context) : explicit RadarProductLayerImpl(std::shared_ptr<MapContext> context) :
shaderProgram_(context->gl_), shaderProgram_(nullptr),
uMVPMatrixLocation_(GL_INVALID_INDEX), uMVPMatrixLocation_(GL_INVALID_INDEX),
uMapScreenCoordLocation_(GL_INVALID_INDEX), uMapScreenCoordLocation_(GL_INVALID_INDEX),
uDataMomentOffsetLocation_(GL_INVALID_INDEX), uDataMomentOffsetLocation_(GL_INVALID_INDEX),
@ -50,7 +50,8 @@ public:
} }
~RadarProductLayerImpl() = default; ~RadarProductLayerImpl() = default;
gl::ShaderProgram shaderProgram_; std::shared_ptr<gl::ShaderProgram> shaderProgram_;
GLint uMVPMatrixLocation_; GLint uMVPMatrixLocation_;
GLint uMapScreenCoordLocation_; GLint uMapScreenCoordLocation_;
GLint uDataMomentOffsetLocation_; GLint uDataMomentOffsetLocation_;
@ -78,47 +79,48 @@ void RadarProductLayer::Initialize()
{ {
logger_->debug("Initialize()"); logger_->debug("Initialize()");
gl::OpenGLFunctions& gl = context()->gl_; gl::OpenGLFunctions& gl = context()->gl();
// Load and configure radar shader // Load and configure radar shader
p->shaderProgram_.Load(":/gl/radar.vert", ":/gl/radar.frag"); p->shaderProgram_ =
context()->GetShaderProgram(":/gl/radar.vert", ":/gl/radar.frag");
p->uMVPMatrixLocation_ = p->uMVPMatrixLocation_ =
gl.glGetUniformLocation(p->shaderProgram_.id(), "uMVPMatrix"); gl.glGetUniformLocation(p->shaderProgram_->id(), "uMVPMatrix");
if (p->uMVPMatrixLocation_ == -1) if (p->uMVPMatrixLocation_ == -1)
{ {
logger_->warn("Could not find uMVPMatrix"); logger_->warn("Could not find uMVPMatrix");
} }
p->uMapScreenCoordLocation_ = p->uMapScreenCoordLocation_ =
gl.glGetUniformLocation(p->shaderProgram_.id(), "uMapScreenCoord"); gl.glGetUniformLocation(p->shaderProgram_->id(), "uMapScreenCoord");
if (p->uMapScreenCoordLocation_ == -1) if (p->uMapScreenCoordLocation_ == -1)
{ {
logger_->warn("Could not find uMapScreenCoord"); logger_->warn("Could not find uMapScreenCoord");
} }
p->uDataMomentOffsetLocation_ = p->uDataMomentOffsetLocation_ =
gl.glGetUniformLocation(p->shaderProgram_.id(), "uDataMomentOffset"); gl.glGetUniformLocation(p->shaderProgram_->id(), "uDataMomentOffset");
if (p->uDataMomentOffsetLocation_ == -1) if (p->uDataMomentOffsetLocation_ == -1)
{ {
logger_->warn("Could not find uDataMomentOffset"); logger_->warn("Could not find uDataMomentOffset");
} }
p->uDataMomentScaleLocation_ = p->uDataMomentScaleLocation_ =
gl.glGetUniformLocation(p->shaderProgram_.id(), "uDataMomentScale"); gl.glGetUniformLocation(p->shaderProgram_->id(), "uDataMomentScale");
if (p->uDataMomentScaleLocation_ == -1) if (p->uDataMomentScaleLocation_ == -1)
{ {
logger_->warn("Could not find uDataMomentScale"); logger_->warn("Could not find uDataMomentScale");
} }
p->uCFPEnabledLocation_ = p->uCFPEnabledLocation_ =
gl.glGetUniformLocation(p->shaderProgram_.id(), "uCFPEnabled"); gl.glGetUniformLocation(p->shaderProgram_->id(), "uCFPEnabled");
if (p->uCFPEnabledLocation_ == -1) if (p->uCFPEnabledLocation_ == -1)
{ {
logger_->warn("Could not find uCFPEnabled"); logger_->warn("Could not find uCFPEnabled");
} }
p->shaderProgram_.Use(); p->shaderProgram_->Use();
// Generate a vertex array object // Generate a vertex array object
gl.glGenVertexArrays(1, &p->vao_); gl.glGenVertexArrays(1, &p->vao_);
@ -138,11 +140,12 @@ void RadarProductLayer::Initialize()
gl.glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gl.glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
gl.glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); gl.glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
connect(context()->radarProductView_.get(), auto radarProductView = context()->radar_product_view();
connect(radarProductView.get(),
&view::RadarProductView::ColorTableUpdated, &view::RadarProductView::ColorTableUpdated,
this, this,
[=]() { p->colorTableNeedsUpdate_ = true; }); [=]() { p->colorTableNeedsUpdate_ = true; });
connect(context()->radarProductView_.get(), connect(radarProductView.get(),
&view::RadarProductView::SweepComputed, &view::RadarProductView::SweepComputed,
this, this,
[=]() { p->sweepNeedsUpdate_ = true; }); [=]() { p->sweepNeedsUpdate_ = true; });
@ -152,12 +155,12 @@ void RadarProductLayer::UpdateSweep()
{ {
logger_->debug("UpdateSweep()"); logger_->debug("UpdateSweep()");
gl::OpenGLFunctions& gl = context()->gl_; gl::OpenGLFunctions& gl = context()->gl();
boost::timer::cpu_timer timer; boost::timer::cpu_timer timer;
std::shared_ptr<view::RadarProductView> radarProductView = std::shared_ptr<view::RadarProductView> radarProductView =
context()->radarProductView_; context()->radar_product_view();
std::unique_lock sweepLock(radarProductView->sweep_mutex(), std::unique_lock sweepLock(radarProductView->sweep_mutex(),
std::try_to_lock); std::try_to_lock);
@ -253,9 +256,9 @@ void RadarProductLayer::UpdateSweep()
void RadarProductLayer::Render( void RadarProductLayer::Render(
const QMapbox::CustomLayerRenderParameters& params) const QMapbox::CustomLayerRenderParameters& params)
{ {
gl::OpenGLFunctions& gl = context()->gl_; gl::OpenGLFunctions& gl = context()->gl();
p->shaderProgram_.Use(); p->shaderProgram_->Use();
if (p->colorTableNeedsUpdate_) if (p->colorTableNeedsUpdate_)
{ {
@ -300,7 +303,7 @@ void RadarProductLayer::Deinitialize()
{ {
logger_->debug("Deinitialize()"); logger_->debug("Deinitialize()");
gl::OpenGLFunctions& gl = context()->gl_; gl::OpenGLFunctions& gl = context()->gl();
gl.glDeleteVertexArrays(1, &p->vao_); gl.glDeleteVertexArrays(1, &p->vao_);
gl.glDeleteBuffers(3, p->vbo_.data()); gl.glDeleteBuffers(3, p->vbo_.data());
@ -321,9 +324,9 @@ void RadarProductLayer::UpdateColorTable()
p->colorTableNeedsUpdate_ = false; p->colorTableNeedsUpdate_ = false;
gl::OpenGLFunctions& gl = context()->gl_; gl::OpenGLFunctions& gl = context()->gl();
std::shared_ptr<view::RadarProductView> radarProductView = std::shared_ptr<view::RadarProductView> radarProductView =
context()->radarProductView_; context()->radar_product_view();
const std::vector<boost::gil::rgba8_pixel_t>& colorTable = const std::vector<boost::gil::rgba8_pixel_t>& colorTable =
radarProductView->color_table(); radarProductView->color_table();