mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 16:10:04 +00:00
Add visibility to icon draw items
This commit is contained in:
parent
d905abd3e7
commit
931b5d8481
7 changed files with 248 additions and 102 deletions
|
|
@ -25,6 +25,7 @@ out VertexData
|
||||||
vec3 texCoord;
|
vec3 texCoord;
|
||||||
vec4 color;
|
vec4 color;
|
||||||
ivec2 timeRange;
|
ivec2 timeRange;
|
||||||
|
bool displayed;
|
||||||
} vsOut;
|
} vsOut;
|
||||||
|
|
||||||
smooth out vec3 texCoord;
|
smooth out vec3 texCoord;
|
||||||
|
|
@ -41,6 +42,9 @@ vec2 latLngToScreenCoordinate(in vec2 latLng)
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
// Always set displayed to true
|
||||||
|
vsOut.displayed = true;
|
||||||
|
|
||||||
// Pass the threshold and time range to the geometry shader
|
// Pass the threshold and time range to the geometry shader
|
||||||
vsOut.threshold = aThreshold;
|
vsOut.threshold = aThreshold;
|
||||||
vsOut.timeRange = aTimeRange;
|
vsOut.timeRange = aTimeRange;
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,16 @@ out VertexData
|
||||||
vec3 texCoord;
|
vec3 texCoord;
|
||||||
vec4 color;
|
vec4 color;
|
||||||
ivec2 timeRange;
|
ivec2 timeRange;
|
||||||
|
bool displayed;
|
||||||
} vsOut;
|
} vsOut;
|
||||||
|
|
||||||
smooth out vec4 color;
|
smooth out vec4 color;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
// Always set displayed to true
|
||||||
|
vsOut.displayed = true;
|
||||||
|
|
||||||
// Pass the threshold and time range to the geometry shader
|
// Pass the threshold and time range to the geometry shader
|
||||||
vsOut.threshold = aThreshold;
|
vsOut.threshold = aThreshold;
|
||||||
vsOut.timeRange = aTimeRange;
|
vsOut.timeRange = aTimeRange;
|
||||||
|
|
|
||||||
|
|
@ -7,20 +7,42 @@ layout (location = 1) in vec2 aXYOffset;
|
||||||
layout (location = 2) in vec3 aTexCoord;
|
layout (location = 2) in vec3 aTexCoord;
|
||||||
layout (location = 3) in vec4 aModulate;
|
layout (location = 3) in vec4 aModulate;
|
||||||
layout (location = 4) in float aAngleDeg;
|
layout (location = 4) in float aAngleDeg;
|
||||||
|
layout (location = 5) in int aDisplayed;
|
||||||
|
|
||||||
uniform mat4 uMVPMatrix;
|
uniform mat4 uMVPMatrix;
|
||||||
|
|
||||||
|
out VertexData
|
||||||
|
{
|
||||||
|
int threshold;
|
||||||
|
vec3 texCoord;
|
||||||
|
vec4 color;
|
||||||
|
ivec2 timeRange;
|
||||||
|
bool displayed;
|
||||||
|
} vsOut;
|
||||||
|
|
||||||
smooth out vec3 texCoord;
|
smooth out vec3 texCoord;
|
||||||
smooth out vec4 color;
|
smooth out vec4 color;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
// Always set threshold and time range to zero
|
||||||
|
vsOut.threshold = 0;
|
||||||
|
vsOut.timeRange = ivec2(0, 0);
|
||||||
|
|
||||||
|
// Pass displayed to the geometry shader
|
||||||
|
vsOut.displayed = (aDisplayed != 0);
|
||||||
|
|
||||||
|
// Pass the texture coordinate and color modulate to the geometry and
|
||||||
|
// fragment shaders
|
||||||
|
vsOut.texCoord = aTexCoord;
|
||||||
|
vsOut.color = aModulate;
|
||||||
|
texCoord = aTexCoord;
|
||||||
|
color = aModulate;
|
||||||
|
|
||||||
// Rotate clockwise
|
// Rotate clockwise
|
||||||
float angle = aAngleDeg * DEG2RAD;
|
float angle = aAngleDeg * DEG2RAD;
|
||||||
mat2 rotate = mat2(cos(angle), -sin(angle),
|
mat2 rotate = mat2(cos(angle), -sin(angle),
|
||||||
sin(angle), cos(angle));
|
sin(angle), cos(angle));
|
||||||
|
|
||||||
gl_Position = uMVPMatrix * vec4(aVertex + rotate * aXYOffset, 0.0f, 1.0f);
|
gl_Position = uMVPMatrix * vec4(aVertex + rotate * aXYOffset, 0.0f, 1.0f);
|
||||||
texCoord = aTexCoord;
|
|
||||||
color = aModulate;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ in VertexData
|
||||||
vec3 texCoord;
|
vec3 texCoord;
|
||||||
vec4 color;
|
vec4 color;
|
||||||
ivec2 timeRange;
|
ivec2 timeRange;
|
||||||
|
bool displayed;
|
||||||
} gsIn[];
|
} gsIn[];
|
||||||
|
|
||||||
smooth out vec3 texCoord;
|
smooth out vec3 texCoord;
|
||||||
|
|
@ -19,7 +20,8 @@ smooth out vec4 color;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
if ((gsIn[0].threshold <= 0 || // If Threshold: 0 was specified, no threshold
|
if (gsIn[0].displayed &&
|
||||||
|
(gsIn[0].threshold <= 0 || // If Threshold: 0 was specified, no threshold
|
||||||
gsIn[0].threshold >= uMapDistance || // If Threshold is above current map distance
|
gsIn[0].threshold >= uMapDistance || // If Threshold is above current map distance
|
||||||
gsIn[0].threshold >= 999) && // If Threshold: 999 was specified (or greater), no threshold
|
gsIn[0].threshold >= 999) && // If Threshold: 999 was specified (or greater), no threshold
|
||||||
(gsIn[0].timeRange[0] == 0 || // If there is no start time specified
|
(gsIn[0].timeRange[0] == 0 || // If there is no start time specified
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include <execution>
|
#include <execution>
|
||||||
|
|
||||||
#include <boost/unordered/unordered_flat_map.hpp>
|
#include <boost/unordered/unordered_flat_map.hpp>
|
||||||
|
#include <boost/unordered/unordered_flat_set.hpp>
|
||||||
|
|
||||||
namespace scwx
|
namespace scwx
|
||||||
{
|
{
|
||||||
|
|
@ -24,7 +25,7 @@ static constexpr std::size_t kNumRectangles = 1;
|
||||||
static constexpr std::size_t kNumTriangles = kNumRectangles * 2;
|
static constexpr std::size_t kNumTriangles = kNumRectangles * 2;
|
||||||
static constexpr std::size_t kVerticesPerTriangle = 3;
|
static constexpr std::size_t kVerticesPerTriangle = 3;
|
||||||
static constexpr std::size_t kVerticesPerRectangle = kVerticesPerTriangle * 2;
|
static constexpr std::size_t kVerticesPerRectangle = kVerticesPerTriangle * 2;
|
||||||
static constexpr std::size_t kPointsPerVertex = 9;
|
static constexpr std::size_t kPointsPerVertex = 10;
|
||||||
static constexpr std::size_t kPointsPerTexCoord = 3;
|
static constexpr std::size_t kPointsPerTexCoord = 3;
|
||||||
static constexpr std::size_t kIconBufferLength =
|
static constexpr std::size_t kIconBufferLength =
|
||||||
kNumTriangles * kVerticesPerTriangle * kPointsPerVertex;
|
kNumTriangles * kVerticesPerTriangle * kPointsPerVertex;
|
||||||
|
|
@ -34,12 +35,15 @@ static constexpr std::size_t kTextureBufferLength =
|
||||||
struct IconDrawItem : types::EventHandler
|
struct IconDrawItem : types::EventHandler
|
||||||
{
|
{
|
||||||
boost::gil::rgba32f_pixel_t modulate_ {1.0f, 1.0f, 1.0f, 1.0f};
|
boost::gil::rgba32f_pixel_t modulate_ {1.0f, 1.0f, 1.0f, 1.0f};
|
||||||
|
bool visible_ {true};
|
||||||
double x_ {};
|
double x_ {};
|
||||||
double y_ {};
|
double y_ {};
|
||||||
units::degrees<double> angle_ {};
|
units::degrees<double> angle_ {};
|
||||||
std::string iconSheet_ {};
|
std::string iconSheet_ {};
|
||||||
std::size_t iconIndex_ {};
|
std::size_t iconIndex_ {};
|
||||||
std::string hoverText_ {};
|
std::string hoverText_ {};
|
||||||
|
|
||||||
|
std::shared_ptr<types::IconInfo> iconInfo_ {};
|
||||||
};
|
};
|
||||||
|
|
||||||
class Icons::Impl
|
class Icons::Impl
|
||||||
|
|
@ -68,7 +72,12 @@ public:
|
||||||
~Impl() {}
|
~Impl() {}
|
||||||
|
|
||||||
void UpdateBuffers();
|
void UpdateBuffers();
|
||||||
|
static void UpdateSingleBuffer(const std::shared_ptr<IconDrawItem>& di,
|
||||||
|
std::size_t iconIndex,
|
||||||
|
std::vector<float>& iconBuffer,
|
||||||
|
std::vector<IconHoverEntry>& hoverIcons);
|
||||||
void UpdateTextureBuffer();
|
void UpdateTextureBuffer();
|
||||||
|
void UpdateModifiedIconBuffers();
|
||||||
void Update(bool textureAtlasChanged);
|
void Update(bool textureAtlasChanged);
|
||||||
|
|
||||||
std::shared_ptr<GlContext> context_;
|
std::shared_ptr<GlContext> context_;
|
||||||
|
|
@ -77,6 +86,8 @@ public:
|
||||||
bool dirty_ {false};
|
bool dirty_ {false};
|
||||||
bool lastTextureAtlasChanged_ {false};
|
bool lastTextureAtlasChanged_ {false};
|
||||||
|
|
||||||
|
boost::unordered_flat_set<std::shared_ptr<IconDrawItem>> dirtyIcons_ {};
|
||||||
|
|
||||||
std::mutex iconMutex_;
|
std::mutex iconMutex_;
|
||||||
|
|
||||||
boost::unordered_flat_map<std::string, std::shared_ptr<types::IconInfo>>
|
boost::unordered_flat_map<std::string, std::shared_ptr<types::IconInfo>>
|
||||||
|
|
@ -120,6 +131,7 @@ void Icons::Initialize()
|
||||||
|
|
||||||
p->shaderProgram_ = p->context_->GetShaderProgram(
|
p->shaderProgram_ = p->context_->GetShaderProgram(
|
||||||
{{GL_VERTEX_SHADER, ":/gl/texture2d_array.vert"},
|
{{GL_VERTEX_SHADER, ":/gl/texture2d_array.vert"},
|
||||||
|
{GL_GEOMETRY_SHADER, ":/gl/threshold.geom"},
|
||||||
{GL_FRAGMENT_SHADER, ":/gl/texture2d_array.frag"}});
|
{GL_FRAGMENT_SHADER, ":/gl/texture2d_array.frag"}});
|
||||||
|
|
||||||
p->uMVPMatrixLocation_ = p->shaderProgram_->GetUniformLocation("uMVPMatrix");
|
p->uMVPMatrixLocation_ = p->shaderProgram_->GetUniformLocation("uMVPMatrix");
|
||||||
|
|
@ -167,6 +179,15 @@ void Icons::Initialize()
|
||||||
reinterpret_cast<void*>(8 * sizeof(float)));
|
reinterpret_cast<void*>(8 * sizeof(float)));
|
||||||
gl.glEnableVertexAttribArray(4);
|
gl.glEnableVertexAttribArray(4);
|
||||||
|
|
||||||
|
// aAngle
|
||||||
|
gl.glVertexAttribPointer(5,
|
||||||
|
1,
|
||||||
|
GL_FLOAT,
|
||||||
|
GL_FALSE,
|
||||||
|
kPointsPerVertex * sizeof(float),
|
||||||
|
reinterpret_cast<void*>(9 * sizeof(float)));
|
||||||
|
gl.glEnableVertexAttribArray(5);
|
||||||
|
|
||||||
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]);
|
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]);
|
||||||
gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
|
@ -292,12 +313,20 @@ std::shared_ptr<IconDrawItem> Icons::AddIcon()
|
||||||
return p->newIconList_.emplace_back(std::make_shared<IconDrawItem>());
|
return p->newIconList_.emplace_back(std::make_shared<IconDrawItem>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Icons::SetIconVisible(const std::shared_ptr<IconDrawItem>& di,
|
||||||
|
bool visible)
|
||||||
|
{
|
||||||
|
di->visible_ = visible;
|
||||||
|
p->dirtyIcons_.insert(di);
|
||||||
|
}
|
||||||
|
|
||||||
void Icons::SetIconTexture(const std::shared_ptr<IconDrawItem>& di,
|
void Icons::SetIconTexture(const std::shared_ptr<IconDrawItem>& di,
|
||||||
const std::string& iconSheet,
|
const std::string& iconSheet,
|
||||||
std::size_t iconIndex)
|
std::size_t iconIndex)
|
||||||
{
|
{
|
||||||
di->iconSheet_ = iconSheet;
|
di->iconSheet_ = iconSheet;
|
||||||
di->iconIndex_ = iconIndex;
|
di->iconIndex_ = iconIndex;
|
||||||
|
p->dirtyIcons_.insert(di);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Icons::SetIconLocation(const std::shared_ptr<IconDrawItem>& di,
|
void Icons::SetIconLocation(const std::shared_ptr<IconDrawItem>& di,
|
||||||
|
|
@ -306,12 +335,14 @@ void Icons::SetIconLocation(const std::shared_ptr<IconDrawItem>& di,
|
||||||
{
|
{
|
||||||
di->x_ = x;
|
di->x_ = x;
|
||||||
di->y_ = y;
|
di->y_ = y;
|
||||||
|
p->dirtyIcons_.insert(di);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Icons::SetIconAngle(const std::shared_ptr<IconDrawItem>& di,
|
void Icons::SetIconAngle(const std::shared_ptr<IconDrawItem>& di,
|
||||||
units::angle::degrees<double> angle)
|
units::angle::degrees<double> angle)
|
||||||
{
|
{
|
||||||
di->angle_ = angle;
|
di->angle_ = angle;
|
||||||
|
p->dirtyIcons_.insert(di);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Icons::SetIconModulate(const std::shared_ptr<IconDrawItem>& di,
|
void Icons::SetIconModulate(const std::shared_ptr<IconDrawItem>& di,
|
||||||
|
|
@ -321,18 +352,21 @@ void Icons::SetIconModulate(const std::shared_ptr<IconDrawItem>& di,
|
||||||
modulate[1] / 255.0f,
|
modulate[1] / 255.0f,
|
||||||
modulate[2] / 255.0f,
|
modulate[2] / 255.0f,
|
||||||
modulate[3] / 255.0f};
|
modulate[3] / 255.0f};
|
||||||
|
p->dirtyIcons_.insert(di);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Icons::SetIconModulate(const std::shared_ptr<IconDrawItem>& di,
|
void Icons::SetIconModulate(const std::shared_ptr<IconDrawItem>& di,
|
||||||
boost::gil::rgba32f_pixel_t modulate)
|
boost::gil::rgba32f_pixel_t modulate)
|
||||||
{
|
{
|
||||||
di->modulate_ = modulate;
|
di->modulate_ = modulate;
|
||||||
|
p->dirtyIcons_.insert(di);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Icons::SetIconHoverText(const std::shared_ptr<IconDrawItem>& di,
|
void Icons::SetIconHoverText(const std::shared_ptr<IconDrawItem>& di,
|
||||||
const std::string& text)
|
const std::string& text)
|
||||||
{
|
{
|
||||||
di->hoverText_ = text;
|
di->hoverText_ = text;
|
||||||
|
p->dirtyIcons_.insert(di);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Icons::FinishIcons()
|
void Icons::FinishIcons()
|
||||||
|
|
@ -375,6 +409,7 @@ void Icons::Impl::UpdateBuffers()
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& icon = it->second;
|
auto& icon = it->second;
|
||||||
|
di->iconInfo_ = icon;
|
||||||
|
|
||||||
// Validate icon
|
// Validate icon
|
||||||
if (di->iconIndex_ >= icon->numIcons_)
|
if (di->iconIndex_ >= icon->numIcons_)
|
||||||
|
|
@ -387,6 +422,22 @@ void Icons::Impl::UpdateBuffers()
|
||||||
// Icon is valid, add to valid icon list
|
// Icon is valid, add to valid icon list
|
||||||
newValidIconList_.push_back(di);
|
newValidIconList_.push_back(di);
|
||||||
|
|
||||||
|
// Update icon buffer
|
||||||
|
UpdateSingleBuffer(
|
||||||
|
di, newValidIconList_.size() - 1, newIconBuffer_, newHoverIcons_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// All icons have been updated
|
||||||
|
dirtyIcons_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Icons::Impl::UpdateSingleBuffer(const std::shared_ptr<IconDrawItem>& di,
|
||||||
|
std::size_t iconIndex,
|
||||||
|
std::vector<float>& iconBuffer,
|
||||||
|
std::vector<IconHoverEntry>& hoverIcons)
|
||||||
|
{
|
||||||
|
auto& icon = di->iconInfo_;
|
||||||
|
|
||||||
// Base X/Y offsets in pixels
|
// Base X/Y offsets in pixels
|
||||||
const float x = static_cast<float>(di->x_);
|
const float x = static_cast<float>(di->x_);
|
||||||
const float y = static_cast<float>(di->y_);
|
const float y = static_cast<float>(di->y_);
|
||||||
|
|
@ -415,18 +466,43 @@ void Icons::Impl::UpdateBuffers()
|
||||||
const float mc2 = di->modulate_[2];
|
const float mc2 = di->modulate_[2];
|
||||||
const float mc3 = di->modulate_[3];
|
const float mc3 = di->modulate_[3];
|
||||||
|
|
||||||
newIconBuffer_.insert(newIconBuffer_.end(),
|
// Visibility
|
||||||
{
|
const float v = static_cast<float>(di->visible_);
|
||||||
// Icon
|
|
||||||
x, y, lx, by, mc0, mc1, mc2, mc3, a, // BL
|
|
||||||
x, y, lx, ty, mc0, mc1, mc2, mc3, a, // TL
|
|
||||||
x, y, rx, by, mc0, mc1, mc2, mc3, a, // BR
|
|
||||||
x, y, rx, by, mc0, mc1, mc2, mc3, a, // BR
|
|
||||||
x, y, rx, ty, mc0, mc1, mc2, mc3, a, // TR
|
|
||||||
x, y, lx, ty, mc0, mc1, mc2, mc3, a // TL
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!di->hoverText_.empty() || di->event_ != nullptr)
|
// Icon initializer list data
|
||||||
|
const auto iconData = {
|
||||||
|
// Icon
|
||||||
|
x, y, lx, by, mc0, mc1, mc2, mc3, a, v, // BL
|
||||||
|
x, y, lx, ty, mc0, mc1, mc2, mc3, a, v, // TL
|
||||||
|
x, y, rx, by, mc0, mc1, mc2, mc3, a, v, // BR
|
||||||
|
x, y, rx, by, mc0, mc1, mc2, mc3, a, v, // BR
|
||||||
|
x, y, rx, ty, mc0, mc1, mc2, mc3, a, v, // TR
|
||||||
|
x, y, lx, ty, mc0, mc1, mc2, mc3, a, v // TL
|
||||||
|
};
|
||||||
|
|
||||||
|
// Buffer position data
|
||||||
|
auto iconBufferPosition = iconBuffer.end();
|
||||||
|
auto iconBufferOffset = iconIndex * kIconBufferLength;
|
||||||
|
|
||||||
|
if (iconBufferOffset < iconBuffer.size())
|
||||||
|
{
|
||||||
|
iconBufferPosition = iconBuffer.begin() + iconBufferOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iconBufferPosition == iconBuffer.cend())
|
||||||
|
{
|
||||||
|
iconBuffer.insert(iconBufferPosition, iconData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::copy(iconData.begin(), iconData.end(), iconBufferPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto hoverIt = std::find_if(hoverIcons.begin(),
|
||||||
|
hoverIcons.end(),
|
||||||
|
[&di](auto& entry) { return entry.di_ == di; });
|
||||||
|
|
||||||
|
if (di->visible_ && (!di->hoverText_.empty() || di->event_ != nullptr))
|
||||||
{
|
{
|
||||||
const units::angle::radians<double> radians = angle;
|
const units::angle::radians<double> radians = angle;
|
||||||
|
|
||||||
|
|
@ -440,8 +516,21 @@ void Icons::Impl::UpdateBuffers()
|
||||||
const glm::vec2 obl = rotate * glm::vec2 {lx, by};
|
const glm::vec2 obl = rotate * glm::vec2 {lx, by};
|
||||||
const glm::vec2 obr = rotate * glm::vec2 {rx, by};
|
const glm::vec2 obr = rotate * glm::vec2 {rx, by};
|
||||||
|
|
||||||
newHoverIcons_.emplace_back(IconHoverEntry {di, otl, otr, obl, obr});
|
if (hoverIt == hoverIcons.end())
|
||||||
|
{
|
||||||
|
hoverIcons.emplace_back(IconHoverEntry {di, otl, otr, obl, obr});
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hoverIt->otl_ = otl;
|
||||||
|
hoverIt->otr_ = otr;
|
||||||
|
hoverIt->obl_ = obl;
|
||||||
|
hoverIt->obr_ = obr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (hoverIt != hoverIcons.end())
|
||||||
|
{
|
||||||
|
hoverIcons.erase(hoverIt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -533,10 +622,40 @@ void Icons::Impl::UpdateTextureBuffer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Icons::Impl::UpdateModifiedIconBuffers()
|
||||||
|
{
|
||||||
|
// Update buffers for modified icons
|
||||||
|
for (auto& di : dirtyIcons_)
|
||||||
|
{
|
||||||
|
// Find modified icon in the current list
|
||||||
|
auto it =
|
||||||
|
std::find(currentIconList_.cbegin(), currentIconList_.cend(), di);
|
||||||
|
|
||||||
|
// Ignore invalid icons
|
||||||
|
if (it == currentIconList_.cend())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto iconIndex = std::distance(currentIconList_.cbegin(), it);
|
||||||
|
|
||||||
|
UpdateSingleBuffer(di, iconIndex, currentIconBuffer_, currentHoverIcons_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear list of modified icons
|
||||||
|
if (!dirtyIcons_.empty())
|
||||||
|
{
|
||||||
|
dirtyIcons_.clear();
|
||||||
|
dirty_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Icons::Impl::Update(bool textureAtlasChanged)
|
void Icons::Impl::Update(bool textureAtlasChanged)
|
||||||
{
|
{
|
||||||
gl::OpenGLFunctions& gl = context_->gl();
|
gl::OpenGLFunctions& gl = context_->gl();
|
||||||
|
|
||||||
|
UpdateModifiedIconBuffers();
|
||||||
|
|
||||||
// If the texture atlas has changed
|
// If the texture atlas has changed
|
||||||
if (dirty_ || textureAtlasChanged || lastTextureAtlasChanged_)
|
if (dirty_ || textureAtlasChanged || lastTextureAtlasChanged_)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,12 @@ public:
|
||||||
*/
|
*/
|
||||||
std::shared_ptr<IconDrawItem> AddIcon();
|
std::shared_ptr<IconDrawItem> AddIcon();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param [in] di Icon draw item
|
||||||
|
* @param [in] visible Visibility of the icon
|
||||||
|
*/
|
||||||
|
void SetIconVisible(const std::shared_ptr<IconDrawItem>& di, bool visible);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the texture of an icon.
|
* Sets the texture of an icon.
|
||||||
*
|
*
|
||||||
|
|
@ -103,7 +109,7 @@ public:
|
||||||
* @param [in] iconSheet The name of the icon sheet in the texture atlas
|
* @param [in] iconSheet The name of the icon sheet in the texture atlas
|
||||||
* @param [in] iconIndex The zero-based index of the icon in the icon sheet
|
* @param [in] iconIndex The zero-based index of the icon in the icon sheet
|
||||||
*/
|
*/
|
||||||
static void SetIconTexture(const std::shared_ptr<IconDrawItem>& di,
|
void SetIconTexture(const std::shared_ptr<IconDrawItem>& di,
|
||||||
const std::string& iconSheet,
|
const std::string& iconSheet,
|
||||||
std::size_t iconIndex);
|
std::size_t iconIndex);
|
||||||
|
|
||||||
|
|
@ -114,7 +120,7 @@ public:
|
||||||
* @param [in] x The x location of the icon in pixels.
|
* @param [in] x The x location of the icon in pixels.
|
||||||
* @param [in] y The y location of the icon in pixels.
|
* @param [in] y The y location of the icon in pixels.
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
SetIconLocation(const std::shared_ptr<IconDrawItem>& di, double x, double y);
|
SetIconLocation(const std::shared_ptr<IconDrawItem>& di, double x, double y);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -123,7 +129,7 @@ public:
|
||||||
* @param [in] di Icon draw item
|
* @param [in] di Icon draw item
|
||||||
* @param [in] angle Angle in degrees
|
* @param [in] angle Angle in degrees
|
||||||
*/
|
*/
|
||||||
static void SetIconAngle(const std::shared_ptr<IconDrawItem>& di,
|
void SetIconAngle(const std::shared_ptr<IconDrawItem>& di,
|
||||||
units::angle::degrees<double> angle);
|
units::angle::degrees<double> angle);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -132,7 +138,7 @@ public:
|
||||||
* @param [in] di Icon draw item
|
* @param [in] di Icon draw item
|
||||||
* @param [in] modulate Modulate color
|
* @param [in] modulate Modulate color
|
||||||
*/
|
*/
|
||||||
static void SetIconModulate(const std::shared_ptr<IconDrawItem>& di,
|
void SetIconModulate(const std::shared_ptr<IconDrawItem>& di,
|
||||||
boost::gil::rgba8_pixel_t modulate);
|
boost::gil::rgba8_pixel_t modulate);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -141,7 +147,7 @@ public:
|
||||||
* @param [in] di Icon draw item
|
* @param [in] di Icon draw item
|
||||||
* @param [in] modulate Modulate color
|
* @param [in] modulate Modulate color
|
||||||
*/
|
*/
|
||||||
static void SetIconModulate(const std::shared_ptr<IconDrawItem>& di,
|
void SetIconModulate(const std::shared_ptr<IconDrawItem>& di,
|
||||||
boost::gil::rgba32f_pixel_t modulate);
|
boost::gil::rgba32f_pixel_t modulate);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -150,7 +156,7 @@ public:
|
||||||
* @param [in] di Icon draw item
|
* @param [in] di Icon draw item
|
||||||
* @param [in] text Hover text
|
* @param [in] text Hover text
|
||||||
*/
|
*/
|
||||||
static void SetIconHoverText(const std::shared_ptr<IconDrawItem>& di,
|
void SetIconHoverText(const std::shared_ptr<IconDrawItem>& di,
|
||||||
const std::string& text);
|
const std::string& text);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <scwx/qt/manager/font_manager.hpp>
|
#include <scwx/qt/manager/font_manager.hpp>
|
||||||
#include <scwx/qt/manager/position_manager.hpp>
|
#include <scwx/qt/manager/position_manager.hpp>
|
||||||
#include <scwx/qt/map/map_settings.hpp>
|
#include <scwx/qt/map/map_settings.hpp>
|
||||||
|
#include <scwx/qt/settings/general_settings.hpp>
|
||||||
#include <scwx/qt/types/texture_types.hpp>
|
#include <scwx/qt/types/texture_types.hpp>
|
||||||
#include <scwx/qt/view/radar_product_view.hpp>
|
#include <scwx/qt/view/radar_product_view.hpp>
|
||||||
#include <scwx/util/logger.hpp>
|
#include <scwx/util/logger.hpp>
|
||||||
|
|
@ -74,7 +75,6 @@ public:
|
||||||
types::GetTextureName(types::ImageTexture::MapTilerLogo)};
|
types::GetTextureName(types::ImageTexture::MapTilerLogo)};
|
||||||
|
|
||||||
std::shared_ptr<gl::draw::IconDrawItem> compassIcon_ {};
|
std::shared_ptr<gl::draw::IconDrawItem> compassIcon_ {};
|
||||||
bool compassIconDirty_ {false};
|
|
||||||
double lastBearing_ {0.0};
|
double lastBearing_ {0.0};
|
||||||
|
|
||||||
std::shared_ptr<gl::draw::IconDrawItem> mapLogoIcon_ {};
|
std::shared_ptr<gl::draw::IconDrawItem> mapLogoIcon_ {};
|
||||||
|
|
@ -147,8 +147,7 @@ void OverlayLayer::Initialize()
|
||||||
|
|
||||||
p->icons_->StartIcons();
|
p->icons_->StartIcons();
|
||||||
p->compassIcon_ = p->icons_->AddIcon();
|
p->compassIcon_ = p->icons_->AddIcon();
|
||||||
gl::draw::Icons::SetIconTexture(
|
p->icons_->SetIconTexture(p->compassIcon_, p->cardinalPointIconName_, 0);
|
||||||
p->compassIcon_, p->cardinalPointIconName_, 0);
|
|
||||||
gl::draw::Icons::RegisterEventHandler(
|
gl::draw::Icons::RegisterEventHandler(
|
||||||
p->compassIcon_,
|
p->compassIcon_,
|
||||||
[this](QEvent* ev)
|
[this](QEvent* ev)
|
||||||
|
|
@ -157,18 +156,16 @@ void OverlayLayer::Initialize()
|
||||||
{
|
{
|
||||||
case QEvent::Type::Enter:
|
case QEvent::Type::Enter:
|
||||||
// Highlight icon on mouse enter
|
// Highlight icon on mouse enter
|
||||||
gl::draw::Icons::SetIconModulate(
|
p->icons_->SetIconModulate(
|
||||||
p->compassIcon_,
|
p->compassIcon_,
|
||||||
boost::gil::rgba32f_pixel_t {1.5f, 1.5f, 1.5f, 1.0f});
|
boost::gil::rgba32f_pixel_t {1.5f, 1.5f, 1.5f, 1.0f});
|
||||||
p->compassIconDirty_ = true;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QEvent::Type::Leave:
|
case QEvent::Type::Leave:
|
||||||
// Restore icon on mouse leave
|
// Restore icon on mouse leave
|
||||||
gl::draw::Icons::SetIconModulate(
|
p->icons_->SetIconModulate(
|
||||||
p->compassIcon_,
|
p->compassIcon_,
|
||||||
boost::gil::rgba32f_pixel_t {1.0f, 1.0f, 1.0f, 1.0f});
|
boost::gil::rgba32f_pixel_t {1.0f, 1.0f, 1.0f, 1.0f});
|
||||||
p->compassIconDirty_ = true;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QEvent::Type::MouseButtonPress:
|
case QEvent::Type::MouseButtonPress:
|
||||||
|
|
@ -196,13 +193,11 @@ void OverlayLayer::Initialize()
|
||||||
p->mapLogoIcon_ = p->icons_->AddIcon();
|
p->mapLogoIcon_ = p->icons_->AddIcon();
|
||||||
if (context()->map_provider() == MapProvider::Mapbox)
|
if (context()->map_provider() == MapProvider::Mapbox)
|
||||||
{
|
{
|
||||||
gl::draw::Icons::SetIconTexture(
|
p->icons_->SetIconTexture(p->mapLogoIcon_, p->mapboxLogoImageName_, 0);
|
||||||
p->mapLogoIcon_, p->mapboxLogoImageName_, 0);
|
|
||||||
}
|
}
|
||||||
else if (context()->map_provider() == MapProvider::MapTiler)
|
else if (context()->map_provider() == MapProvider::MapTiler)
|
||||||
{
|
{
|
||||||
gl::draw::Icons::SetIconTexture(
|
p->icons_->SetIconTexture(p->mapLogoIcon_, p->mapTilerLogoImageName_, 0);
|
||||||
p->mapLogoIcon_, p->mapTilerLogoImageName_, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p->icons_->FinishIcons();
|
p->icons_->FinishIcons();
|
||||||
|
|
@ -283,42 +278,29 @@ void OverlayLayer::Render(const QMapLibre::CustomLayerRenderParameters& params)
|
||||||
ImGui::GetFontSize() != p->lastFontSize_)
|
ImGui::GetFontSize() != p->lastFontSize_)
|
||||||
{
|
{
|
||||||
// Set the compass icon in the upper right, below the sweep time window
|
// Set the compass icon in the upper right, below the sweep time window
|
||||||
gl::draw::Icons::SetIconLocation(p->compassIcon_,
|
p->icons_->SetIconLocation(p->compassIcon_,
|
||||||
params.width - 24,
|
params.width - 24,
|
||||||
params.height -
|
params.height - (ImGui::GetFontSize() + 32));
|
||||||
(ImGui::GetFontSize() + 32));
|
|
||||||
p->compassIconDirty_ = true;
|
|
||||||
}
|
}
|
||||||
if (params.bearing != p->lastBearing_)
|
if (params.bearing != p->lastBearing_)
|
||||||
{
|
{
|
||||||
if (params.bearing == 0.0)
|
if (params.bearing == 0.0)
|
||||||
{
|
{
|
||||||
// Use cardinal point icon when bearing is oriented north-up
|
// Use cardinal point icon when bearing is oriented north-up
|
||||||
gl::draw::Icons::SetIconTexture(
|
p->icons_->SetIconTexture(
|
||||||
p->compassIcon_, p->cardinalPointIconName_, 0);
|
p->compassIcon_, p->cardinalPointIconName_, 0);
|
||||||
gl::draw::Icons::SetIconAngle(p->compassIcon_,
|
p->icons_->SetIconAngle(p->compassIcon_,
|
||||||
units::angle::degrees<double> {0.0});
|
units::angle::degrees<double> {0.0});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Use rotated compass icon when bearing is rotated away from north-up
|
// Use rotated compass icon when bearing is rotated away from north-up
|
||||||
gl::draw::Icons::SetIconTexture(
|
p->icons_->SetIconTexture(p->compassIcon_, p->compassIconName_, 0);
|
||||||
p->compassIcon_, p->compassIconName_, 0);
|
p->icons_->SetIconAngle(
|
||||||
gl::draw::Icons::SetIconAngle(
|
|
||||||
p->compassIcon_,
|
p->compassIcon_,
|
||||||
units::angle::degrees<double> {-45 - params.bearing});
|
units::angle::degrees<double> {-45 - params.bearing});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark icon for re-drawing
|
|
||||||
p->compassIconDirty_ = true;
|
|
||||||
}
|
}
|
||||||
if (p->compassIconDirty_)
|
|
||||||
{
|
|
||||||
// Update icon render buffers
|
|
||||||
p->icons_->FinishIcons();
|
|
||||||
}
|
|
||||||
|
|
||||||
DrawLayer::Render(params);
|
|
||||||
|
|
||||||
if (radarProductView != nullptr)
|
if (radarProductView != nullptr)
|
||||||
{
|
{
|
||||||
|
|
@ -381,18 +363,25 @@ void OverlayLayer::Render(const QMapLibre::CustomLayerRenderParameters& params)
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& generalSettings = settings::GeneralSettings::Instance();
|
||||||
|
|
||||||
QMargins colorTableMargins = context()->color_table_margins();
|
QMargins colorTableMargins = context()->color_table_margins();
|
||||||
if (colorTableMargins != p->lastColorTableMargins_ || p->firstRender_)
|
if (colorTableMargins != p->lastColorTableMargins_ || p->firstRender_)
|
||||||
{
|
{
|
||||||
// Draw map logo with a 10x10 indent from the bottom left
|
// Draw map logo with a 10x10 indent from the bottom left
|
||||||
gl::draw::Icons::SetIconLocation(p->mapLogoIcon_,
|
p->icons_->SetIconLocation(p->mapLogoIcon_,
|
||||||
10 + colorTableMargins.left(),
|
10 + colorTableMargins.left(),
|
||||||
10 + colorTableMargins.bottom());
|
10 + colorTableMargins.bottom());
|
||||||
p->icons_->FinishIcons();
|
p->icons_->FinishIcons();
|
||||||
}
|
}
|
||||||
|
p->icons_->SetIconVisible(p->mapLogoIcon_,
|
||||||
|
generalSettings.show_map_logo().GetValue());
|
||||||
|
|
||||||
|
DrawLayer::Render(params);
|
||||||
|
|
||||||
auto mapCopyrights = context()->map_copyrights();
|
auto mapCopyrights = context()->map_copyrights();
|
||||||
if (mapCopyrights.length() > 0)
|
if (mapCopyrights.length() > 0 &&
|
||||||
|
generalSettings.show_map_attribution().GetValue())
|
||||||
{
|
{
|
||||||
auto attributionFont = manager::FontManager::Instance().GetImGuiFont(
|
auto attributionFont = manager::FontManager::Instance().GetImGuiFont(
|
||||||
types::FontCategory::Attribution);
|
types::FontCategory::Attribution);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue