mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-30 12:30:05 +00:00 
			
		
		
		
	Merge pull request #478 from dpaulat/feature/opengl-3.3-core
Use GLEW instead of QOpenGLFunctions
This commit is contained in:
		
						commit
						01ae858906
					
				
					 35 changed files with 996 additions and 1026 deletions
				
			
		|  | @ -30,13 +30,11 @@ static const std::string logPrefix_ = "scwx::qt::gl::draw::draw_item"; | |||
| class DrawItem::Impl | ||||
| { | ||||
| public: | ||||
|    explicit Impl(OpenGLFunctions& gl) : gl_ {gl} {} | ||||
|    ~Impl() {} | ||||
| 
 | ||||
|    OpenGLFunctions& gl_; | ||||
|    explicit Impl() = default; | ||||
|    ~Impl()         = default; | ||||
| }; | ||||
| 
 | ||||
| DrawItem::DrawItem(OpenGLFunctions& gl) : p(std::make_unique<Impl>(gl)) {} | ||||
| DrawItem::DrawItem() : p(std::make_unique<Impl>()) {} | ||||
| DrawItem::~DrawItem() = default; | ||||
| 
 | ||||
| DrawItem::DrawItem(DrawItem&&) noexcept            = default; | ||||
|  | @ -74,7 +72,7 @@ void DrawItem::UseDefaultProjection( | |||
|                                      0.0f, | ||||
|                                      static_cast<float>(params.height)); | ||||
| 
 | ||||
|    p->gl_.glUniformMatrix4fv( | ||||
|    glUniformMatrix4fv( | ||||
|       uMVPMatrixLocation, 1, GL_FALSE, glm::value_ptr(projection)); | ||||
| } | ||||
| 
 | ||||
|  | @ -91,7 +89,7 @@ void DrawItem::UseRotationProjection( | |||
|                             glm::radians<float>(params.bearing), | ||||
|                             glm::vec3(0.0f, 0.0f, 1.0f)); | ||||
| 
 | ||||
|    p->gl_.glUniformMatrix4fv( | ||||
|    glUniformMatrix4fv( | ||||
|       uMVPMatrixLocation, 1, GL_FALSE, glm::value_ptr(projection)); | ||||
| } | ||||
| 
 | ||||
|  | @ -100,16 +98,14 @@ void DrawItem::UseMapProjection( | |||
|    GLint                                         uMVPMatrixLocation, | ||||
|    GLint                                         uMapScreenCoordLocation) | ||||
| { | ||||
|    OpenGLFunctions& gl = p->gl_; | ||||
| 
 | ||||
|    const glm::mat4 uMVPMatrix = util::maplibre::GetMapMatrix(params); | ||||
| 
 | ||||
|    gl.glUniform2fv(uMapScreenCoordLocation, | ||||
|                    1, | ||||
|                    glm::value_ptr(util::maplibre::LatLongToScreenCoordinate( | ||||
|                       {params.latitude, params.longitude}))); | ||||
|    glUniform2fv(uMapScreenCoordLocation, | ||||
|                 1, | ||||
|                 glm::value_ptr(util::maplibre::LatLongToScreenCoordinate( | ||||
|                    {params.latitude, params.longitude}))); | ||||
| 
 | ||||
|    gl.glUniformMatrix4fv( | ||||
|    glUniformMatrix4fv( | ||||
|       uMVPMatrixLocation, 1, GL_FALSE, glm::value_ptr(uMVPMatrix)); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -21,7 +21,7 @@ namespace draw | |||
| class DrawItem | ||||
| { | ||||
| public: | ||||
|    explicit DrawItem(OpenGLFunctions& gl); | ||||
|    explicit DrawItem(); | ||||
|    virtual ~DrawItem(); | ||||
| 
 | ||||
|    DrawItem(const DrawItem&)            = delete; | ||||
|  |  | |||
|  | @ -144,7 +144,7 @@ public: | |||
| }; | ||||
| 
 | ||||
| GeoIcons::GeoIcons(const std::shared_ptr<GlContext>& context) : | ||||
|     DrawItem(context->gl()), p(std::make_unique<Impl>(context)) | ||||
|     DrawItem(), p(std::make_unique<Impl>(context)) | ||||
| { | ||||
| } | ||||
| GeoIcons::~GeoIcons() = default; | ||||
|  | @ -165,8 +165,6 @@ void GeoIcons::set_thresholded(bool thresholded) | |||
| 
 | ||||
| void GeoIcons::Initialize() | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
| 
 | ||||
|    p->shaderProgram_ = p->context_->GetShaderProgram( | ||||
|       {{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"}, | ||||
|        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, | ||||
|  | @ -181,87 +179,95 @@ void GeoIcons::Initialize() | |||
|    p->uSelectedTimeLocation_ = | ||||
|       p->shaderProgram_->GetUniformLocation("uSelectedTime"); | ||||
| 
 | ||||
|    gl.glGenVertexArrays(1, &p->vao_); | ||||
|    gl.glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||
|    glGenVertexArrays(1, &p->vao_); | ||||
|    glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||
| 
 | ||||
|    gl.glBindVertexArray(p->vao_); | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
|    glBindVertexArray(p->vao_); | ||||
|    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|    // NOLINTBEGIN(modernize-use-nullptr)
 | ||||
|    // NOLINTBEGIN(performance-no-int-to-ptr)
 | ||||
|    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||
| 
 | ||||
|    // aLatLong
 | ||||
|    gl.glVertexAttribPointer(0, | ||||
|                             2, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(0); | ||||
|    glVertexAttribPointer(0, | ||||
|                          2, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          static_cast<void*>(0)); | ||||
|    glEnableVertexAttribArray(0); | ||||
| 
 | ||||
|    // aXYOffset
 | ||||
|    gl.glVertexAttribPointer(1, | ||||
|                             2, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(2 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(1); | ||||
|    glVertexAttribPointer(1, | ||||
|                          2, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          reinterpret_cast<void*>(2 * sizeof(float))); | ||||
|    glEnableVertexAttribArray(1); | ||||
| 
 | ||||
|    // aModulate
 | ||||
|    gl.glVertexAttribPointer(3, | ||||
|                             4, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(4 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(3); | ||||
|    glVertexAttribPointer(3, | ||||
|                          4, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          reinterpret_cast<void*>(4 * sizeof(float))); | ||||
|    glEnableVertexAttribArray(3); | ||||
| 
 | ||||
|    // aAngle
 | ||||
|    gl.glVertexAttribPointer(4, | ||||
|                             1, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(8 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(4); | ||||
|    glVertexAttribPointer(4, | ||||
|                          1, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          reinterpret_cast<void*>(8 * sizeof(float))); | ||||
|    glEnableVertexAttribArray(4); | ||||
| 
 | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
|    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||
|    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|    // aTexCoord
 | ||||
|    gl.glVertexAttribPointer(2, | ||||
|                             3, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerTexCoord * sizeof(float), | ||||
|                             static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(2); | ||||
|    glVertexAttribPointer(2, | ||||
|                          3, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerTexCoord * sizeof(float), | ||||
|                          static_cast<void*>(0)); | ||||
|    glEnableVertexAttribArray(2); | ||||
| 
 | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[2]); | ||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
|    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[2]); | ||||
|    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|    // aThreshold
 | ||||
|    gl.glVertexAttribIPointer(5, //
 | ||||
|                              1, | ||||
|                              GL_INT, | ||||
|                              0, | ||||
|                              static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(5); | ||||
|    glVertexAttribIPointer(5, //
 | ||||
|                           1, | ||||
|                           GL_INT, | ||||
|                           0, | ||||
|                           static_cast<void*>(0)); | ||||
|    glEnableVertexAttribArray(5); | ||||
| 
 | ||||
|    // aTimeRange
 | ||||
|    gl.glVertexAttribIPointer(6, //
 | ||||
|                              2, | ||||
|                              GL_INT, | ||||
|                              kIntegersPerVertex_ * sizeof(GLint), | ||||
|                              reinterpret_cast<void*>(1 * sizeof(GLint))); | ||||
|    gl.glEnableVertexAttribArray(6); | ||||
|    glVertexAttribIPointer(6, //
 | ||||
|                           2, | ||||
|                           GL_INT, | ||||
|                           kIntegersPerVertex_ * sizeof(GLint), | ||||
|                           reinterpret_cast<void*>(1 * sizeof(GLint))); | ||||
|    glEnableVertexAttribArray(6); | ||||
| 
 | ||||
|    // aDisplayed
 | ||||
|    gl.glVertexAttribIPointer(7, | ||||
|                              1, | ||||
|                              GL_INT, | ||||
|                              kIntegersPerVertex_ * sizeof(GLint), | ||||
|                              reinterpret_cast<void*>(3 * sizeof(GLint))); | ||||
|    gl.glEnableVertexAttribArray(7); | ||||
|    glVertexAttribIPointer(7, | ||||
|                           1, | ||||
|                           GL_INT, | ||||
|                           kIntegersPerVertex_ * sizeof(GLint), | ||||
|                           reinterpret_cast<void*>(3 * sizeof(GLint))); | ||||
|    glEnableVertexAttribArray(7); | ||||
| 
 | ||||
|    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||
|    // NOLINTEND(performance-no-int-to-ptr)
 | ||||
|    // NOLINTEND(modernize-use-nullptr)
 | ||||
| 
 | ||||
|    p->dirty_ = true; | ||||
| } | ||||
|  | @ -283,9 +289,7 @@ void GeoIcons::Render(const QMapLibre::CustomLayerRenderParameters& params, | |||
| 
 | ||||
|    if (!p->currentIconList_.empty()) | ||||
|    { | ||||
|       gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
| 
 | ||||
|       gl.glBindVertexArray(p->vao_); | ||||
|       glBindVertexArray(p->vao_); | ||||
| 
 | ||||
|       p->Update(textureAtlasChanged); | ||||
|       p->shaderProgram_->Use(); | ||||
|  | @ -298,12 +302,12 @@ void GeoIcons::Render(const QMapLibre::CustomLayerRenderParameters& params, | |||
|          // If thresholding is enabled, set the map distance
 | ||||
|          units::length::nautical_miles<float> mapDistance = | ||||
|             util::maplibre::GetMapDistance(params); | ||||
|          gl.glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); | ||||
|          glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          // If thresholding is disabled, set the map distance to 0
 | ||||
|          gl.glUniform1f(p->uMapDistanceLocation_, 0.0f); | ||||
|          glUniform1f(p->uMapDistanceLocation_, 0.0f); | ||||
|       } | ||||
| 
 | ||||
|       // Selected time
 | ||||
|  | @ -311,27 +315,25 @@ void GeoIcons::Render(const QMapLibre::CustomLayerRenderParameters& params, | |||
|          (p->selectedTime_ == std::chrono::system_clock::time_point {}) ? | ||||
|             std::chrono::system_clock::now() : | ||||
|             p->selectedTime_; | ||||
|       gl.glUniform1i( | ||||
|       glUniform1i( | ||||
|          p->uSelectedTimeLocation_, | ||||
|          static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>( | ||||
|                                selectedTime.time_since_epoch()) | ||||
|                                .count())); | ||||
| 
 | ||||
|       // Interpolate texture coordinates
 | ||||
|       gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||||
|       gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||||
|       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||||
|       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||||
| 
 | ||||
|       // Draw icons
 | ||||
|       gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||
|       glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| void GeoIcons::Deinitialize() | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
| 
 | ||||
|    gl.glDeleteVertexArrays(1, &p->vao_); | ||||
|    gl.glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||
|    glDeleteVertexArrays(1, &p->vao_); | ||||
|    glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||
| 
 | ||||
|    std::unique_lock lock {p->iconMutex_}; | ||||
| 
 | ||||
|  | @ -847,8 +849,6 @@ void GeoIcons::Impl::UpdateModifiedIconBuffers() | |||
| 
 | ||||
| void GeoIcons::Impl::Update(bool textureAtlasChanged) | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = context_->gl(); | ||||
| 
 | ||||
|    UpdateModifiedIconBuffers(); | ||||
| 
 | ||||
|    // If the texture atlas has changed
 | ||||
|  | @ -864,11 +864,12 @@ void GeoIcons::Impl::Update(bool textureAtlasChanged) | |||
|       UpdateTextureBuffer(); | ||||
| 
 | ||||
|       // Buffer texture data
 | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||
|       gl.glBufferData(GL_ARRAY_BUFFER, | ||||
|                       sizeof(float) * textureBuffer_.size(), | ||||
|                       textureBuffer_.data(), | ||||
|                       GL_DYNAMIC_DRAW); | ||||
|       glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||
|       glBufferData( | ||||
|          GL_ARRAY_BUFFER, | ||||
|          static_cast<GLsizeiptr>(sizeof(float) * textureBuffer_.size()), | ||||
|          textureBuffer_.data(), | ||||
|          GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|       lastTextureAtlasChanged_ = false; | ||||
|    } | ||||
|  | @ -877,18 +878,20 @@ void GeoIcons::Impl::Update(bool textureAtlasChanged) | |||
|    if (dirty_) | ||||
|    { | ||||
|       // Buffer vertex data
 | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||
|       gl.glBufferData(GL_ARRAY_BUFFER, | ||||
|                       sizeof(float) * currentIconBuffer_.size(), | ||||
|                       currentIconBuffer_.data(), | ||||
|                       GL_DYNAMIC_DRAW); | ||||
|       glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||
|       glBufferData( | ||||
|          GL_ARRAY_BUFFER, | ||||
|          static_cast<GLsizeiptr>(sizeof(float) * currentIconBuffer_.size()), | ||||
|          currentIconBuffer_.data(), | ||||
|          GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|       // Buffer threshold data
 | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[2]); | ||||
|       gl.glBufferData(GL_ARRAY_BUFFER, | ||||
|                       sizeof(GLint) * currentIntegerBuffer_.size(), | ||||
|                       currentIntegerBuffer_.data(), | ||||
|                       GL_DYNAMIC_DRAW); | ||||
|       glBindBuffer(GL_ARRAY_BUFFER, vbo_[2]); | ||||
|       glBufferData( | ||||
|          GL_ARRAY_BUFFER, | ||||
|          static_cast<GLsizeiptr>(sizeof(GLint) * currentIntegerBuffer_.size()), | ||||
|          currentIntegerBuffer_.data(), | ||||
|          GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|       numVertices_ = | ||||
|          static_cast<GLsizei>(currentIconBuffer_.size() / kPointsPerVertex); | ||||
|  |  | |||
|  | @ -130,7 +130,7 @@ public: | |||
| }; | ||||
| 
 | ||||
| GeoLines::GeoLines(std::shared_ptr<GlContext> context) : | ||||
|     DrawItem(context->gl()), p(std::make_unique<Impl>(context)) | ||||
|     DrawItem(), p(std::make_unique<Impl>(context)) | ||||
| { | ||||
| } | ||||
| GeoLines::~GeoLines() = default; | ||||
|  | @ -151,8 +151,6 @@ void GeoLines::set_thresholded(bool thresholded) | |||
| 
 | ||||
| void GeoLines::Initialize() | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
| 
 | ||||
|    p->shaderProgram_ = p->context_->GetShaderProgram( | ||||
|       {{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"}, | ||||
|        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, | ||||
|  | @ -167,78 +165,86 @@ void GeoLines::Initialize() | |||
|    p->uSelectedTimeLocation_ = | ||||
|       p->shaderProgram_->GetUniformLocation("uSelectedTime"); | ||||
| 
 | ||||
|    gl.glGenVertexArrays(1, &p->vao_); | ||||
|    gl.glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||
|    glGenVertexArrays(1, &p->vao_); | ||||
|    glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||
| 
 | ||||
|    gl.glBindVertexArray(p->vao_); | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|    gl.glBufferData(GL_ARRAY_BUFFER, | ||||
|                    sizeof(float) * kLineBufferLength_, | ||||
|                    nullptr, | ||||
|                    GL_DYNAMIC_DRAW); | ||||
|    glBindVertexArray(p->vao_); | ||||
|    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|    glBufferData(GL_ARRAY_BUFFER, | ||||
|                 sizeof(float) * kLineBufferLength_, | ||||
|                 nullptr, | ||||
|                 GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|    // NOLINTBEGIN(modernize-use-nullptr)
 | ||||
|    // NOLINTBEGIN(performance-no-int-to-ptr)
 | ||||
|    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||
| 
 | ||||
|    // aLatLong
 | ||||
|    gl.glVertexAttribPointer(0, | ||||
|                             2, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(0); | ||||
|    glVertexAttribPointer(0, | ||||
|                          2, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          static_cast<void*>(0)); | ||||
|    glEnableVertexAttribArray(0); | ||||
| 
 | ||||
|    // aXYOffset
 | ||||
|    gl.glVertexAttribPointer(1, | ||||
|                             2, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(2 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(1); | ||||
|    glVertexAttribPointer(1, | ||||
|                          2, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          reinterpret_cast<void*>(2 * sizeof(float))); | ||||
|    glEnableVertexAttribArray(1); | ||||
| 
 | ||||
|    // aModulate
 | ||||
|    gl.glVertexAttribPointer(3, | ||||
|                             4, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(4 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(3); | ||||
|    glVertexAttribPointer(3, | ||||
|                          4, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          reinterpret_cast<void*>(4 * sizeof(float))); | ||||
|    glEnableVertexAttribArray(3); | ||||
| 
 | ||||
|    // aAngle
 | ||||
|    gl.glVertexAttribPointer(4, | ||||
|                             1, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(8 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(4); | ||||
|    glVertexAttribPointer(4, | ||||
|                          1, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          reinterpret_cast<void*>(8 * sizeof(float))); | ||||
|    glEnableVertexAttribArray(4); | ||||
| 
 | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
|    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||
|    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|    // aThreshold
 | ||||
|    gl.glVertexAttribIPointer(5, //
 | ||||
|                              1, | ||||
|                              GL_INT, | ||||
|                              kIntegersPerVertex_ * sizeof(GLint), | ||||
|                              static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(5); | ||||
|    glVertexAttribIPointer(5, //
 | ||||
|                           1, | ||||
|                           GL_INT, | ||||
|                           kIntegersPerVertex_ * sizeof(GLint), | ||||
|                           static_cast<void*>(0)); | ||||
|    glEnableVertexAttribArray(5); | ||||
| 
 | ||||
|    // aTimeRange
 | ||||
|    gl.glVertexAttribIPointer(6, //
 | ||||
|                              2, | ||||
|                              GL_INT, | ||||
|                              kIntegersPerVertex_ * sizeof(GLint), | ||||
|                              reinterpret_cast<void*>(1 * sizeof(GLint))); | ||||
|    gl.glEnableVertexAttribArray(6); | ||||
|    glVertexAttribIPointer(6, //
 | ||||
|                           2, | ||||
|                           GL_INT, | ||||
|                           kIntegersPerVertex_ * sizeof(GLint), | ||||
|                           reinterpret_cast<void*>(1 * sizeof(GLint))); | ||||
|    glEnableVertexAttribArray(6); | ||||
| 
 | ||||
|    // aDisplayed
 | ||||
|    gl.glVertexAttribIPointer(7, | ||||
|                              1, | ||||
|                              GL_INT, | ||||
|                              kIntegersPerVertex_ * sizeof(GLint), | ||||
|                              reinterpret_cast<void*>(3 * sizeof(GLint))); | ||||
|    gl.glEnableVertexAttribArray(7); | ||||
|    glVertexAttribIPointer(7, | ||||
|                           1, | ||||
|                           GL_INT, | ||||
|                           kIntegersPerVertex_ * sizeof(GLint), | ||||
|                           reinterpret_cast<void*>(3 * sizeof(GLint))); | ||||
|    glEnableVertexAttribArray(7); | ||||
| 
 | ||||
|    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||
|    // NOLINTEND(performance-no-int-to-ptr)
 | ||||
|    // NOLINTEND(modernize-use-nullptr)
 | ||||
| 
 | ||||
|    p->dirty_ = true; | ||||
| } | ||||
|  | @ -254,9 +260,7 @@ void GeoLines::Render(const QMapLibre::CustomLayerRenderParameters& params) | |||
| 
 | ||||
|    if (p->newLineList_.size() > 0) | ||||
|    { | ||||
|       gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
| 
 | ||||
|       gl.glBindVertexArray(p->vao_); | ||||
|       glBindVertexArray(p->vao_); | ||||
| 
 | ||||
|       p->Update(); | ||||
|       p->shaderProgram_->Use(); | ||||
|  | @ -269,12 +273,12 @@ void GeoLines::Render(const QMapLibre::CustomLayerRenderParameters& params) | |||
|          // If thresholding is enabled, set the map distance
 | ||||
|          units::length::nautical_miles<float> mapDistance = | ||||
|             util::maplibre::GetMapDistance(params); | ||||
|          gl.glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); | ||||
|          glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          // If thresholding is disabled, set the map distance to 0
 | ||||
|          gl.glUniform1f(p->uMapDistanceLocation_, 0.0f); | ||||
|          glUniform1f(p->uMapDistanceLocation_, 0.0f); | ||||
|       } | ||||
| 
 | ||||
|       // Selected time
 | ||||
|  | @ -282,26 +286,24 @@ void GeoLines::Render(const QMapLibre::CustomLayerRenderParameters& params) | |||
|          (p->selectedTime_ == std::chrono::system_clock::time_point {}) ? | ||||
|             std::chrono::system_clock::now() : | ||||
|             p->selectedTime_; | ||||
|       gl.glUniform1i( | ||||
|       glUniform1i( | ||||
|          p->uSelectedTimeLocation_, | ||||
|          static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>( | ||||
|                                selectedTime.time_since_epoch()) | ||||
|                                .count())); | ||||
| 
 | ||||
|       // Draw icons
 | ||||
|       gl.glDrawArrays(GL_TRIANGLES, | ||||
|                       0, | ||||
|                       static_cast<GLsizei>(p->currentLineList_.size() * | ||||
|                                            kVerticesPerRectangle)); | ||||
|       glDrawArrays(GL_TRIANGLES, | ||||
|                    0, | ||||
|                    static_cast<GLsizei>(p->currentLineList_.size() * | ||||
|                                         kVerticesPerRectangle)); | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| void GeoLines::Deinitialize() | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
| 
 | ||||
|    gl.glDeleteVertexArrays(1, &p->vao_); | ||||
|    gl.glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||
|    glDeleteVertexArrays(1, &p->vao_); | ||||
|    glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||
| 
 | ||||
|    std::unique_lock lock {p->lineMutex_}; | ||||
| 
 | ||||
|  | @ -671,21 +673,21 @@ void GeoLines::Impl::Update() | |||
|    // If the lines have been updated
 | ||||
|    if (dirty_) | ||||
|    { | ||||
|       gl::OpenGLFunctions& gl = context_->gl(); | ||||
| 
 | ||||
|       // Buffer lines data
 | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||
|       gl.glBufferData(GL_ARRAY_BUFFER, | ||||
|                       sizeof(float) * currentLinesBuffer_.size(), | ||||
|                       currentLinesBuffer_.data(), | ||||
|                       GL_DYNAMIC_DRAW); | ||||
|       glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||
|       glBufferData( | ||||
|          GL_ARRAY_BUFFER, | ||||
|          static_cast<GLsizeiptr>(sizeof(float) * currentLinesBuffer_.size()), | ||||
|          currentLinesBuffer_.data(), | ||||
|          GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|       // Buffer threshold data
 | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||
|       gl.glBufferData(GL_ARRAY_BUFFER, | ||||
|                       sizeof(GLint) * currentIntegerBuffer_.size(), | ||||
|                       currentIntegerBuffer_.data(), | ||||
|                       GL_DYNAMIC_DRAW); | ||||
|       glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||
|       glBufferData( | ||||
|          GL_ARRAY_BUFFER, | ||||
|          static_cast<GLsizeiptr>(sizeof(GLint) * currentIntegerBuffer_.size()), | ||||
|          currentIntegerBuffer_.data(), | ||||
|          GL_DYNAMIC_DRAW); | ||||
|    } | ||||
| 
 | ||||
|    dirty_ = false; | ||||
|  |  | |||
|  | @ -21,11 +21,11 @@ namespace draw | |||
| static const std::string logPrefix_ = "scwx::qt::gl::draw::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 kPointsPerVertex      = 10; | ||||
| static constexpr std::size_t kPointsPerTexCoord    = 3; | ||||
| 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 kPointsPerVertex     = 10; | ||||
| static constexpr std::size_t kPointsPerTexCoord   = 3; | ||||
| static constexpr std::size_t kIconBufferLength = | ||||
|    kNumTriangles * kVerticesPerTriangle * kPointsPerVertex; | ||||
| static constexpr std::size_t kTextureBufferLength = | ||||
|  | @ -116,7 +116,7 @@ public: | |||
| }; | ||||
| 
 | ||||
| Icons::Icons(const std::shared_ptr<GlContext>& context) : | ||||
|     DrawItem(context->gl()), p(std::make_unique<Impl>(context)) | ||||
|     DrawItem(), p(std::make_unique<Impl>(context)) | ||||
| { | ||||
| } | ||||
| Icons::~Icons() = default; | ||||
|  | @ -126,8 +126,6 @@ Icons& Icons::operator=(Icons&&) noexcept = default; | |||
| 
 | ||||
| void Icons::Initialize() | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
| 
 | ||||
|    p->shaderProgram_ = p->context_->GetShaderProgram( | ||||
|       {{GL_VERTEX_SHADER, ":/gl/texture2d_array.vert"}, | ||||
|        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, | ||||
|  | @ -135,69 +133,77 @@ void Icons::Initialize() | |||
| 
 | ||||
|    p->uMVPMatrixLocation_ = p->shaderProgram_->GetUniformLocation("uMVPMatrix"); | ||||
| 
 | ||||
|    gl.glGenVertexArrays(1, &p->vao_); | ||||
|    gl.glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||
|    glGenVertexArrays(1, &p->vao_); | ||||
|    glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||
| 
 | ||||
|    gl.glBindVertexArray(p->vao_); | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
|    glBindVertexArray(p->vao_); | ||||
|    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|    // NOLINTBEGIN(modernize-use-nullptr)
 | ||||
|    // NOLINTBEGIN(performance-no-int-to-ptr)
 | ||||
|    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||
| 
 | ||||
|    // aVertex
 | ||||
|    gl.glVertexAttribPointer(0, | ||||
|                             2, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(0); | ||||
|    glVertexAttribPointer(0, | ||||
|                          2, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          reinterpret_cast<void*>(0)); | ||||
|    glEnableVertexAttribArray(0); | ||||
| 
 | ||||
|    // aXYOffset
 | ||||
|    gl.glVertexAttribPointer(1, | ||||
|                             2, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(2 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(1); | ||||
|    glVertexAttribPointer(1, | ||||
|                          2, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          reinterpret_cast<void*>(2 * sizeof(float))); | ||||
|    glEnableVertexAttribArray(1); | ||||
| 
 | ||||
|    // aModulate
 | ||||
|    gl.glVertexAttribPointer(3, | ||||
|                             4, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(4 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(3); | ||||
|    glVertexAttribPointer(3, | ||||
|                          4, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          reinterpret_cast<void*>(4 * sizeof(float))); | ||||
|    glEnableVertexAttribArray(3); | ||||
| 
 | ||||
|    // aAngle
 | ||||
|    gl.glVertexAttribPointer(4, | ||||
|                             1, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(8 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(4); | ||||
|    glVertexAttribPointer(4, | ||||
|                          1, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          reinterpret_cast<void*>(8 * sizeof(float))); | ||||
|    glEnableVertexAttribArray(4); | ||||
| 
 | ||||
|    // aDisplayed
 | ||||
|    gl.glVertexAttribPointer(5, | ||||
|                             1, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(9 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(5); | ||||
|    glVertexAttribPointer(5, | ||||
|                          1, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          reinterpret_cast<void*>(9 * sizeof(float))); | ||||
|    glEnableVertexAttribArray(5); | ||||
| 
 | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
|    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||
|    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|    // aTexCoord
 | ||||
|    gl.glVertexAttribPointer(2, | ||||
|                             3, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerTexCoord * sizeof(float), | ||||
|                             static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(2); | ||||
|    glVertexAttribPointer(2, | ||||
|                          3, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerTexCoord * sizeof(float), | ||||
|                          static_cast<void*>(0)); | ||||
|    glEnableVertexAttribArray(2); | ||||
| 
 | ||||
|    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||
|    // NOLINTEND(performance-no-int-to-ptr)
 | ||||
|    // NOLINTEND(modernize-use-nullptr)
 | ||||
| 
 | ||||
|    p->dirty_ = true; | ||||
| } | ||||
|  | @ -219,29 +225,25 @@ void Icons::Render(const QMapLibre::CustomLayerRenderParameters& params, | |||
| 
 | ||||
|    if (!p->currentIconList_.empty()) | ||||
|    { | ||||
|       gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
| 
 | ||||
|       gl.glBindVertexArray(p->vao_); | ||||
|       glBindVertexArray(p->vao_); | ||||
| 
 | ||||
|       p->Update(textureAtlasChanged); | ||||
|       p->shaderProgram_->Use(); | ||||
|       UseDefaultProjection(params, p->uMVPMatrixLocation_); | ||||
| 
 | ||||
|       // Interpolate texture coordinates
 | ||||
|       gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||||
|       gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||||
|       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||||
|       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||||
| 
 | ||||
|       // Draw icons
 | ||||
|       gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||
|       glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| void Icons::Deinitialize() | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
| 
 | ||||
|    gl.glDeleteVertexArrays(1, &p->vao_); | ||||
|    gl.glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||
|    glDeleteVertexArrays(1, &p->vao_); | ||||
|    glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||
| 
 | ||||
|    std::unique_lock lock {p->iconMutex_}; | ||||
| 
 | ||||
|  | @ -679,8 +681,6 @@ void Icons::Impl::UpdateModifiedIconBuffers() | |||
| 
 | ||||
| void Icons::Impl::Update(bool textureAtlasChanged) | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = context_->gl(); | ||||
| 
 | ||||
|    UpdateModifiedIconBuffers(); | ||||
| 
 | ||||
|    // If the texture atlas has changed
 | ||||
|  | @ -696,11 +696,12 @@ void Icons::Impl::Update(bool textureAtlasChanged) | |||
|       UpdateTextureBuffer(); | ||||
| 
 | ||||
|       // Buffer texture data
 | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||
|       gl.glBufferData(GL_ARRAY_BUFFER, | ||||
|                       sizeof(float) * textureBuffer_.size(), | ||||
|                       textureBuffer_.data(), | ||||
|                       GL_DYNAMIC_DRAW); | ||||
|       glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||
|       glBufferData( | ||||
|          GL_ARRAY_BUFFER, | ||||
|          static_cast<GLsizeiptr>(sizeof(float) * textureBuffer_.size()), | ||||
|          textureBuffer_.data(), | ||||
|          GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|       lastTextureAtlasChanged_ = false; | ||||
|    } | ||||
|  | @ -709,11 +710,12 @@ void Icons::Impl::Update(bool textureAtlasChanged) | |||
|    if (dirty_) | ||||
|    { | ||||
|       // Buffer vertex data
 | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||
|       gl.glBufferData(GL_ARRAY_BUFFER, | ||||
|                       sizeof(float) * currentIconBuffer_.size(), | ||||
|                       currentIconBuffer_.data(), | ||||
|                       GL_DYNAMIC_DRAW); | ||||
|       glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||
|       glBufferData( | ||||
|          GL_ARRAY_BUFFER, | ||||
|          static_cast<GLsizeiptr>(sizeof(float) * currentIconBuffer_.size()), | ||||
|          currentIconBuffer_.data(), | ||||
|          GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|       numVertices_ = | ||||
|          static_cast<GLsizei>(currentIconBuffer_.size() / kPointsPerVertex); | ||||
|  |  | |||
|  | @ -63,14 +63,12 @@ class LinkedVectors::Impl | |||
| { | ||||
| public: | ||||
|    explicit Impl(std::shared_ptr<GlContext> context) : | ||||
|        context_ {context}, geoLines_ {std::make_shared<GeoLines>(context)} | ||||
|        geoLines_ {std::make_shared<GeoLines>(context)} | ||||
|    { | ||||
|    } | ||||
| 
 | ||||
|    ~Impl() {} | ||||
| 
 | ||||
|    std::shared_ptr<GlContext> context_; | ||||
| 
 | ||||
|    bool borderEnabled_ {true}; | ||||
|    bool visible_ {true}; | ||||
| 
 | ||||
|  | @ -79,7 +77,7 @@ public: | |||
| }; | ||||
| 
 | ||||
| LinkedVectors::LinkedVectors(std::shared_ptr<GlContext> context) : | ||||
|     DrawItem(context->gl()), p(std::make_unique<Impl>(context)) | ||||
|     DrawItem(), p(std::make_unique<Impl>(context)) | ||||
| { | ||||
| } | ||||
| LinkedVectors::~LinkedVectors() = default; | ||||
|  |  | |||
|  | @ -140,7 +140,7 @@ public: | |||
| }; | ||||
| 
 | ||||
| PlacefileIcons::PlacefileIcons(const std::shared_ptr<GlContext>& context) : | ||||
|     DrawItem(context->gl()), p(std::make_unique<Impl>(context)) | ||||
|     DrawItem(), p(std::make_unique<Impl>(context)) | ||||
| { | ||||
| } | ||||
| PlacefileIcons::~PlacefileIcons() = default; | ||||
|  | @ -161,12 +161,6 @@ void PlacefileIcons::set_thresholded(bool thresholded) | |||
| 
 | ||||
| void PlacefileIcons::Initialize() | ||||
| { | ||||
|    gl::OpenGLFunctions& gl   = p->context_->gl(); | ||||
| 
 | ||||
| #if !defined(__APPLE__) | ||||
|    auto&                gl30 = p->context_->gl30(); | ||||
| #endif | ||||
| 
 | ||||
|    p->shaderProgram_ = p->context_->GetShaderProgram( | ||||
|       {{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"}, | ||||
|        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, | ||||
|  | @ -181,86 +175,90 @@ void PlacefileIcons::Initialize() | |||
|    p->uSelectedTimeLocation_ = | ||||
|       p->shaderProgram_->GetUniformLocation("uSelectedTime"); | ||||
| 
 | ||||
|    gl.glGenVertexArrays(1, &p->vao_); | ||||
|    gl.glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||
|    glGenVertexArrays(1, &p->vao_); | ||||
|    glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||
| 
 | ||||
|    gl.glBindVertexArray(p->vao_); | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
|    glBindVertexArray(p->vao_); | ||||
|    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|    // NOLINTBEGIN(modernize-use-nullptr)
 | ||||
|    // NOLINTBEGIN(performance-no-int-to-ptr)
 | ||||
|    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||
| 
 | ||||
|    // aLatLong
 | ||||
|    gl.glVertexAttribPointer(0, | ||||
|                             2, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(0); | ||||
|    glVertexAttribPointer(0, | ||||
|                          2, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          static_cast<void*>(0)); | ||||
|    glEnableVertexAttribArray(0); | ||||
| 
 | ||||
|    // aXYOffset
 | ||||
|    gl.glVertexAttribPointer(1, | ||||
|                             2, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(2 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(1); | ||||
|    glVertexAttribPointer(1, | ||||
|                          2, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          reinterpret_cast<void*>(2 * sizeof(float))); | ||||
|    glEnableVertexAttribArray(1); | ||||
| 
 | ||||
|    // aModulate
 | ||||
|    gl.glVertexAttribPointer(3, | ||||
|                             4, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(4 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(3); | ||||
|    glVertexAttribPointer(3, | ||||
|                          4, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          reinterpret_cast<void*>(4 * sizeof(float))); | ||||
|    glEnableVertexAttribArray(3); | ||||
| 
 | ||||
|    // aAngle
 | ||||
|    gl.glVertexAttribPointer(4, | ||||
|                             1, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(8 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(4); | ||||
|    glVertexAttribPointer(4, | ||||
|                          1, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          reinterpret_cast<void*>(8 * sizeof(float))); | ||||
|    glEnableVertexAttribArray(4); | ||||
| 
 | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
|    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||
|    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|    // aTexCoord
 | ||||
|    gl.glVertexAttribPointer(2, | ||||
|                             3, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerTexCoord * sizeof(float), | ||||
|                             static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(2); | ||||
|    glVertexAttribPointer(2, | ||||
|                          3, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerTexCoord * sizeof(float), | ||||
|                          static_cast<void*>(0)); | ||||
|    glEnableVertexAttribArray(2); | ||||
| 
 | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[2]); | ||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
|    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[2]); | ||||
|    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|    // aThreshold
 | ||||
|    gl.glVertexAttribIPointer(5, //
 | ||||
|                              1, | ||||
|                              GL_INT, | ||||
|                              0, | ||||
|                              static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(5); | ||||
|    glVertexAttribIPointer(5, //
 | ||||
|                           1, | ||||
|                           GL_INT, | ||||
|                           0, | ||||
|                           static_cast<void*>(0)); | ||||
|    glEnableVertexAttribArray(5); | ||||
| 
 | ||||
|    // aTimeRange
 | ||||
|    gl.glVertexAttribIPointer(6, //
 | ||||
|                              2, | ||||
|                              GL_INT, | ||||
|                              kIntegersPerVertex_ * sizeof(GLint), | ||||
|                              reinterpret_cast<void*>(1 * sizeof(GLint))); | ||||
|    gl.glEnableVertexAttribArray(6); | ||||
|    glVertexAttribIPointer(6, //
 | ||||
|                           2, | ||||
|                           GL_INT, | ||||
|                           kIntegersPerVertex_ * sizeof(GLint), | ||||
|                           reinterpret_cast<void*>(1 * sizeof(GLint))); | ||||
|    glEnableVertexAttribArray(6); | ||||
| 
 | ||||
|    // aDisplayed
 | ||||
| #if !defined(__APPLE__) | ||||
|    gl30.glVertexAttribI1i(7, 1); | ||||
| #else | ||||
|    glVertexAttribI1i(7, 1); | ||||
| #endif | ||||
| 
 | ||||
|    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||
|    // NOLINTEND(performance-no-int-to-ptr)
 | ||||
|    // NOLINTEND(modernize-use-nullptr)
 | ||||
| 
 | ||||
|    p->dirty_ = true; | ||||
| } | ||||
|  | @ -273,9 +271,7 @@ void PlacefileIcons::Render( | |||
| 
 | ||||
|    if (!p->currentIconList_.empty()) | ||||
|    { | ||||
|       gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
| 
 | ||||
|       gl.glBindVertexArray(p->vao_); | ||||
|       glBindVertexArray(p->vao_); | ||||
| 
 | ||||
|       p->Update(textureAtlasChanged); | ||||
|       p->shaderProgram_->Use(); | ||||
|  | @ -288,12 +284,12 @@ void PlacefileIcons::Render( | |||
|          // If thresholding is enabled, set the map distance
 | ||||
|          units::length::nautical_miles<float> mapDistance = | ||||
|             util::maplibre::GetMapDistance(params); | ||||
|          gl.glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); | ||||
|          glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          // If thresholding is disabled, set the map distance to 0
 | ||||
|          gl.glUniform1f(p->uMapDistanceLocation_, 0.0f); | ||||
|          glUniform1f(p->uMapDistanceLocation_, 0.0f); | ||||
|       } | ||||
| 
 | ||||
|       // Selected time
 | ||||
|  | @ -301,27 +297,25 @@ void PlacefileIcons::Render( | |||
|          (p->selectedTime_ == std::chrono::system_clock::time_point {}) ? | ||||
|             std::chrono::system_clock::now() : | ||||
|             p->selectedTime_; | ||||
|       gl.glUniform1i( | ||||
|       glUniform1i( | ||||
|          p->uSelectedTimeLocation_, | ||||
|          static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>( | ||||
|                                selectedTime.time_since_epoch()) | ||||
|                                .count())); | ||||
| 
 | ||||
|       // Interpolate texture coordinates
 | ||||
|       gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||||
|       gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||||
|       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||||
|       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||||
| 
 | ||||
|       // Draw icons
 | ||||
|       gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||
|       glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| void PlacefileIcons::Deinitialize() | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
| 
 | ||||
|    gl.glDeleteVertexArrays(1, &p->vao_); | ||||
|    gl.glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||
|    glDeleteVertexArrays(1, &p->vao_); | ||||
|    glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||
| 
 | ||||
|    std::unique_lock lock {p->iconMutex_}; | ||||
| 
 | ||||
|  | @ -649,8 +643,6 @@ void PlacefileIcons::Impl::UpdateTextureBuffer() | |||
| 
 | ||||
| void PlacefileIcons::Impl::Update(bool textureAtlasChanged) | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = context_->gl(); | ||||
| 
 | ||||
|    // If the texture atlas has changed
 | ||||
|    if (dirty_ || textureAtlasChanged) | ||||
|    { | ||||
|  | @ -664,29 +656,32 @@ void PlacefileIcons::Impl::Update(bool textureAtlasChanged) | |||
|       UpdateTextureBuffer(); | ||||
| 
 | ||||
|       // Buffer texture data
 | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||
|       gl.glBufferData(GL_ARRAY_BUFFER, | ||||
|                       sizeof(float) * textureBuffer_.size(), | ||||
|                       textureBuffer_.data(), | ||||
|                       GL_DYNAMIC_DRAW); | ||||
|       glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||
|       glBufferData( | ||||
|          GL_ARRAY_BUFFER, | ||||
|          static_cast<GLsizeiptr>(sizeof(float) * textureBuffer_.size()), | ||||
|          textureBuffer_.data(), | ||||
|          GL_DYNAMIC_DRAW); | ||||
|    } | ||||
| 
 | ||||
|    // If buffers need updating
 | ||||
|    if (dirty_) | ||||
|    { | ||||
|       // Buffer vertex data
 | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||
|       gl.glBufferData(GL_ARRAY_BUFFER, | ||||
|                       sizeof(float) * currentIconBuffer_.size(), | ||||
|                       currentIconBuffer_.data(), | ||||
|                       GL_DYNAMIC_DRAW); | ||||
|       glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||
|       glBufferData( | ||||
|          GL_ARRAY_BUFFER, | ||||
|          static_cast<GLsizeiptr>(sizeof(float) * currentIconBuffer_.size()), | ||||
|          currentIconBuffer_.data(), | ||||
|          GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|       // Buffer threshold data
 | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[2]); | ||||
|       gl.glBufferData(GL_ARRAY_BUFFER, | ||||
|                       sizeof(GLint) * currentIntegerBuffer_.size(), | ||||
|                       currentIntegerBuffer_.data(), | ||||
|                       GL_DYNAMIC_DRAW); | ||||
|       glBindBuffer(GL_ARRAY_BUFFER, vbo_[2]); | ||||
|       glBufferData( | ||||
|          GL_ARRAY_BUFFER, | ||||
|          static_cast<GLsizeiptr>(sizeof(GLint) * currentIntegerBuffer_.size()), | ||||
|          currentIntegerBuffer_.data(), | ||||
|          GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|       numVertices_ = | ||||
|          static_cast<GLsizei>(currentIconBuffer_.size() / kPointsPerVertex); | ||||
|  |  | |||
|  | @ -117,7 +117,7 @@ public: | |||
| }; | ||||
| 
 | ||||
| PlacefileImages::PlacefileImages(const std::shared_ptr<GlContext>& context) : | ||||
|     DrawItem(context->gl()), p(std::make_unique<Impl>(context)) | ||||
|     DrawItem(), p(std::make_unique<Impl>(context)) | ||||
| { | ||||
| } | ||||
| PlacefileImages::~PlacefileImages() = default; | ||||
|  | @ -139,12 +139,6 @@ void PlacefileImages::set_thresholded(bool thresholded) | |||
| 
 | ||||
| void PlacefileImages::Initialize() | ||||
| { | ||||
|    gl::OpenGLFunctions& gl   = p->context_->gl(); | ||||
| 
 | ||||
| #if !defined(__APPLE__) | ||||
|    auto&                gl30 = p->context_->gl30(); | ||||
| #endif | ||||
| 
 | ||||
|    p->shaderProgram_ = p->context_->GetShaderProgram( | ||||
|       {{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"}, | ||||
|        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, | ||||
|  | @ -159,77 +153,81 @@ void PlacefileImages::Initialize() | |||
|    p->uSelectedTimeLocation_ = | ||||
|       p->shaderProgram_->GetUniformLocation("uSelectedTime"); | ||||
| 
 | ||||
|    gl.glGenVertexArrays(1, &p->vao_); | ||||
|    gl.glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||
|    glGenVertexArrays(1, &p->vao_); | ||||
|    glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||
| 
 | ||||
|    gl.glBindVertexArray(p->vao_); | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
|    glBindVertexArray(p->vao_); | ||||
|    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|    // NOLINTBEGIN(modernize-use-nullptr)
 | ||||
|    // NOLINTBEGIN(performance-no-int-to-ptr)
 | ||||
|    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||
| 
 | ||||
|    // aLatLong
 | ||||
|    gl.glVertexAttribPointer(0, | ||||
|                             2, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(0); | ||||
|    glVertexAttribPointer(0, | ||||
|                          2, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          static_cast<void*>(0)); | ||||
|    glEnableVertexAttribArray(0); | ||||
| 
 | ||||
|    // aXYOffset
 | ||||
|    gl.glVertexAttribPointer(1, | ||||
|                             2, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(2 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(1); | ||||
|    glVertexAttribPointer(1, | ||||
|                          2, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          reinterpret_cast<void*>(2 * sizeof(float))); | ||||
|    glEnableVertexAttribArray(1); | ||||
| 
 | ||||
|    // aModulate
 | ||||
|    gl.glVertexAttribPointer(3, | ||||
|                             4, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(4 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(3); | ||||
|    glVertexAttribPointer(3, | ||||
|                          4, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          reinterpret_cast<void*>(4 * sizeof(float))); | ||||
|    glEnableVertexAttribArray(3); | ||||
| 
 | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
|    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||
|    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|    // aTexCoord
 | ||||
|    gl.glVertexAttribPointer(2, | ||||
|                             3, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerTexCoord * sizeof(float), | ||||
|                             static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(2); | ||||
|    glVertexAttribPointer(2, | ||||
|                          3, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerTexCoord * sizeof(float), | ||||
|                          static_cast<void*>(0)); | ||||
|    glEnableVertexAttribArray(2); | ||||
| 
 | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[2]); | ||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
|    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[2]); | ||||
|    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|    // aThreshold
 | ||||
|    gl.glVertexAttribIPointer(5, //
 | ||||
|                              1, | ||||
|                              GL_INT, | ||||
|                              kIntegersPerVertex_ * sizeof(GLint), | ||||
|                              static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(5); | ||||
|    glVertexAttribIPointer(5, //
 | ||||
|                           1, | ||||
|                           GL_INT, | ||||
|                           kIntegersPerVertex_ * sizeof(GLint), | ||||
|                           static_cast<void*>(0)); | ||||
|    glEnableVertexAttribArray(5); | ||||
| 
 | ||||
|    // aTimeRange
 | ||||
|    gl.glVertexAttribIPointer(6, //
 | ||||
|                              2, | ||||
|                              GL_INT, | ||||
|                              kIntegersPerVertex_ * sizeof(GLint), | ||||
|                              reinterpret_cast<void*>(1 * sizeof(GLint))); | ||||
|    gl.glEnableVertexAttribArray(6); | ||||
|    glVertexAttribIPointer(6, //
 | ||||
|                           2, | ||||
|                           GL_INT, | ||||
|                           kIntegersPerVertex_ * sizeof(GLint), | ||||
|                           reinterpret_cast<void*>(1 * sizeof(GLint))); | ||||
|    glEnableVertexAttribArray(6); | ||||
| 
 | ||||
|    // aDisplayed
 | ||||
| #if !defined(__APPLE__) | ||||
|    gl30.glVertexAttribI1i(7, 1); | ||||
| #else | ||||
|    glVertexAttribI1i(7, 1); | ||||
| #endif | ||||
| 
 | ||||
|    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||
|    // NOLINTEND(performance-no-int-to-ptr)
 | ||||
|    // NOLINTEND(modernize-use-nullptr)
 | ||||
| 
 | ||||
|    p->dirty_ = true; | ||||
| } | ||||
|  | @ -242,9 +240,7 @@ void PlacefileImages::Render( | |||
| 
 | ||||
|    if (!p->currentImageList_.empty()) | ||||
|    { | ||||
|       gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
| 
 | ||||
|       gl.glBindVertexArray(p->vao_); | ||||
|       glBindVertexArray(p->vao_); | ||||
| 
 | ||||
|       p->Update(textureAtlasChanged); | ||||
|       p->shaderProgram_->Use(); | ||||
|  | @ -257,12 +253,12 @@ void PlacefileImages::Render( | |||
|          // If thresholding is enabled, set the map distance
 | ||||
|          units::length::nautical_miles<float> mapDistance = | ||||
|             util::maplibre::GetMapDistance(params); | ||||
|          gl.glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); | ||||
|          glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          // If thresholding is disabled, set the map distance to 0
 | ||||
|          gl.glUniform1f(p->uMapDistanceLocation_, 0.0f); | ||||
|          glUniform1f(p->uMapDistanceLocation_, 0.0f); | ||||
|       } | ||||
| 
 | ||||
|       // Selected time
 | ||||
|  | @ -270,27 +266,25 @@ void PlacefileImages::Render( | |||
|          (p->selectedTime_ == std::chrono::system_clock::time_point {}) ? | ||||
|             std::chrono::system_clock::now() : | ||||
|             p->selectedTime_; | ||||
|       gl.glUniform1i( | ||||
|       glUniform1i( | ||||
|          p->uSelectedTimeLocation_, | ||||
|          static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>( | ||||
|                                selectedTime.time_since_epoch()) | ||||
|                                .count())); | ||||
| 
 | ||||
|       // Interpolate texture coordinates
 | ||||
|       gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||||
|       gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||||
|       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||||
|       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||||
| 
 | ||||
|       // Draw images
 | ||||
|       gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||
|       glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| void PlacefileImages::Deinitialize() | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
| 
 | ||||
|    gl.glDeleteVertexArrays(1, &p->vao_); | ||||
|    gl.glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||
|    glDeleteVertexArrays(1, &p->vao_); | ||||
|    glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||
| 
 | ||||
|    std::unique_lock lock {p->imageMutex_}; | ||||
| 
 | ||||
|  | @ -446,8 +440,6 @@ void PlacefileImages::Impl::UpdateTextureBuffer() | |||
| 
 | ||||
| void PlacefileImages::Impl::Update(bool textureAtlasChanged) | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = context_->gl(); | ||||
| 
 | ||||
|    // If the texture atlas has changed
 | ||||
|    if (dirty_ || textureAtlasChanged) | ||||
|    { | ||||
|  | @ -461,29 +453,32 @@ void PlacefileImages::Impl::Update(bool textureAtlasChanged) | |||
|       UpdateTextureBuffer(); | ||||
| 
 | ||||
|       // Buffer texture data
 | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||
|       gl.glBufferData(GL_ARRAY_BUFFER, | ||||
|                       sizeof(float) * textureBuffer_.size(), | ||||
|                       textureBuffer_.data(), | ||||
|                       GL_DYNAMIC_DRAW); | ||||
|       glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||
|       glBufferData( | ||||
|          GL_ARRAY_BUFFER, | ||||
|          static_cast<GLsizeiptr>(sizeof(float) * textureBuffer_.size()), | ||||
|          textureBuffer_.data(), | ||||
|          GL_DYNAMIC_DRAW); | ||||
|    } | ||||
| 
 | ||||
|    // If buffers need updating
 | ||||
|    if (dirty_) | ||||
|    { | ||||
|       // Buffer vertex data
 | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||
|       gl.glBufferData(GL_ARRAY_BUFFER, | ||||
|                       sizeof(float) * currentImageBuffer_.size(), | ||||
|                       currentImageBuffer_.data(), | ||||
|                       GL_DYNAMIC_DRAW); | ||||
|       glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||
|       glBufferData( | ||||
|          GL_ARRAY_BUFFER, | ||||
|          static_cast<GLsizeiptr>(sizeof(float) * currentImageBuffer_.size()), | ||||
|          currentImageBuffer_.data(), | ||||
|          GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|       // Buffer threshold data
 | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[2]); | ||||
|       gl.glBufferData(GL_ARRAY_BUFFER, | ||||
|                       sizeof(GLint) * currentIntegerBuffer_.size(), | ||||
|                       currentIntegerBuffer_.data(), | ||||
|                       GL_DYNAMIC_DRAW); | ||||
|       glBindBuffer(GL_ARRAY_BUFFER, vbo_[2]); | ||||
|       glBufferData( | ||||
|          GL_ARRAY_BUFFER, | ||||
|          static_cast<GLsizeiptr>(sizeof(GLint) * currentIntegerBuffer_.size()), | ||||
|          currentIntegerBuffer_.data(), | ||||
|          GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|       numVertices_ = | ||||
|          static_cast<GLsizei>(currentImageBuffer_.size() / kPointsPerVertex); | ||||
|  |  | |||
|  | @ -106,7 +106,7 @@ public: | |||
| }; | ||||
| 
 | ||||
| PlacefileLines::PlacefileLines(const std::shared_ptr<GlContext>& context) : | ||||
|     DrawItem(context->gl()), p(std::make_unique<Impl>(context)) | ||||
|     DrawItem(), p(std::make_unique<Impl>(context)) | ||||
| { | ||||
| } | ||||
| PlacefileLines::~PlacefileLines() = default; | ||||
|  | @ -127,12 +127,6 @@ void PlacefileLines::set_thresholded(bool thresholded) | |||
| 
 | ||||
| void PlacefileLines::Initialize() | ||||
| { | ||||
|    gl::OpenGLFunctions& gl   = p->context_->gl(); | ||||
| 
 | ||||
| #if !defined(__APPLE__) | ||||
|    auto&                gl30 = p->context_->gl30(); | ||||
| #endif | ||||
| 
 | ||||
|    p->shaderProgram_ = p->context_->GetShaderProgram( | ||||
|       {{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"}, | ||||
|        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, | ||||
|  | @ -147,74 +141,78 @@ void PlacefileLines::Initialize() | |||
|    p->uSelectedTimeLocation_ = | ||||
|       p->shaderProgram_->GetUniformLocation("uSelectedTime"); | ||||
| 
 | ||||
|    gl.glGenVertexArrays(1, &p->vao_); | ||||
|    gl.glGenBuffers(2, p->vbo_.data()); | ||||
|    glGenVertexArrays(1, &p->vao_); | ||||
|    glGenBuffers(2, p->vbo_.data()); | ||||
| 
 | ||||
|    gl.glBindVertexArray(p->vao_); | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
|    glBindVertexArray(p->vao_); | ||||
|    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|    // NOLINTBEGIN(modernize-use-nullptr)
 | ||||
|    // NOLINTBEGIN(performance-no-int-to-ptr)
 | ||||
|    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||
| 
 | ||||
|    // aLatLong
 | ||||
|    gl.glVertexAttribPointer(0, | ||||
|                             2, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(0); | ||||
|    glVertexAttribPointer(0, | ||||
|                          2, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          static_cast<void*>(0)); | ||||
|    glEnableVertexAttribArray(0); | ||||
| 
 | ||||
|    // aXYOffset
 | ||||
|    gl.glVertexAttribPointer(1, | ||||
|                             2, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(2 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(1); | ||||
|    glVertexAttribPointer(1, | ||||
|                          2, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          reinterpret_cast<void*>(2 * sizeof(float))); | ||||
|    glEnableVertexAttribArray(1); | ||||
| 
 | ||||
|    // aModulate
 | ||||
|    gl.glVertexAttribPointer(3, | ||||
|                             4, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(4 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(3); | ||||
|    glVertexAttribPointer(3, | ||||
|                          4, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          reinterpret_cast<void*>(4 * sizeof(float))); | ||||
|    glEnableVertexAttribArray(3); | ||||
| 
 | ||||
|    // aAngle
 | ||||
|    gl.glVertexAttribPointer(4, | ||||
|                             1, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(8 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(4); | ||||
|    glVertexAttribPointer(4, | ||||
|                          1, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          reinterpret_cast<void*>(8 * sizeof(float))); | ||||
|    glEnableVertexAttribArray(4); | ||||
| 
 | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
|    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||
|    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|    // aThreshold
 | ||||
|    gl.glVertexAttribIPointer(5, //
 | ||||
|                              1, | ||||
|                              GL_INT, | ||||
|                              kIntegersPerVertex_ * sizeof(GLint), | ||||
|                              static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(5); | ||||
|    glVertexAttribIPointer(5, //
 | ||||
|                           1, | ||||
|                           GL_INT, | ||||
|                           kIntegersPerVertex_ * sizeof(GLint), | ||||
|                           static_cast<void*>(0)); | ||||
|    glEnableVertexAttribArray(5); | ||||
| 
 | ||||
|    // aTimeRange
 | ||||
|    gl.glVertexAttribIPointer(6, //
 | ||||
|                              2, | ||||
|                              GL_INT, | ||||
|                              kIntegersPerVertex_ * sizeof(GLint), | ||||
|                              reinterpret_cast<void*>(1 * sizeof(GLint))); | ||||
|    gl.glEnableVertexAttribArray(6); | ||||
|    glVertexAttribIPointer(6, //
 | ||||
|                           2, | ||||
|                           GL_INT, | ||||
|                           kIntegersPerVertex_ * sizeof(GLint), | ||||
|                           reinterpret_cast<void*>(1 * sizeof(GLint))); | ||||
|    glEnableVertexAttribArray(6); | ||||
| 
 | ||||
|    // aDisplayed
 | ||||
| #if !defined(__APPLE__) | ||||
|    gl30.glVertexAttribI1i(7, 1); | ||||
| #else | ||||
|    glVertexAttribI1i(7, 1); | ||||
| #endif | ||||
| 
 | ||||
|    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||
|    // NOLINTEND(performance-no-int-to-ptr)
 | ||||
|    // NOLINTEND(modernize-use-nullptr)
 | ||||
| 
 | ||||
|    p->dirty_ = true; | ||||
| } | ||||
|  | @ -226,9 +224,7 @@ void PlacefileLines::Render( | |||
| 
 | ||||
|    if (p->currentNumLines_ > 0) | ||||
|    { | ||||
|       gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
| 
 | ||||
|       gl.glBindVertexArray(p->vao_); | ||||
|       glBindVertexArray(p->vao_); | ||||
| 
 | ||||
|       p->Update(); | ||||
|       p->shaderProgram_->Use(); | ||||
|  | @ -241,12 +237,12 @@ void PlacefileLines::Render( | |||
|          // If thresholding is enabled, set the map distance
 | ||||
|          units::length::nautical_miles<float> mapDistance = | ||||
|             util::maplibre::GetMapDistance(params); | ||||
|          gl.glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); | ||||
|          glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          // If thresholding is disabled, set the map distance to 0
 | ||||
|          gl.glUniform1f(p->uMapDistanceLocation_, 0.0f); | ||||
|          glUniform1f(p->uMapDistanceLocation_, 0.0f); | ||||
|       } | ||||
| 
 | ||||
|       // Selected time
 | ||||
|  | @ -254,23 +250,21 @@ void PlacefileLines::Render( | |||
|          (p->selectedTime_ == std::chrono::system_clock::time_point {}) ? | ||||
|             std::chrono::system_clock::now() : | ||||
|             p->selectedTime_; | ||||
|       gl.glUniform1i( | ||||
|       glUniform1i( | ||||
|          p->uSelectedTimeLocation_, | ||||
|          static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>( | ||||
|                                selectedTime.time_since_epoch()) | ||||
|                                .count())); | ||||
| 
 | ||||
|       // Draw icons
 | ||||
|       gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||
|       glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| void PlacefileLines::Deinitialize() | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
| 
 | ||||
|    gl.glDeleteVertexArrays(1, &p->vao_); | ||||
|    gl.glDeleteBuffers(2, p->vbo_.data()); | ||||
|    glDeleteVertexArrays(1, &p->vao_); | ||||
|    glDeleteBuffers(2, p->vbo_.data()); | ||||
| 
 | ||||
|    std::unique_lock lock {p->lineMutex_}; | ||||
| 
 | ||||
|  | @ -482,21 +476,21 @@ void PlacefileLines::Impl::Update() | |||
|    // If the placefile has been updated
 | ||||
|    if (dirty_) | ||||
|    { | ||||
|       gl::OpenGLFunctions& gl = context_->gl(); | ||||
| 
 | ||||
|       // Buffer lines data
 | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||
|       gl.glBufferData(GL_ARRAY_BUFFER, | ||||
|                       sizeof(float) * currentLinesBuffer_.size(), | ||||
|                       currentLinesBuffer_.data(), | ||||
|                       GL_DYNAMIC_DRAW); | ||||
|       glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||
|       glBufferData( | ||||
|          GL_ARRAY_BUFFER, | ||||
|          static_cast<GLsizeiptr>(sizeof(float) * currentLinesBuffer_.size()), | ||||
|          currentLinesBuffer_.data(), | ||||
|          GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|       // Buffer threshold data
 | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||
|       gl.glBufferData(GL_ARRAY_BUFFER, | ||||
|                       sizeof(GLint) * currentIntegerBuffer_.size(), | ||||
|                       currentIntegerBuffer_.data(), | ||||
|                       GL_DYNAMIC_DRAW); | ||||
|       glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||
|       glBufferData( | ||||
|          GL_ARRAY_BUFFER, | ||||
|          static_cast<GLsizeiptr>(sizeof(GLint) * currentIntegerBuffer_.size()), | ||||
|          currentIntegerBuffer_.data(), | ||||
|          GL_DYNAMIC_DRAW); | ||||
|    } | ||||
| 
 | ||||
|    dirty_ = false; | ||||
|  |  | |||
|  | @ -130,7 +130,7 @@ public: | |||
| 
 | ||||
| PlacefilePolygons::PlacefilePolygons( | ||||
|    const std::shared_ptr<GlContext>& context) : | ||||
|     DrawItem(context->gl()), p(std::make_unique<Impl>(context)) | ||||
|     DrawItem(), p(std::make_unique<Impl>(context)) | ||||
| { | ||||
| } | ||||
| PlacefilePolygons::~PlacefilePolygons() = default; | ||||
|  | @ -152,8 +152,6 @@ void PlacefilePolygons::set_thresholded(bool thresholded) | |||
| 
 | ||||
| void PlacefilePolygons::Initialize() | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
| 
 | ||||
|    p->shaderProgram_ = p->context_->GetShaderProgram( | ||||
|       {{GL_VERTEX_SHADER, ":/gl/map_color.vert"}, | ||||
|        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, | ||||
|  | @ -168,58 +166,66 @@ void PlacefilePolygons::Initialize() | |||
|    p->uSelectedTimeLocation_ = | ||||
|       p->shaderProgram_->GetUniformLocation("uSelectedTime"); | ||||
| 
 | ||||
|    gl.glGenVertexArrays(1, &p->vao_); | ||||
|    gl.glGenBuffers(2, p->vbo_.data()); | ||||
|    glGenVertexArrays(1, &p->vao_); | ||||
|    glGenBuffers(2, p->vbo_.data()); | ||||
| 
 | ||||
|    gl.glBindVertexArray(p->vao_); | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
|    glBindVertexArray(p->vao_); | ||||
|    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|    // NOLINTBEGIN(modernize-use-nullptr)
 | ||||
|    // NOLINTBEGIN(performance-no-int-to-ptr)
 | ||||
|    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||
| 
 | ||||
|    // aScreenCoord
 | ||||
|    gl.glVertexAttribPointer(0, | ||||
|                             2, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(0); | ||||
|    glVertexAttribPointer(0, | ||||
|                          2, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          static_cast<void*>(0)); | ||||
|    glEnableVertexAttribArray(0); | ||||
| 
 | ||||
|    // aXYOffset
 | ||||
|    gl.glVertexAttribPointer(1, | ||||
|                             2, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(2 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(1); | ||||
|    glVertexAttribPointer(1, | ||||
|                          2, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          reinterpret_cast<void*>(2 * sizeof(float))); | ||||
|    glEnableVertexAttribArray(1); | ||||
| 
 | ||||
|    // aColor
 | ||||
|    gl.glVertexAttribPointer(2, | ||||
|                             4, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(4 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(2); | ||||
|    glVertexAttribPointer(2, | ||||
|                          4, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          reinterpret_cast<void*>(4 * sizeof(float))); | ||||
|    glEnableVertexAttribArray(2); | ||||
| 
 | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
|    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||
|    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|    // aThreshold
 | ||||
|    gl.glVertexAttribIPointer(3, //
 | ||||
|                              1, | ||||
|                              GL_INT, | ||||
|                              kIntegersPerVertex_ * sizeof(GLint), | ||||
|                              static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(3); | ||||
|    glVertexAttribIPointer(3, //
 | ||||
|                           1, | ||||
|                           GL_INT, | ||||
|                           kIntegersPerVertex_ * sizeof(GLint), | ||||
|                           static_cast<void*>(0)); | ||||
|    glEnableVertexAttribArray(3); | ||||
| 
 | ||||
|    // aTimeRange
 | ||||
|    gl.glVertexAttribIPointer(4, //
 | ||||
|                              2, | ||||
|                              GL_INT, | ||||
|                              kIntegersPerVertex_ * sizeof(GLint), | ||||
|                              reinterpret_cast<void*>(1 * sizeof(GLint))); | ||||
|    gl.glEnableVertexAttribArray(4); | ||||
|    glVertexAttribIPointer(4, //
 | ||||
|                           2, | ||||
|                           GL_INT, | ||||
|                           kIntegersPerVertex_ * sizeof(GLint), | ||||
|                           reinterpret_cast<void*>(1 * sizeof(GLint))); | ||||
|    glEnableVertexAttribArray(4); | ||||
| 
 | ||||
|    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||
|    // NOLINTEND(performance-no-int-to-ptr)
 | ||||
|    // NOLINTEND(modernize-use-nullptr)
 | ||||
| 
 | ||||
|    p->dirty_ = true; | ||||
| } | ||||
|  | @ -229,9 +235,7 @@ void PlacefilePolygons::Render( | |||
| { | ||||
|    if (!p->currentBuffer_.empty()) | ||||
|    { | ||||
|       gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
| 
 | ||||
|       gl.glBindVertexArray(p->vao_); | ||||
|       glBindVertexArray(p->vao_); | ||||
| 
 | ||||
|       p->Update(); | ||||
|       p->shaderProgram_->Use(); | ||||
|  | @ -244,12 +248,12 @@ void PlacefilePolygons::Render( | |||
|          // If thresholding is enabled, set the map distance
 | ||||
|          units::length::nautical_miles<float> mapDistance = | ||||
|             util::maplibre::GetMapDistance(params); | ||||
|          gl.glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); | ||||
|          glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          // If thresholding is disabled, set the map distance to 0
 | ||||
|          gl.glUniform1f(p->uMapDistanceLocation_, 0.0f); | ||||
|          glUniform1f(p->uMapDistanceLocation_, 0.0f); | ||||
|       } | ||||
| 
 | ||||
|       // Selected time
 | ||||
|  | @ -257,23 +261,21 @@ void PlacefilePolygons::Render( | |||
|          (p->selectedTime_ == std::chrono::system_clock::time_point {}) ? | ||||
|             std::chrono::system_clock::now() : | ||||
|             p->selectedTime_; | ||||
|       gl.glUniform1i( | ||||
|       glUniform1i( | ||||
|          p->uSelectedTimeLocation_, | ||||
|          static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>( | ||||
|                                selectedTime.time_since_epoch()) | ||||
|                                .count())); | ||||
| 
 | ||||
|       // Draw icons
 | ||||
|       gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||
|       glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| void PlacefilePolygons::Deinitialize() | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
| 
 | ||||
|    gl.glDeleteVertexArrays(1, &p->vao_); | ||||
|    gl.glDeleteBuffers(2, p->vbo_.data()); | ||||
|    glDeleteVertexArrays(1, &p->vao_); | ||||
|    glDeleteBuffers(2, p->vbo_.data()); | ||||
| 
 | ||||
|    std::unique_lock lock {p->bufferMutex_}; | ||||
| 
 | ||||
|  | @ -318,23 +320,23 @@ void PlacefilePolygons::Impl::Update() | |||
| { | ||||
|    if (dirty_) | ||||
|    { | ||||
|       gl::OpenGLFunctions& gl = context_->gl(); | ||||
| 
 | ||||
|       std::unique_lock lock {bufferMutex_}; | ||||
| 
 | ||||
|       // Buffer vertex data
 | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||
|       gl.glBufferData(GL_ARRAY_BUFFER, | ||||
|                       sizeof(GLfloat) * currentBuffer_.size(), | ||||
|                       currentBuffer_.data(), | ||||
|                       GL_DYNAMIC_DRAW); | ||||
|       glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||
|       glBufferData( | ||||
|          GL_ARRAY_BUFFER, | ||||
|          static_cast<GLsizeiptr>(sizeof(GLfloat) * currentBuffer_.size()), | ||||
|          currentBuffer_.data(), | ||||
|          GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|       // Buffer threshold data
 | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||
|       gl.glBufferData(GL_ARRAY_BUFFER, | ||||
|                       sizeof(GLint) * currentIntegerBuffer_.size(), | ||||
|                       currentIntegerBuffer_.data(), | ||||
|                       GL_DYNAMIC_DRAW); | ||||
|       glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||
|       glBufferData( | ||||
|          GL_ARRAY_BUFFER, | ||||
|          static_cast<GLsizeiptr>(sizeof(GLint) * currentIntegerBuffer_.size()), | ||||
|          currentIntegerBuffer_.data(), | ||||
|          GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|       numVertices_ = | ||||
|          static_cast<GLsizei>(currentBuffer_.size() / kPointsPerVertex); | ||||
|  |  | |||
|  | @ -10,13 +10,7 @@ | |||
| #include <imgui.h> | ||||
| #include <mbgl/util/constants.hpp> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
| { | ||||
| namespace gl | ||||
| { | ||||
| namespace draw | ||||
| namespace scwx::qt::gl::draw | ||||
| { | ||||
| 
 | ||||
| static const std::string logPrefix_ = "scwx::qt::gl::draw::placefile_text"; | ||||
|  | @ -25,13 +19,16 @@ static const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | |||
| class PlacefileText::Impl | ||||
| { | ||||
| public: | ||||
|    explicit Impl(const std::shared_ptr<GlContext>& context, | ||||
|                  const std::string&                placefileName) : | ||||
|        context_ {context}, placefileName_ {placefileName} | ||||
|    explicit Impl(std::string placefileName) : | ||||
|        placefileName_ {std::move(placefileName)} | ||||
|    { | ||||
|    } | ||||
|    ~Impl() = default; | ||||
| 
 | ||||
|    ~Impl() {} | ||||
|    Impl(const Impl&)             = delete; | ||||
|    Impl& operator=(const Impl&)  = delete; | ||||
|    Impl(const Impl&&)            = delete; | ||||
|    Impl& operator=(const Impl&&) = delete; | ||||
| 
 | ||||
|    void RenderTextDrawItem( | ||||
|       const QMapLibre::CustomLayerRenderParameters&             params, | ||||
|  | @ -43,8 +40,6 @@ public: | |||
|                    float                                         x, | ||||
|                    float                                         y); | ||||
| 
 | ||||
|    std::shared_ptr<GlContext> context_; | ||||
| 
 | ||||
|    std::string placefileName_; | ||||
| 
 | ||||
|    bool thresholded_ {false}; | ||||
|  | @ -70,9 +65,8 @@ public: | |||
|    std::vector<std::shared_ptr<types::ImGuiFont>> newFonts_ {}; | ||||
| }; | ||||
| 
 | ||||
| PlacefileText::PlacefileText(const std::shared_ptr<GlContext>& context, | ||||
|                              const std::string&                placefileName) : | ||||
|     DrawItem(context->gl()), p(std::make_unique<Impl>(context, placefileName)) | ||||
| PlacefileText::PlacefileText(const std::string& placefileName) : | ||||
|     DrawItem(), p(std::make_unique<Impl>(placefileName)) | ||||
| { | ||||
| } | ||||
| PlacefileText::~PlacefileText() = default; | ||||
|  | @ -310,7 +304,4 @@ void PlacefileText::FinishText() | |||
|    p->newFonts_.clear(); | ||||
| } | ||||
| 
 | ||||
| } // namespace draw
 | ||||
| } // namespace gl
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
| } // namespace scwx::qt::gl::draw
 | ||||
|  |  | |||
|  | @ -19,8 +19,7 @@ namespace draw | |||
| class PlacefileText : public DrawItem | ||||
| { | ||||
| public: | ||||
|    explicit PlacefileText(const std::shared_ptr<GlContext>& context, | ||||
|                           const std::string&                placefileName); | ||||
|    explicit PlacefileText(const std::string& placefileName); | ||||
|    ~PlacefileText(); | ||||
| 
 | ||||
|    PlacefileText(const PlacefileText&)            = delete; | ||||
|  |  | |||
|  | @ -74,7 +74,7 @@ public: | |||
| 
 | ||||
| PlacefileTriangles::PlacefileTriangles( | ||||
|    const std::shared_ptr<GlContext>& context) : | ||||
|     DrawItem(context->gl()), p(std::make_unique<Impl>(context)) | ||||
|     DrawItem(), p(std::make_unique<Impl>(context)) | ||||
| { | ||||
| } | ||||
| PlacefileTriangles::~PlacefileTriangles() = default; | ||||
|  | @ -96,8 +96,6 @@ void PlacefileTriangles::set_thresholded(bool thresholded) | |||
| 
 | ||||
| void PlacefileTriangles::Initialize() | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
| 
 | ||||
|    p->shaderProgram_ = p->context_->GetShaderProgram( | ||||
|       {{GL_VERTEX_SHADER, ":/gl/map_color.vert"}, | ||||
|        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, | ||||
|  | @ -112,58 +110,66 @@ void PlacefileTriangles::Initialize() | |||
|    p->uSelectedTimeLocation_ = | ||||
|       p->shaderProgram_->GetUniformLocation("uSelectedTime"); | ||||
| 
 | ||||
|    gl.glGenVertexArrays(1, &p->vao_); | ||||
|    gl.glGenBuffers(2, p->vbo_.data()); | ||||
|    glGenVertexArrays(1, &p->vao_); | ||||
|    glGenBuffers(2, p->vbo_.data()); | ||||
| 
 | ||||
|    gl.glBindVertexArray(p->vao_); | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
|    glBindVertexArray(p->vao_); | ||||
|    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|    // NOLINTBEGIN(modernize-use-nullptr)
 | ||||
|    // NOLINTBEGIN(performance-no-int-to-ptr)
 | ||||
|    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||
| 
 | ||||
|    // aScreenCoord
 | ||||
|    gl.glVertexAttribPointer(0, | ||||
|                             2, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(0); | ||||
|    glVertexAttribPointer(0, | ||||
|                          2, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          static_cast<void*>(0)); | ||||
|    glEnableVertexAttribArray(0); | ||||
| 
 | ||||
|    // aXYOffset
 | ||||
|    gl.glVertexAttribPointer(1, | ||||
|                             2, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(2 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(1); | ||||
|    glVertexAttribPointer(1, | ||||
|                          2, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          reinterpret_cast<void*>(2 * sizeof(float))); | ||||
|    glEnableVertexAttribArray(1); | ||||
| 
 | ||||
|    // aColor
 | ||||
|    gl.glVertexAttribPointer(2, | ||||
|                             4, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(4 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(2); | ||||
|    glVertexAttribPointer(2, | ||||
|                          4, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          kPointsPerVertex * sizeof(float), | ||||
|                          reinterpret_cast<void*>(4 * sizeof(float))); | ||||
|    glEnableVertexAttribArray(2); | ||||
| 
 | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
|    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||
|    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|    // aThreshold
 | ||||
|    gl.glVertexAttribIPointer(3, //
 | ||||
|                              1, | ||||
|                              GL_INT, | ||||
|                              kIntegersPerVertex_ * sizeof(GLint), | ||||
|                              static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(3); | ||||
|    glVertexAttribIPointer(3, //
 | ||||
|                           1, | ||||
|                           GL_INT, | ||||
|                           kIntegersPerVertex_ * sizeof(GLint), | ||||
|                           static_cast<void*>(0)); | ||||
|    glEnableVertexAttribArray(3); | ||||
| 
 | ||||
|    // aTimeRange
 | ||||
|    gl.glVertexAttribIPointer(4, //
 | ||||
|                              2, | ||||
|                              GL_INT, | ||||
|                              kIntegersPerVertex_ * sizeof(GLint), | ||||
|                              reinterpret_cast<void*>(1 * sizeof(GLint))); | ||||
|    gl.glEnableVertexAttribArray(4); | ||||
|    glVertexAttribIPointer(4, //
 | ||||
|                           2, | ||||
|                           GL_INT, | ||||
|                           kIntegersPerVertex_ * sizeof(GLint), | ||||
|                           reinterpret_cast<void*>(1 * sizeof(GLint))); | ||||
|    glEnableVertexAttribArray(4); | ||||
| 
 | ||||
|    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||
|    // NOLINTEND(performance-no-int-to-ptr)
 | ||||
|    // NOLINTEND(modernize-use-nullptr)
 | ||||
| 
 | ||||
|    p->dirty_ = true; | ||||
| } | ||||
|  | @ -173,9 +179,7 @@ void PlacefileTriangles::Render( | |||
| { | ||||
|    if (!p->currentBuffer_.empty()) | ||||
|    { | ||||
|       gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
| 
 | ||||
|       gl.glBindVertexArray(p->vao_); | ||||
|       glBindVertexArray(p->vao_); | ||||
| 
 | ||||
|       p->Update(); | ||||
|       p->shaderProgram_->Use(); | ||||
|  | @ -188,12 +192,12 @@ void PlacefileTriangles::Render( | |||
|          // If thresholding is enabled, set the map distance
 | ||||
|          units::length::nautical_miles<float> mapDistance = | ||||
|             util::maplibre::GetMapDistance(params); | ||||
|          gl.glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); | ||||
|          glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          // If thresholding is disabled, set the map distance to 0
 | ||||
|          gl.glUniform1f(p->uMapDistanceLocation_, 0.0f); | ||||
|          glUniform1f(p->uMapDistanceLocation_, 0.0f); | ||||
|       } | ||||
| 
 | ||||
|       // Selected time
 | ||||
|  | @ -201,23 +205,21 @@ void PlacefileTriangles::Render( | |||
|          (p->selectedTime_ == std::chrono::system_clock::time_point {}) ? | ||||
|             std::chrono::system_clock::now() : | ||||
|             p->selectedTime_; | ||||
|       gl.glUniform1i( | ||||
|       glUniform1i( | ||||
|          p->uSelectedTimeLocation_, | ||||
|          static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>( | ||||
|                                selectedTime.time_since_epoch()) | ||||
|                                .count())); | ||||
| 
 | ||||
|       // Draw icons
 | ||||
|       gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||
|       glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| void PlacefileTriangles::Deinitialize() | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
| 
 | ||||
|    gl.glDeleteVertexArrays(1, &p->vao_); | ||||
|    gl.glDeleteBuffers(2, p->vbo_.data()); | ||||
|    glDeleteVertexArrays(1, &p->vao_); | ||||
|    glDeleteBuffers(2, p->vbo_.data()); | ||||
| 
 | ||||
|    std::unique_lock lock {p->bufferMutex_}; | ||||
| 
 | ||||
|  | @ -320,23 +322,23 @@ void PlacefileTriangles::Impl::Update() | |||
| { | ||||
|    if (dirty_) | ||||
|    { | ||||
|       gl::OpenGLFunctions& gl = context_->gl(); | ||||
| 
 | ||||
|       std::unique_lock lock {bufferMutex_}; | ||||
| 
 | ||||
|       // Buffer vertex data
 | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||
|       gl.glBufferData(GL_ARRAY_BUFFER, | ||||
|                       sizeof(GLfloat) * currentBuffer_.size(), | ||||
|                       currentBuffer_.data(), | ||||
|                       GL_DYNAMIC_DRAW); | ||||
|       glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||
|       glBufferData( | ||||
|          GL_ARRAY_BUFFER, | ||||
|          static_cast<GLsizeiptr>(sizeof(GLfloat) * currentBuffer_.size()), | ||||
|          currentBuffer_.data(), | ||||
|          GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|       // Buffer threshold data
 | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||
|       gl.glBufferData(GL_ARRAY_BUFFER, | ||||
|                       sizeof(GLint) * currentIntegerBuffer_.size(), | ||||
|                       currentIntegerBuffer_.data(), | ||||
|                       GL_DYNAMIC_DRAW); | ||||
|       glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||
|       glBufferData( | ||||
|          GL_ARRAY_BUFFER, | ||||
|          static_cast<GLsizeiptr>(sizeof(GLint) * currentIntegerBuffer_.size()), | ||||
|          currentIntegerBuffer_.data(), | ||||
|          GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|       numVertices_ = | ||||
|          static_cast<GLsizei>(currentBuffer_.size() / kPointsPerVertex); | ||||
|  |  | |||
|  | @ -3,13 +3,7 @@ | |||
| 
 | ||||
| #include <optional> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
| { | ||||
| namespace gl | ||||
| { | ||||
| namespace draw | ||||
| namespace scwx::qt::gl::draw | ||||
| { | ||||
| 
 | ||||
| static const std::string logPrefix_ = "scwx::qt::gl::draw::rectangle"; | ||||
|  | @ -27,7 +21,7 @@ class Rectangle::Impl | |||
| { | ||||
| public: | ||||
|    explicit Impl(std::shared_ptr<GlContext> context) : | ||||
|        context_ {context}, | ||||
|        context_ {std::move(context)}, | ||||
|        dirty_ {false}, | ||||
|        visible_ {true}, | ||||
|        x_ {0.0f}, | ||||
|  | @ -44,8 +38,12 @@ public: | |||
|        vbo_ {GL_INVALID_INDEX} | ||||
|    { | ||||
|    } | ||||
|    ~Impl() = default; | ||||
| 
 | ||||
|    ~Impl() {} | ||||
|    Impl(const Impl&)             = delete; | ||||
|    Impl& operator=(const Impl&)  = delete; | ||||
|    Impl(const Impl&&)            = delete; | ||||
|    Impl& operator=(const Impl&&) = delete; | ||||
| 
 | ||||
|    std::shared_ptr<GlContext> context_; | ||||
| 
 | ||||
|  | @ -73,7 +71,7 @@ public: | |||
| }; | ||||
| 
 | ||||
| Rectangle::Rectangle(std::shared_ptr<GlContext> context) : | ||||
|     DrawItem(context->gl()), p(std::make_unique<Impl>(context)) | ||||
|     DrawItem(), p(std::make_unique<Impl>(context)) | ||||
| { | ||||
| } | ||||
| Rectangle::~Rectangle() = default; | ||||
|  | @ -83,41 +81,45 @@ Rectangle& Rectangle::operator=(Rectangle&&) noexcept = default; | |||
| 
 | ||||
| void Rectangle::Initialize() | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
| 
 | ||||
|    p->shaderProgram_ = | ||||
|       p->context_->GetShaderProgram(":/gl/color.vert", ":/gl/color.frag"); | ||||
| 
 | ||||
|    p->uMVPMatrixLocation_ = | ||||
|       gl.glGetUniformLocation(p->shaderProgram_->id(), "uMVPMatrix"); | ||||
|       glGetUniformLocation(p->shaderProgram_->id(), "uMVPMatrix"); | ||||
|    if (p->uMVPMatrixLocation_ == -1) | ||||
|    { | ||||
|       logger_->warn("Could not find uMVPMatrix"); | ||||
|    } | ||||
| 
 | ||||
|    gl.glGenVertexArrays(1, &p->vao_); | ||||
|    gl.glGenBuffers(1, &p->vbo_); | ||||
|    glGenVertexArrays(1, &p->vao_); | ||||
|    glGenBuffers(1, &p->vbo_); | ||||
| 
 | ||||
|    gl.glBindVertexArray(p->vao_); | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_); | ||||
|    gl.glBufferData( | ||||
|    glBindVertexArray(p->vao_); | ||||
|    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_); | ||||
|    glBufferData( | ||||
|       GL_ARRAY_BUFFER, sizeof(float) * BUFFER_LENGTH, nullptr, GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|    gl.glVertexAttribPointer(0, | ||||
|                             3, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             POINTS_PER_VERTEX * sizeof(float), | ||||
|                             static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(0); | ||||
|    // NOLINTBEGIN(modernize-use-nullptr)
 | ||||
|    // NOLINTBEGIN(performance-no-int-to-ptr)
 | ||||
| 
 | ||||
|    gl.glVertexAttribPointer(1, | ||||
|                             4, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             POINTS_PER_VERTEX * sizeof(float), | ||||
|                             reinterpret_cast<void*>(3 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(1); | ||||
|    glVertexAttribPointer(0, | ||||
|                          3, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          POINTS_PER_VERTEX * sizeof(float), | ||||
|                          static_cast<void*>(0)); | ||||
|    glEnableVertexAttribArray(0); | ||||
| 
 | ||||
|    glVertexAttribPointer(1, | ||||
|                          4, | ||||
|                          GL_FLOAT, | ||||
|                          GL_FALSE, | ||||
|                          POINTS_PER_VERTEX * sizeof(float), | ||||
|                          reinterpret_cast<void*>(3 * sizeof(float))); | ||||
|    glEnableVertexAttribArray(1); | ||||
| 
 | ||||
|    // NOLINTEND(performance-no-int-to-ptr)
 | ||||
|    // NOLINTEND(modernize-use-nullptr)
 | ||||
| 
 | ||||
|    p->dirty_ = true; | ||||
| } | ||||
|  | @ -126,10 +128,8 @@ void Rectangle::Render(const QMapLibre::CustomLayerRenderParameters& params) | |||
| { | ||||
|    if (p->visible_) | ||||
|    { | ||||
|       gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
| 
 | ||||
|       gl.glBindVertexArray(p->vao_); | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_); | ||||
|       glBindVertexArray(p->vao_); | ||||
|       glBindBuffer(GL_ARRAY_BUFFER, p->vbo_); | ||||
| 
 | ||||
|       p->Update(); | ||||
|       p->shaderProgram_->Use(); | ||||
|  | @ -138,23 +138,23 @@ void Rectangle::Render(const QMapLibre::CustomLayerRenderParameters& params) | |||
|       if (p->fillColor_.has_value()) | ||||
|       { | ||||
|          // Draw fill
 | ||||
|          gl.glDrawArrays(GL_TRIANGLES, 24, 6); | ||||
|          // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
 | ||||
|          glDrawArrays(GL_TRIANGLES, 24, 6); | ||||
|       } | ||||
| 
 | ||||
|       if (p->borderWidth_ > 0.0f) | ||||
|       { | ||||
|          // Draw border
 | ||||
|          gl.glDrawArrays(GL_TRIANGLES, 0, 24); | ||||
|          // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
 | ||||
|          glDrawArrays(GL_TRIANGLES, 0, 24); | ||||
|       } | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| void Rectangle::Deinitialize() | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
| 
 | ||||
|    gl.glDeleteVertexArrays(1, &p->vao_); | ||||
|    gl.glDeleteBuffers(1, &p->vbo_); | ||||
|    glDeleteVertexArrays(1, &p->vao_); | ||||
|    glDeleteBuffers(1, &p->vbo_); | ||||
| } | ||||
| 
 | ||||
| void Rectangle::SetBorder(float width, boost::gil::rgba8_pixel_t color) | ||||
|  | @ -206,8 +206,6 @@ void Rectangle::Impl::Update() | |||
| { | ||||
|    if (dirty_) | ||||
|    { | ||||
|       gl::OpenGLFunctions& gl = context_->gl(); | ||||
| 
 | ||||
|       const float lox = x_; | ||||
|       const float rox = x_ + width_; | ||||
|       const float boy = y_; | ||||
|  | @ -289,16 +287,13 @@ void Rectangle::Impl::Update() | |||
|              {lox, toy, z_, fc0, fc1, fc2, fc3}  // TL
 | ||||
|           }}; | ||||
| 
 | ||||
|       gl.glBufferData(GL_ARRAY_BUFFER, | ||||
|                       sizeof(float) * BUFFER_LENGTH, | ||||
|                       buffer, | ||||
|                       GL_DYNAMIC_DRAW); | ||||
|       glBufferData(GL_ARRAY_BUFFER, | ||||
|                    sizeof(float) * BUFFER_LENGTH, | ||||
|                    static_cast<const void*>(buffer), | ||||
|                    GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|       dirty_ = false; | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| } // namespace draw
 | ||||
| } // namespace gl
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
| } // namespace scwx::qt::gl::draw
 | ||||
|  |  | |||
|  | @ -1,25 +1,12 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <QOpenGLFunctions_3_3_Core> | ||||
| #include <GL/glew.h> | ||||
| 
 | ||||
| #define SCWX_GL_CHECK_ERROR()                                                  \ | ||||
|    {                                                                           \ | ||||
|       GLenum err;                                                              \ | ||||
|       while ((err = gl.glGetError()) != GL_NO_ERROR)                           \ | ||||
|       while ((err = glGetError()) != GL_NO_ERROR)                              \ | ||||
|       {                                                                        \ | ||||
|          logger_->error("GL Error: {}, {}: {}", err, __FILE__, __LINE__);      \ | ||||
|       }                                                                        \ | ||||
|    } | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
| { | ||||
| namespace gl | ||||
| { | ||||
| 
 | ||||
| using OpenGLFunctions = QOpenGLFunctions_3_3_Core; | ||||
| 
 | ||||
| } | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
|  |  | |||
|  | @ -3,12 +3,9 @@ | |||
| #include <scwx/util/logger.hpp> | ||||
| 
 | ||||
| #include <boost/container_hash/hash.hpp> | ||||
| #include <QMessageBox> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
| { | ||||
| namespace gl | ||||
| namespace scwx::qt::gl | ||||
| { | ||||
| 
 | ||||
| static const std::string logPrefix_ = "scwx::qt::gl::gl_context"; | ||||
|  | @ -30,9 +27,6 @@ public: | |||
|    static std::size_t | ||||
|    GetShaderKey(std::initializer_list<std::pair<GLenum, std::string>> shaders); | ||||
| 
 | ||||
|    gl::OpenGLFunctions*  gl_ {nullptr}; | ||||
|    QOpenGLFunctions_3_0* gl30_ {nullptr}; | ||||
| 
 | ||||
|    bool glInitialized_ {false}; | ||||
| 
 | ||||
|    std::unordered_map<std::size_t, std::shared_ptr<gl::ShaderProgram>> | ||||
|  | @ -51,18 +45,6 @@ GlContext::~GlContext() = default; | |||
| GlContext::GlContext(GlContext&&) noexcept            = default; | ||||
| GlContext& GlContext::operator=(GlContext&&) noexcept = default; | ||||
| 
 | ||||
| gl::OpenGLFunctions& GlContext::gl() | ||||
| { | ||||
|    return *p->gl_; | ||||
| } | ||||
| 
 | ||||
| #if !defined(__APPLE__) | ||||
| QOpenGLFunctions_3_0& GlContext::gl30() | ||||
| { | ||||
|    return *p->gl30_; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| std::uint64_t GlContext::texture_buffer_count() const | ||||
| { | ||||
|    return p->textureBufferCount_; | ||||
|  | @ -75,26 +57,54 @@ void GlContext::Impl::InitializeGL() | |||
|       return; | ||||
|    } | ||||
| 
 | ||||
|    // QOpenGLFunctions objects will not be freed. Since "destruction" takes
 | ||||
|    // place at the end of program execution, it is OK to intentionally leak
 | ||||
|    // these.
 | ||||
|    const GLenum error = glewInit(); | ||||
|    if (error != GLEW_OK) | ||||
|    { | ||||
|       auto glewErrorString = | ||||
|          reinterpret_cast<const char*>(glewGetErrorString(error)); | ||||
|       logger_->error("glewInit failed: {}", glewErrorString); | ||||
| 
 | ||||
|    // NOLINTBEGIN(cppcoreguidelines-owning-memory)
 | ||||
|    gl_   = new gl::OpenGLFunctions(); | ||||
|    gl30_ = new QOpenGLFunctions_3_0(); | ||||
|    // NOLINTEND(cppcoreguidelines-owning-memory)
 | ||||
|       QMessageBox::critical( | ||||
|          nullptr, | ||||
|          "Supercell Wx", | ||||
|          QString("Unable to initialize OpenGL: %1").arg(glewErrorString)); | ||||
| 
 | ||||
|    gl_->initializeOpenGLFunctions(); | ||||
|    gl30_->initializeOpenGLFunctions(); | ||||
|       throw std::runtime_error("Unable to initialize OpenGL"); | ||||
|    } | ||||
| 
 | ||||
|    logger_->info("OpenGL Version: {}", | ||||
|                  reinterpret_cast<const char*>(gl_->glGetString(GL_VERSION))); | ||||
|    logger_->info("OpenGL Vendor: {}", | ||||
|                  reinterpret_cast<const char*>(gl_->glGetString(GL_VENDOR))); | ||||
|    logger_->info("OpenGL Renderer: {}", | ||||
|                  reinterpret_cast<const char*>(gl_->glGetString(GL_RENDERER))); | ||||
|    auto glVersion  = reinterpret_cast<const char*>(glGetString(GL_VERSION)); | ||||
|    auto glVendor   = reinterpret_cast<const char*>(glGetString(GL_VENDOR)); | ||||
|    auto glRenderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER)); | ||||
| 
 | ||||
|    gl_->glGenTextures(1, &textureAtlas_); | ||||
|    logger_->info("OpenGL Version: {}", glVersion); | ||||
|    logger_->info("OpenGL Vendor: {}", glVendor); | ||||
|    logger_->info("OpenGL Renderer: {}", glRenderer); | ||||
| 
 | ||||
|    // Get OpenGL version
 | ||||
|    GLint major = 0; | ||||
|    GLint minor = 0; | ||||
|    glGetIntegerv(GL_MAJOR_VERSION, &major); | ||||
|    glGetIntegerv(GL_MINOR_VERSION, &minor); | ||||
| 
 | ||||
|    if (major < 3 || (major == 3 && minor < 3)) | ||||
|    { | ||||
|       logger_->error( | ||||
|          "OpenGL 3.3 or greater is required, found {}.{}", major, minor); | ||||
| 
 | ||||
|       QMessageBox::critical( | ||||
|          nullptr, | ||||
|          "Supercell Wx", | ||||
|          QString("OpenGL 3.3 or greater is required, found %1.%2\n\n%3\n%4\n%5") | ||||
|             .arg(major) | ||||
|             .arg(minor) | ||||
|             .arg(glVersion) | ||||
|             .arg(glVendor) | ||||
|             .arg(glRenderer)); | ||||
| 
 | ||||
|       throw std::runtime_error("OpenGL version too low"); | ||||
|    } | ||||
| 
 | ||||
|    glGenTextures(1, &textureAtlas_); | ||||
| 
 | ||||
|    glInitialized_ = true; | ||||
| } | ||||
|  | @ -119,7 +129,7 @@ std::shared_ptr<gl::ShaderProgram> GlContext::GetShaderProgram( | |||
| 
 | ||||
|    if (it == p->shaderProgramMap_.end()) | ||||
|    { | ||||
|       shaderProgram = std::make_shared<gl::ShaderProgram>(*p->gl_); | ||||
|       shaderProgram = std::make_shared<gl::ShaderProgram>(); | ||||
|       shaderProgram->Load(shaders); | ||||
|       p->shaderProgramMap_[key] = shaderProgram; | ||||
|    } | ||||
|  | @ -142,7 +152,7 @@ GLuint GlContext::GetTextureAtlas() | |||
|    if (p->textureBufferCount_ != textureAtlas.BuildCount()) | ||||
|    { | ||||
|       p->textureBufferCount_ = textureAtlas.BuildCount(); | ||||
|       textureAtlas.BufferAtlas(*p->gl_, p->textureAtlas_); | ||||
|       textureAtlas.BufferAtlas(p->textureAtlas_); | ||||
|    } | ||||
| 
 | ||||
|    return p->textureAtlas_; | ||||
|  | @ -155,10 +165,8 @@ void GlContext::Initialize() | |||
| 
 | ||||
| void GlContext::StartFrame() | ||||
| { | ||||
|    auto& gl = p->gl_; | ||||
| 
 | ||||
|    gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | ||||
|    gl->glClear(GL_COLOR_BUFFER_BIT); | ||||
|    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | ||||
|    glClear(GL_COLOR_BUFFER_BIT); | ||||
| } | ||||
| 
 | ||||
| std::size_t GlContext::Impl::GetShaderKey( | ||||
|  | @ -173,6 +181,4 @@ std::size_t GlContext::Impl::GetShaderKey( | |||
|    return seed; | ||||
| } | ||||
| 
 | ||||
| } // namespace gl
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
| } // namespace scwx::qt::gl
 | ||||
|  |  | |||
|  | @ -3,8 +3,6 @@ | |||
| #include <scwx/qt/gl/gl.hpp> | ||||
| #include <scwx/qt/gl/shader_program.hpp> | ||||
| 
 | ||||
| #include <QOpenGLFunctions_3_0> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
|  | @ -24,12 +22,6 @@ public: | |||
|    GlContext(GlContext&&) noexcept; | ||||
|    GlContext& operator=(GlContext&&) noexcept; | ||||
| 
 | ||||
|    gl::OpenGLFunctions&  gl(); | ||||
| 
 | ||||
| #if !defined(__APPLE__) | ||||
|    QOpenGLFunctions_3_0& gl30(); | ||||
| #endif | ||||
| 
 | ||||
|    std::uint64_t texture_buffer_count() const; | ||||
| 
 | ||||
|    std::shared_ptr<gl::ShaderProgram> | ||||
|  |  | |||
|  | @ -2,12 +2,9 @@ | |||
| #include <scwx/util/logger.hpp> | ||||
| 
 | ||||
| #include <QFile> | ||||
| #include <QTextStream> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
| { | ||||
| namespace gl | ||||
| namespace scwx::qt::gl | ||||
| { | ||||
| 
 | ||||
| static const std::string logPrefix_ = "scwx::qt::gl::shader_program"; | ||||
|  | @ -23,29 +20,25 @@ static const std::unordered_map<GLenum, std::string> kShaderNames_ { | |||
| class ShaderProgram::Impl | ||||
| { | ||||
| public: | ||||
|    explicit Impl(OpenGLFunctions& gl) : gl_(gl), id_ {GL_INVALID_INDEX} | ||||
|    { | ||||
|       // Create shader program
 | ||||
|       id_ = gl_.glCreateProgram(); | ||||
|    } | ||||
|    explicit Impl() : id_ {glCreateProgram()} {} | ||||
| 
 | ||||
|    ~Impl() | ||||
|    { | ||||
|       // Delete shader program
 | ||||
|       gl_.glDeleteProgram(id_); | ||||
|       glDeleteProgram(id_); | ||||
|    } | ||||
| 
 | ||||
|    static std::string ShaderName(GLenum type); | ||||
|    Impl(const Impl&)             = delete; | ||||
|    Impl& operator=(const Impl&)  = delete; | ||||
|    Impl(const Impl&&)            = delete; | ||||
|    Impl& operator=(const Impl&&) = delete; | ||||
| 
 | ||||
|    OpenGLFunctions& gl_; | ||||
|    static std::string ShaderName(GLenum type); | ||||
| 
 | ||||
|    GLuint id_; | ||||
| }; | ||||
| 
 | ||||
| ShaderProgram::ShaderProgram(OpenGLFunctions& gl) : | ||||
|     p(std::make_unique<Impl>(gl)) | ||||
| { | ||||
| } | ||||
| ShaderProgram::ShaderProgram() : p(std::make_unique<Impl>()) {} | ||||
| ShaderProgram::~ShaderProgram() = default; | ||||
| 
 | ||||
| ShaderProgram::ShaderProgram(ShaderProgram&&) noexcept            = default; | ||||
|  | @ -58,7 +51,7 @@ GLuint ShaderProgram::id() const | |||
| 
 | ||||
| GLint ShaderProgram::GetUniformLocation(const std::string& name) | ||||
| { | ||||
|    GLint location = p->gl_.glGetUniformLocation(p->id_, name.c_str()); | ||||
|    const GLint location = glGetUniformLocation(p->id_, name.c_str()); | ||||
|    if (location == -1) | ||||
|    { | ||||
|       logger_->warn("Could not find {}", name); | ||||
|  | @ -88,8 +81,6 @@ bool ShaderProgram::Load( | |||
| { | ||||
|    logger_->debug("Load()"); | ||||
| 
 | ||||
|    OpenGLFunctions& gl = p->gl_; | ||||
| 
 | ||||
|    GLint   glSuccess; | ||||
|    bool    success = true; | ||||
|    char    infoLog[kInfoLogBufSize]; | ||||
|  | @ -120,16 +111,17 @@ bool ShaderProgram::Load( | |||
|       const char* shaderSourceC = shaderSource.c_str(); | ||||
| 
 | ||||
|       // Create a shader
 | ||||
|       GLuint shaderId = gl.glCreateShader(shader.first); | ||||
|       const GLuint shaderId = glCreateShader(shader.first); | ||||
|       shaderIds.push_back(shaderId); | ||||
| 
 | ||||
|       // Attach the shader source code and compile the shader
 | ||||
|       gl.glShaderSource(shaderId, 1, &shaderSourceC, NULL); | ||||
|       gl.glCompileShader(shaderId); | ||||
|       glShaderSource(shaderId, 1, &shaderSourceC, nullptr); | ||||
|       glCompileShader(shaderId); | ||||
| 
 | ||||
|       // Check for errors
 | ||||
|       gl.glGetShaderiv(shaderId, GL_COMPILE_STATUS, &glSuccess); | ||||
|       gl.glGetShaderInfoLog(shaderId, kInfoLogBufSize, &logLength, infoLog); | ||||
|       glGetShaderiv(shaderId, GL_COMPILE_STATUS, &glSuccess); | ||||
|       glGetShaderInfoLog( | ||||
|          shaderId, kInfoLogBufSize, &logLength, static_cast<GLchar*>(infoLog)); | ||||
|       if (!glSuccess) | ||||
|       { | ||||
|          logger_->error("Shader compilation failed: {}", infoLog); | ||||
|  | @ -146,13 +138,14 @@ bool ShaderProgram::Load( | |||
|    { | ||||
|       for (auto& shaderId : shaderIds) | ||||
|       { | ||||
|          gl.glAttachShader(p->id_, shaderId); | ||||
|          glAttachShader(p->id_, shaderId); | ||||
|       } | ||||
|       gl.glLinkProgram(p->id_); | ||||
|       glLinkProgram(p->id_); | ||||
| 
 | ||||
|       // Check for errors
 | ||||
|       gl.glGetProgramiv(p->id_, GL_LINK_STATUS, &glSuccess); | ||||
|       gl.glGetProgramInfoLog(p->id_, kInfoLogBufSize, &logLength, infoLog); | ||||
|       glGetProgramiv(p->id_, GL_LINK_STATUS, &glSuccess); | ||||
|       glGetProgramInfoLog( | ||||
|          p->id_, kInfoLogBufSize, &logLength, static_cast<GLchar*>(infoLog)); | ||||
|       if (!glSuccess) | ||||
|       { | ||||
|          logger_->error("Shader program link failed: {}", infoLog); | ||||
|  | @ -167,7 +160,7 @@ bool ShaderProgram::Load( | |||
|    // Delete shaders
 | ||||
|    for (auto& shaderId : shaderIds) | ||||
|    { | ||||
|       gl.glDeleteShader(shaderId); | ||||
|       glDeleteShader(shaderId); | ||||
|    } | ||||
| 
 | ||||
|    return success; | ||||
|  | @ -175,9 +168,7 @@ bool ShaderProgram::Load( | |||
| 
 | ||||
| void ShaderProgram::Use() const | ||||
| { | ||||
|    p->gl_.glUseProgram(p->id_); | ||||
|    glUseProgram(p->id_); | ||||
| } | ||||
| 
 | ||||
| } // namespace gl
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
| } // namespace scwx::qt::gl
 | ||||
|  |  | |||
|  | @ -19,7 +19,7 @@ namespace gl | |||
| class ShaderProgram | ||||
| { | ||||
| public: | ||||
|    explicit ShaderProgram(OpenGLFunctions& gl); | ||||
|    explicit ShaderProgram(); | ||||
|    virtual ~ShaderProgram(); | ||||
| 
 | ||||
|    ShaderProgram(const ShaderProgram&)            = delete; | ||||
|  |  | |||
|  | @ -43,6 +43,7 @@ static const std::string logPrefix_ = "scwx::main"; | |||
| static const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | ||||
| 
 | ||||
| static void ConfigureTheme(const std::vector<std::string>& args); | ||||
| static void InitializeOpenGL(); | ||||
| static void OverrideDefaultStyle(const std::vector<std::string>& args); | ||||
| static void OverridePlatform(); | ||||
| 
 | ||||
|  | @ -66,17 +67,7 @@ int main(int argc, char* argv[]) | |||
|                  scwx::qt::main::kBuildNumber_, | ||||
|                  scwx::qt::main::kCommitString_); | ||||
| 
 | ||||
|    QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true); | ||||
| 
 | ||||
| #if defined(__APPLE__) | ||||
|    // For macOS, we must choose between OpenGL 4.1 Core and OpenGL 2.1
 | ||||
|    // Compatibility. OpenGL 2.1 does not meet requirements for shaders used by
 | ||||
|    // Supercell Wx.
 | ||||
|    QSurfaceFormat surfaceFormat = QSurfaceFormat::defaultFormat(); | ||||
|    surfaceFormat.setVersion(4, 1); | ||||
|    surfaceFormat.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile); | ||||
|    QSurfaceFormat::setDefaultFormat(surfaceFormat); | ||||
| #endif | ||||
|    InitializeOpenGL(); | ||||
| 
 | ||||
|    QApplication a(argc, argv); | ||||
| 
 | ||||
|  | @ -160,8 +151,23 @@ int main(int argc, char* argv[]) | |||
|       // Run Qt main loop
 | ||||
|       { | ||||
|          scwx::qt::main::MainWindow w; | ||||
|          w.show(); | ||||
|          result = a.exec(); | ||||
| 
 | ||||
|          bool initialized = false; | ||||
| 
 | ||||
|          try | ||||
|          { | ||||
|             w.show(); | ||||
|             initialized = true; | ||||
|          } | ||||
|          catch (const std::exception& ex) | ||||
|          { | ||||
|             logger_->critical(ex.what()); | ||||
|          } | ||||
| 
 | ||||
|          if (initialized) | ||||
|          { | ||||
|             result = a.exec(); | ||||
|          } | ||||
|       } | ||||
|    } | ||||
| 
 | ||||
|  | @ -234,6 +240,23 @@ static void ConfigureTheme(const std::vector<std::string>& args) | |||
|    } | ||||
| } | ||||
| 
 | ||||
| static void InitializeOpenGL() | ||||
| { | ||||
|    QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true); | ||||
| 
 | ||||
|    QSurfaceFormat surfaceFormat = QSurfaceFormat::defaultFormat(); | ||||
|    surfaceFormat.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile); | ||||
| 
 | ||||
| #if defined(__APPLE__) | ||||
|    // For macOS, we must choose between OpenGL 4.1 Core and OpenGL 2.1
 | ||||
|    // Compatibility. OpenGL 2.1 does not meet requirements for shaders used by
 | ||||
|    // Supercell Wx.
 | ||||
|    surfaceFormat.setVersion(4, 1); | ||||
| #endif | ||||
| 
 | ||||
|    QSurfaceFormat::setDefaultFormat(surfaceFormat); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| OverrideDefaultStyle([[maybe_unused]] const std::vector<std::string>& args) | ||||
| { | ||||
|  |  | |||
|  | @ -300,8 +300,6 @@ void AlertLayer::Initialize(const std::shared_ptr<MapContext>& mapContext) | |||
| void AlertLayer::Render(const std::shared_ptr<MapContext>& mapContext, | ||||
|                         const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = gl_context()->gl(); | ||||
| 
 | ||||
|    for (auto alertActive : {false, true}) | ||||
|    { | ||||
|       p->geoLines_.at(alertActive)->set_selected_time(p->selectedTime_); | ||||
|  |  | |||
|  | @ -55,40 +55,42 @@ void ColorTableLayer::Initialize(const std::shared_ptr<MapContext>& mapContext) | |||
| 
 | ||||
|    auto glContext = gl_context(); | ||||
| 
 | ||||
|    gl::OpenGLFunctions& gl = glContext->gl(); | ||||
| 
 | ||||
|    // Load and configure overlay shader
 | ||||
|    p->shaderProgram_ = | ||||
|       glContext->GetShaderProgram(":/gl/texture1d.vert", ":/gl/texture1d.frag"); | ||||
| 
 | ||||
|    p->uMVPMatrixLocation_ = | ||||
|       gl.glGetUniformLocation(p->shaderProgram_->id(), "uMVPMatrix"); | ||||
|       glGetUniformLocation(p->shaderProgram_->id(), "uMVPMatrix"); | ||||
|    if (p->uMVPMatrixLocation_ == -1) | ||||
|    { | ||||
|       logger_->warn("Could not find uMVPMatrix"); | ||||
|    } | ||||
| 
 | ||||
|    gl.glGenTextures(1, &p->texture_); | ||||
|    glGenTextures(1, &p->texture_); | ||||
| 
 | ||||
|    p->shaderProgram_->Use(); | ||||
| 
 | ||||
|    // Generate a vertex array object
 | ||||
|    gl.glGenVertexArrays(1, &p->vao_); | ||||
|    glGenVertexArrays(1, &p->vao_); | ||||
| 
 | ||||
|    // Generate vertex buffer objects
 | ||||
|    gl.glGenBuffers(2, p->vbo_.data()); | ||||
|    glGenBuffers(2, p->vbo_.data()); | ||||
| 
 | ||||
|    gl.glBindVertexArray(p->vao_); | ||||
|    glBindVertexArray(p->vao_); | ||||
| 
 | ||||
|    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||
|    // NOLINTBEGIN(modernize-use-nullptr)
 | ||||
| 
 | ||||
|    // Bottom panel
 | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|    gl.glBufferData( | ||||
|    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|    glBufferData( | ||||
|       GL_ARRAY_BUFFER, sizeof(float) * 6 * 2, nullptr, GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|    gl.glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(0); | ||||
|    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, static_cast<void*>(0)); | ||||
|    glEnableVertexAttribArray(0); | ||||
| 
 | ||||
|    // Color table panel texture coordinates
 | ||||
|    // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays)
 | ||||
|    const float textureCoords[6][1] = {{0.0f}, // TL
 | ||||
|                                       {0.0f}, // BL
 | ||||
|                                       {1.0f}, // TR
 | ||||
|  | @ -96,12 +98,17 @@ void ColorTableLayer::Initialize(const std::shared_ptr<MapContext>& mapContext) | |||
|                                       {0.0f},  // BL
 | ||||
|                                       {1.0f},  // TR
 | ||||
|                                       {1.0f}}; // BR
 | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||
|    gl.glBufferData( | ||||
|       GL_ARRAY_BUFFER, sizeof(textureCoords), textureCoords, GL_STATIC_DRAW); | ||||
|    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||
|    glBufferData(GL_ARRAY_BUFFER, | ||||
|                 sizeof(textureCoords), | ||||
|                 static_cast<const void*>(textureCoords), | ||||
|                 GL_STATIC_DRAW); | ||||
| 
 | ||||
|    gl.glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(1); | ||||
|    glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, static_cast<void*>(0)); | ||||
|    glEnableVertexAttribArray(1); | ||||
| 
 | ||||
|    // NOLINTEND(modernize-use-nullptr)
 | ||||
|    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||
| 
 | ||||
|    connect(mapContext->radar_product_view().get(), | ||||
|            &view::RadarProductView::ColorTableLutUpdated, | ||||
|  | @ -113,8 +120,7 @@ void ColorTableLayer::Render( | |||
|    const std::shared_ptr<MapContext>&            mapContext, | ||||
|    const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    gl::OpenGLFunctions& gl               = gl_context()->gl(); | ||||
|    auto                 radarProductView = mapContext->radar_product_view(); | ||||
|    auto radarProductView = mapContext->radar_product_view(); | ||||
| 
 | ||||
|    if (radarProductView == nullptr || !radarProductView->IsInitialized()) | ||||
|    { | ||||
|  | @ -130,33 +136,36 @@ void ColorTableLayer::Render( | |||
|    p->shaderProgram_->Use(); | ||||
| 
 | ||||
|    // Set OpenGL blend mode for transparency
 | ||||
|    gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||||
|    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||||
| 
 | ||||
|    gl.glUniformMatrix4fv( | ||||
|    glUniformMatrix4fv( | ||||
|       p->uMVPMatrixLocation_, 1, GL_FALSE, glm::value_ptr(projection)); | ||||
| 
 | ||||
|    if (p->colorTableNeedsUpdate_) | ||||
|    { | ||||
|       p->colorTable_ = radarProductView->color_table_lut(); | ||||
| 
 | ||||
|       gl.glActiveTexture(GL_TEXTURE0); | ||||
|       gl.glBindTexture(GL_TEXTURE_1D, p->texture_); | ||||
|       gl.glTexImage1D(GL_TEXTURE_1D, | ||||
|                       0, | ||||
|                       GL_RGBA, | ||||
|                       (GLsizei) p->colorTable_.size(), | ||||
|                       0, | ||||
|                       GL_RGBA, | ||||
|                       GL_UNSIGNED_BYTE, | ||||
|                       p->colorTable_.data()); | ||||
|       gl.glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||||
|       gl.glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||||
|       gl.glGenerateMipmap(GL_TEXTURE_1D); | ||||
|       glActiveTexture(GL_TEXTURE0); | ||||
|       glBindTexture(GL_TEXTURE_1D, p->texture_); | ||||
|       glTexImage1D(GL_TEXTURE_1D, | ||||
|                    0, | ||||
|                    GL_RGBA, | ||||
|                    (GLsizei) p->colorTable_.size(), | ||||
|                    0, | ||||
|                    GL_RGBA, | ||||
|                    GL_UNSIGNED_BYTE, | ||||
|                    p->colorTable_.data()); | ||||
|       glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||||
|       glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||||
|       glGenerateMipmap(GL_TEXTURE_1D); | ||||
|    } | ||||
| 
 | ||||
|    if (p->colorTable_.size() > 0 && radarProductView->sweep_time() != | ||||
|                                        std::chrono::system_clock::time_point()) | ||||
|    { | ||||
|       // NOLINTBEGIN(cppcoreguidelines-avoid-c-arrays)
 | ||||
|       // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||
| 
 | ||||
|       // Color table panel vertices
 | ||||
|       const float vertexLX       = 0.0f; | ||||
|       const float vertexRX       = static_cast<float>(params.width); | ||||
|  | @ -171,10 +180,13 @@ void ColorTableLayer::Render( | |||
|                                     {vertexRX, vertexBY}}; // BR
 | ||||
| 
 | ||||
|       // Draw vertices
 | ||||
|       gl.glBindVertexArray(p->vao_); | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|       gl.glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); | ||||
|       gl.glDrawArrays(GL_TRIANGLES, 0, 6); | ||||
|       glBindVertexArray(p->vao_); | ||||
|       glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|       glBufferSubData(GL_ARRAY_BUFFER, | ||||
|                       0, | ||||
|                       sizeof(vertices), | ||||
|                       static_cast<const void*>(vertices)); | ||||
|       glDrawArrays(GL_TRIANGLES, 0, 6); | ||||
| 
 | ||||
|       static constexpr int kLeftMargin_   = 0; | ||||
|       static constexpr int kTopMargin_    = 0; | ||||
|  | @ -183,6 +195,9 @@ void ColorTableLayer::Render( | |||
| 
 | ||||
|       mapContext->set_color_table_margins( | ||||
|          QMargins {kLeftMargin_, kTopMargin_, kRightMargin_, kBottomMargin_}); | ||||
| 
 | ||||
|       // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||
|       // NOLINTEND(cppcoreguidelines-avoid-c-arrays)
 | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|  | @ -196,11 +211,9 @@ void ColorTableLayer::Deinitialize() | |||
| { | ||||
|    logger_->debug("Deinitialize()"); | ||||
| 
 | ||||
|    gl::OpenGLFunctions& gl = gl_context()->gl(); | ||||
| 
 | ||||
|    gl.glDeleteVertexArrays(1, &p->vao_); | ||||
|    gl.glDeleteBuffers(2, p->vbo_.data()); | ||||
|    gl.glDeleteTextures(1, &p->texture_); | ||||
|    glDeleteVertexArrays(1, &p->vao_); | ||||
|    glDeleteBuffers(2, p->vbo_.data()); | ||||
|    glDeleteTextures(1, &p->texture_); | ||||
| 
 | ||||
|    p->uMVPMatrixLocation_ = GL_INVALID_INDEX; | ||||
|    p->vao_                = GL_INVALID_INDEX; | ||||
|  |  | |||
|  | @ -127,8 +127,7 @@ void DrawLayer::RenderWithoutImGui( | |||
| { | ||||
|    auto& glContext = p->glContext_; | ||||
| 
 | ||||
|    gl::OpenGLFunctions& gl = glContext->gl(); | ||||
|    p->textureAtlas_        = glContext->GetTextureAtlas(); | ||||
|    p->textureAtlas_ = glContext->GetTextureAtlas(); | ||||
| 
 | ||||
|    // Determine if the texture atlas changed since last render
 | ||||
|    const std::uint64_t newTextureAtlasBuildCount = | ||||
|  | @ -137,10 +136,10 @@ void DrawLayer::RenderWithoutImGui( | |||
|       newTextureAtlasBuildCount != p->textureAtlasBuildCount_; | ||||
| 
 | ||||
|    // Set OpenGL blend mode for transparency
 | ||||
|    gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||||
|    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||||
| 
 | ||||
|    gl.glActiveTexture(GL_TEXTURE0); | ||||
|    gl.glBindTexture(GL_TEXTURE_2D_ARRAY, p->textureAtlas_); | ||||
|    glActiveTexture(GL_TEXTURE0); | ||||
|    glBindTexture(GL_TEXTURE_2D_ARRAY, p->textureAtlas_); | ||||
| 
 | ||||
|    for (auto& item : p->drawList_) | ||||
|    { | ||||
|  |  | |||
|  | @ -2011,10 +2011,14 @@ void MapWidgetImpl::RadarProductViewConnect() | |||
|             std::shared_ptr<config::RadarSite> radarSite = | ||||
|                radarProductManager_->radar_site(); | ||||
| 
 | ||||
|             RadarRangeLayer::Update( | ||||
|                map_, | ||||
|                radarProductView->range(), | ||||
|                {radarSite->latitude(), radarSite->longitude()}); | ||||
|             if (map_ != nullptr) | ||||
|             { | ||||
|                RadarRangeLayer::Update( | ||||
|                   map_, | ||||
|                   radarProductView->range(), | ||||
|                   {radarSite->latitude(), radarSite->longitude()}); | ||||
|             } | ||||
| 
 | ||||
|             widget_->update(); | ||||
|             Q_EMIT widget_->RadarSweepUpdated(); | ||||
|          }, | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ | |||
| #include <scwx/common/geographic.hpp> | ||||
| #include <scwx/common/products.hpp> | ||||
| #include <scwx/qt/config/radar_site.hpp> | ||||
| #include <scwx/qt/gl/gl.hpp> | ||||
| #include <scwx/qt/types/map_types.hpp> | ||||
| #include <scwx/qt/types/radar_product_record.hpp> | ||||
| #include <scwx/qt/types/text_event_key.hpp> | ||||
|  |  | |||
|  | @ -165,8 +165,6 @@ void MarkerLayer::Impl::set_icon_sheets() | |||
| void MarkerLayer::Render(const std::shared_ptr<MapContext>& mapContext, | ||||
|                          const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = gl_context()->gl(); | ||||
| 
 | ||||
|    DrawLayer::Render(mapContext, params); | ||||
| 
 | ||||
|    SCWX_GL_CHECK_ERROR(); | ||||
|  |  | |||
|  | @ -338,10 +338,9 @@ void OverlayLayer::Render(const std::shared_ptr<MapContext>& mapContext, | |||
| { | ||||
|    const std::unique_lock lock {p->renderMutex_}; | ||||
| 
 | ||||
|    gl::OpenGLFunctions& gl               = gl_context()->gl(); | ||||
|    auto                 radarProductView = mapContext->radar_product_view(); | ||||
|    auto&                settings         = mapContext->settings(); | ||||
|    const float          pixelRatio       = mapContext->pixel_ratio(); | ||||
|    auto        radarProductView = mapContext->radar_product_view(); | ||||
|    auto&       settings         = mapContext->settings(); | ||||
|    const float pixelRatio       = mapContext->pixel_ratio(); | ||||
| 
 | ||||
|    ImGuiFrameStart(mapContext); | ||||
| 
 | ||||
|  |  | |||
|  | @ -142,8 +142,6 @@ void OverlayProductLayer::Render( | |||
|    const std::shared_ptr<MapContext>&            mapContext, | ||||
|    const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = gl_context()->gl(); | ||||
| 
 | ||||
|    if (p->stiNeedsUpdate_) | ||||
|    { | ||||
|       p->UpdateStormTrackingInformation(mapContext); | ||||
|  |  | |||
|  | @ -34,8 +34,7 @@ public: | |||
|           std::make_shared<gl::draw::PlacefilePolygons>(glContext)}, | ||||
|        placefileTriangles_ { | ||||
|           std::make_shared<gl::draw::PlacefileTriangles>(glContext)}, | ||||
|        placefileText_ { | ||||
|           std::make_shared<gl::draw::PlacefileText>(glContext, placefileName)} | ||||
|        placefileText_ {std::make_shared<gl::draw::PlacefileText>(placefileName)} | ||||
|    { | ||||
|       ConnectSignals(); | ||||
|    } | ||||
|  | @ -132,8 +131,6 @@ void PlacefileLayer::Render( | |||
|    const std::shared_ptr<MapContext>&            mapContext, | ||||
|    const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = gl_context()->gl(); | ||||
| 
 | ||||
|    std::shared_ptr<manager::PlacefileManager> placefileManager = | ||||
|       manager::PlacefileManager::Instance(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -78,42 +78,40 @@ void RadarProductLayer::Initialize( | |||
| 
 | ||||
|    auto glContext = gl_context(); | ||||
| 
 | ||||
|    gl::OpenGLFunctions& gl = glContext->gl(); | ||||
| 
 | ||||
|    // Load and configure radar shader
 | ||||
|    p->shaderProgram_ = | ||||
|       glContext->GetShaderProgram(":/gl/radar.vert", ":/gl/radar.frag"); | ||||
| 
 | ||||
|    p->uMVPMatrixLocation_ = | ||||
|       gl.glGetUniformLocation(p->shaderProgram_->id(), "uMVPMatrix"); | ||||
|       glGetUniformLocation(p->shaderProgram_->id(), "uMVPMatrix"); | ||||
|    if (p->uMVPMatrixLocation_ == -1) | ||||
|    { | ||||
|       logger_->warn("Could not find uMVPMatrix"); | ||||
|    } | ||||
| 
 | ||||
|    p->uMapScreenCoordLocation_ = | ||||
|       gl.glGetUniformLocation(p->shaderProgram_->id(), "uMapScreenCoord"); | ||||
|       glGetUniformLocation(p->shaderProgram_->id(), "uMapScreenCoord"); | ||||
|    if (p->uMapScreenCoordLocation_ == -1) | ||||
|    { | ||||
|       logger_->warn("Could not find uMapScreenCoord"); | ||||
|    } | ||||
| 
 | ||||
|    p->uDataMomentOffsetLocation_ = | ||||
|       gl.glGetUniformLocation(p->shaderProgram_->id(), "uDataMomentOffset"); | ||||
|       glGetUniformLocation(p->shaderProgram_->id(), "uDataMomentOffset"); | ||||
|    if (p->uDataMomentOffsetLocation_ == -1) | ||||
|    { | ||||
|       logger_->warn("Could not find uDataMomentOffset"); | ||||
|    } | ||||
| 
 | ||||
|    p->uDataMomentScaleLocation_ = | ||||
|       gl.glGetUniformLocation(p->shaderProgram_->id(), "uDataMomentScale"); | ||||
|       glGetUniformLocation(p->shaderProgram_->id(), "uDataMomentScale"); | ||||
|    if (p->uDataMomentScaleLocation_ == -1) | ||||
|    { | ||||
|       logger_->warn("Could not find uDataMomentScale"); | ||||
|    } | ||||
| 
 | ||||
|    p->uCFPEnabledLocation_ = | ||||
|       gl.glGetUniformLocation(p->shaderProgram_->id(), "uCFPEnabled"); | ||||
|       glGetUniformLocation(p->shaderProgram_->id(), "uCFPEnabled"); | ||||
|    if (p->uCFPEnabledLocation_ == -1) | ||||
|    { | ||||
|       logger_->warn("Could not find uCFPEnabled"); | ||||
|  | @ -122,22 +120,22 @@ void RadarProductLayer::Initialize( | |||
|    p->shaderProgram_->Use(); | ||||
| 
 | ||||
|    // Generate a vertex array object
 | ||||
|    gl.glGenVertexArrays(1, &p->vao_); | ||||
|    glGenVertexArrays(1, &p->vao_); | ||||
| 
 | ||||
|    // Generate vertex buffer objects
 | ||||
|    gl.glGenBuffers(3, p->vbo_.data()); | ||||
|    glGenBuffers(3, p->vbo_.data()); | ||||
| 
 | ||||
|    // Update radar sweep
 | ||||
|    p->sweepNeedsUpdate_ = true; | ||||
|    UpdateSweep(mapContext); | ||||
| 
 | ||||
|    // Create color table
 | ||||
|    gl.glGenTextures(1, &p->texture_); | ||||
|    glGenTextures(1, &p->texture_); | ||||
|    p->colorTableNeedsUpdate_ = true; | ||||
|    UpdateColorTable(mapContext); | ||||
|    gl.glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||||
|    gl.glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||||
|    gl.glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||||
|    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||||
|    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||||
|    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||||
| 
 | ||||
|    auto radarProductView = mapContext->radar_product_view(); | ||||
|    connect(radarProductView.get(), | ||||
|  | @ -153,7 +151,8 @@ void RadarProductLayer::Initialize( | |||
| void RadarProductLayer::UpdateSweep( | ||||
|    const std::shared_ptr<MapContext>& mapContext) | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = gl_context()->gl(); | ||||
|    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||
|    // NOLINTBEGIN(modernize-use-nullptr)
 | ||||
| 
 | ||||
|    boost::timer::cpu_timer timer; | ||||
| 
 | ||||
|  | @ -174,20 +173,20 @@ void RadarProductLayer::UpdateSweep( | |||
|    const std::vector<float>& vertices = radarProductView->vertices(); | ||||
| 
 | ||||
|    // Bind a vertex array object
 | ||||
|    gl.glBindVertexArray(p->vao_); | ||||
|    glBindVertexArray(p->vao_); | ||||
| 
 | ||||
|    // Buffer vertices
 | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|    timer.start(); | ||||
|    gl.glBufferData(GL_ARRAY_BUFFER, | ||||
|                    vertices.size() * sizeof(GLfloat), | ||||
|                    vertices.data(), | ||||
|                    GL_STATIC_DRAW); | ||||
|    glBufferData(GL_ARRAY_BUFFER, | ||||
|                 static_cast<GLsizeiptr>(vertices.size() * sizeof(GLfloat)), | ||||
|                 vertices.data(), | ||||
|                 GL_STATIC_DRAW); | ||||
|    timer.stop(); | ||||
|    logger_->debug("Vertices buffered in {}", timer.format(6, "%ws")); | ||||
| 
 | ||||
|    gl.glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(0); | ||||
|    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, static_cast<void*>(0)); | ||||
|    glEnableVertexAttribArray(0); | ||||
| 
 | ||||
|    // Buffer data moments
 | ||||
|    const GLvoid* data; | ||||
|  | @ -206,14 +205,14 @@ void RadarProductLayer::UpdateSweep( | |||
|       type = GL_UNSIGNED_SHORT; | ||||
|    } | ||||
| 
 | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||
|    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||
|    timer.start(); | ||||
|    gl.glBufferData(GL_ARRAY_BUFFER, dataSize, data, GL_STATIC_DRAW); | ||||
|    glBufferData(GL_ARRAY_BUFFER, dataSize, data, GL_STATIC_DRAW); | ||||
|    timer.stop(); | ||||
|    logger_->debug("Data moments buffered in {}", timer.format(6, "%ws")); | ||||
| 
 | ||||
|    gl.glVertexAttribIPointer(1, 1, type, 0, static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(1); | ||||
|    glVertexAttribIPointer(1, 1, type, 0, static_cast<void*>(0)); | ||||
|    glEnableVertexAttribArray(1); | ||||
| 
 | ||||
|    // Buffer CFP data
 | ||||
|    const GLvoid* cfpData; | ||||
|  | @ -235,39 +234,41 @@ void RadarProductLayer::UpdateSweep( | |||
|          cfpType = GL_UNSIGNED_SHORT; | ||||
|       } | ||||
| 
 | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[2]); | ||||
|       glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[2]); | ||||
|       timer.start(); | ||||
|       gl.glBufferData(GL_ARRAY_BUFFER, cfpDataSize, cfpData, GL_STATIC_DRAW); | ||||
|       glBufferData(GL_ARRAY_BUFFER, cfpDataSize, cfpData, GL_STATIC_DRAW); | ||||
|       timer.stop(); | ||||
|       logger_->debug("CFP moments buffered in {}", timer.format(6, "%ws")); | ||||
| 
 | ||||
|       gl.glVertexAttribIPointer(2, 1, cfpType, 0, static_cast<void*>(0)); | ||||
|       gl.glEnableVertexAttribArray(2); | ||||
|       glVertexAttribIPointer(2, 1, cfpType, 0, static_cast<void*>(0)); | ||||
|       glEnableVertexAttribArray(2); | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       gl.glDisableVertexAttribArray(2); | ||||
|       glDisableVertexAttribArray(2); | ||||
|    } | ||||
| 
 | ||||
|    p->numVertices_ = vertices.size() / 2; | ||||
|    p->numVertices_ = static_cast<GLsizeiptr>(vertices.size() / 2); | ||||
| 
 | ||||
|    // NOLINTEND(modernize-use-nullptr)
 | ||||
|    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||
| } | ||||
| 
 | ||||
| void RadarProductLayer::Render( | ||||
|    const std::shared_ptr<MapContext>&            mapContext, | ||||
|    const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = gl_context()->gl(); | ||||
| 
 | ||||
|    p->shaderProgram_->Use(); | ||||
| 
 | ||||
|    // Set OpenGL blend mode for transparency
 | ||||
|    gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||||
|    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||||
| 
 | ||||
|    const bool wireframeEnabled = mapContext->settings().radarWireframeEnabled_; | ||||
|    if (wireframeEnabled) | ||||
|    { | ||||
|       // Set polygon mode to draw wireframe
 | ||||
|       gl.glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | ||||
|       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | ||||
|    } | ||||
| 
 | ||||
|    if (p->colorTableNeedsUpdate_) | ||||
|  | @ -291,28 +292,28 @@ void RadarProductLayer::Render( | |||
|                             glm::radians<float>(params.bearing), | ||||
|                             glm::vec3(0.0f, 0.0f, 1.0f)); | ||||
| 
 | ||||
|    gl.glUniform2fv(p->uMapScreenCoordLocation_, | ||||
|                    1, | ||||
|                    glm::value_ptr(util::maplibre::LatLongToScreenCoordinate( | ||||
|                       {params.latitude, params.longitude}))); | ||||
|    glUniform2fv(p->uMapScreenCoordLocation_, | ||||
|                 1, | ||||
|                 glm::value_ptr(util::maplibre::LatLongToScreenCoordinate( | ||||
|                    {params.latitude, params.longitude}))); | ||||
| 
 | ||||
|    gl.glUniformMatrix4fv( | ||||
|    glUniformMatrix4fv( | ||||
|       p->uMVPMatrixLocation_, 1, GL_FALSE, glm::value_ptr(uMVPMatrix)); | ||||
| 
 | ||||
|    gl.glUniform1i(p->uCFPEnabledLocation_, p->cfpEnabled_ ? 1 : 0); | ||||
|    glUniform1i(p->uCFPEnabledLocation_, p->cfpEnabled_ ? 1 : 0); | ||||
| 
 | ||||
|    gl.glUniform1ui(p->uDataMomentOffsetLocation_, p->rangeMin_); | ||||
|    gl.glUniform1f(p->uDataMomentScaleLocation_, p->scale_); | ||||
|    glUniform1ui(p->uDataMomentOffsetLocation_, p->rangeMin_); | ||||
|    glUniform1f(p->uDataMomentScaleLocation_, p->scale_); | ||||
| 
 | ||||
|    gl.glActiveTexture(GL_TEXTURE0); | ||||
|    gl.glBindTexture(GL_TEXTURE_1D, p->texture_); | ||||
|    gl.glBindVertexArray(p->vao_); | ||||
|    gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||
|    glActiveTexture(GL_TEXTURE0); | ||||
|    glBindTexture(GL_TEXTURE_1D, p->texture_); | ||||
|    glBindVertexArray(p->vao_); | ||||
|    glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(p->numVertices_)); | ||||
| 
 | ||||
|    if (wireframeEnabled) | ||||
|    { | ||||
|       // Restore polygon mode to default
 | ||||
|       gl.glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | ||||
|       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | ||||
|    } | ||||
| 
 | ||||
|    SCWX_GL_CHECK_ERROR(); | ||||
|  | @ -322,10 +323,8 @@ void RadarProductLayer::Deinitialize() | |||
| { | ||||
|    logger_->debug("Deinitialize()"); | ||||
| 
 | ||||
|    gl::OpenGLFunctions& gl = gl_context()->gl(); | ||||
| 
 | ||||
|    gl.glDeleteVertexArrays(1, &p->vao_); | ||||
|    gl.glDeleteBuffers(3, p->vbo_.data()); | ||||
|    glDeleteVertexArrays(1, &p->vao_); | ||||
|    glDeleteBuffers(3, p->vbo_.data()); | ||||
| 
 | ||||
|    p->uMVPMatrixLocation_        = GL_INVALID_INDEX; | ||||
|    p->uMapScreenCoordLocation_   = GL_INVALID_INDEX; | ||||
|  | @ -536,7 +535,6 @@ void RadarProductLayer::UpdateColorTable( | |||
| 
 | ||||
|    p->colorTableNeedsUpdate_ = false; | ||||
| 
 | ||||
|    gl::OpenGLFunctions&                    gl = gl_context()->gl(); | ||||
|    std::shared_ptr<view::RadarProductView> radarProductView = | ||||
|       mapContext->radar_product_view(); | ||||
| 
 | ||||
|  | @ -547,17 +545,17 @@ void RadarProductLayer::UpdateColorTable( | |||
| 
 | ||||
|    const float scale = rangeMax - rangeMin; | ||||
| 
 | ||||
|    gl.glActiveTexture(GL_TEXTURE0); | ||||
|    gl.glBindTexture(GL_TEXTURE_1D, p->texture_); | ||||
|    gl.glTexImage1D(GL_TEXTURE_1D, | ||||
|                    0, | ||||
|                    GL_RGBA, | ||||
|                    (GLsizei) colorTable.size(), | ||||
|                    0, | ||||
|                    GL_RGBA, | ||||
|                    GL_UNSIGNED_BYTE, | ||||
|                    colorTable.data()); | ||||
|    gl.glGenerateMipmap(GL_TEXTURE_1D); | ||||
|    glActiveTexture(GL_TEXTURE0); | ||||
|    glBindTexture(GL_TEXTURE_1D, p->texture_); | ||||
|    glTexImage1D(GL_TEXTURE_1D, | ||||
|                 0, | ||||
|                 GL_RGBA, | ||||
|                 (GLsizei) colorTable.size(), | ||||
|                 0, | ||||
|                 GL_RGBA, | ||||
|                 GL_UNSIGNED_BYTE, | ||||
|                 colorTable.data()); | ||||
|    glGenerateMipmap(GL_TEXTURE_1D); | ||||
| 
 | ||||
|    p->rangeMin_ = rangeMin; | ||||
|    p->scale_    = scale; | ||||
|  |  | |||
|  | @ -107,8 +107,6 @@ void RadarSiteLayer::Render( | |||
|       return; | ||||
|    } | ||||
| 
 | ||||
|    gl::OpenGLFunctions& gl = gl_context()->gl(); | ||||
| 
 | ||||
|    // Update map screen coordinate and scale information
 | ||||
|    p->mapScreenCoordLocation_ = util::maplibre::LatLongToScreenCoordinate( | ||||
|       {params.latitude, params.longitude}); | ||||
|  |  | |||
|  | @ -1,5 +1,4 @@ | |||
| #include <scwx/qt/ui/imgui_debug_widget.hpp> | ||||
| #include <scwx/qt/gl/gl.hpp> | ||||
| #include <scwx/qt/manager/font_manager.hpp> | ||||
| #include <scwx/qt/model/imgui_context_model.hpp> | ||||
| 
 | ||||
|  | @ -60,8 +59,6 @@ public: | |||
| 
 | ||||
|    ImGuiContext* currentContext_; | ||||
| 
 | ||||
|    gl::OpenGLFunctions gl_; | ||||
| 
 | ||||
|    std::set<ImGuiContext*> renderedSet_ {}; | ||||
|    bool                    imGuiRendererInitialized_ {false}; | ||||
|    std::uint64_t           imGuiFontsBuildCount_ {}; | ||||
|  | @ -106,9 +103,6 @@ void ImGuiDebugWidget::initializeGL() | |||
| { | ||||
|    makeCurrent(); | ||||
| 
 | ||||
|    // Initialize OpenGL Functions
 | ||||
|    p->gl_.initializeOpenGLFunctions(); | ||||
| 
 | ||||
|    // Initialize ImGui OpenGL3 backend
 | ||||
|    ImGui::SetCurrentContext(p->context_); | ||||
|    ImGui_ImplOpenGL3_Init(); | ||||
|  | @ -119,8 +113,8 @@ void ImGuiDebugWidget::initializeGL() | |||
| 
 | ||||
| void ImGuiDebugWidget::paintGL() | ||||
| { | ||||
|    p->gl_.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | ||||
|    p->gl_.glClear(GL_COLOR_BUFFER_BIT); | ||||
|    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | ||||
|    glClear(GL_COLOR_BUFFER_BIT); | ||||
| 
 | ||||
|    ImGui::SetCurrentContext(p->currentContext_); | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,5 +1,7 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <scwx/qt/gl/gl.hpp> | ||||
| 
 | ||||
| #include <QOpenGLWidget> | ||||
| 
 | ||||
| struct ImGuiContext; | ||||
|  |  | |||
|  | @ -314,7 +314,7 @@ void TextureAtlas::BuildAtlas(std::size_t width, std::size_t height) | |||
|    logger_->debug("Texture atlas built in {}", timer.format(6, "%ws")); | ||||
| } | ||||
| 
 | ||||
| void TextureAtlas::BufferAtlas(gl::OpenGLFunctions& gl, GLuint texture) | ||||
| void TextureAtlas::BufferAtlas(GLuint texture) | ||||
| { | ||||
|    std::shared_lock lock(p->atlasMutex_); | ||||
| 
 | ||||
|  | @ -343,25 +343,23 @@ void TextureAtlas::BufferAtlas(gl::OpenGLFunctions& gl, GLuint texture) | |||
| 
 | ||||
|       lock.unlock(); | ||||
| 
 | ||||
|       gl.glBindTexture(GL_TEXTURE_2D_ARRAY, texture); | ||||
|       glBindTexture(GL_TEXTURE_2D_ARRAY, texture); | ||||
| 
 | ||||
|       gl.glTexParameteri( | ||||
|          GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||||
|       gl.glTexParameteri( | ||||
|          GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||||
|       gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||||
|       gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||||
|       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||||
|       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||||
|       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||||
|       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||||
| 
 | ||||
|       gl.glTexImage3D(GL_TEXTURE_2D_ARRAY, | ||||
|                       0, | ||||
|                       GL_RGBA, | ||||
|                       static_cast<GLsizei>(width), | ||||
|                       static_cast<GLsizei>(height), | ||||
|                       static_cast<GLsizei>(numLayers), | ||||
|                       0, | ||||
|                       GL_RGBA, | ||||
|                       GL_UNSIGNED_BYTE, | ||||
|                       pixelData.data()); | ||||
|       glTexImage3D(GL_TEXTURE_2D_ARRAY, | ||||
|                    0, | ||||
|                    GL_RGBA, | ||||
|                    static_cast<GLsizei>(width), | ||||
|                    static_cast<GLsizei>(height), | ||||
|                    static_cast<GLsizei>(numLayers), | ||||
|                    0, | ||||
|                    GL_RGBA, | ||||
|                    GL_UNSIGNED_BYTE, | ||||
|                    pixelData.data()); | ||||
|    } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -77,7 +77,7 @@ public: | |||
|    std::shared_ptr<boost::gil::rgba8_image_t> CacheTexture( | ||||
|       const std::string& name, const std::string& path, double scale = 1); | ||||
|    void BuildAtlas(std::size_t width, std::size_t height); | ||||
|    void BufferAtlas(gl::OpenGLFunctions& gl, GLuint texture); | ||||
|    void BufferAtlas(GLuint texture); | ||||
| 
 | ||||
|    TextureAttributes GetTextureAttributes(const std::string& name); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat