mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 01:20:06 +00:00 
			
		
		
		
	Use geometry shaders for icon and polygon thresholds, fix threshold method to map distance for placefile text
This commit is contained in:
		
							parent
							
								
									69f93d6faf
								
							
						
					
					
						commit
						12833202b7
					
				
					 7 changed files with 174 additions and 100 deletions
				
			
		|  | @ -1,4 +1,5 @@ | ||||||
| #include <scwx/qt/gl/draw/placefile_icons.hpp> | #include <scwx/qt/gl/draw/placefile_icons.hpp> | ||||||
|  | #include <scwx/qt/util/maplibre.hpp> | ||||||
| #include <scwx/qt/util/texture_atlas.hpp> | #include <scwx/qt/util/texture_atlas.hpp> | ||||||
| #include <scwx/util/logger.hpp> | #include <scwx/util/logger.hpp> | ||||||
| 
 | 
 | ||||||
|  | @ -84,6 +85,7 @@ public: | ||||||
|        uMVPMatrixLocation_(GL_INVALID_INDEX), |        uMVPMatrixLocation_(GL_INVALID_INDEX), | ||||||
|        uMapMatrixLocation_(GL_INVALID_INDEX), |        uMapMatrixLocation_(GL_INVALID_INDEX), | ||||||
|        uMapScreenCoordLocation_(GL_INVALID_INDEX), |        uMapScreenCoordLocation_(GL_INVALID_INDEX), | ||||||
|  |        uMapDistanceLocation_(GL_INVALID_INDEX), | ||||||
|        vao_ {GL_INVALID_INDEX}, |        vao_ {GL_INVALID_INDEX}, | ||||||
|        vbo_ {GL_INVALID_INDEX}, |        vbo_ {GL_INVALID_INDEX}, | ||||||
|        numVertices_ {0} |        numVertices_ {0} | ||||||
|  | @ -95,6 +97,7 @@ public: | ||||||
|    std::shared_ptr<GlContext> context_; |    std::shared_ptr<GlContext> context_; | ||||||
| 
 | 
 | ||||||
|    bool dirty_ {false}; |    bool dirty_ {false}; | ||||||
|  |    bool thresholded_ {false}; | ||||||
| 
 | 
 | ||||||
|    boost::unordered_flat_map<std::size_t, const PlacefileIconInfo> |    boost::unordered_flat_map<std::size_t, const PlacefileIconInfo> | ||||||
|       iconFiles_ {}; |       iconFiles_ {}; | ||||||
|  | @ -105,9 +108,10 @@ public: | ||||||
|    GLint                          uMVPMatrixLocation_; |    GLint                          uMVPMatrixLocation_; | ||||||
|    GLint                          uMapMatrixLocation_; |    GLint                          uMapMatrixLocation_; | ||||||
|    GLint                          uMapScreenCoordLocation_; |    GLint                          uMapScreenCoordLocation_; | ||||||
|  |    GLint                          uMapDistanceLocation_; | ||||||
| 
 | 
 | ||||||
|    GLuint                vao_; |    GLuint                vao_; | ||||||
|    GLuint vbo_; |    std::array<GLuint, 2> vbo_; | ||||||
| 
 | 
 | ||||||
|    GLsizei numVertices_; |    GLsizei numVertices_; | ||||||
| 
 | 
 | ||||||
|  | @ -123,39 +127,32 @@ PlacefileIcons::~PlacefileIcons() = default; | ||||||
| PlacefileIcons::PlacefileIcons(PlacefileIcons&&) noexcept            = default; | PlacefileIcons::PlacefileIcons(PlacefileIcons&&) noexcept            = default; | ||||||
| PlacefileIcons& PlacefileIcons::operator=(PlacefileIcons&&) noexcept = default; | PlacefileIcons& PlacefileIcons::operator=(PlacefileIcons&&) noexcept = default; | ||||||
| 
 | 
 | ||||||
|  | void PlacefileIcons::set_thresholded(bool thresholded) | ||||||
|  | { | ||||||
|  |    p->thresholded_ = thresholded; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void PlacefileIcons::Initialize() | void PlacefileIcons::Initialize() | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); |    gl::OpenGLFunctions& gl = p->context_->gl(); | ||||||
| 
 | 
 | ||||||
|    p->shaderProgram_ = p->context_->GetShaderProgram(":/gl/geo_texture2d.vert", |    p->shaderProgram_ = p->context_->GetShaderProgram( | ||||||
|                                                      ":/gl/texture2d.frag"); |       {{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"}, | ||||||
| 
 |        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, | ||||||
|    p->uMVPMatrixLocation_ = |        {GL_FRAGMENT_SHADER, ":/gl/texture2d.frag"}}); | ||||||
|       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->uMVPMatrixLocation_ = p->shaderProgram_->GetUniformLocation("uMVPMatrix"); | ||||||
|  |    p->uMapMatrixLocation_ = p->shaderProgram_->GetUniformLocation("uMapMatrix"); | ||||||
|    p->uMapScreenCoordLocation_ = |    p->uMapScreenCoordLocation_ = | ||||||
|       gl.glGetUniformLocation(p->shaderProgram_->id(), "uMapScreenCoord"); |       p->shaderProgram_->GetUniformLocation("uMapScreenCoord"); | ||||||
|    if (p->uMapScreenCoordLocation_ == -1) |    p->uMapDistanceLocation_ = | ||||||
|    { |       p->shaderProgram_->GetUniformLocation("uMapDistance"); | ||||||
|       logger_->warn("Could not find uMapScreenCoord"); |  | ||||||
|    } |  | ||||||
| 
 | 
 | ||||||
|    gl.glGenVertexArrays(1, &p->vao_); |    gl.glGenVertexArrays(1, &p->vao_); | ||||||
|    gl.glGenBuffers(1, &p->vbo_); |    gl.glGenBuffers(2, p->vbo_.data()); | ||||||
| 
 | 
 | ||||||
|    gl.glBindVertexArray(p->vao_); |    gl.glBindVertexArray(p->vao_); | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_); |    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); |    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|    // aLatLong
 |    // aLatLong
 | ||||||
|  | @ -203,6 +200,17 @@ void PlacefileIcons::Initialize() | ||||||
|                             reinterpret_cast<void*>(10 * sizeof(float))); |                             reinterpret_cast<void*>(10 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(4); |    gl.glEnableVertexAttribArray(4); | ||||||
| 
 | 
 | ||||||
|  |    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||||
|  |    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||||
|  | 
 | ||||||
|  |    // aThreshold
 | ||||||
|  |    gl.glVertexAttribIPointer(5, //
 | ||||||
|  |                              1, | ||||||
|  |                              GL_INT, | ||||||
|  |                              0, | ||||||
|  |                              static_cast<void*>(0)); | ||||||
|  |    gl.glEnableVertexAttribArray(5); | ||||||
|  | 
 | ||||||
|    p->dirty_ = true; |    p->dirty_ = true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -214,7 +222,6 @@ void PlacefileIcons::Render( | ||||||
|       gl::OpenGLFunctions& gl = p->context_->gl(); |       gl::OpenGLFunctions& gl = p->context_->gl(); | ||||||
| 
 | 
 | ||||||
|       gl.glBindVertexArray(p->vao_); |       gl.glBindVertexArray(p->vao_); | ||||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_); |  | ||||||
| 
 | 
 | ||||||
|       p->Update(); |       p->Update(); | ||||||
|       p->shaderProgram_->Use(); |       p->shaderProgram_->Use(); | ||||||
|  | @ -222,6 +229,21 @@ void PlacefileIcons::Render( | ||||||
|       UseMapProjection( |       UseMapProjection( | ||||||
|          params, p->uMapMatrixLocation_, p->uMapScreenCoordLocation_); |          params, p->uMapMatrixLocation_, p->uMapScreenCoordLocation_); | ||||||
| 
 | 
 | ||||||
|  |       if (p->thresholded_) | ||||||
|  |       { | ||||||
|  |          // If thresholding is enabled, set the map distance
 | ||||||
|  |          // TODO: nautical miles
 | ||||||
|  |          auto mapDistance = | ||||||
|  |             util::maplibre::GetMapDistance(params).value() / 1852.0f; | ||||||
|  |          gl.glUniform1f(p->uMapDistanceLocation_, | ||||||
|  |                         static_cast<float>(mapDistance)); | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  |          // If thresholding is disabled, set the map distance to 0
 | ||||||
|  |          gl.glUniform1f(p->uMapDistanceLocation_, 0.0f); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|       // Don't interpolate texture coordinates
 |       // Don't interpolate texture coordinates
 | ||||||
|       gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |       gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||||||
|       gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |       gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||||||
|  | @ -236,7 +258,7 @@ void PlacefileIcons::Deinitialize() | ||||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); |    gl::OpenGLFunctions& gl = p->context_->gl(); | ||||||
| 
 | 
 | ||||||
|    gl.glDeleteVertexArrays(1, &p->vao_); |    gl.glDeleteVertexArrays(1, &p->vao_); | ||||||
|    gl.glDeleteBuffers(1, &p->vbo_); |    gl.glDeleteBuffers(2, p->vbo_.data()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void PlacefileIcons::SetIconFiles( | void PlacefileIcons::SetIconFiles( | ||||||
|  | @ -279,8 +301,11 @@ void PlacefileIcons::Impl::Update() | ||||||
|    if (dirty_) |    if (dirty_) | ||||||
|    { |    { | ||||||
|       static std::vector<float> buffer {}; |       static std::vector<float> buffer {}; | ||||||
|  |       static std::vector<GLint> thresholds {}; | ||||||
|       buffer.clear(); |       buffer.clear(); | ||||||
|       buffer.reserve(iconList_.size() * kBufferLength); |       buffer.reserve(iconList_.size() * kBufferLength); | ||||||
|  |       thresholds.clear(); | ||||||
|  |       thresholds.reserve(iconList_.size() * kVerticesPerRectangle); | ||||||
|       numVertices_ = 0; |       numVertices_ = 0; | ||||||
| 
 | 
 | ||||||
|       for (auto& di : iconList_) |       for (auto& di : iconList_) | ||||||
|  | @ -303,6 +328,10 @@ void PlacefileIcons::Impl::Update() | ||||||
|             continue; |             continue; | ||||||
|          } |          } | ||||||
| 
 | 
 | ||||||
|  |          // TODO: nautical miles
 | ||||||
|  |          GLint threshold = | ||||||
|  |             static_cast<GLint>(std::roundf(di->threshold_.value() / 1852.0f)); | ||||||
|  | 
 | ||||||
|          // Latitude and longitude coordinates in degrees
 |          // Latitude and longitude coordinates in degrees
 | ||||||
|          const float lat = static_cast<float>(di->latitude_); |          const float lat = static_cast<float>(di->latitude_); | ||||||
|          const float lon = static_cast<float>(di->longitude_); |          const float lon = static_cast<float>(di->longitude_); | ||||||
|  | @ -357,17 +386,33 @@ void PlacefileIcons::Impl::Update() | ||||||
|                           lat, lon, rx, ty, rs, tt, mc0, mc1, mc2, mc3, a, // TR
 |                           lat, lon, rx, ty, rs, tt, mc0, mc1, mc2, mc3, a, // TR
 | ||||||
|                           lat, lon, lx, ty, ls, tt, mc0, mc1, mc2, mc3, a  // TL
 |                           lat, lon, lx, ty, ls, tt, mc0, mc1, mc2, mc3, a  // TL
 | ||||||
|                        }); |                        }); | ||||||
|  |          thresholds.insert(thresholds.end(), | ||||||
|  |                            {threshold, //
 | ||||||
|  |                             threshold, | ||||||
|  |                             threshold, | ||||||
|  |                             threshold, | ||||||
|  |                             threshold, | ||||||
|  |                             threshold}); | ||||||
| 
 | 
 | ||||||
|          numVertices_ += 6; |          numVertices_ += 6; | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       gl::OpenGLFunctions& gl = context_->gl(); |       gl::OpenGLFunctions& gl = context_->gl(); | ||||||
| 
 | 
 | ||||||
|  |       // Buffer vertex data
 | ||||||
|  |       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||||
|       gl.glBufferData(GL_ARRAY_BUFFER, |       gl.glBufferData(GL_ARRAY_BUFFER, | ||||||
|                       sizeof(float) * buffer.size(), |                       sizeof(float) * buffer.size(), | ||||||
|                       buffer.data(), |                       buffer.data(), | ||||||
|                       GL_DYNAMIC_DRAW); |                       GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|  |       // Buffer threshold data
 | ||||||
|  |       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||||
|  |       gl.glBufferData(GL_ARRAY_BUFFER, | ||||||
|  |                       sizeof(GLint) * thresholds.size(), | ||||||
|  |                       thresholds.data(), | ||||||
|  |                       GL_DYNAMIC_DRAW); | ||||||
|  | 
 | ||||||
|       dirty_ = false; |       dirty_ = false; | ||||||
|    } |    } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -27,6 +27,8 @@ public: | ||||||
|    PlacefileIcons(PlacefileIcons&&) noexcept; |    PlacefileIcons(PlacefileIcons&&) noexcept; | ||||||
|    PlacefileIcons& operator=(PlacefileIcons&&) noexcept; |    PlacefileIcons& operator=(PlacefileIcons&&) noexcept; | ||||||
| 
 | 
 | ||||||
|  |    void set_thresholded(bool thresholded); | ||||||
|  | 
 | ||||||
|    void Initialize() override; |    void Initialize() override; | ||||||
|    void Render(const QMapLibreGL::CustomLayerRenderParameters& params) override; |    void Render(const QMapLibreGL::CustomLayerRenderParameters& params) override; | ||||||
|    void Deinitialize() override; |    void Deinitialize() override; | ||||||
|  |  | ||||||
|  | @ -6,6 +6,7 @@ | ||||||
| 
 | 
 | ||||||
| #include <GL/glu.h> | #include <GL/glu.h> | ||||||
| #include <boost/container/stable_vector.hpp> | #include <boost/container/stable_vector.hpp> | ||||||
|  | #include <boost/units/base_units/metric/nautical_mile.hpp> | ||||||
| 
 | 
 | ||||||
| #if defined(_WIN32) | #if defined(_WIN32) | ||||||
| typedef void (*_GLUfuncptr)(void); | typedef void (*_GLUfuncptr)(void); | ||||||
|  | @ -48,6 +49,7 @@ public: | ||||||
|        uMVPMatrixLocation_(GL_INVALID_INDEX), |        uMVPMatrixLocation_(GL_INVALID_INDEX), | ||||||
|        uMapMatrixLocation_(GL_INVALID_INDEX), |        uMapMatrixLocation_(GL_INVALID_INDEX), | ||||||
|        uMapScreenCoordLocation_(GL_INVALID_INDEX), |        uMapScreenCoordLocation_(GL_INVALID_INDEX), | ||||||
|  |        uMapDistanceLocation_(GL_INVALID_INDEX), | ||||||
|        vao_ {GL_INVALID_INDEX}, |        vao_ {GL_INVALID_INDEX}, | ||||||
|        vbo_ {GL_INVALID_INDEX}, |        vbo_ {GL_INVALID_INDEX}, | ||||||
|        numVertices_ {0} |        numVertices_ {0} | ||||||
|  | @ -88,6 +90,7 @@ public: | ||||||
|    std::shared_ptr<GlContext> context_; |    std::shared_ptr<GlContext> context_; | ||||||
| 
 | 
 | ||||||
|    bool dirty_ {false}; |    bool dirty_ {false}; | ||||||
|  |    bool thresholded_ {false}; | ||||||
| 
 | 
 | ||||||
|    std::vector<std::shared_ptr<const gr::Placefile::PolygonDrawItem>> |    std::vector<std::shared_ptr<const gr::Placefile::PolygonDrawItem>> | ||||||
|       polygonList_ {}; |       polygonList_ {}; | ||||||
|  | @ -96,7 +99,9 @@ public: | ||||||
| 
 | 
 | ||||||
|    std::mutex           bufferMutex_ {}; |    std::mutex           bufferMutex_ {}; | ||||||
|    std::vector<GLfloat> currentBuffer_ {}; |    std::vector<GLfloat> currentBuffer_ {}; | ||||||
|  |    std::vector<GLint>   currentThresholdBuffer_ {}; | ||||||
|    std::vector<GLfloat> newBuffer_ {}; |    std::vector<GLfloat> newBuffer_ {}; | ||||||
|  |    std::vector<GLint>   newThresholdBuffer_ {}; | ||||||
| 
 | 
 | ||||||
|    GLUtesselator* tessellator_; |    GLUtesselator* tessellator_; | ||||||
| 
 | 
 | ||||||
|  | @ -104,13 +109,14 @@ public: | ||||||
|    GLint                          uMVPMatrixLocation_; |    GLint                          uMVPMatrixLocation_; | ||||||
|    GLint                          uMapMatrixLocation_; |    GLint                          uMapMatrixLocation_; | ||||||
|    GLint                          uMapScreenCoordLocation_; |    GLint                          uMapScreenCoordLocation_; | ||||||
|  |    GLint                          uMapDistanceLocation_; | ||||||
| 
 | 
 | ||||||
|    GLuint                vao_; |    GLuint                vao_; | ||||||
|    GLuint vbo_; |    std::array<GLuint, 2> vbo_; | ||||||
| 
 | 
 | ||||||
|    GLsizei numVertices_; |    GLsizei numVertices_; | ||||||
| 
 | 
 | ||||||
|    boost::gil::rgba8_pixel_t currentColor_ {255, 255, 255, 255}; |    GLint currentThreshold_; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| PlacefilePolygons::PlacefilePolygons(std::shared_ptr<GlContext> context) : | PlacefilePolygons::PlacefilePolygons(std::shared_ptr<GlContext> context) : | ||||||
|  | @ -123,39 +129,32 @@ PlacefilePolygons::PlacefilePolygons(PlacefilePolygons&&) noexcept = default; | ||||||
| PlacefilePolygons& | PlacefilePolygons& | ||||||
| PlacefilePolygons::operator=(PlacefilePolygons&&) noexcept = default; | PlacefilePolygons::operator=(PlacefilePolygons&&) noexcept = default; | ||||||
| 
 | 
 | ||||||
|  | void PlacefilePolygons::set_thresholded(bool thresholded) | ||||||
|  | { | ||||||
|  |    p->thresholded_ = thresholded; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void PlacefilePolygons::Initialize() | void PlacefilePolygons::Initialize() | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); |    gl::OpenGLFunctions& gl = p->context_->gl(); | ||||||
| 
 | 
 | ||||||
|    p->shaderProgram_ = |    p->shaderProgram_ = p->context_->GetShaderProgram( | ||||||
|       p->context_->GetShaderProgram(":/gl/map_color.vert", ":/gl/color.frag"); |       {{GL_VERTEX_SHADER, ":/gl/map_color.vert"}, | ||||||
| 
 |        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, | ||||||
|    p->uMVPMatrixLocation_ = |        {GL_FRAGMENT_SHADER, ":/gl/color.frag"}}); | ||||||
|       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->uMVPMatrixLocation_ = p->shaderProgram_->GetUniformLocation("uMVPMatrix"); | ||||||
|  |    p->uMapMatrixLocation_ = p->shaderProgram_->GetUniformLocation("uMapMatrix"); | ||||||
|    p->uMapScreenCoordLocation_ = |    p->uMapScreenCoordLocation_ = | ||||||
|       gl.glGetUniformLocation(p->shaderProgram_->id(), "uMapScreenCoord"); |       p->shaderProgram_->GetUniformLocation("uMapScreenCoord"); | ||||||
|    if (p->uMapScreenCoordLocation_ == -1) |    p->uMapDistanceLocation_ = | ||||||
|    { |       p->shaderProgram_->GetUniformLocation("uMapDistance"); | ||||||
|       logger_->warn("Could not find uMapScreenCoord"); |  | ||||||
|    } |  | ||||||
| 
 | 
 | ||||||
|    gl.glGenVertexArrays(1, &p->vao_); |    gl.glGenVertexArrays(1, &p->vao_); | ||||||
|    gl.glGenBuffers(1, &p->vbo_); |    gl.glGenBuffers(2, p->vbo_.data()); | ||||||
| 
 | 
 | ||||||
|    gl.glBindVertexArray(p->vao_); |    gl.glBindVertexArray(p->vao_); | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_); |    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); |    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|    // aScreenCoord
 |    // aScreenCoord
 | ||||||
|  | @ -185,18 +184,28 @@ void PlacefilePolygons::Initialize() | ||||||
|                             reinterpret_cast<void*>(4 * sizeof(float))); |                             reinterpret_cast<void*>(4 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(2); |    gl.glEnableVertexAttribArray(2); | ||||||
| 
 | 
 | ||||||
|  |    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||||
|  |    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||||
|  | 
 | ||||||
|  |    // aThreshold
 | ||||||
|  |    gl.glVertexAttribIPointer(3, //
 | ||||||
|  |                              1, | ||||||
|  |                              GL_INT, | ||||||
|  |                              0, | ||||||
|  |                              static_cast<void*>(0)); | ||||||
|  |    gl.glEnableVertexAttribArray(3); | ||||||
|  | 
 | ||||||
|    p->dirty_ = true; |    p->dirty_ = true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void PlacefilePolygons::Render( | void PlacefilePolygons::Render( | ||||||
|    const QMapLibreGL::CustomLayerRenderParameters& params) |    const QMapLibreGL::CustomLayerRenderParameters& params) | ||||||
| { | { | ||||||
|    if (!p->polygonList_.empty()) |    if (!p->currentBuffer_.empty()) | ||||||
|    { |    { | ||||||
|       gl::OpenGLFunctions& gl = p->context_->gl(); |       gl::OpenGLFunctions& gl = p->context_->gl(); | ||||||
| 
 | 
 | ||||||
|       gl.glBindVertexArray(p->vao_); |       gl.glBindVertexArray(p->vao_); | ||||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_); |  | ||||||
| 
 | 
 | ||||||
|       p->Update(); |       p->Update(); | ||||||
|       p->shaderProgram_->Use(); |       p->shaderProgram_->Use(); | ||||||
|  | @ -204,6 +213,21 @@ void PlacefilePolygons::Render( | ||||||
|       UseMapProjection( |       UseMapProjection( | ||||||
|          params, p->uMapMatrixLocation_, p->uMapScreenCoordLocation_); |          params, p->uMapMatrixLocation_, p->uMapScreenCoordLocation_); | ||||||
| 
 | 
 | ||||||
|  |       if (p->thresholded_) | ||||||
|  |       { | ||||||
|  |          // If thresholding is enabled, set the map distance
 | ||||||
|  |          // TODO: nautical miles
 | ||||||
|  |          auto mapDistance = | ||||||
|  |             util::maplibre::GetMapDistance(params).value() / 1852.0f; | ||||||
|  |          gl.glUniform1f(p->uMapDistanceLocation_, | ||||||
|  |                         static_cast<float>(mapDistance)); | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  |          // If thresholding is disabled, set the map distance to 0
 | ||||||
|  |          gl.glUniform1f(p->uMapDistanceLocation_, 0.0f); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|       // Draw icons
 |       // Draw icons
 | ||||||
|       gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); |       gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||||
|    } |    } | ||||||
|  | @ -214,13 +238,14 @@ void PlacefilePolygons::Deinitialize() | ||||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); |    gl::OpenGLFunctions& gl = p->context_->gl(); | ||||||
| 
 | 
 | ||||||
|    gl.glDeleteVertexArrays(1, &p->vao_); |    gl.glDeleteVertexArrays(1, &p->vao_); | ||||||
|    gl.glDeleteBuffers(1, &p->vbo_); |    gl.glDeleteBuffers(2, p->vbo_.data()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void PlacefilePolygons::StartPolygons() | void PlacefilePolygons::StartPolygons() | ||||||
| { | { | ||||||
|    // Clear the new buffer
 |    // Clear the new buffer
 | ||||||
|    p->newBuffer_.clear(); |    p->newBuffer_.clear(); | ||||||
|  |    p->newThresholdBuffer_.clear(); | ||||||
| 
 | 
 | ||||||
|    // Clear the polygon list
 |    // Clear the polygon list
 | ||||||
|    p->polygonList_.clear(); |    p->polygonList_.clear(); | ||||||
|  | @ -242,6 +267,7 @@ void PlacefilePolygons::FinishPolygons() | ||||||
| 
 | 
 | ||||||
|    // Swap buffers
 |    // Swap buffers
 | ||||||
|    p->currentBuffer_.swap(p->newBuffer_); |    p->currentBuffer_.swap(p->newBuffer_); | ||||||
|  |    p->currentThresholdBuffer_.swap(p->newThresholdBuffer_); | ||||||
| 
 | 
 | ||||||
|    // Mark the draw item dirty
 |    // Mark the draw item dirty
 | ||||||
|    p->dirty_ = true; |    p->dirty_ = true; | ||||||
|  | @ -255,11 +281,20 @@ void PlacefilePolygons::Impl::Update() | ||||||
| 
 | 
 | ||||||
|       std::unique_lock lock {bufferMutex_}; |       std::unique_lock lock {bufferMutex_}; | ||||||
| 
 | 
 | ||||||
|  |       // Buffer vertex data
 | ||||||
|  |       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||||
|       gl.glBufferData(GL_ARRAY_BUFFER, |       gl.glBufferData(GL_ARRAY_BUFFER, | ||||||
|                       sizeof(GLfloat) * currentBuffer_.size(), |                       sizeof(GLfloat) * currentBuffer_.size(), | ||||||
|                       currentBuffer_.data(), |                       currentBuffer_.data(), | ||||||
|                       GL_DYNAMIC_DRAW); |                       GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|  |       // Buffer threshold data
 | ||||||
|  |       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||||
|  |       gl.glBufferData(GL_ARRAY_BUFFER, | ||||||
|  |                       sizeof(GLint) * currentThresholdBuffer_.size(), | ||||||
|  |                       currentThresholdBuffer_.data(), | ||||||
|  |                       GL_DYNAMIC_DRAW); | ||||||
|  | 
 | ||||||
|       numVertices_ = |       numVertices_ = | ||||||
|          static_cast<GLsizei>(currentBuffer_.size() / kPointsPerVertex); |          static_cast<GLsizei>(currentBuffer_.size() / kPointsPerVertex); | ||||||
| 
 | 
 | ||||||
|  | @ -276,6 +311,10 @@ void PlacefilePolygons::Impl::Tessellate( | ||||||
|    // Default color to "Color" statement
 |    // Default color to "Color" statement
 | ||||||
|    boost::gil::rgba8_pixel_t lastColor = di->color_; |    boost::gil::rgba8_pixel_t lastColor = di->color_; | ||||||
| 
 | 
 | ||||||
|  |    // TODO: nautical miles
 | ||||||
|  |    currentThreshold_ = | ||||||
|  |       static_cast<GLint>(std::roundf(di->threshold_.value() / 1852.0f)); | ||||||
|  | 
 | ||||||
|    gluTessBeginPolygon(tessellator_, this); |    gluTessBeginPolygon(tessellator_, this); | ||||||
| 
 | 
 | ||||||
|    for (auto& contour : di->contours_) |    for (auto& contour : di->contours_) | ||||||
|  | @ -322,6 +361,7 @@ void PlacefilePolygons::Impl::Tessellate( | ||||||
|    while (newBuffer_.size() % kVerticesPerTriangle != 0) |    while (newBuffer_.size() % kVerticesPerTriangle != 0) | ||||||
|    { |    { | ||||||
|       newBuffer_.pop_back(); |       newBuffer_.pop_back(); | ||||||
|  |       newThresholdBuffer_.pop_back(); | ||||||
|    } |    } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -382,6 +422,7 @@ void PlacefilePolygons::Impl::TessellateVertexCallback(void* vertexData, | ||||||
|                             static_cast<float>(data[kTessVertexG_]), |                             static_cast<float>(data[kTessVertexG_]), | ||||||
|                             static_cast<float>(data[kTessVertexB_]), |                             static_cast<float>(data[kTessVertexB_]), | ||||||
|                             static_cast<float>(data[kTessVertexA_])}); |                             static_cast<float>(data[kTessVertexA_])}); | ||||||
|  |    self->newThresholdBuffer_.push_back(self->currentThreshold_); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void PlacefilePolygons::Impl::TessellateErrorCallback(GLenum errorCode) | void PlacefilePolygons::Impl::TessellateErrorCallback(GLenum errorCode) | ||||||
|  |  | ||||||
|  | @ -27,6 +27,8 @@ public: | ||||||
|    PlacefilePolygons(PlacefilePolygons&&) noexcept; |    PlacefilePolygons(PlacefilePolygons&&) noexcept; | ||||||
|    PlacefilePolygons& operator=(PlacefilePolygons&&) noexcept; |    PlacefilePolygons& operator=(PlacefilePolygons&&) noexcept; | ||||||
| 
 | 
 | ||||||
|  |    void set_thresholded(bool thresholded); | ||||||
|  | 
 | ||||||
|    void Initialize() override; |    void Initialize() override; | ||||||
|    void Render(const QMapLibreGL::CustomLayerRenderParameters& params) override; |    void Render(const QMapLibreGL::CustomLayerRenderParameters& params) override; | ||||||
|    void Deinitialize() override; |    void Deinitialize() override; | ||||||
|  |  | ||||||
|  | @ -56,6 +56,16 @@ GLuint ShaderProgram::id() const | ||||||
|    return p->id_; |    return p->id_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | GLint ShaderProgram::GetUniformLocation(const std::string& name) | ||||||
|  | { | ||||||
|  |    GLint location = p->gl_.glGetUniformLocation(p->id_, name.c_str()); | ||||||
|  |    if (location == -1) | ||||||
|  |    { | ||||||
|  |       logger_->warn("Could not find {}", name); | ||||||
|  |    } | ||||||
|  |    return location; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| std::string ShaderProgram::Impl::ShaderName(GLenum type) | std::string ShaderProgram::Impl::ShaderName(GLenum type) | ||||||
| { | { | ||||||
|    auto it = kShaderNames_.find(type); |    auto it = kShaderNames_.find(type); | ||||||
|  |  | ||||||
|  | @ -30,6 +30,8 @@ public: | ||||||
| 
 | 
 | ||||||
|    GLuint id() const; |    GLuint id() const; | ||||||
| 
 | 
 | ||||||
|  |    GLint GetUniformLocation(const std::string& name); | ||||||
|  | 
 | ||||||
|    bool Load(const std::string& vertexPath, const std::string& fragmentPath); |    bool Load(const std::string& vertexPath, const std::string& fragmentPath); | ||||||
|    bool Load(std::initializer_list<std::pair<GLenum, std::string>> shaderPaths); |    bool Load(std::initializer_list<std::pair<GLenum, std::string>> shaderPaths); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -4,11 +4,11 @@ | ||||||
| #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> | ||||||
| #include <scwx/qt/util/geographic_lib.hpp> |  | ||||||
| #include <scwx/qt/util/maplibre.hpp> | #include <scwx/qt/util/maplibre.hpp> | ||||||
| #include <scwx/common/geographic.hpp> | #include <scwx/common/geographic.hpp> | ||||||
| #include <scwx/util/logger.hpp> | #include <scwx/util/logger.hpp> | ||||||
| 
 | 
 | ||||||
|  | #include <boost/units/base_units/metric/nautical_mile.hpp> | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
| #include <imgui.h> | #include <imgui.h> | ||||||
| #include <mbgl/util/constants.hpp> | #include <mbgl/util/constants.hpp> | ||||||
|  | @ -41,12 +41,8 @@ public: | ||||||
| 
 | 
 | ||||||
|    void ConnectSignals(); |    void ConnectSignals(); | ||||||
| 
 | 
 | ||||||
|    void |    void AddIcon(const std::shared_ptr<gr::Placefile::IconDrawItem>& di); | ||||||
|    RenderIconDrawItem(const QMapLibreGL::CustomLayerRenderParameters& params, |    void AddPolygon(const std::shared_ptr<gr::Placefile::PolygonDrawItem>& di); | ||||||
|                       const std::shared_ptr<gr::Placefile::IconDrawItem>& di); |  | ||||||
|    void RenderPolygonDrawItem( |  | ||||||
|       const QMapLibreGL::CustomLayerRenderParameters&        params, |  | ||||||
|       const std::shared_ptr<gr::Placefile::PolygonDrawItem>& di); |  | ||||||
|    void |    void | ||||||
|    RenderTextDrawItem(const QMapLibreGL::CustomLayerRenderParameters& params, |    RenderTextDrawItem(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||||
|                       const std::shared_ptr<gr::Placefile::TextDrawItem>& di); |                       const std::shared_ptr<gr::Placefile::TextDrawItem>& di); | ||||||
|  | @ -73,6 +69,8 @@ public: | ||||||
|    bool          thresholded_ {true}; |    bool          thresholded_ {true}; | ||||||
|    ImFont*       monospaceFont_ {}; |    ImFont*       monospaceFont_ {}; | ||||||
| 
 | 
 | ||||||
|  |    boost::units::quantity<boost::units::si::length> mapDistance_ {}; | ||||||
|  | 
 | ||||||
|    std::shared_ptr<gl::draw::PlacefileIcons>    placefileIcons_; |    std::shared_ptr<gl::draw::PlacefileIcons>    placefileIcons_; | ||||||
|    std::shared_ptr<gl::draw::PlacefilePolygons> placefilePolygons_; |    std::shared_ptr<gl::draw::PlacefilePolygons> placefilePolygons_; | ||||||
| }; | }; | ||||||
|  | @ -122,8 +120,7 @@ void PlacefileLayer::Initialize() | ||||||
|    DrawLayer::Initialize(); |    DrawLayer::Initialize(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void PlacefileLayer::Impl::RenderIconDrawItem( | void PlacefileLayer::Impl::AddIcon( | ||||||
|    const QMapLibreGL::CustomLayerRenderParameters&     params, |  | ||||||
|    const std::shared_ptr<gr::Placefile::IconDrawItem>& di) |    const std::shared_ptr<gr::Placefile::IconDrawItem>& di) | ||||||
| { | { | ||||||
|    if (!dirty_) |    if (!dirty_) | ||||||
|  | @ -131,51 +128,25 @@ void PlacefileLayer::Impl::RenderIconDrawItem( | ||||||
|       return; |       return; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    auto distance = |  | ||||||
|       (thresholded_) ? |  | ||||||
|          util::GeographicLib::GetDistance( |  | ||||||
|             params.latitude, params.longitude, di->latitude_, di->longitude_) : |  | ||||||
|          0; |  | ||||||
| 
 |  | ||||||
|    if (distance < di->threshold_) |  | ||||||
|    { |  | ||||||
|    placefileIcons_->AddIcon(di); |    placefileIcons_->AddIcon(di); | ||||||
| } | } | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| void PlacefileLayer::Impl::RenderPolygonDrawItem( | void PlacefileLayer::Impl::AddPolygon( | ||||||
|    const QMapLibreGL::CustomLayerRenderParameters&        params, |  | ||||||
|    const std::shared_ptr<gr::Placefile::PolygonDrawItem>& di) |    const std::shared_ptr<gr::Placefile::PolygonDrawItem>& di) | ||||||
| { | { | ||||||
|    if (!dirty_) |    if (!dirty_) | ||||||
|    { |    { | ||||||
|       return; |       return; | ||||||
|    } |    }; | ||||||
| 
 | 
 | ||||||
|    auto distance = (thresholded_) ? |  | ||||||
|                       util::GeographicLib::GetDistance(params.latitude, |  | ||||||
|                                                        params.longitude, |  | ||||||
|                                                        di->center_.latitude_, |  | ||||||
|                                                        di->center_.longitude_) : |  | ||||||
|                       0; |  | ||||||
| 
 |  | ||||||
|    if (distance < di->threshold_) |  | ||||||
|    { |  | ||||||
|    placefilePolygons_->AddPolygon(di); |    placefilePolygons_->AddPolygon(di); | ||||||
| } | } | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| void PlacefileLayer::Impl::RenderTextDrawItem( | void PlacefileLayer::Impl::RenderTextDrawItem( | ||||||
|    const QMapLibreGL::CustomLayerRenderParameters&     params, |    const QMapLibreGL::CustomLayerRenderParameters&     params, | ||||||
|    const std::shared_ptr<gr::Placefile::TextDrawItem>& di) |    const std::shared_ptr<gr::Placefile::TextDrawItem>& di) | ||||||
| { | { | ||||||
|    auto distance = |    if (!thresholded_ || mapDistance_ <= di->threshold_) | ||||||
|       (thresholded_) ? |  | ||||||
|          util::GeographicLib::GetDistance( |  | ||||||
|             params.latitude, params.longitude, di->latitude_, di->longitude_) : |  | ||||||
|          0; |  | ||||||
| 
 |  | ||||||
|    if (distance < di->threshold_) |  | ||||||
|    { |    { | ||||||
|       const auto screenCoordinates = (util::maplibre::LatLongToScreenCoordinate( |       const auto screenCoordinates = (util::maplibre::LatLongToScreenCoordinate( | ||||||
|                                          {di->latitude_, di->longitude_}) - |                                          {di->latitude_, di->longitude_}) - | ||||||
|  | @ -265,6 +236,7 @@ void PlacefileLayer::Render( | ||||||
|    p->mapBearingSin_ = sinf(params.bearing * common::kDegreesToRadians); |    p->mapBearingSin_ = sinf(params.bearing * common::kDegreesToRadians); | ||||||
|    p->halfWidth_     = params.width * 0.5f; |    p->halfWidth_     = params.width * 0.5f; | ||||||
|    p->halfHeight_    = params.height * 0.5f; |    p->halfHeight_    = params.height * 0.5f; | ||||||
|  |    p->mapDistance_   = util::maplibre::GetMapDistance(params); | ||||||
| 
 | 
 | ||||||
|    // Get monospace font pointer
 |    // Get monospace font pointer
 | ||||||
|    std::size_t fontSize = 16; |    std::size_t fontSize = 16; | ||||||
|  | @ -292,6 +264,8 @@ void PlacefileLayer::Render( | ||||||
|    { |    { | ||||||
|       p->thresholded_ = |       p->thresholded_ = | ||||||
|          placefileManager->placefile_thresholded(placefile->name()); |          placefileManager->placefile_thresholded(placefile->name()); | ||||||
|  |       p->placefileIcons_->set_thresholded(p->thresholded_); | ||||||
|  |       p->placefilePolygons_->set_thresholded(p->thresholded_); | ||||||
| 
 | 
 | ||||||
|       if (p->dirty_) |       if (p->dirty_) | ||||||
|       { |       { | ||||||
|  | @ -315,14 +289,12 @@ void PlacefileLayer::Render( | ||||||
|             break; |             break; | ||||||
| 
 | 
 | ||||||
|          case gr::Placefile::ItemType::Icon: |          case gr::Placefile::ItemType::Icon: | ||||||
|             p->RenderIconDrawItem( |             p->AddIcon( | ||||||
|                params, |  | ||||||
|                std::static_pointer_cast<gr::Placefile::IconDrawItem>(drawItem)); |                std::static_pointer_cast<gr::Placefile::IconDrawItem>(drawItem)); | ||||||
|             break; |             break; | ||||||
| 
 | 
 | ||||||
|          case gr::Placefile::ItemType::Polygon: |          case gr::Placefile::ItemType::Polygon: | ||||||
|             p->RenderPolygonDrawItem( |             p->AddPolygon( | ||||||
|                params, |  | ||||||
|                std::static_pointer_cast<gr::Placefile::PolygonDrawItem>( |                std::static_pointer_cast<gr::Placefile::PolygonDrawItem>( | ||||||
|                   drawItem)); |                   drawItem)); | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat