mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 16:30:05 +00:00
191 lines
5.6 KiB
C++
191 lines
5.6 KiB
C++
#include <scwx/qt/map/overlay_layer.hpp>
|
|
#include <scwx/qt/gl/draw/rectangle.hpp>
|
|
#include <scwx/qt/gl/shader_program.hpp>
|
|
#include <scwx/qt/gl/text_shader.hpp>
|
|
#include <scwx/qt/util/font.hpp>
|
|
#include <scwx/util/logger.hpp>
|
|
#include <scwx/util/time.hpp>
|
|
|
|
#include <chrono>
|
|
#include <execution>
|
|
|
|
#pragma warning(push, 0)
|
|
#include <boost/date_time.hpp>
|
|
#include <boost/date_time/local_time/local_time.hpp>
|
|
#include <boost/timer/timer.hpp>
|
|
#include <GeographicLib/Geodesic.hpp>
|
|
#include <glm/glm.hpp>
|
|
#include <glm/gtc/matrix_transform.hpp>
|
|
#include <glm/gtc/type_ptr.hpp>
|
|
#include <mbgl/util/constants.hpp>
|
|
#pragma warning(pop)
|
|
|
|
namespace scwx
|
|
{
|
|
namespace qt
|
|
{
|
|
namespace map
|
|
{
|
|
|
|
static const std::string logPrefix_ = "scwx::qt::map::overlay_layer";
|
|
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
|
|
|
class OverlayLayerImpl
|
|
{
|
|
public:
|
|
explicit OverlayLayerImpl(std::shared_ptr<MapContext> context) :
|
|
textShader_(context),
|
|
font_(util::Font::Create(":/res/fonts/din1451alt.ttf")),
|
|
texture_ {GL_INVALID_INDEX},
|
|
activeBoxOuter_ {std::make_shared<gl::draw::Rectangle>(context)},
|
|
activeBoxInner_ {std::make_shared<gl::draw::Rectangle>(context)},
|
|
timeBox_ {std::make_shared<gl::draw::Rectangle>(context)},
|
|
sweepTimeString_ {},
|
|
sweepTimeNeedsUpdate_ {true}
|
|
{
|
|
// TODO: Manage font at the global level, texture at the view level
|
|
}
|
|
~OverlayLayerImpl() = default;
|
|
|
|
gl::TextShader textShader_;
|
|
std::shared_ptr<util::Font> font_;
|
|
GLuint texture_;
|
|
|
|
std::shared_ptr<gl::draw::Rectangle> activeBoxOuter_;
|
|
std::shared_ptr<gl::draw::Rectangle> activeBoxInner_;
|
|
std::shared_ptr<gl::draw::Rectangle> timeBox_;
|
|
|
|
std::string sweepTimeString_;
|
|
bool sweepTimeNeedsUpdate_;
|
|
};
|
|
|
|
OverlayLayer::OverlayLayer(std::shared_ptr<MapContext> context) :
|
|
DrawLayer(context), p(std::make_unique<OverlayLayerImpl>(context))
|
|
{
|
|
AddDrawItem(p->timeBox_);
|
|
AddDrawItem(p->activeBoxOuter_);
|
|
AddDrawItem(p->activeBoxInner_);
|
|
|
|
p->activeBoxOuter_->SetPosition(0.0f, 0.0f);
|
|
p->activeBoxOuter_->SetBorder(1.0f, {0, 0, 0, 255});
|
|
p->activeBoxInner_->SetBorder(1.0f, {255, 255, 255, 255});
|
|
p->activeBoxInner_->SetPosition(1.0f, 1.0f);
|
|
p->timeBox_->SetFill({0, 0, 0, 192});
|
|
}
|
|
|
|
OverlayLayer::~OverlayLayer() = default;
|
|
|
|
void OverlayLayer::Initialize()
|
|
{
|
|
logger_->debug("Initialize()");
|
|
|
|
DrawLayer::Initialize();
|
|
|
|
gl::OpenGLFunctions& gl = context()->gl();
|
|
auto radarProductView = context()->radar_product_view();
|
|
|
|
p->textShader_.Initialize();
|
|
|
|
if (p->texture_ == GL_INVALID_INDEX)
|
|
{
|
|
p->texture_ = p->font_->GenerateTexture(gl);
|
|
}
|
|
|
|
if (radarProductView != nullptr)
|
|
{
|
|
connect(radarProductView.get(),
|
|
&view::RadarProductView::SweepComputed,
|
|
this,
|
|
&OverlayLayer::UpdateSweepTimeNextFrame);
|
|
}
|
|
}
|
|
|
|
void OverlayLayer::Render(const QMapbox::CustomLayerRenderParameters& params)
|
|
{
|
|
constexpr float fontSize = 16.0f;
|
|
|
|
gl::OpenGLFunctions& gl = context()->gl();
|
|
auto radarProductView = context()->radar_product_view();
|
|
auto& settings = context()->settings();
|
|
|
|
if (p->sweepTimeNeedsUpdate_ && radarProductView != nullptr)
|
|
{
|
|
p->sweepTimeString_ = scwx::util::TimeString(
|
|
radarProductView->sweep_time(), std::chrono::current_zone(), false);
|
|
p->sweepTimeNeedsUpdate_ = false;
|
|
}
|
|
|
|
glm::mat4 projection = glm::ortho(0.0f,
|
|
static_cast<float>(params.width),
|
|
0.0f,
|
|
static_cast<float>(params.height));
|
|
|
|
// Active Box
|
|
p->activeBoxOuter_->SetVisible(settings.isActive_);
|
|
p->activeBoxInner_->SetVisible(settings.isActive_);
|
|
if (settings.isActive_)
|
|
{
|
|
p->activeBoxOuter_->SetSize(params.width, params.height);
|
|
p->activeBoxInner_->SetSize(params.width - 2.0f, params.height - 2.0f);
|
|
}
|
|
|
|
if (p->sweepTimeString_.length() > 0)
|
|
{
|
|
const float textLength =
|
|
p->font_->TextLength(p->sweepTimeString_, fontSize);
|
|
|
|
p->timeBox_->SetPosition(static_cast<float>(params.width) - textLength -
|
|
14.0f,
|
|
static_cast<float>(params.height) - 22.0f);
|
|
p->timeBox_->SetSize(textLength + 14.0f, 22.0f);
|
|
}
|
|
|
|
DrawLayer::Render(params);
|
|
|
|
if (p->sweepTimeString_.length() > 0)
|
|
{
|
|
// Render time
|
|
p->textShader_.RenderText(p->sweepTimeString_,
|
|
params.width - 7.0f,
|
|
static_cast<float>(params.height) - 16.0f,
|
|
fontSize,
|
|
projection,
|
|
boost::gil::rgba8_pixel_t(255, 255, 255, 204),
|
|
p->font_,
|
|
p->texture_,
|
|
gl::TextAlign::Right);
|
|
}
|
|
|
|
SCWX_GL_CHECK_ERROR();
|
|
}
|
|
|
|
void OverlayLayer::Deinitialize()
|
|
{
|
|
logger_->debug("Deinitialize()");
|
|
|
|
DrawLayer::Deinitialize();
|
|
|
|
gl::OpenGLFunctions& gl = context()->gl();
|
|
auto radarProductView = context()->radar_product_view();
|
|
|
|
gl.glDeleteTextures(1, &p->texture_);
|
|
|
|
p->texture_ = GL_INVALID_INDEX;
|
|
|
|
if (radarProductView != nullptr)
|
|
{
|
|
disconnect(radarProductView.get(),
|
|
&view::RadarProductView::SweepComputed,
|
|
this,
|
|
&OverlayLayer::UpdateSweepTimeNextFrame);
|
|
}
|
|
}
|
|
|
|
void OverlayLayer::UpdateSweepTimeNextFrame()
|
|
{
|
|
p->sweepTimeNeedsUpdate_ = true;
|
|
}
|
|
|
|
} // namespace map
|
|
} // namespace qt
|
|
} // namespace scwx
|