mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 10:10:05 +00:00 
			
		
		
		
	First attempt at rendering placefile icons, does not work yet
This commit is contained in:
		
							parent
							
								
									4c093d65f6
								
							
						
					
					
						commit
						f074e487de
					
				
					 6 changed files with 527 additions and 7 deletions
				
			
		
							
								
								
									
										42
									
								
								scwx-qt/gl/geo_texture2d.vert
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								scwx-qt/gl/geo_texture2d.vert
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,42 @@ | ||||||
|  | #version 330 core | ||||||
|  | 
 | ||||||
|  | #define DEGREES_MAX   360.0f | ||||||
|  | #define LATITUDE_MAX  85.051128779806604f | ||||||
|  | #define LONGITUDE_MAX 180.0f | ||||||
|  | #define PI            3.1415926535897932384626433f | ||||||
|  | #define RAD2DEG       57.295779513082320876798156332941f | ||||||
|  | 
 | ||||||
|  | layout (location = 0) in vec2  aLatLong; | ||||||
|  | layout (location = 1) in vec2  aXYOffset; | ||||||
|  | layout (location = 2) in vec2  aTexCoord; | ||||||
|  | layout (location = 3) in vec4  aModulate; | ||||||
|  | layout (location = 4) in float aAngle; | ||||||
|  | 
 | ||||||
|  | uniform mat4 uMVPMatrix; | ||||||
|  | uniform mat4 uMapMatrix; | ||||||
|  | uniform vec2 uMapScreenCoord; | ||||||
|  | 
 | ||||||
|  | smooth out vec2 texCoord; | ||||||
|  | flat   out vec4 modulate; | ||||||
|  | 
 | ||||||
|  | vec2 latLngToScreenCoordinate(in vec2 latLng) | ||||||
|  | { | ||||||
|  |    vec2 p; | ||||||
|  |    latLng.x = clamp(latLng.x, -LATITUDE_MAX, LATITUDE_MAX); | ||||||
|  |    p.xy     = vec2(LONGITUDE_MAX + latLng.y, | ||||||
|  |                    -(LONGITUDE_MAX - RAD2DEG * log(tan(PI / 4 + latLng.x * PI / DEGREES_MAX)))); | ||||||
|  |    return p; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void main() | ||||||
|  | { | ||||||
|  |    // Pass the texture coordinate and color modulate to the fragment shader | ||||||
|  |    texCoord = aTexCoord; | ||||||
|  |    modulate = aModulate; | ||||||
|  | 
 | ||||||
|  |    vec2 p = latLngToScreenCoordinate(aLatLong) - uMapScreenCoord; | ||||||
|  | 
 | ||||||
|  |    // Transform the position to screen coordinates | ||||||
|  |    gl_Position = uMapMatrix * vec4(p, 0.0f, 1.0f) - | ||||||
|  |                  uMVPMatrix * vec4(aXYOffset, 0.0f, 0.0f); | ||||||
|  | } | ||||||
|  | @ -57,9 +57,11 @@ set(SRC_GL source/scwx/qt/gl/gl_context.cpp | ||||||
|            source/scwx/qt/gl/text_shader.cpp) |            source/scwx/qt/gl/text_shader.cpp) | ||||||
| set(HDR_GL_DRAW source/scwx/qt/gl/draw/draw_item.hpp | set(HDR_GL_DRAW source/scwx/qt/gl/draw/draw_item.hpp | ||||||
|                 source/scwx/qt/gl/draw/geo_line.hpp |                 source/scwx/qt/gl/draw/geo_line.hpp | ||||||
|  |                 source/scwx/qt/gl/draw/placefile_icons.hpp | ||||||
|                 source/scwx/qt/gl/draw/rectangle.hpp) |                 source/scwx/qt/gl/draw/rectangle.hpp) | ||||||
| set(SRC_GL_DRAW source/scwx/qt/gl/draw/draw_item.cpp | set(SRC_GL_DRAW source/scwx/qt/gl/draw/draw_item.cpp | ||||||
|                 source/scwx/qt/gl/draw/geo_line.cpp |                 source/scwx/qt/gl/draw/geo_line.cpp | ||||||
|  |                 source/scwx/qt/gl/draw/placefile_icons.cpp | ||||||
|                 source/scwx/qt/gl/draw/rectangle.cpp) |                 source/scwx/qt/gl/draw/rectangle.cpp) | ||||||
| set(HDR_MANAGER source/scwx/qt/manager/placefile_manager.hpp | set(HDR_MANAGER source/scwx/qt/manager/placefile_manager.hpp | ||||||
|                 source/scwx/qt/manager/radar_product_manager.hpp |                 source/scwx/qt/manager/radar_product_manager.hpp | ||||||
|  | @ -240,6 +242,7 @@ set(RESOURCE_FILES scwx-qt.qrc) | ||||||
| set(SHADER_FILES gl/color.frag | set(SHADER_FILES gl/color.frag | ||||||
|                  gl/color.vert |                  gl/color.vert | ||||||
|                  gl/geo_line.vert |                  gl/geo_line.vert | ||||||
|  |                  gl/geo_texture2d.vert | ||||||
|                  gl/radar.frag |                  gl/radar.frag | ||||||
|                  gl/radar.vert |                  gl/radar.vert | ||||||
|                  gl/text.frag |                  gl/text.frag | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ | ||||||
|         <file>gl/color.frag</file> |         <file>gl/color.frag</file> | ||||||
|         <file>gl/color.vert</file> |         <file>gl/color.vert</file> | ||||||
|         <file>gl/geo_line.vert</file> |         <file>gl/geo_line.vert</file> | ||||||
|  |         <file>gl/geo_texture2d.vert</file> | ||||||
|         <file>gl/radar.frag</file> |         <file>gl/radar.frag</file> | ||||||
|         <file>gl/radar.vert</file> |         <file>gl/radar.vert</file> | ||||||
|         <file>gl/text.frag</file> |         <file>gl/text.frag</file> | ||||||
|  |  | ||||||
							
								
								
									
										370
									
								
								scwx-qt/source/scwx/qt/gl/draw/placefile_icons.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										370
									
								
								scwx-qt/source/scwx/qt/gl/draw/placefile_icons.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,370 @@ | ||||||
|  | #include <scwx/qt/gl/draw/placefile_icons.hpp> | ||||||
|  | #include <scwx/qt/util/texture_atlas.hpp> | ||||||
|  | #include <scwx/util/logger.hpp> | ||||||
|  | 
 | ||||||
|  | #include <QUrl> | ||||||
|  | #include <boost/unordered/unordered_flat_map.hpp> | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace qt | ||||||
|  | { | ||||||
|  | namespace gl | ||||||
|  | { | ||||||
|  | namespace draw | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | static const std::string logPrefix_ = "scwx::qt::gl::draw::placefile_icons"; | ||||||
|  | static const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | ||||||
|  | 
 | ||||||
|  | static constexpr std::size_t kNumRectangles        = 1; | ||||||
|  | static constexpr std::size_t kNumTriangles         = kNumRectangles * 2; | ||||||
|  | static constexpr std::size_t kVerticesPerTriangle  = 3; | ||||||
|  | static constexpr std::size_t kVerticesPerRectangle = kVerticesPerTriangle * 2; | ||||||
|  | static constexpr std::size_t kPointsPerVertex      = 11; | ||||||
|  | static constexpr std::size_t kBufferLength = | ||||||
|  |    kNumTriangles * kVerticesPerTriangle * kPointsPerVertex; | ||||||
|  | 
 | ||||||
|  | struct PlacefileIconInfo | ||||||
|  | { | ||||||
|  |    PlacefileIconInfo( | ||||||
|  |       const std::shared_ptr<const gr::Placefile::IconFile>& iconFile, | ||||||
|  |       const std::string&                                    baseUrlString) : | ||||||
|  |        iconFile_ {iconFile} | ||||||
|  |    { | ||||||
|  |       // Resolve using base URL
 | ||||||
|  |       auto baseUrl = QUrl::fromUserInput(QString::fromStdString(baseUrlString)); | ||||||
|  |       auto relativeUrl = QUrl(QString::fromStdString(iconFile->filename_)); | ||||||
|  | 
 | ||||||
|  |       texture_ = util::TextureAtlas::Instance().GetTextureAttributes( | ||||||
|  |          baseUrl.resolved(relativeUrl).toString().toStdString()); | ||||||
|  | 
 | ||||||
|  |       if (iconFile->iconWidth_ > 0 && iconFile->iconHeight_ > 0) | ||||||
|  |       { | ||||||
|  |          columns_ = texture_.size_.x / iconFile->iconWidth_; | ||||||
|  |          rows_    = texture_.size_.y / iconFile->iconHeight_; | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  |          columns_ = 0u; | ||||||
|  |          rows_    = 0u; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       numIcons_ = columns_ * rows_; | ||||||
|  | 
 | ||||||
|  |       float xFactor = 0.0f; | ||||||
|  |       float yFactor = 0.0f; | ||||||
|  | 
 | ||||||
|  |       if (texture_.size_.x > 0 && texture_.size_.y > 0) | ||||||
|  |       { | ||||||
|  |          xFactor = (texture_.sRight_ - texture_.sLeft_) / texture_.size_.x; | ||||||
|  |          yFactor = (texture_.tBottom_ - texture_.tTop_) / texture_.size_.y; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       scaledWidth_  = iconFile_->iconWidth_ * xFactor; | ||||||
|  |       scaledHeight_ = iconFile_->iconHeight_ * yFactor; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    std::shared_ptr<const gr::Placefile::IconFile> iconFile_; | ||||||
|  |    util::TextureAttributes                        texture_; | ||||||
|  |    std::size_t                                    rows_ {}; | ||||||
|  |    std::size_t                                    columns_ {}; | ||||||
|  |    std::size_t                                    numIcons_ {}; | ||||||
|  |    float                                          scaledWidth_ {}; | ||||||
|  |    float                                          scaledHeight_ {}; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | class PlacefileIcons::Impl | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |    explicit Impl(std::shared_ptr<GlContext> context) : | ||||||
|  |        context_ {context}, | ||||||
|  |        shaderProgram_ {nullptr}, | ||||||
|  |        uMVPMatrixLocation_(GL_INVALID_INDEX), | ||||||
|  |        uMapMatrixLocation_(GL_INVALID_INDEX), | ||||||
|  |        uMapScreenCoordLocation_(GL_INVALID_INDEX), | ||||||
|  |        vao_ {GL_INVALID_INDEX}, | ||||||
|  |        vbo_ {GL_INVALID_INDEX}, | ||||||
|  |        numVertices_ {0} | ||||||
|  |    { | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    ~Impl() {} | ||||||
|  | 
 | ||||||
|  |    std::shared_ptr<GlContext> context_; | ||||||
|  | 
 | ||||||
|  |    bool dirty_ {false}; | ||||||
|  | 
 | ||||||
|  |    boost::unordered_flat_map<std::size_t, const PlacefileIconInfo> | ||||||
|  |       iconFiles_ {}; | ||||||
|  | 
 | ||||||
|  |    std::vector<std::shared_ptr<const gr::Placefile::IconDrawItem>> iconList_ {}; | ||||||
|  | 
 | ||||||
|  |    std::shared_ptr<ShaderProgram> shaderProgram_; | ||||||
|  |    GLint                          uMVPMatrixLocation_; | ||||||
|  |    GLint                          uMapMatrixLocation_; | ||||||
|  |    GLint                          uMapScreenCoordLocation_; | ||||||
|  | 
 | ||||||
|  |    GLuint vao_; | ||||||
|  |    GLuint vbo_; | ||||||
|  | 
 | ||||||
|  |    GLsizei numVertices_; | ||||||
|  | 
 | ||||||
|  |    void Update(); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | PlacefileIcons::PlacefileIcons(std::shared_ptr<GlContext> context) : | ||||||
|  |     DrawItem(context->gl()), p(std::make_unique<Impl>(context)) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | PlacefileIcons::~PlacefileIcons() = default; | ||||||
|  | 
 | ||||||
|  | PlacefileIcons::PlacefileIcons(PlacefileIcons&&) noexcept            = default; | ||||||
|  | PlacefileIcons& PlacefileIcons::operator=(PlacefileIcons&&) noexcept = default; | ||||||
|  | 
 | ||||||
|  | void PlacefileIcons::Initialize() | ||||||
|  | { | ||||||
|  |    gl::OpenGLFunctions& gl = p->context_->gl(); | ||||||
|  | 
 | ||||||
|  |    p->shaderProgram_ = p->context_->GetShaderProgram(":/gl/geo_texture2d.vert", | ||||||
|  |                                                      ":/gl/texture2d.frag"); | ||||||
|  | 
 | ||||||
|  |    p->uMVPMatrixLocation_ = | ||||||
|  |       gl.glGetUniformLocation(p->shaderProgram_->id(), "uMVPMatrix"); | ||||||
|  |    if (p->uMVPMatrixLocation_ == -1) | ||||||
|  |    { | ||||||
|  |       logger_->warn("Could not find uMVPMatrix"); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    p->uMapMatrixLocation_ = | ||||||
|  |       gl.glGetUniformLocation(p->shaderProgram_->id(), "uMapMatrix"); | ||||||
|  |    if (p->uMapMatrixLocation_ == -1) | ||||||
|  |    { | ||||||
|  |       logger_->warn("Could not find uMapMatrix"); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    p->uMapScreenCoordLocation_ = | ||||||
|  |       gl.glGetUniformLocation(p->shaderProgram_->id(), "uMapScreenCoord"); | ||||||
|  |    if (p->uMapScreenCoordLocation_ == -1) | ||||||
|  |    { | ||||||
|  |       logger_->warn("Could not find uMapScreenCoord"); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    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, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||||
|  | 
 | ||||||
|  |    // aLatLong
 | ||||||
|  |    gl.glVertexAttribPointer(0, | ||||||
|  |                             2, | ||||||
|  |                             GL_FLOAT, | ||||||
|  |                             GL_FALSE, | ||||||
|  |                             kPointsPerVertex * sizeof(float), | ||||||
|  |                             static_cast<void*>(0)); | ||||||
|  |    gl.glEnableVertexAttribArray(0); | ||||||
|  | 
 | ||||||
|  |    // aXYOffset
 | ||||||
|  |    gl.glVertexAttribPointer(1, | ||||||
|  |                             2, | ||||||
|  |                             GL_FLOAT, | ||||||
|  |                             GL_FALSE, | ||||||
|  |                             kPointsPerVertex * sizeof(float), | ||||||
|  |                             reinterpret_cast<void*>(2 * sizeof(float))); | ||||||
|  |    gl.glEnableVertexAttribArray(1); | ||||||
|  | 
 | ||||||
|  |    // aTexCoord
 | ||||||
|  |    gl.glVertexAttribPointer(2, | ||||||
|  |                             2, | ||||||
|  |                             GL_FLOAT, | ||||||
|  |                             GL_FALSE, | ||||||
|  |                             kPointsPerVertex * sizeof(float), | ||||||
|  |                             reinterpret_cast<void*>(4 * sizeof(float))); | ||||||
|  |    gl.glEnableVertexAttribArray(2); | ||||||
|  | 
 | ||||||
|  |    // aModulate
 | ||||||
|  |    gl.glVertexAttribPointer(3, | ||||||
|  |                             4, | ||||||
|  |                             GL_FLOAT, | ||||||
|  |                             GL_FALSE, | ||||||
|  |                             kPointsPerVertex * sizeof(float), | ||||||
|  |                             reinterpret_cast<void*>(6 * sizeof(float))); | ||||||
|  |    gl.glEnableVertexAttribArray(3); | ||||||
|  | 
 | ||||||
|  |    // aAngle
 | ||||||
|  |    gl.glVertexAttribPointer(4, | ||||||
|  |                             1, | ||||||
|  |                             GL_FLOAT, | ||||||
|  |                             GL_FALSE, | ||||||
|  |                             kPointsPerVertex * sizeof(float), | ||||||
|  |                             reinterpret_cast<void*>(10 * sizeof(float))); | ||||||
|  |    gl.glEnableVertexAttribArray(4); | ||||||
|  | 
 | ||||||
|  |    p->dirty_ = true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void PlacefileIcons::Render( | ||||||
|  |    const QMapLibreGL::CustomLayerRenderParameters& params) | ||||||
|  | { | ||||||
|  |    if (!p->iconList_.empty()) | ||||||
|  |    { | ||||||
|  |       gl::OpenGLFunctions& gl = p->context_->gl(); | ||||||
|  | 
 | ||||||
|  |       gl.glBindVertexArray(p->vao_); | ||||||
|  |       gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_); | ||||||
|  | 
 | ||||||
|  |       p->Update(); | ||||||
|  |       p->shaderProgram_->Use(); | ||||||
|  |       UseDefaultProjection(params, p->uMVPMatrixLocation_); | ||||||
|  |       UseMapProjection( | ||||||
|  |          params, p->uMapMatrixLocation_, p->uMapScreenCoordLocation_); | ||||||
|  | 
 | ||||||
|  |       // Draw icons
 | ||||||
|  |       gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void PlacefileIcons::Deinitialize() | ||||||
|  | { | ||||||
|  |    gl::OpenGLFunctions& gl = p->context_->gl(); | ||||||
|  | 
 | ||||||
|  |    gl.glDeleteVertexArrays(1, &p->vao_); | ||||||
|  |    gl.glDeleteBuffers(1, &p->vbo_); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void PlacefileIcons::SetIconFiles( | ||||||
|  |    const std::vector<std::shared_ptr<const gr::Placefile::IconFile>>& iconFiles, | ||||||
|  |    const std::string&                                                 baseUrl) | ||||||
|  | { | ||||||
|  |    p->dirty_ = true; | ||||||
|  | 
 | ||||||
|  |    // Populate icon file map
 | ||||||
|  |    p->iconFiles_.clear(); | ||||||
|  | 
 | ||||||
|  |    for (auto& file : iconFiles) | ||||||
|  |    { | ||||||
|  |       p->iconFiles_.emplace( | ||||||
|  |          std::piecewise_construct, | ||||||
|  |          std::tuple {file->fileNumber_}, | ||||||
|  |          std::forward_as_tuple(PlacefileIconInfo {file, baseUrl})); | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void PlacefileIcons::AddIcon( | ||||||
|  |    const std::shared_ptr<gr::Placefile::IconDrawItem>& di) | ||||||
|  | { | ||||||
|  |    if (di != nullptr) | ||||||
|  |    { | ||||||
|  |       p->iconList_.emplace_back(di); | ||||||
|  |       p->dirty_ = true; | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void PlacefileIcons::Reset() | ||||||
|  | { | ||||||
|  |    // Clear the icon list, and mark the draw item dirty
 | ||||||
|  |    p->iconList_.clear(); | ||||||
|  |    p->dirty_ = true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void PlacefileIcons::Impl::Update() | ||||||
|  | { | ||||||
|  |    if (dirty_) | ||||||
|  |    { | ||||||
|  |       static std::vector<float> buffer {}; | ||||||
|  |       buffer.clear(); | ||||||
|  |       buffer.reserve(iconList_.size() * kBufferLength); | ||||||
|  |       numVertices_ = 0; | ||||||
|  | 
 | ||||||
|  |       for (auto& di : iconList_) | ||||||
|  |       { | ||||||
|  |          auto it = iconFiles_.find(di->fileNumber_); | ||||||
|  |          if (it == iconFiles_.cend()) | ||||||
|  |          { | ||||||
|  |             // No file found
 | ||||||
|  |             logger_->trace("Could not find file number: {}", di->fileNumber_); | ||||||
|  |             continue; | ||||||
|  |          } | ||||||
|  | 
 | ||||||
|  |          auto& icon = it->second; | ||||||
|  | 
 | ||||||
|  |          // Validate icon
 | ||||||
|  |          if (di->iconNumber_ == 0 || di->iconNumber_ > icon.numIcons_) | ||||||
|  |          { | ||||||
|  |             // No icon found
 | ||||||
|  |             logger_->trace("Invalid icon number: {}", di->iconNumber_); | ||||||
|  |             continue; | ||||||
|  |          } | ||||||
|  | 
 | ||||||
|  |          // Latitude and longitude coordinates in degrees
 | ||||||
|  |          const float lat = static_cast<float>(di->latitude_); | ||||||
|  |          const float lon = static_cast<float>(di->longitude_); | ||||||
|  | 
 | ||||||
|  |          // Base X/Y offsets in pixels
 | ||||||
|  |          const float x = static_cast<float>(di->x_); | ||||||
|  |          const float y = static_cast<float>(di->y_); | ||||||
|  | 
 | ||||||
|  |          // Half icon size
 | ||||||
|  |          const float hw = static_cast<float>(icon.iconFile_->iconWidth_) * 0.5f; | ||||||
|  |          const float hh = | ||||||
|  |             static_cast<float>(icon.iconFile_->iconHeight_) * 0.5f; | ||||||
|  | 
 | ||||||
|  |          // Final X/Y offsets in pixels
 | ||||||
|  |          const float lx = x - hw; | ||||||
|  |          const float rx = x + hw; | ||||||
|  |          const float by = y - hh; | ||||||
|  |          const float ty = y + hh; | ||||||
|  | 
 | ||||||
|  |          // Angle in degrees
 | ||||||
|  |          // TODO: Properly convert
 | ||||||
|  |          const float a = static_cast<float>(di->angle_.value()); | ||||||
|  | 
 | ||||||
|  |          // Texture coordinates
 | ||||||
|  |          const std::size_t iconRow    = (di->iconNumber_ - 1) / icon.columns_; | ||||||
|  |          const std::size_t iconColumn = (di->iconNumber_ - 1) % icon.columns_; | ||||||
|  | 
 | ||||||
|  |          const float iconX = iconColumn * icon.scaledWidth_; | ||||||
|  |          const float iconY = iconRow * icon.scaledHeight_; | ||||||
|  | 
 | ||||||
|  |          const float ls = icon.texture_.sLeft_ + iconX; | ||||||
|  |          const float rs = ls + icon.scaledWidth_; | ||||||
|  |          const float tt = icon.texture_.tTop_ + iconY; | ||||||
|  |          const float bt = tt + icon.scaledHeight_; | ||||||
|  | 
 | ||||||
|  |          // Fixed modulate color
 | ||||||
|  |          const float mc0 = 1.0f; | ||||||
|  |          const float mc1 = 1.0f; | ||||||
|  |          const float mc2 = 1.0f; | ||||||
|  |          const float mc3 = 1.0f; | ||||||
|  | 
 | ||||||
|  |          buffer.insert(buffer.end(), | ||||||
|  |                        { | ||||||
|  |                           // Icon
 | ||||||
|  |                           lat, lon, lx, by, ls, bt, mc0, mc1, mc2, mc3, a, // BL
 | ||||||
|  |                           lat, lon, lx, by, ls, tt, mc0, mc1, mc2, mc3, a, // TL
 | ||||||
|  |                           lat, lon, rx, ty, rs, bt, mc0, mc1, mc2, mc3, a, // BR
 | ||||||
|  |                           lat, lon, rx, ty, rs, bt, mc0, mc1, mc2, mc3, a, // BR
 | ||||||
|  |                           lat, lon, rx, ty, rs, tt, mc0, mc1, mc2, mc3, a, // TR
 | ||||||
|  |                           lat, lon, lx, by, ls, tt, mc0, mc1, mc2, mc3, a  // TL
 | ||||||
|  |                        }); | ||||||
|  | 
 | ||||||
|  |          numVertices_ += 6; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       gl::OpenGLFunctions& gl = context_->gl(); | ||||||
|  | 
 | ||||||
|  |       gl.glBufferData(GL_ARRAY_BUFFER, | ||||||
|  |                       sizeof(float) * buffer.size(), | ||||||
|  |                       buffer.data(), | ||||||
|  |                       GL_DYNAMIC_DRAW); | ||||||
|  | 
 | ||||||
|  |       dirty_ = false; | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // namespace draw
 | ||||||
|  | } // namespace gl
 | ||||||
|  | } // namespace qt
 | ||||||
|  | } // namespace scwx
 | ||||||
							
								
								
									
										66
									
								
								scwx-qt/source/scwx/qt/gl/draw/placefile_icons.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								scwx-qt/source/scwx/qt/gl/draw/placefile_icons.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,66 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <scwx/qt/gl/gl_context.hpp> | ||||||
|  | #include <scwx/qt/gl/draw/draw_item.hpp> | ||||||
|  | #include <scwx/gr/placefile.hpp> | ||||||
|  | 
 | ||||||
|  | #include <boost/gil.hpp> | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace qt | ||||||
|  | { | ||||||
|  | namespace gl | ||||||
|  | { | ||||||
|  | namespace draw | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | class PlacefileIcons : public DrawItem | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |    explicit PlacefileIcons(std::shared_ptr<GlContext> context); | ||||||
|  |    ~PlacefileIcons(); | ||||||
|  | 
 | ||||||
|  |    PlacefileIcons(const PlacefileIcons&)            = delete; | ||||||
|  |    PlacefileIcons& operator=(const PlacefileIcons&) = delete; | ||||||
|  | 
 | ||||||
|  |    PlacefileIcons(PlacefileIcons&&) noexcept; | ||||||
|  |    PlacefileIcons& operator=(PlacefileIcons&&) noexcept; | ||||||
|  | 
 | ||||||
|  |    void Initialize() override; | ||||||
|  |    void Render(const QMapLibreGL::CustomLayerRenderParameters& params) override; | ||||||
|  |    void Deinitialize() override; | ||||||
|  | 
 | ||||||
|  |    /**
 | ||||||
|  |     * Configures the textures for drawing the placefile icons. | ||||||
|  |     * | ||||||
|  |     * @param [in] iconFiles A list of icon files | ||||||
|  |     * @param [in] baseUrl The base URL of the placefile | ||||||
|  |     */ | ||||||
|  |    void SetIconFiles( | ||||||
|  |       const std::vector<std::shared_ptr<const gr::Placefile::IconFile>>& | ||||||
|  |                          iconFiles, | ||||||
|  |       const std::string& baseUrl); | ||||||
|  | 
 | ||||||
|  |    /**
 | ||||||
|  |     * Adds a placefile icon to the internal draw list. | ||||||
|  |     * | ||||||
|  |     * @param [in] di Placefile icon | ||||||
|  |     */ | ||||||
|  |    void AddIcon(const std::shared_ptr<gr::Placefile::IconDrawItem>& di); | ||||||
|  | 
 | ||||||
|  |    /**
 | ||||||
|  |     * Resets the list of icons in preparation for rendering a new frame. | ||||||
|  |     */ | ||||||
|  |    void Reset(); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |    class Impl; | ||||||
|  | 
 | ||||||
|  |    std::unique_ptr<Impl> p; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | } // namespace draw
 | ||||||
|  | } // namespace gl
 | ||||||
|  | } // namespace qt
 | ||||||
|  | } // namespace scwx
 | ||||||
|  | @ -1,4 +1,5 @@ | ||||||
| #include <scwx/qt/map/placefile_layer.hpp> | #include <scwx/qt/map/placefile_layer.hpp> | ||||||
|  | #include <scwx/qt/gl/draw/placefile_icons.hpp> | ||||||
| #include <scwx/qt/manager/placefile_manager.hpp> | #include <scwx/qt/manager/placefile_manager.hpp> | ||||||
| #include <scwx/qt/manager/resource_manager.hpp> | #include <scwx/qt/manager/resource_manager.hpp> | ||||||
| #include <scwx/qt/manager/settings_manager.hpp> | #include <scwx/qt/manager/settings_manager.hpp> | ||||||
|  | @ -23,12 +24,18 @@ static const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | ||||||
| class PlacefileLayer::Impl | class PlacefileLayer::Impl | ||||||
| { | { | ||||||
| public: | public: | ||||||
|    explicit Impl() {}; |    explicit Impl(std::shared_ptr<MapContext> context) : | ||||||
|  |        placefileIcons_ {std::make_shared<gl::draw::PlacefileIcons>(context)} | ||||||
|  |    { | ||||||
|  |    } | ||||||
|    ~Impl() = default; |    ~Impl() = default; | ||||||
| 
 | 
 | ||||||
|  |    void | ||||||
|  |    RenderIconDrawItem(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||||
|  |                       const std::shared_ptr<gr::Placefile::IconDrawItem>& di); | ||||||
|    void |    void | ||||||
|    RenderTextDrawItem(const QMapLibreGL::CustomLayerRenderParameters& params, |    RenderTextDrawItem(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||||
|                       std::shared_ptr<gr::Placefile::TextDrawItem>    di); |                       const std::shared_ptr<gr::Placefile::TextDrawItem>& di); | ||||||
| 
 | 
 | ||||||
|    void RenderText(const QMapLibreGL::CustomLayerRenderParameters& params, |    void RenderText(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||||
|                    const std::string&                              text, |                    const std::string&                              text, | ||||||
|  | @ -44,11 +51,14 @@ public: | ||||||
|    float         halfHeight_ {}; |    float         halfHeight_ {}; | ||||||
|    bool          thresholded_ {true}; |    bool          thresholded_ {true}; | ||||||
|    ImFont*       monospaceFont_ {}; |    ImFont*       monospaceFont_ {}; | ||||||
|  | 
 | ||||||
|  |    std::shared_ptr<gl::draw::PlacefileIcons> placefileIcons_; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| PlacefileLayer::PlacefileLayer(std::shared_ptr<MapContext> context) : | PlacefileLayer::PlacefileLayer(std::shared_ptr<MapContext> context) : | ||||||
|     DrawLayer(context), p(std::make_unique<PlacefileLayer::Impl>()) |     DrawLayer(context), p(std::make_unique<PlacefileLayer::Impl>(context)) | ||||||
| { | { | ||||||
|  |    AddDrawItem(p->placefileIcons_); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| PlacefileLayer::~PlacefileLayer() = default; | PlacefileLayer::~PlacefileLayer() = default; | ||||||
|  | @ -60,9 +70,25 @@ void PlacefileLayer::Initialize() | ||||||
|    DrawLayer::Initialize(); |    DrawLayer::Initialize(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void PlacefileLayer::Impl::RenderIconDrawItem( | ||||||
|  |    const QMapLibreGL::CustomLayerRenderParameters&     params, | ||||||
|  |    const std::shared_ptr<gr::Placefile::IconDrawItem>& di) | ||||||
|  | { | ||||||
|  |    auto distance = | ||||||
|  |       (thresholded_) ? | ||||||
|  |          util::GeographicLib::GetDistance( | ||||||
|  |             params.latitude, params.longitude, di->latitude_, di->longitude_) : | ||||||
|  |          0; | ||||||
|  | 
 | ||||||
|  |    if (distance < di->threshold_) | ||||||
|  |    { | ||||||
|  |       placefileIcons_->AddIcon(di); | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void PlacefileLayer::Impl::RenderTextDrawItem( | void PlacefileLayer::Impl::RenderTextDrawItem( | ||||||
|    const QMapLibreGL::CustomLayerRenderParameters& params, |    const QMapLibreGL::CustomLayerRenderParameters&     params, | ||||||
|    std::shared_ptr<gr::Placefile::TextDrawItem>    di) |    const std::shared_ptr<gr::Placefile::TextDrawItem>& di) | ||||||
| { | { | ||||||
|    auto distance = |    auto distance = | ||||||
|       (thresholded_) ? |       (thresholded_) ? | ||||||
|  | @ -133,11 +159,12 @@ void PlacefileLayer::Render( | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = context()->gl(); |    gl::OpenGLFunctions& gl = context()->gl(); | ||||||
| 
 | 
 | ||||||
|    DrawLayer::Render(params); |  | ||||||
| 
 |  | ||||||
|    // Reset text ID per frame
 |    // Reset text ID per frame
 | ||||||
|    p->textId_ = 0; |    p->textId_ = 0; | ||||||
| 
 | 
 | ||||||
|  |    // Reset graphics
 | ||||||
|  |    p->placefileIcons_->Reset(); | ||||||
|  | 
 | ||||||
|    // Update map screen coordinate and scale information
 |    // Update map screen coordinate and scale information
 | ||||||
|    p->mapScreenCoordLocation_ = util::maplibre::LatLongToScreenCoordinate( |    p->mapScreenCoordLocation_ = util::maplibre::LatLongToScreenCoordinate( | ||||||
|       {params.latitude, params.longitude}); |       {params.latitude, params.longitude}); | ||||||
|  | @ -171,6 +198,9 @@ void PlacefileLayer::Render( | ||||||
|       p->thresholded_ = |       p->thresholded_ = | ||||||
|          placefileManager->placefile_thresholded(placefile->name()); |          placefileManager->placefile_thresholded(placefile->name()); | ||||||
| 
 | 
 | ||||||
|  |       p->placefileIcons_->SetIconFiles(placefile->icon_files(), | ||||||
|  |                                        placefile->name()); | ||||||
|  | 
 | ||||||
|       for (auto& drawItem : placefile->GetDrawItems()) |       for (auto& drawItem : placefile->GetDrawItems()) | ||||||
|       { |       { | ||||||
|          switch (drawItem->itemType_) |          switch (drawItem->itemType_) | ||||||
|  | @ -181,12 +211,20 @@ void PlacefileLayer::Render( | ||||||
|                std::static_pointer_cast<gr::Placefile::TextDrawItem>(drawItem)); |                std::static_pointer_cast<gr::Placefile::TextDrawItem>(drawItem)); | ||||||
|             break; |             break; | ||||||
| 
 | 
 | ||||||
|  |          case gr::Placefile::ItemType::Icon: | ||||||
|  |             p->RenderIconDrawItem( | ||||||
|  |                params, | ||||||
|  |                std::static_pointer_cast<gr::Placefile::IconDrawItem>(drawItem)); | ||||||
|  |             break; | ||||||
|  | 
 | ||||||
|          default: |          default: | ||||||
|             break; |             break; | ||||||
|          } |          } | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |    DrawLayer::Render(params); | ||||||
|  | 
 | ||||||
|    SCWX_GL_CHECK_ERROR(); |    SCWX_GL_CHECK_ERROR(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat