mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 10:30:06 +00:00 
			
		
		
		
	Use GLEW instead of QOpenGLFunctions
This commit is contained in:
		
							parent
							
								
									4bd749d976
								
							
						
					
					
						commit
						331b2d855f
					
				
					 33 changed files with 788 additions and 959 deletions
				
			
		|  | @ -30,13 +30,11 @@ static const std::string logPrefix_ = "scwx::qt::gl::draw::draw_item"; | ||||||
| class DrawItem::Impl | class DrawItem::Impl | ||||||
| { | { | ||||||
| public: | public: | ||||||
|    explicit Impl(OpenGLFunctions& gl) : gl_ {gl} {} |    explicit Impl() {} | ||||||
|    ~Impl() {} |    ~Impl() {} | ||||||
| 
 |  | ||||||
|    OpenGLFunctions& gl_; |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| DrawItem::DrawItem(OpenGLFunctions& gl) : p(std::make_unique<Impl>(gl)) {} | DrawItem::DrawItem() : p(std::make_unique<Impl>()) {} | ||||||
| DrawItem::~DrawItem() = default; | DrawItem::~DrawItem() = default; | ||||||
| 
 | 
 | ||||||
| DrawItem::DrawItem(DrawItem&&) noexcept            = default; | DrawItem::DrawItem(DrawItem&&) noexcept            = default; | ||||||
|  | @ -74,7 +72,7 @@ void DrawItem::UseDefaultProjection( | ||||||
|                                      0.0f, |                                      0.0f, | ||||||
|                                      static_cast<float>(params.height)); |                                      static_cast<float>(params.height)); | ||||||
| 
 | 
 | ||||||
|    p->gl_.glUniformMatrix4fv( |    glUniformMatrix4fv( | ||||||
|       uMVPMatrixLocation, 1, GL_FALSE, glm::value_ptr(projection)); |       uMVPMatrixLocation, 1, GL_FALSE, glm::value_ptr(projection)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -91,7 +89,7 @@ void DrawItem::UseRotationProjection( | ||||||
|                             glm::radians<float>(params.bearing), |                             glm::radians<float>(params.bearing), | ||||||
|                             glm::vec3(0.0f, 0.0f, 1.0f)); |                             glm::vec3(0.0f, 0.0f, 1.0f)); | ||||||
| 
 | 
 | ||||||
|    p->gl_.glUniformMatrix4fv( |    glUniformMatrix4fv( | ||||||
|       uMVPMatrixLocation, 1, GL_FALSE, glm::value_ptr(projection)); |       uMVPMatrixLocation, 1, GL_FALSE, glm::value_ptr(projection)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -100,16 +98,14 @@ void DrawItem::UseMapProjection( | ||||||
|    GLint                                         uMVPMatrixLocation, |    GLint                                         uMVPMatrixLocation, | ||||||
|    GLint                                         uMapScreenCoordLocation) |    GLint                                         uMapScreenCoordLocation) | ||||||
| { | { | ||||||
|    OpenGLFunctions& gl = p->gl_; |  | ||||||
| 
 |  | ||||||
|    const glm::mat4 uMVPMatrix = util::maplibre::GetMapMatrix(params); |    const glm::mat4 uMVPMatrix = util::maplibre::GetMapMatrix(params); | ||||||
| 
 | 
 | ||||||
|    gl.glUniform2fv(uMapScreenCoordLocation, |    glUniform2fv(uMapScreenCoordLocation, | ||||||
|                 1, |                 1, | ||||||
|                 glm::value_ptr(util::maplibre::LatLongToScreenCoordinate( |                 glm::value_ptr(util::maplibre::LatLongToScreenCoordinate( | ||||||
|                    {params.latitude, params.longitude}))); |                    {params.latitude, params.longitude}))); | ||||||
| 
 | 
 | ||||||
|    gl.glUniformMatrix4fv( |    glUniformMatrix4fv( | ||||||
|       uMVPMatrixLocation, 1, GL_FALSE, glm::value_ptr(uMVPMatrix)); |       uMVPMatrixLocation, 1, GL_FALSE, glm::value_ptr(uMVPMatrix)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -21,7 +21,7 @@ namespace draw | ||||||
| class DrawItem | class DrawItem | ||||||
| { | { | ||||||
| public: | public: | ||||||
|    explicit DrawItem(OpenGLFunctions& gl); |    explicit DrawItem(); | ||||||
|    virtual ~DrawItem(); |    virtual ~DrawItem(); | ||||||
| 
 | 
 | ||||||
|    DrawItem(const DrawItem&)            = delete; |    DrawItem(const DrawItem&)            = delete; | ||||||
|  |  | ||||||
|  | @ -144,7 +144,7 @@ public: | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| GeoIcons::GeoIcons(const std::shared_ptr<GlContext>& context) : | 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; | GeoIcons::~GeoIcons() = default; | ||||||
|  | @ -165,8 +165,6 @@ void GeoIcons::set_thresholded(bool thresholded) | ||||||
| 
 | 
 | ||||||
| void GeoIcons::Initialize() | void GeoIcons::Initialize() | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); |  | ||||||
| 
 |  | ||||||
|    p->shaderProgram_ = p->context_->GetShaderProgram( |    p->shaderProgram_ = p->context_->GetShaderProgram( | ||||||
|       {{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"}, |       {{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"}, | ||||||
|        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, |        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, | ||||||
|  | @ -181,87 +179,87 @@ void GeoIcons::Initialize() | ||||||
|    p->uSelectedTimeLocation_ = |    p->uSelectedTimeLocation_ = | ||||||
|       p->shaderProgram_->GetUniformLocation("uSelectedTime"); |       p->shaderProgram_->GetUniformLocation("uSelectedTime"); | ||||||
| 
 | 
 | ||||||
|    gl.glGenVertexArrays(1, &p->vao_); |    glGenVertexArrays(1, &p->vao_); | ||||||
|    gl.glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); |    glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||||
| 
 | 
 | ||||||
|    gl.glBindVertexArray(p->vao_); |    glBindVertexArray(p->vao_); | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); |    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); |    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|    // aLatLong
 |    // aLatLong
 | ||||||
|    gl.glVertexAttribPointer(0, |    glVertexAttribPointer(0, | ||||||
|                          2, |                          2, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          static_cast<void*>(0)); |                          static_cast<void*>(0)); | ||||||
|    gl.glEnableVertexAttribArray(0); |    glEnableVertexAttribArray(0); | ||||||
| 
 | 
 | ||||||
|    // aXYOffset
 |    // aXYOffset
 | ||||||
|    gl.glVertexAttribPointer(1, |    glVertexAttribPointer(1, | ||||||
|                          2, |                          2, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          reinterpret_cast<void*>(2 * sizeof(float))); |                          reinterpret_cast<void*>(2 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(1); |    glEnableVertexAttribArray(1); | ||||||
| 
 | 
 | ||||||
|    // aModulate
 |    // aModulate
 | ||||||
|    gl.glVertexAttribPointer(3, |    glVertexAttribPointer(3, | ||||||
|                          4, |                          4, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          reinterpret_cast<void*>(4 * sizeof(float))); |                          reinterpret_cast<void*>(4 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(3); |    glEnableVertexAttribArray(3); | ||||||
| 
 | 
 | ||||||
|    // aAngle
 |    // aAngle
 | ||||||
|    gl.glVertexAttribPointer(4, |    glVertexAttribPointer(4, | ||||||
|                          1, |                          1, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          reinterpret_cast<void*>(8 * sizeof(float))); |                          reinterpret_cast<void*>(8 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(4); |    glEnableVertexAttribArray(4); | ||||||
| 
 | 
 | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); |    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); |    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|    // aTexCoord
 |    // aTexCoord
 | ||||||
|    gl.glVertexAttribPointer(2, |    glVertexAttribPointer(2, | ||||||
|                          3, |                          3, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerTexCoord * sizeof(float), |                          kPointsPerTexCoord * sizeof(float), | ||||||
|                          static_cast<void*>(0)); |                          static_cast<void*>(0)); | ||||||
|    gl.glEnableVertexAttribArray(2); |    glEnableVertexAttribArray(2); | ||||||
| 
 | 
 | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[2]); |    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[2]); | ||||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); |    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|    // aThreshold
 |    // aThreshold
 | ||||||
|    gl.glVertexAttribIPointer(5, //
 |    glVertexAttribIPointer(5, //
 | ||||||
|                           1, |                           1, | ||||||
|                           GL_INT, |                           GL_INT, | ||||||
|                           0, |                           0, | ||||||
|                           static_cast<void*>(0)); |                           static_cast<void*>(0)); | ||||||
|    gl.glEnableVertexAttribArray(5); |    glEnableVertexAttribArray(5); | ||||||
| 
 | 
 | ||||||
|    // aTimeRange
 |    // aTimeRange
 | ||||||
|    gl.glVertexAttribIPointer(6, //
 |    glVertexAttribIPointer(6, //
 | ||||||
|                           2, |                           2, | ||||||
|                           GL_INT, |                           GL_INT, | ||||||
|                           kIntegersPerVertex_ * sizeof(GLint), |                           kIntegersPerVertex_ * sizeof(GLint), | ||||||
|                           reinterpret_cast<void*>(1 * sizeof(GLint))); |                           reinterpret_cast<void*>(1 * sizeof(GLint))); | ||||||
|    gl.glEnableVertexAttribArray(6); |    glEnableVertexAttribArray(6); | ||||||
| 
 | 
 | ||||||
|    // aDisplayed
 |    // aDisplayed
 | ||||||
|    gl.glVertexAttribIPointer(7, |    glVertexAttribIPointer(7, | ||||||
|                           1, |                           1, | ||||||
|                           GL_INT, |                           GL_INT, | ||||||
|                           kIntegersPerVertex_ * sizeof(GLint), |                           kIntegersPerVertex_ * sizeof(GLint), | ||||||
|                           reinterpret_cast<void*>(3 * sizeof(GLint))); |                           reinterpret_cast<void*>(3 * sizeof(GLint))); | ||||||
|    gl.glEnableVertexAttribArray(7); |    glEnableVertexAttribArray(7); | ||||||
| 
 | 
 | ||||||
|    p->dirty_ = true; |    p->dirty_ = true; | ||||||
| } | } | ||||||
|  | @ -283,9 +281,7 @@ void GeoIcons::Render(const QMapLibre::CustomLayerRenderParameters& params, | ||||||
| 
 | 
 | ||||||
|    if (!p->currentIconList_.empty()) |    if (!p->currentIconList_.empty()) | ||||||
|    { |    { | ||||||
|       gl::OpenGLFunctions& gl = p->context_->gl(); |       glBindVertexArray(p->vao_); | ||||||
| 
 |  | ||||||
|       gl.glBindVertexArray(p->vao_); |  | ||||||
| 
 | 
 | ||||||
|       p->Update(textureAtlasChanged); |       p->Update(textureAtlasChanged); | ||||||
|       p->shaderProgram_->Use(); |       p->shaderProgram_->Use(); | ||||||
|  | @ -298,12 +294,12 @@ void GeoIcons::Render(const QMapLibre::CustomLayerRenderParameters& params, | ||||||
|          // If thresholding is enabled, set the map distance
 |          // If thresholding is enabled, set the map distance
 | ||||||
|          units::length::nautical_miles<float> mapDistance = |          units::length::nautical_miles<float> mapDistance = | ||||||
|             util::maplibre::GetMapDistance(params); |             util::maplibre::GetMapDistance(params); | ||||||
|          gl.glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); |          glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); | ||||||
|       } |       } | ||||||
|       else |       else | ||||||
|       { |       { | ||||||
|          // If thresholding is disabled, set the map distance to 0
 |          // If thresholding is disabled, set the map distance to 0
 | ||||||
|          gl.glUniform1f(p->uMapDistanceLocation_, 0.0f); |          glUniform1f(p->uMapDistanceLocation_, 0.0f); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       // Selected time
 |       // Selected time
 | ||||||
|  | @ -311,27 +307,25 @@ void GeoIcons::Render(const QMapLibre::CustomLayerRenderParameters& params, | ||||||
|          (p->selectedTime_ == std::chrono::system_clock::time_point {}) ? |          (p->selectedTime_ == std::chrono::system_clock::time_point {}) ? | ||||||
|             std::chrono::system_clock::now() : |             std::chrono::system_clock::now() : | ||||||
|             p->selectedTime_; |             p->selectedTime_; | ||||||
|       gl.glUniform1i( |       glUniform1i( | ||||||
|          p->uSelectedTimeLocation_, |          p->uSelectedTimeLocation_, | ||||||
|          static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>( |          static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>( | ||||||
|                                selectedTime.time_since_epoch()) |                                selectedTime.time_since_epoch()) | ||||||
|                                .count())); |                                .count())); | ||||||
| 
 | 
 | ||||||
|       // Interpolate texture coordinates
 |       // Interpolate texture coordinates
 | ||||||
|       gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |       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_MAG_FILTER, GL_LINEAR); | ||||||
| 
 | 
 | ||||||
|       // Draw icons
 |       // Draw icons
 | ||||||
|       gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); |       glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||||
|    } |    } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GeoIcons::Deinitialize() | void GeoIcons::Deinitialize() | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); |    glDeleteVertexArrays(1, &p->vao_); | ||||||
| 
 |    glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||||
|    gl.glDeleteVertexArrays(1, &p->vao_); |  | ||||||
|    gl.glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); |  | ||||||
| 
 | 
 | ||||||
|    std::unique_lock lock {p->iconMutex_}; |    std::unique_lock lock {p->iconMutex_}; | ||||||
| 
 | 
 | ||||||
|  | @ -847,8 +841,6 @@ void GeoIcons::Impl::UpdateModifiedIconBuffers() | ||||||
| 
 | 
 | ||||||
| void GeoIcons::Impl::Update(bool textureAtlasChanged) | void GeoIcons::Impl::Update(bool textureAtlasChanged) | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = context_->gl(); |  | ||||||
| 
 |  | ||||||
|    UpdateModifiedIconBuffers(); |    UpdateModifiedIconBuffers(); | ||||||
| 
 | 
 | ||||||
|    // If the texture atlas has changed
 |    // If the texture atlas has changed
 | ||||||
|  | @ -864,8 +856,8 @@ void GeoIcons::Impl::Update(bool textureAtlasChanged) | ||||||
|       UpdateTextureBuffer(); |       UpdateTextureBuffer(); | ||||||
| 
 | 
 | ||||||
|       // Buffer texture data
 |       // Buffer texture data
 | ||||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); |       glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||||
|       gl.glBufferData(GL_ARRAY_BUFFER, |       glBufferData(GL_ARRAY_BUFFER, | ||||||
|                    sizeof(float) * textureBuffer_.size(), |                    sizeof(float) * textureBuffer_.size(), | ||||||
|                    textureBuffer_.data(), |                    textureBuffer_.data(), | ||||||
|                    GL_DYNAMIC_DRAW); |                    GL_DYNAMIC_DRAW); | ||||||
|  | @ -877,15 +869,15 @@ void GeoIcons::Impl::Update(bool textureAtlasChanged) | ||||||
|    if (dirty_) |    if (dirty_) | ||||||
|    { |    { | ||||||
|       // Buffer vertex data
 |       // Buffer vertex data
 | ||||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); |       glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||||
|       gl.glBufferData(GL_ARRAY_BUFFER, |       glBufferData(GL_ARRAY_BUFFER, | ||||||
|                    sizeof(float) * currentIconBuffer_.size(), |                    sizeof(float) * currentIconBuffer_.size(), | ||||||
|                    currentIconBuffer_.data(), |                    currentIconBuffer_.data(), | ||||||
|                    GL_DYNAMIC_DRAW); |                    GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|       // Buffer threshold data
 |       // Buffer threshold data
 | ||||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[2]); |       glBindBuffer(GL_ARRAY_BUFFER, vbo_[2]); | ||||||
|       gl.glBufferData(GL_ARRAY_BUFFER, |       glBufferData(GL_ARRAY_BUFFER, | ||||||
|                    sizeof(GLint) * currentIntegerBuffer_.size(), |                    sizeof(GLint) * currentIntegerBuffer_.size(), | ||||||
|                    currentIntegerBuffer_.data(), |                    currentIntegerBuffer_.data(), | ||||||
|                    GL_DYNAMIC_DRAW); |                    GL_DYNAMIC_DRAW); | ||||||
|  |  | ||||||
|  | @ -130,7 +130,7 @@ public: | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| GeoLines::GeoLines(std::shared_ptr<GlContext> context) : | 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; | GeoLines::~GeoLines() = default; | ||||||
|  | @ -151,8 +151,6 @@ void GeoLines::set_thresholded(bool thresholded) | ||||||
| 
 | 
 | ||||||
| void GeoLines::Initialize() | void GeoLines::Initialize() | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); |  | ||||||
| 
 |  | ||||||
|    p->shaderProgram_ = p->context_->GetShaderProgram( |    p->shaderProgram_ = p->context_->GetShaderProgram( | ||||||
|       {{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"}, |       {{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"}, | ||||||
|        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, |        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, | ||||||
|  | @ -167,78 +165,78 @@ void GeoLines::Initialize() | ||||||
|    p->uSelectedTimeLocation_ = |    p->uSelectedTimeLocation_ = | ||||||
|       p->shaderProgram_->GetUniformLocation("uSelectedTime"); |       p->shaderProgram_->GetUniformLocation("uSelectedTime"); | ||||||
| 
 | 
 | ||||||
|    gl.glGenVertexArrays(1, &p->vao_); |    glGenVertexArrays(1, &p->vao_); | ||||||
|    gl.glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); |    glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||||
| 
 | 
 | ||||||
|    gl.glBindVertexArray(p->vao_); |    glBindVertexArray(p->vao_); | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); |    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||||
|    gl.glBufferData(GL_ARRAY_BUFFER, |    glBufferData(GL_ARRAY_BUFFER, | ||||||
|                 sizeof(float) * kLineBufferLength_, |                 sizeof(float) * kLineBufferLength_, | ||||||
|                 nullptr, |                 nullptr, | ||||||
|                 GL_DYNAMIC_DRAW); |                 GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|    // aLatLong
 |    // aLatLong
 | ||||||
|    gl.glVertexAttribPointer(0, |    glVertexAttribPointer(0, | ||||||
|                          2, |                          2, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          static_cast<void*>(0)); |                          static_cast<void*>(0)); | ||||||
|    gl.glEnableVertexAttribArray(0); |    glEnableVertexAttribArray(0); | ||||||
| 
 | 
 | ||||||
|    // aXYOffset
 |    // aXYOffset
 | ||||||
|    gl.glVertexAttribPointer(1, |    glVertexAttribPointer(1, | ||||||
|                          2, |                          2, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          reinterpret_cast<void*>(2 * sizeof(float))); |                          reinterpret_cast<void*>(2 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(1); |    glEnableVertexAttribArray(1); | ||||||
| 
 | 
 | ||||||
|    // aModulate
 |    // aModulate
 | ||||||
|    gl.glVertexAttribPointer(3, |    glVertexAttribPointer(3, | ||||||
|                          4, |                          4, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          reinterpret_cast<void*>(4 * sizeof(float))); |                          reinterpret_cast<void*>(4 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(3); |    glEnableVertexAttribArray(3); | ||||||
| 
 | 
 | ||||||
|    // aAngle
 |    // aAngle
 | ||||||
|    gl.glVertexAttribPointer(4, |    glVertexAttribPointer(4, | ||||||
|                          1, |                          1, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          reinterpret_cast<void*>(8 * sizeof(float))); |                          reinterpret_cast<void*>(8 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(4); |    glEnableVertexAttribArray(4); | ||||||
| 
 | 
 | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); |    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); |    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|    // aThreshold
 |    // aThreshold
 | ||||||
|    gl.glVertexAttribIPointer(5, //
 |    glVertexAttribIPointer(5, //
 | ||||||
|                           1, |                           1, | ||||||
|                           GL_INT, |                           GL_INT, | ||||||
|                           kIntegersPerVertex_ * sizeof(GLint), |                           kIntegersPerVertex_ * sizeof(GLint), | ||||||
|                           static_cast<void*>(0)); |                           static_cast<void*>(0)); | ||||||
|    gl.glEnableVertexAttribArray(5); |    glEnableVertexAttribArray(5); | ||||||
| 
 | 
 | ||||||
|    // aTimeRange
 |    // aTimeRange
 | ||||||
|    gl.glVertexAttribIPointer(6, //
 |    glVertexAttribIPointer(6, //
 | ||||||
|                           2, |                           2, | ||||||
|                           GL_INT, |                           GL_INT, | ||||||
|                           kIntegersPerVertex_ * sizeof(GLint), |                           kIntegersPerVertex_ * sizeof(GLint), | ||||||
|                           reinterpret_cast<void*>(1 * sizeof(GLint))); |                           reinterpret_cast<void*>(1 * sizeof(GLint))); | ||||||
|    gl.glEnableVertexAttribArray(6); |    glEnableVertexAttribArray(6); | ||||||
| 
 | 
 | ||||||
|    // aDisplayed
 |    // aDisplayed
 | ||||||
|    gl.glVertexAttribIPointer(7, |    glVertexAttribIPointer(7, | ||||||
|                           1, |                           1, | ||||||
|                           GL_INT, |                           GL_INT, | ||||||
|                           kIntegersPerVertex_ * sizeof(GLint), |                           kIntegersPerVertex_ * sizeof(GLint), | ||||||
|                           reinterpret_cast<void*>(3 * sizeof(GLint))); |                           reinterpret_cast<void*>(3 * sizeof(GLint))); | ||||||
|    gl.glEnableVertexAttribArray(7); |    glEnableVertexAttribArray(7); | ||||||
| 
 | 
 | ||||||
|    p->dirty_ = true; |    p->dirty_ = true; | ||||||
| } | } | ||||||
|  | @ -254,9 +252,7 @@ void GeoLines::Render(const QMapLibre::CustomLayerRenderParameters& params) | ||||||
| 
 | 
 | ||||||
|    if (p->newLineList_.size() > 0) |    if (p->newLineList_.size() > 0) | ||||||
|    { |    { | ||||||
|       gl::OpenGLFunctions& gl = p->context_->gl(); |       glBindVertexArray(p->vao_); | ||||||
| 
 |  | ||||||
|       gl.glBindVertexArray(p->vao_); |  | ||||||
| 
 | 
 | ||||||
|       p->Update(); |       p->Update(); | ||||||
|       p->shaderProgram_->Use(); |       p->shaderProgram_->Use(); | ||||||
|  | @ -269,12 +265,12 @@ void GeoLines::Render(const QMapLibre::CustomLayerRenderParameters& params) | ||||||
|          // If thresholding is enabled, set the map distance
 |          // If thresholding is enabled, set the map distance
 | ||||||
|          units::length::nautical_miles<float> mapDistance = |          units::length::nautical_miles<float> mapDistance = | ||||||
|             util::maplibre::GetMapDistance(params); |             util::maplibre::GetMapDistance(params); | ||||||
|          gl.glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); |          glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); | ||||||
|       } |       } | ||||||
|       else |       else | ||||||
|       { |       { | ||||||
|          // If thresholding is disabled, set the map distance to 0
 |          // If thresholding is disabled, set the map distance to 0
 | ||||||
|          gl.glUniform1f(p->uMapDistanceLocation_, 0.0f); |          glUniform1f(p->uMapDistanceLocation_, 0.0f); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       // Selected time
 |       // Selected time
 | ||||||
|  | @ -282,14 +278,14 @@ void GeoLines::Render(const QMapLibre::CustomLayerRenderParameters& params) | ||||||
|          (p->selectedTime_ == std::chrono::system_clock::time_point {}) ? |          (p->selectedTime_ == std::chrono::system_clock::time_point {}) ? | ||||||
|             std::chrono::system_clock::now() : |             std::chrono::system_clock::now() : | ||||||
|             p->selectedTime_; |             p->selectedTime_; | ||||||
|       gl.glUniform1i( |       glUniform1i( | ||||||
|          p->uSelectedTimeLocation_, |          p->uSelectedTimeLocation_, | ||||||
|          static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>( |          static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>( | ||||||
|                                selectedTime.time_since_epoch()) |                                selectedTime.time_since_epoch()) | ||||||
|                                .count())); |                                .count())); | ||||||
| 
 | 
 | ||||||
|       // Draw icons
 |       // Draw icons
 | ||||||
|       gl.glDrawArrays(GL_TRIANGLES, |       glDrawArrays(GL_TRIANGLES, | ||||||
|                    0, |                    0, | ||||||
|                    static_cast<GLsizei>(p->currentLineList_.size() * |                    static_cast<GLsizei>(p->currentLineList_.size() * | ||||||
|                                         kVerticesPerRectangle)); |                                         kVerticesPerRectangle)); | ||||||
|  | @ -298,10 +294,8 @@ void GeoLines::Render(const QMapLibre::CustomLayerRenderParameters& params) | ||||||
| 
 | 
 | ||||||
| void GeoLines::Deinitialize() | void GeoLines::Deinitialize() | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); |    glDeleteVertexArrays(1, &p->vao_); | ||||||
| 
 |    glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||||
|    gl.glDeleteVertexArrays(1, &p->vao_); |  | ||||||
|    gl.glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); |  | ||||||
| 
 | 
 | ||||||
|    std::unique_lock lock {p->lineMutex_}; |    std::unique_lock lock {p->lineMutex_}; | ||||||
| 
 | 
 | ||||||
|  | @ -671,18 +665,16 @@ void GeoLines::Impl::Update() | ||||||
|    // If the lines have been updated
 |    // If the lines have been updated
 | ||||||
|    if (dirty_) |    if (dirty_) | ||||||
|    { |    { | ||||||
|       gl::OpenGLFunctions& gl = context_->gl(); |  | ||||||
| 
 |  | ||||||
|       // Buffer lines data
 |       // Buffer lines data
 | ||||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); |       glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||||
|       gl.glBufferData(GL_ARRAY_BUFFER, |       glBufferData(GL_ARRAY_BUFFER, | ||||||
|                    sizeof(float) * currentLinesBuffer_.size(), |                    sizeof(float) * currentLinesBuffer_.size(), | ||||||
|                    currentLinesBuffer_.data(), |                    currentLinesBuffer_.data(), | ||||||
|                    GL_DYNAMIC_DRAW); |                    GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|       // Buffer threshold data
 |       // Buffer threshold data
 | ||||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); |       glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||||
|       gl.glBufferData(GL_ARRAY_BUFFER, |       glBufferData(GL_ARRAY_BUFFER, | ||||||
|                    sizeof(GLint) * currentIntegerBuffer_.size(), |                    sizeof(GLint) * currentIntegerBuffer_.size(), | ||||||
|                    currentIntegerBuffer_.data(), |                    currentIntegerBuffer_.data(), | ||||||
|                    GL_DYNAMIC_DRAW); |                    GL_DYNAMIC_DRAW); | ||||||
|  |  | ||||||
|  | @ -116,7 +116,7 @@ public: | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Icons::Icons(const std::shared_ptr<GlContext>& context) : | 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; | Icons::~Icons() = default; | ||||||
|  | @ -126,8 +126,6 @@ Icons& Icons::operator=(Icons&&) noexcept = default; | ||||||
| 
 | 
 | ||||||
| void Icons::Initialize() | void Icons::Initialize() | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); |  | ||||||
| 
 |  | ||||||
|    p->shaderProgram_ = p->context_->GetShaderProgram( |    p->shaderProgram_ = p->context_->GetShaderProgram( | ||||||
|       {{GL_VERTEX_SHADER, ":/gl/texture2d_array.vert"}, |       {{GL_VERTEX_SHADER, ":/gl/texture2d_array.vert"}, | ||||||
|        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, |        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, | ||||||
|  | @ -135,69 +133,69 @@ void Icons::Initialize() | ||||||
| 
 | 
 | ||||||
|    p->uMVPMatrixLocation_ = p->shaderProgram_->GetUniformLocation("uMVPMatrix"); |    p->uMVPMatrixLocation_ = p->shaderProgram_->GetUniformLocation("uMVPMatrix"); | ||||||
| 
 | 
 | ||||||
|    gl.glGenVertexArrays(1, &p->vao_); |    glGenVertexArrays(1, &p->vao_); | ||||||
|    gl.glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); |    glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||||
| 
 | 
 | ||||||
|    gl.glBindVertexArray(p->vao_); |    glBindVertexArray(p->vao_); | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); |    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); |    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|    // aVertex
 |    // aVertex
 | ||||||
|    gl.glVertexAttribPointer(0, |    glVertexAttribPointer(0, | ||||||
|                          2, |                          2, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          reinterpret_cast<void*>(0)); |                          reinterpret_cast<void*>(0)); | ||||||
|    gl.glEnableVertexAttribArray(0); |    glEnableVertexAttribArray(0); | ||||||
| 
 | 
 | ||||||
|    // aXYOffset
 |    // aXYOffset
 | ||||||
|    gl.glVertexAttribPointer(1, |    glVertexAttribPointer(1, | ||||||
|                          2, |                          2, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          reinterpret_cast<void*>(2 * sizeof(float))); |                          reinterpret_cast<void*>(2 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(1); |    glEnableVertexAttribArray(1); | ||||||
| 
 | 
 | ||||||
|    // aModulate
 |    // aModulate
 | ||||||
|    gl.glVertexAttribPointer(3, |    glVertexAttribPointer(3, | ||||||
|                          4, |                          4, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          reinterpret_cast<void*>(4 * sizeof(float))); |                          reinterpret_cast<void*>(4 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(3); |    glEnableVertexAttribArray(3); | ||||||
| 
 | 
 | ||||||
|    // aAngle
 |    // aAngle
 | ||||||
|    gl.glVertexAttribPointer(4, |    glVertexAttribPointer(4, | ||||||
|                          1, |                          1, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          reinterpret_cast<void*>(8 * sizeof(float))); |                          reinterpret_cast<void*>(8 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(4); |    glEnableVertexAttribArray(4); | ||||||
| 
 | 
 | ||||||
|    // aDisplayed
 |    // aDisplayed
 | ||||||
|    gl.glVertexAttribPointer(5, |    glVertexAttribPointer(5, | ||||||
|                          1, |                          1, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          reinterpret_cast<void*>(9 * sizeof(float))); |                          reinterpret_cast<void*>(9 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(5); |    glEnableVertexAttribArray(5); | ||||||
| 
 | 
 | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); |    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); |    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|    // aTexCoord
 |    // aTexCoord
 | ||||||
|    gl.glVertexAttribPointer(2, |    glVertexAttribPointer(2, | ||||||
|                          3, |                          3, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerTexCoord * sizeof(float), |                          kPointsPerTexCoord * sizeof(float), | ||||||
|                          static_cast<void*>(0)); |                          static_cast<void*>(0)); | ||||||
|    gl.glEnableVertexAttribArray(2); |    glEnableVertexAttribArray(2); | ||||||
| 
 | 
 | ||||||
|    p->dirty_ = true; |    p->dirty_ = true; | ||||||
| } | } | ||||||
|  | @ -219,29 +217,25 @@ void Icons::Render(const QMapLibre::CustomLayerRenderParameters& params, | ||||||
| 
 | 
 | ||||||
|    if (!p->currentIconList_.empty()) |    if (!p->currentIconList_.empty()) | ||||||
|    { |    { | ||||||
|       gl::OpenGLFunctions& gl = p->context_->gl(); |       glBindVertexArray(p->vao_); | ||||||
| 
 |  | ||||||
|       gl.glBindVertexArray(p->vao_); |  | ||||||
| 
 | 
 | ||||||
|       p->Update(textureAtlasChanged); |       p->Update(textureAtlasChanged); | ||||||
|       p->shaderProgram_->Use(); |       p->shaderProgram_->Use(); | ||||||
|       UseDefaultProjection(params, p->uMVPMatrixLocation_); |       UseDefaultProjection(params, p->uMVPMatrixLocation_); | ||||||
| 
 | 
 | ||||||
|       // Interpolate texture coordinates
 |       // Interpolate texture coordinates
 | ||||||
|       gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |       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_MAG_FILTER, GL_LINEAR); | ||||||
| 
 | 
 | ||||||
|       // Draw icons
 |       // Draw icons
 | ||||||
|       gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); |       glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||||
|    } |    } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Icons::Deinitialize() | void Icons::Deinitialize() | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); |    glDeleteVertexArrays(1, &p->vao_); | ||||||
| 
 |    glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||||
|    gl.glDeleteVertexArrays(1, &p->vao_); |  | ||||||
|    gl.glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); |  | ||||||
| 
 | 
 | ||||||
|    std::unique_lock lock {p->iconMutex_}; |    std::unique_lock lock {p->iconMutex_}; | ||||||
| 
 | 
 | ||||||
|  | @ -679,8 +673,6 @@ void Icons::Impl::UpdateModifiedIconBuffers() | ||||||
| 
 | 
 | ||||||
| void Icons::Impl::Update(bool textureAtlasChanged) | void Icons::Impl::Update(bool textureAtlasChanged) | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = context_->gl(); |  | ||||||
| 
 |  | ||||||
|    UpdateModifiedIconBuffers(); |    UpdateModifiedIconBuffers(); | ||||||
| 
 | 
 | ||||||
|    // If the texture atlas has changed
 |    // If the texture atlas has changed
 | ||||||
|  | @ -696,8 +688,8 @@ void Icons::Impl::Update(bool textureAtlasChanged) | ||||||
|       UpdateTextureBuffer(); |       UpdateTextureBuffer(); | ||||||
| 
 | 
 | ||||||
|       // Buffer texture data
 |       // Buffer texture data
 | ||||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); |       glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||||
|       gl.glBufferData(GL_ARRAY_BUFFER, |       glBufferData(GL_ARRAY_BUFFER, | ||||||
|                    sizeof(float) * textureBuffer_.size(), |                    sizeof(float) * textureBuffer_.size(), | ||||||
|                    textureBuffer_.data(), |                    textureBuffer_.data(), | ||||||
|                    GL_DYNAMIC_DRAW); |                    GL_DYNAMIC_DRAW); | ||||||
|  | @ -709,8 +701,8 @@ void Icons::Impl::Update(bool textureAtlasChanged) | ||||||
|    if (dirty_) |    if (dirty_) | ||||||
|    { |    { | ||||||
|       // Buffer vertex data
 |       // Buffer vertex data
 | ||||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); |       glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||||
|       gl.glBufferData(GL_ARRAY_BUFFER, |       glBufferData(GL_ARRAY_BUFFER, | ||||||
|                    sizeof(float) * currentIconBuffer_.size(), |                    sizeof(float) * currentIconBuffer_.size(), | ||||||
|                    currentIconBuffer_.data(), |                    currentIconBuffer_.data(), | ||||||
|                    GL_DYNAMIC_DRAW); |                    GL_DYNAMIC_DRAW); | ||||||
|  |  | ||||||
|  | @ -79,7 +79,7 @@ public: | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| LinkedVectors::LinkedVectors(std::shared_ptr<GlContext> context) : | 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; | LinkedVectors::~LinkedVectors() = default; | ||||||
|  |  | ||||||
|  | @ -140,7 +140,7 @@ public: | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| PlacefileIcons::PlacefileIcons(const std::shared_ptr<GlContext>& context) : | 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; | PlacefileIcons::~PlacefileIcons() = default; | ||||||
|  | @ -161,12 +161,6 @@ void PlacefileIcons::set_thresholded(bool thresholded) | ||||||
| 
 | 
 | ||||||
| void PlacefileIcons::Initialize() | void PlacefileIcons::Initialize() | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl   = p->context_->gl(); |  | ||||||
| 
 |  | ||||||
| #if !defined(__APPLE__) |  | ||||||
|    auto&                gl30 = p->context_->gl30(); |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
|    p->shaderProgram_ = p->context_->GetShaderProgram( |    p->shaderProgram_ = p->context_->GetShaderProgram( | ||||||
|       {{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"}, |       {{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"}, | ||||||
|        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, |        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, | ||||||
|  | @ -181,86 +175,82 @@ void PlacefileIcons::Initialize() | ||||||
|    p->uSelectedTimeLocation_ = |    p->uSelectedTimeLocation_ = | ||||||
|       p->shaderProgram_->GetUniformLocation("uSelectedTime"); |       p->shaderProgram_->GetUniformLocation("uSelectedTime"); | ||||||
| 
 | 
 | ||||||
|    gl.glGenVertexArrays(1, &p->vao_); |    glGenVertexArrays(1, &p->vao_); | ||||||
|    gl.glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); |    glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||||
| 
 | 
 | ||||||
|    gl.glBindVertexArray(p->vao_); |    glBindVertexArray(p->vao_); | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); |    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); |    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|    // aLatLong
 |    // aLatLong
 | ||||||
|    gl.glVertexAttribPointer(0, |    glVertexAttribPointer(0, | ||||||
|                          2, |                          2, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          static_cast<void*>(0)); |                          static_cast<void*>(0)); | ||||||
|    gl.glEnableVertexAttribArray(0); |    glEnableVertexAttribArray(0); | ||||||
| 
 | 
 | ||||||
|    // aXYOffset
 |    // aXYOffset
 | ||||||
|    gl.glVertexAttribPointer(1, |    glVertexAttribPointer(1, | ||||||
|                          2, |                          2, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          reinterpret_cast<void*>(2 * sizeof(float))); |                          reinterpret_cast<void*>(2 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(1); |    glEnableVertexAttribArray(1); | ||||||
| 
 | 
 | ||||||
|    // aModulate
 |    // aModulate
 | ||||||
|    gl.glVertexAttribPointer(3, |    glVertexAttribPointer(3, | ||||||
|                          4, |                          4, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          reinterpret_cast<void*>(4 * sizeof(float))); |                          reinterpret_cast<void*>(4 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(3); |    glEnableVertexAttribArray(3); | ||||||
| 
 | 
 | ||||||
|    // aAngle
 |    // aAngle
 | ||||||
|    gl.glVertexAttribPointer(4, |    glVertexAttribPointer(4, | ||||||
|                          1, |                          1, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          reinterpret_cast<void*>(8 * sizeof(float))); |                          reinterpret_cast<void*>(8 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(4); |    glEnableVertexAttribArray(4); | ||||||
| 
 | 
 | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); |    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); |    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|    // aTexCoord
 |    // aTexCoord
 | ||||||
|    gl.glVertexAttribPointer(2, |    glVertexAttribPointer(2, | ||||||
|                          3, |                          3, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerTexCoord * sizeof(float), |                          kPointsPerTexCoord * sizeof(float), | ||||||
|                          static_cast<void*>(0)); |                          static_cast<void*>(0)); | ||||||
|    gl.glEnableVertexAttribArray(2); |    glEnableVertexAttribArray(2); | ||||||
| 
 | 
 | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[2]); |    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[2]); | ||||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); |    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|    // aThreshold
 |    // aThreshold
 | ||||||
|    gl.glVertexAttribIPointer(5, //
 |    glVertexAttribIPointer(5, //
 | ||||||
|                           1, |                           1, | ||||||
|                           GL_INT, |                           GL_INT, | ||||||
|                           0, |                           0, | ||||||
|                           static_cast<void*>(0)); |                           static_cast<void*>(0)); | ||||||
|    gl.glEnableVertexAttribArray(5); |    glEnableVertexAttribArray(5); | ||||||
| 
 | 
 | ||||||
|    // aTimeRange
 |    // aTimeRange
 | ||||||
|    gl.glVertexAttribIPointer(6, //
 |    glVertexAttribIPointer(6, //
 | ||||||
|                           2, |                           2, | ||||||
|                           GL_INT, |                           GL_INT, | ||||||
|                           kIntegersPerVertex_ * sizeof(GLint), |                           kIntegersPerVertex_ * sizeof(GLint), | ||||||
|                           reinterpret_cast<void*>(1 * sizeof(GLint))); |                           reinterpret_cast<void*>(1 * sizeof(GLint))); | ||||||
|    gl.glEnableVertexAttribArray(6); |    glEnableVertexAttribArray(6); | ||||||
| 
 | 
 | ||||||
|    // aDisplayed
 |    // aDisplayed
 | ||||||
| #if !defined(__APPLE__) |  | ||||||
|    gl30.glVertexAttribI1i(7, 1); |  | ||||||
| #else |  | ||||||
|    glVertexAttribI1i(7, 1); |    glVertexAttribI1i(7, 1); | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
|    p->dirty_ = true; |    p->dirty_ = true; | ||||||
| } | } | ||||||
|  | @ -273,9 +263,7 @@ void PlacefileIcons::Render( | ||||||
| 
 | 
 | ||||||
|    if (!p->currentIconList_.empty()) |    if (!p->currentIconList_.empty()) | ||||||
|    { |    { | ||||||
|       gl::OpenGLFunctions& gl = p->context_->gl(); |       glBindVertexArray(p->vao_); | ||||||
| 
 |  | ||||||
|       gl.glBindVertexArray(p->vao_); |  | ||||||
| 
 | 
 | ||||||
|       p->Update(textureAtlasChanged); |       p->Update(textureAtlasChanged); | ||||||
|       p->shaderProgram_->Use(); |       p->shaderProgram_->Use(); | ||||||
|  | @ -288,12 +276,12 @@ void PlacefileIcons::Render( | ||||||
|          // If thresholding is enabled, set the map distance
 |          // If thresholding is enabled, set the map distance
 | ||||||
|          units::length::nautical_miles<float> mapDistance = |          units::length::nautical_miles<float> mapDistance = | ||||||
|             util::maplibre::GetMapDistance(params); |             util::maplibre::GetMapDistance(params); | ||||||
|          gl.glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); |          glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); | ||||||
|       } |       } | ||||||
|       else |       else | ||||||
|       { |       { | ||||||
|          // If thresholding is disabled, set the map distance to 0
 |          // If thresholding is disabled, set the map distance to 0
 | ||||||
|          gl.glUniform1f(p->uMapDistanceLocation_, 0.0f); |          glUniform1f(p->uMapDistanceLocation_, 0.0f); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       // Selected time
 |       // Selected time
 | ||||||
|  | @ -301,27 +289,25 @@ void PlacefileIcons::Render( | ||||||
|          (p->selectedTime_ == std::chrono::system_clock::time_point {}) ? |          (p->selectedTime_ == std::chrono::system_clock::time_point {}) ? | ||||||
|             std::chrono::system_clock::now() : |             std::chrono::system_clock::now() : | ||||||
|             p->selectedTime_; |             p->selectedTime_; | ||||||
|       gl.glUniform1i( |       glUniform1i( | ||||||
|          p->uSelectedTimeLocation_, |          p->uSelectedTimeLocation_, | ||||||
|          static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>( |          static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>( | ||||||
|                                selectedTime.time_since_epoch()) |                                selectedTime.time_since_epoch()) | ||||||
|                                .count())); |                                .count())); | ||||||
| 
 | 
 | ||||||
|       // Interpolate texture coordinates
 |       // Interpolate texture coordinates
 | ||||||
|       gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |       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_MAG_FILTER, GL_LINEAR); | ||||||
| 
 | 
 | ||||||
|       // Draw icons
 |       // Draw icons
 | ||||||
|       gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); |       glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||||
|    } |    } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void PlacefileIcons::Deinitialize() | void PlacefileIcons::Deinitialize() | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); |    glDeleteVertexArrays(1, &p->vao_); | ||||||
| 
 |    glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||||
|    gl.glDeleteVertexArrays(1, &p->vao_); |  | ||||||
|    gl.glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); |  | ||||||
| 
 | 
 | ||||||
|    std::unique_lock lock {p->iconMutex_}; |    std::unique_lock lock {p->iconMutex_}; | ||||||
| 
 | 
 | ||||||
|  | @ -649,8 +635,6 @@ void PlacefileIcons::Impl::UpdateTextureBuffer() | ||||||
| 
 | 
 | ||||||
| void PlacefileIcons::Impl::Update(bool textureAtlasChanged) | void PlacefileIcons::Impl::Update(bool textureAtlasChanged) | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = context_->gl(); |  | ||||||
| 
 |  | ||||||
|    // If the texture atlas has changed
 |    // If the texture atlas has changed
 | ||||||
|    if (dirty_ || textureAtlasChanged) |    if (dirty_ || textureAtlasChanged) | ||||||
|    { |    { | ||||||
|  | @ -664,8 +648,8 @@ void PlacefileIcons::Impl::Update(bool textureAtlasChanged) | ||||||
|       UpdateTextureBuffer(); |       UpdateTextureBuffer(); | ||||||
| 
 | 
 | ||||||
|       // Buffer texture data
 |       // Buffer texture data
 | ||||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); |       glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||||
|       gl.glBufferData(GL_ARRAY_BUFFER, |       glBufferData(GL_ARRAY_BUFFER, | ||||||
|                    sizeof(float) * textureBuffer_.size(), |                    sizeof(float) * textureBuffer_.size(), | ||||||
|                    textureBuffer_.data(), |                    textureBuffer_.data(), | ||||||
|                    GL_DYNAMIC_DRAW); |                    GL_DYNAMIC_DRAW); | ||||||
|  | @ -675,15 +659,15 @@ void PlacefileIcons::Impl::Update(bool textureAtlasChanged) | ||||||
|    if (dirty_) |    if (dirty_) | ||||||
|    { |    { | ||||||
|       // Buffer vertex data
 |       // Buffer vertex data
 | ||||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); |       glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||||
|       gl.glBufferData(GL_ARRAY_BUFFER, |       glBufferData(GL_ARRAY_BUFFER, | ||||||
|                    sizeof(float) * currentIconBuffer_.size(), |                    sizeof(float) * currentIconBuffer_.size(), | ||||||
|                    currentIconBuffer_.data(), |                    currentIconBuffer_.data(), | ||||||
|                    GL_DYNAMIC_DRAW); |                    GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|       // Buffer threshold data
 |       // Buffer threshold data
 | ||||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[2]); |       glBindBuffer(GL_ARRAY_BUFFER, vbo_[2]); | ||||||
|       gl.glBufferData(GL_ARRAY_BUFFER, |       glBufferData(GL_ARRAY_BUFFER, | ||||||
|                    sizeof(GLint) * currentIntegerBuffer_.size(), |                    sizeof(GLint) * currentIntegerBuffer_.size(), | ||||||
|                    currentIntegerBuffer_.data(), |                    currentIntegerBuffer_.data(), | ||||||
|                    GL_DYNAMIC_DRAW); |                    GL_DYNAMIC_DRAW); | ||||||
|  |  | ||||||
|  | @ -117,7 +117,7 @@ public: | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| PlacefileImages::PlacefileImages(const std::shared_ptr<GlContext>& context) : | 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; | PlacefileImages::~PlacefileImages() = default; | ||||||
|  | @ -139,12 +139,6 @@ void PlacefileImages::set_thresholded(bool thresholded) | ||||||
| 
 | 
 | ||||||
| void PlacefileImages::Initialize() | void PlacefileImages::Initialize() | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl   = p->context_->gl(); |  | ||||||
| 
 |  | ||||||
| #if !defined(__APPLE__) |  | ||||||
|    auto&                gl30 = p->context_->gl30(); |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
|    p->shaderProgram_ = p->context_->GetShaderProgram( |    p->shaderProgram_ = p->context_->GetShaderProgram( | ||||||
|       {{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"}, |       {{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"}, | ||||||
|        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, |        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, | ||||||
|  | @ -159,77 +153,73 @@ void PlacefileImages::Initialize() | ||||||
|    p->uSelectedTimeLocation_ = |    p->uSelectedTimeLocation_ = | ||||||
|       p->shaderProgram_->GetUniformLocation("uSelectedTime"); |       p->shaderProgram_->GetUniformLocation("uSelectedTime"); | ||||||
| 
 | 
 | ||||||
|    gl.glGenVertexArrays(1, &p->vao_); |    glGenVertexArrays(1, &p->vao_); | ||||||
|    gl.glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); |    glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||||
| 
 | 
 | ||||||
|    gl.glBindVertexArray(p->vao_); |    glBindVertexArray(p->vao_); | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); |    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); |    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|    // aLatLong
 |    // aLatLong
 | ||||||
|    gl.glVertexAttribPointer(0, |    glVertexAttribPointer(0, | ||||||
|                          2, |                          2, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          static_cast<void*>(0)); |                          static_cast<void*>(0)); | ||||||
|    gl.glEnableVertexAttribArray(0); |    glEnableVertexAttribArray(0); | ||||||
| 
 | 
 | ||||||
|    // aXYOffset
 |    // aXYOffset
 | ||||||
|    gl.glVertexAttribPointer(1, |    glVertexAttribPointer(1, | ||||||
|                          2, |                          2, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          reinterpret_cast<void*>(2 * sizeof(float))); |                          reinterpret_cast<void*>(2 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(1); |    glEnableVertexAttribArray(1); | ||||||
| 
 | 
 | ||||||
|    // aModulate
 |    // aModulate
 | ||||||
|    gl.glVertexAttribPointer(3, |    glVertexAttribPointer(3, | ||||||
|                          4, |                          4, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          reinterpret_cast<void*>(4 * sizeof(float))); |                          reinterpret_cast<void*>(4 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(3); |    glEnableVertexAttribArray(3); | ||||||
| 
 | 
 | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); |    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); |    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|    // aTexCoord
 |    // aTexCoord
 | ||||||
|    gl.glVertexAttribPointer(2, |    glVertexAttribPointer(2, | ||||||
|                          3, |                          3, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerTexCoord * sizeof(float), |                          kPointsPerTexCoord * sizeof(float), | ||||||
|                          static_cast<void*>(0)); |                          static_cast<void*>(0)); | ||||||
|    gl.glEnableVertexAttribArray(2); |    glEnableVertexAttribArray(2); | ||||||
| 
 | 
 | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[2]); |    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[2]); | ||||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); |    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|    // aThreshold
 |    // aThreshold
 | ||||||
|    gl.glVertexAttribIPointer(5, //
 |    glVertexAttribIPointer(5, //
 | ||||||
|                           1, |                           1, | ||||||
|                           GL_INT, |                           GL_INT, | ||||||
|                           kIntegersPerVertex_ * sizeof(GLint), |                           kIntegersPerVertex_ * sizeof(GLint), | ||||||
|                           static_cast<void*>(0)); |                           static_cast<void*>(0)); | ||||||
|    gl.glEnableVertexAttribArray(5); |    glEnableVertexAttribArray(5); | ||||||
| 
 | 
 | ||||||
|    // aTimeRange
 |    // aTimeRange
 | ||||||
|    gl.glVertexAttribIPointer(6, //
 |    glVertexAttribIPointer(6, //
 | ||||||
|                           2, |                           2, | ||||||
|                           GL_INT, |                           GL_INT, | ||||||
|                           kIntegersPerVertex_ * sizeof(GLint), |                           kIntegersPerVertex_ * sizeof(GLint), | ||||||
|                           reinterpret_cast<void*>(1 * sizeof(GLint))); |                           reinterpret_cast<void*>(1 * sizeof(GLint))); | ||||||
|    gl.glEnableVertexAttribArray(6); |    glEnableVertexAttribArray(6); | ||||||
| 
 | 
 | ||||||
|    // aDisplayed
 |    // aDisplayed
 | ||||||
| #if !defined(__APPLE__) |  | ||||||
|    gl30.glVertexAttribI1i(7, 1); |  | ||||||
| #else |  | ||||||
|    glVertexAttribI1i(7, 1); |    glVertexAttribI1i(7, 1); | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
|    p->dirty_ = true; |    p->dirty_ = true; | ||||||
| } | } | ||||||
|  | @ -242,9 +232,7 @@ void PlacefileImages::Render( | ||||||
| 
 | 
 | ||||||
|    if (!p->currentImageList_.empty()) |    if (!p->currentImageList_.empty()) | ||||||
|    { |    { | ||||||
|       gl::OpenGLFunctions& gl = p->context_->gl(); |       glBindVertexArray(p->vao_); | ||||||
| 
 |  | ||||||
|       gl.glBindVertexArray(p->vao_); |  | ||||||
| 
 | 
 | ||||||
|       p->Update(textureAtlasChanged); |       p->Update(textureAtlasChanged); | ||||||
|       p->shaderProgram_->Use(); |       p->shaderProgram_->Use(); | ||||||
|  | @ -257,12 +245,12 @@ void PlacefileImages::Render( | ||||||
|          // If thresholding is enabled, set the map distance
 |          // If thresholding is enabled, set the map distance
 | ||||||
|          units::length::nautical_miles<float> mapDistance = |          units::length::nautical_miles<float> mapDistance = | ||||||
|             util::maplibre::GetMapDistance(params); |             util::maplibre::GetMapDistance(params); | ||||||
|          gl.glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); |          glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); | ||||||
|       } |       } | ||||||
|       else |       else | ||||||
|       { |       { | ||||||
|          // If thresholding is disabled, set the map distance to 0
 |          // If thresholding is disabled, set the map distance to 0
 | ||||||
|          gl.glUniform1f(p->uMapDistanceLocation_, 0.0f); |          glUniform1f(p->uMapDistanceLocation_, 0.0f); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       // Selected time
 |       // Selected time
 | ||||||
|  | @ -270,27 +258,25 @@ void PlacefileImages::Render( | ||||||
|          (p->selectedTime_ == std::chrono::system_clock::time_point {}) ? |          (p->selectedTime_ == std::chrono::system_clock::time_point {}) ? | ||||||
|             std::chrono::system_clock::now() : |             std::chrono::system_clock::now() : | ||||||
|             p->selectedTime_; |             p->selectedTime_; | ||||||
|       gl.glUniform1i( |       glUniform1i( | ||||||
|          p->uSelectedTimeLocation_, |          p->uSelectedTimeLocation_, | ||||||
|          static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>( |          static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>( | ||||||
|                                selectedTime.time_since_epoch()) |                                selectedTime.time_since_epoch()) | ||||||
|                                .count())); |                                .count())); | ||||||
| 
 | 
 | ||||||
|       // Interpolate texture coordinates
 |       // Interpolate texture coordinates
 | ||||||
|       gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |       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_MAG_FILTER, GL_LINEAR); | ||||||
| 
 | 
 | ||||||
|       // Draw images
 |       // Draw images
 | ||||||
|       gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); |       glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||||
|    } |    } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void PlacefileImages::Deinitialize() | void PlacefileImages::Deinitialize() | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); |    glDeleteVertexArrays(1, &p->vao_); | ||||||
| 
 |    glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); | ||||||
|    gl.glDeleteVertexArrays(1, &p->vao_); |  | ||||||
|    gl.glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data()); |  | ||||||
| 
 | 
 | ||||||
|    std::unique_lock lock {p->imageMutex_}; |    std::unique_lock lock {p->imageMutex_}; | ||||||
| 
 | 
 | ||||||
|  | @ -446,8 +432,6 @@ void PlacefileImages::Impl::UpdateTextureBuffer() | ||||||
| 
 | 
 | ||||||
| void PlacefileImages::Impl::Update(bool textureAtlasChanged) | void PlacefileImages::Impl::Update(bool textureAtlasChanged) | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = context_->gl(); |  | ||||||
| 
 |  | ||||||
|    // If the texture atlas has changed
 |    // If the texture atlas has changed
 | ||||||
|    if (dirty_ || textureAtlasChanged) |    if (dirty_ || textureAtlasChanged) | ||||||
|    { |    { | ||||||
|  | @ -461,8 +445,8 @@ void PlacefileImages::Impl::Update(bool textureAtlasChanged) | ||||||
|       UpdateTextureBuffer(); |       UpdateTextureBuffer(); | ||||||
| 
 | 
 | ||||||
|       // Buffer texture data
 |       // Buffer texture data
 | ||||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); |       glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||||
|       gl.glBufferData(GL_ARRAY_BUFFER, |       glBufferData(GL_ARRAY_BUFFER, | ||||||
|                    sizeof(float) * textureBuffer_.size(), |                    sizeof(float) * textureBuffer_.size(), | ||||||
|                    textureBuffer_.data(), |                    textureBuffer_.data(), | ||||||
|                    GL_DYNAMIC_DRAW); |                    GL_DYNAMIC_DRAW); | ||||||
|  | @ -472,15 +456,15 @@ void PlacefileImages::Impl::Update(bool textureAtlasChanged) | ||||||
|    if (dirty_) |    if (dirty_) | ||||||
|    { |    { | ||||||
|       // Buffer vertex data
 |       // Buffer vertex data
 | ||||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); |       glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||||
|       gl.glBufferData(GL_ARRAY_BUFFER, |       glBufferData(GL_ARRAY_BUFFER, | ||||||
|                    sizeof(float) * currentImageBuffer_.size(), |                    sizeof(float) * currentImageBuffer_.size(), | ||||||
|                    currentImageBuffer_.data(), |                    currentImageBuffer_.data(), | ||||||
|                    GL_DYNAMIC_DRAW); |                    GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|       // Buffer threshold data
 |       // Buffer threshold data
 | ||||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[2]); |       glBindBuffer(GL_ARRAY_BUFFER, vbo_[2]); | ||||||
|       gl.glBufferData(GL_ARRAY_BUFFER, |       glBufferData(GL_ARRAY_BUFFER, | ||||||
|                    sizeof(GLint) * currentIntegerBuffer_.size(), |                    sizeof(GLint) * currentIntegerBuffer_.size(), | ||||||
|                    currentIntegerBuffer_.data(), |                    currentIntegerBuffer_.data(), | ||||||
|                    GL_DYNAMIC_DRAW); |                    GL_DYNAMIC_DRAW); | ||||||
|  |  | ||||||
|  | @ -106,7 +106,7 @@ public: | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| PlacefileLines::PlacefileLines(const std::shared_ptr<GlContext>& context) : | 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; | PlacefileLines::~PlacefileLines() = default; | ||||||
|  | @ -127,12 +127,6 @@ void PlacefileLines::set_thresholded(bool thresholded) | ||||||
| 
 | 
 | ||||||
| void PlacefileLines::Initialize() | void PlacefileLines::Initialize() | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl   = p->context_->gl(); |  | ||||||
| 
 |  | ||||||
| #if !defined(__APPLE__) |  | ||||||
|    auto&                gl30 = p->context_->gl30(); |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
|    p->shaderProgram_ = p->context_->GetShaderProgram( |    p->shaderProgram_ = p->context_->GetShaderProgram( | ||||||
|       {{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"}, |       {{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"}, | ||||||
|        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, |        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, | ||||||
|  | @ -147,74 +141,70 @@ void PlacefileLines::Initialize() | ||||||
|    p->uSelectedTimeLocation_ = |    p->uSelectedTimeLocation_ = | ||||||
|       p->shaderProgram_->GetUniformLocation("uSelectedTime"); |       p->shaderProgram_->GetUniformLocation("uSelectedTime"); | ||||||
| 
 | 
 | ||||||
|    gl.glGenVertexArrays(1, &p->vao_); |    glGenVertexArrays(1, &p->vao_); | ||||||
|    gl.glGenBuffers(2, p->vbo_.data()); |    glGenBuffers(2, p->vbo_.data()); | ||||||
| 
 | 
 | ||||||
|    gl.glBindVertexArray(p->vao_); |    glBindVertexArray(p->vao_); | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); |    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); |    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|    // aLatLong
 |    // aLatLong
 | ||||||
|    gl.glVertexAttribPointer(0, |    glVertexAttribPointer(0, | ||||||
|                          2, |                          2, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          static_cast<void*>(0)); |                          static_cast<void*>(0)); | ||||||
|    gl.glEnableVertexAttribArray(0); |    glEnableVertexAttribArray(0); | ||||||
| 
 | 
 | ||||||
|    // aXYOffset
 |    // aXYOffset
 | ||||||
|    gl.glVertexAttribPointer(1, |    glVertexAttribPointer(1, | ||||||
|                          2, |                          2, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          reinterpret_cast<void*>(2 * sizeof(float))); |                          reinterpret_cast<void*>(2 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(1); |    glEnableVertexAttribArray(1); | ||||||
| 
 | 
 | ||||||
|    // aModulate
 |    // aModulate
 | ||||||
|    gl.glVertexAttribPointer(3, |    glVertexAttribPointer(3, | ||||||
|                          4, |                          4, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          reinterpret_cast<void*>(4 * sizeof(float))); |                          reinterpret_cast<void*>(4 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(3); |    glEnableVertexAttribArray(3); | ||||||
| 
 | 
 | ||||||
|    // aAngle
 |    // aAngle
 | ||||||
|    gl.glVertexAttribPointer(4, |    glVertexAttribPointer(4, | ||||||
|                          1, |                          1, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          reinterpret_cast<void*>(8 * sizeof(float))); |                          reinterpret_cast<void*>(8 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(4); |    glEnableVertexAttribArray(4); | ||||||
| 
 | 
 | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); |    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); |    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|    // aThreshold
 |    // aThreshold
 | ||||||
|    gl.glVertexAttribIPointer(5, //
 |    glVertexAttribIPointer(5, //
 | ||||||
|                           1, |                           1, | ||||||
|                           GL_INT, |                           GL_INT, | ||||||
|                           kIntegersPerVertex_ * sizeof(GLint), |                           kIntegersPerVertex_ * sizeof(GLint), | ||||||
|                           static_cast<void*>(0)); |                           static_cast<void*>(0)); | ||||||
|    gl.glEnableVertexAttribArray(5); |    glEnableVertexAttribArray(5); | ||||||
| 
 | 
 | ||||||
|    // aTimeRange
 |    // aTimeRange
 | ||||||
|    gl.glVertexAttribIPointer(6, //
 |    glVertexAttribIPointer(6, //
 | ||||||
|                           2, |                           2, | ||||||
|                           GL_INT, |                           GL_INT, | ||||||
|                           kIntegersPerVertex_ * sizeof(GLint), |                           kIntegersPerVertex_ * sizeof(GLint), | ||||||
|                           reinterpret_cast<void*>(1 * sizeof(GLint))); |                           reinterpret_cast<void*>(1 * sizeof(GLint))); | ||||||
|    gl.glEnableVertexAttribArray(6); |    glEnableVertexAttribArray(6); | ||||||
| 
 | 
 | ||||||
|    // aDisplayed
 |    // aDisplayed
 | ||||||
| #if !defined(__APPLE__) |  | ||||||
|    gl30.glVertexAttribI1i(7, 1); |  | ||||||
| #else |  | ||||||
|    glVertexAttribI1i(7, 1); |    glVertexAttribI1i(7, 1); | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
|    p->dirty_ = true; |    p->dirty_ = true; | ||||||
| } | } | ||||||
|  | @ -226,9 +216,7 @@ void PlacefileLines::Render( | ||||||
| 
 | 
 | ||||||
|    if (p->currentNumLines_ > 0) |    if (p->currentNumLines_ > 0) | ||||||
|    { |    { | ||||||
|       gl::OpenGLFunctions& gl = p->context_->gl(); |       glBindVertexArray(p->vao_); | ||||||
| 
 |  | ||||||
|       gl.glBindVertexArray(p->vao_); |  | ||||||
| 
 | 
 | ||||||
|       p->Update(); |       p->Update(); | ||||||
|       p->shaderProgram_->Use(); |       p->shaderProgram_->Use(); | ||||||
|  | @ -241,12 +229,12 @@ void PlacefileLines::Render( | ||||||
|          // If thresholding is enabled, set the map distance
 |          // If thresholding is enabled, set the map distance
 | ||||||
|          units::length::nautical_miles<float> mapDistance = |          units::length::nautical_miles<float> mapDistance = | ||||||
|             util::maplibre::GetMapDistance(params); |             util::maplibre::GetMapDistance(params); | ||||||
|          gl.glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); |          glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); | ||||||
|       } |       } | ||||||
|       else |       else | ||||||
|       { |       { | ||||||
|          // If thresholding is disabled, set the map distance to 0
 |          // If thresholding is disabled, set the map distance to 0
 | ||||||
|          gl.glUniform1f(p->uMapDistanceLocation_, 0.0f); |          glUniform1f(p->uMapDistanceLocation_, 0.0f); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       // Selected time
 |       // Selected time
 | ||||||
|  | @ -254,23 +242,21 @@ void PlacefileLines::Render( | ||||||
|          (p->selectedTime_ == std::chrono::system_clock::time_point {}) ? |          (p->selectedTime_ == std::chrono::system_clock::time_point {}) ? | ||||||
|             std::chrono::system_clock::now() : |             std::chrono::system_clock::now() : | ||||||
|             p->selectedTime_; |             p->selectedTime_; | ||||||
|       gl.glUniform1i( |       glUniform1i( | ||||||
|          p->uSelectedTimeLocation_, |          p->uSelectedTimeLocation_, | ||||||
|          static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>( |          static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>( | ||||||
|                                selectedTime.time_since_epoch()) |                                selectedTime.time_since_epoch()) | ||||||
|                                .count())); |                                .count())); | ||||||
| 
 | 
 | ||||||
|       // Draw icons
 |       // Draw icons
 | ||||||
|       gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); |       glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||||
|    } |    } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void PlacefileLines::Deinitialize() | void PlacefileLines::Deinitialize() | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); |    glDeleteVertexArrays(1, &p->vao_); | ||||||
| 
 |    glDeleteBuffers(2, p->vbo_.data()); | ||||||
|    gl.glDeleteVertexArrays(1, &p->vao_); |  | ||||||
|    gl.glDeleteBuffers(2, p->vbo_.data()); |  | ||||||
| 
 | 
 | ||||||
|    std::unique_lock lock {p->lineMutex_}; |    std::unique_lock lock {p->lineMutex_}; | ||||||
| 
 | 
 | ||||||
|  | @ -482,18 +468,16 @@ void PlacefileLines::Impl::Update() | ||||||
|    // If the placefile has been updated
 |    // If the placefile has been updated
 | ||||||
|    if (dirty_) |    if (dirty_) | ||||||
|    { |    { | ||||||
|       gl::OpenGLFunctions& gl = context_->gl(); |  | ||||||
| 
 |  | ||||||
|       // Buffer lines data
 |       // Buffer lines data
 | ||||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); |       glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||||
|       gl.glBufferData(GL_ARRAY_BUFFER, |       glBufferData(GL_ARRAY_BUFFER, | ||||||
|                    sizeof(float) * currentLinesBuffer_.size(), |                    sizeof(float) * currentLinesBuffer_.size(), | ||||||
|                    currentLinesBuffer_.data(), |                    currentLinesBuffer_.data(), | ||||||
|                    GL_DYNAMIC_DRAW); |                    GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|       // Buffer threshold data
 |       // Buffer threshold data
 | ||||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); |       glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||||
|       gl.glBufferData(GL_ARRAY_BUFFER, |       glBufferData(GL_ARRAY_BUFFER, | ||||||
|                    sizeof(GLint) * currentIntegerBuffer_.size(), |                    sizeof(GLint) * currentIntegerBuffer_.size(), | ||||||
|                    currentIntegerBuffer_.data(), |                    currentIntegerBuffer_.data(), | ||||||
|                    GL_DYNAMIC_DRAW); |                    GL_DYNAMIC_DRAW); | ||||||
|  |  | ||||||
|  | @ -130,7 +130,7 @@ public: | ||||||
| 
 | 
 | ||||||
| PlacefilePolygons::PlacefilePolygons( | PlacefilePolygons::PlacefilePolygons( | ||||||
|    const std::shared_ptr<GlContext>& context) : |    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; | PlacefilePolygons::~PlacefilePolygons() = default; | ||||||
|  | @ -152,8 +152,6 @@ void PlacefilePolygons::set_thresholded(bool thresholded) | ||||||
| 
 | 
 | ||||||
| void PlacefilePolygons::Initialize() | void PlacefilePolygons::Initialize() | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); |  | ||||||
| 
 |  | ||||||
|    p->shaderProgram_ = p->context_->GetShaderProgram( |    p->shaderProgram_ = p->context_->GetShaderProgram( | ||||||
|       {{GL_VERTEX_SHADER, ":/gl/map_color.vert"}, |       {{GL_VERTEX_SHADER, ":/gl/map_color.vert"}, | ||||||
|        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, |        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, | ||||||
|  | @ -168,58 +166,58 @@ void PlacefilePolygons::Initialize() | ||||||
|    p->uSelectedTimeLocation_ = |    p->uSelectedTimeLocation_ = | ||||||
|       p->shaderProgram_->GetUniformLocation("uSelectedTime"); |       p->shaderProgram_->GetUniformLocation("uSelectedTime"); | ||||||
| 
 | 
 | ||||||
|    gl.glGenVertexArrays(1, &p->vao_); |    glGenVertexArrays(1, &p->vao_); | ||||||
|    gl.glGenBuffers(2, p->vbo_.data()); |    glGenBuffers(2, p->vbo_.data()); | ||||||
| 
 | 
 | ||||||
|    gl.glBindVertexArray(p->vao_); |    glBindVertexArray(p->vao_); | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); |    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); |    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|    // aScreenCoord
 |    // aScreenCoord
 | ||||||
|    gl.glVertexAttribPointer(0, |    glVertexAttribPointer(0, | ||||||
|                          2, |                          2, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          static_cast<void*>(0)); |                          static_cast<void*>(0)); | ||||||
|    gl.glEnableVertexAttribArray(0); |    glEnableVertexAttribArray(0); | ||||||
| 
 | 
 | ||||||
|    // aXYOffset
 |    // aXYOffset
 | ||||||
|    gl.glVertexAttribPointer(1, |    glVertexAttribPointer(1, | ||||||
|                          2, |                          2, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          reinterpret_cast<void*>(2 * sizeof(float))); |                          reinterpret_cast<void*>(2 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(1); |    glEnableVertexAttribArray(1); | ||||||
| 
 | 
 | ||||||
|    // aColor
 |    // aColor
 | ||||||
|    gl.glVertexAttribPointer(2, |    glVertexAttribPointer(2, | ||||||
|                          4, |                          4, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          reinterpret_cast<void*>(4 * sizeof(float))); |                          reinterpret_cast<void*>(4 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(2); |    glEnableVertexAttribArray(2); | ||||||
| 
 | 
 | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); |    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); |    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|    // aThreshold
 |    // aThreshold
 | ||||||
|    gl.glVertexAttribIPointer(3, //
 |    glVertexAttribIPointer(3, //
 | ||||||
|                           1, |                           1, | ||||||
|                           GL_INT, |                           GL_INT, | ||||||
|                           kIntegersPerVertex_ * sizeof(GLint), |                           kIntegersPerVertex_ * sizeof(GLint), | ||||||
|                           static_cast<void*>(0)); |                           static_cast<void*>(0)); | ||||||
|    gl.glEnableVertexAttribArray(3); |    glEnableVertexAttribArray(3); | ||||||
| 
 | 
 | ||||||
|    // aTimeRange
 |    // aTimeRange
 | ||||||
|    gl.glVertexAttribIPointer(4, //
 |    glVertexAttribIPointer(4, //
 | ||||||
|                           2, |                           2, | ||||||
|                           GL_INT, |                           GL_INT, | ||||||
|                           kIntegersPerVertex_ * sizeof(GLint), |                           kIntegersPerVertex_ * sizeof(GLint), | ||||||
|                           reinterpret_cast<void*>(1 * sizeof(GLint))); |                           reinterpret_cast<void*>(1 * sizeof(GLint))); | ||||||
|    gl.glEnableVertexAttribArray(4); |    glEnableVertexAttribArray(4); | ||||||
| 
 | 
 | ||||||
|    p->dirty_ = true; |    p->dirty_ = true; | ||||||
| } | } | ||||||
|  | @ -229,9 +227,7 @@ void PlacefilePolygons::Render( | ||||||
| { | { | ||||||
|    if (!p->currentBuffer_.empty()) |    if (!p->currentBuffer_.empty()) | ||||||
|    { |    { | ||||||
|       gl::OpenGLFunctions& gl = p->context_->gl(); |       glBindVertexArray(p->vao_); | ||||||
| 
 |  | ||||||
|       gl.glBindVertexArray(p->vao_); |  | ||||||
| 
 | 
 | ||||||
|       p->Update(); |       p->Update(); | ||||||
|       p->shaderProgram_->Use(); |       p->shaderProgram_->Use(); | ||||||
|  | @ -244,12 +240,12 @@ void PlacefilePolygons::Render( | ||||||
|          // If thresholding is enabled, set the map distance
 |          // If thresholding is enabled, set the map distance
 | ||||||
|          units::length::nautical_miles<float> mapDistance = |          units::length::nautical_miles<float> mapDistance = | ||||||
|             util::maplibre::GetMapDistance(params); |             util::maplibre::GetMapDistance(params); | ||||||
|          gl.glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); |          glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); | ||||||
|       } |       } | ||||||
|       else |       else | ||||||
|       { |       { | ||||||
|          // If thresholding is disabled, set the map distance to 0
 |          // If thresholding is disabled, set the map distance to 0
 | ||||||
|          gl.glUniform1f(p->uMapDistanceLocation_, 0.0f); |          glUniform1f(p->uMapDistanceLocation_, 0.0f); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       // Selected time
 |       // Selected time
 | ||||||
|  | @ -257,23 +253,21 @@ void PlacefilePolygons::Render( | ||||||
|          (p->selectedTime_ == std::chrono::system_clock::time_point {}) ? |          (p->selectedTime_ == std::chrono::system_clock::time_point {}) ? | ||||||
|             std::chrono::system_clock::now() : |             std::chrono::system_clock::now() : | ||||||
|             p->selectedTime_; |             p->selectedTime_; | ||||||
|       gl.glUniform1i( |       glUniform1i( | ||||||
|          p->uSelectedTimeLocation_, |          p->uSelectedTimeLocation_, | ||||||
|          static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>( |          static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>( | ||||||
|                                selectedTime.time_since_epoch()) |                                selectedTime.time_since_epoch()) | ||||||
|                                .count())); |                                .count())); | ||||||
| 
 | 
 | ||||||
|       // Draw icons
 |       // Draw icons
 | ||||||
|       gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); |       glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||||
|    } |    } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void PlacefilePolygons::Deinitialize() | void PlacefilePolygons::Deinitialize() | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); |    glDeleteVertexArrays(1, &p->vao_); | ||||||
| 
 |    glDeleteBuffers(2, p->vbo_.data()); | ||||||
|    gl.glDeleteVertexArrays(1, &p->vao_); |  | ||||||
|    gl.glDeleteBuffers(2, p->vbo_.data()); |  | ||||||
| 
 | 
 | ||||||
|    std::unique_lock lock {p->bufferMutex_}; |    std::unique_lock lock {p->bufferMutex_}; | ||||||
| 
 | 
 | ||||||
|  | @ -318,20 +312,18 @@ void PlacefilePolygons::Impl::Update() | ||||||
| { | { | ||||||
|    if (dirty_) |    if (dirty_) | ||||||
|    { |    { | ||||||
|       gl::OpenGLFunctions& gl = context_->gl(); |  | ||||||
| 
 |  | ||||||
|       std::unique_lock lock {bufferMutex_}; |       std::unique_lock lock {bufferMutex_}; | ||||||
| 
 | 
 | ||||||
|       // Buffer vertex data
 |       // Buffer vertex data
 | ||||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); |       glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||||
|       gl.glBufferData(GL_ARRAY_BUFFER, |       glBufferData(GL_ARRAY_BUFFER, | ||||||
|                    sizeof(GLfloat) * currentBuffer_.size(), |                    sizeof(GLfloat) * currentBuffer_.size(), | ||||||
|                    currentBuffer_.data(), |                    currentBuffer_.data(), | ||||||
|                    GL_DYNAMIC_DRAW); |                    GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|       // Buffer threshold data
 |       // Buffer threshold data
 | ||||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); |       glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||||
|       gl.glBufferData(GL_ARRAY_BUFFER, |       glBufferData(GL_ARRAY_BUFFER, | ||||||
|                    sizeof(GLint) * currentIntegerBuffer_.size(), |                    sizeof(GLint) * currentIntegerBuffer_.size(), | ||||||
|                    currentIntegerBuffer_.data(), |                    currentIntegerBuffer_.data(), | ||||||
|                    GL_DYNAMIC_DRAW); |                    GL_DYNAMIC_DRAW); | ||||||
|  |  | ||||||
|  | @ -72,7 +72,7 @@ public: | ||||||
| 
 | 
 | ||||||
| PlacefileText::PlacefileText(const std::shared_ptr<GlContext>& context, | PlacefileText::PlacefileText(const std::shared_ptr<GlContext>& context, | ||||||
|                              const std::string&                placefileName) : |                              const std::string&                placefileName) : | ||||||
|     DrawItem(context->gl()), p(std::make_unique<Impl>(context, placefileName)) |     DrawItem(), p(std::make_unique<Impl>(context, placefileName)) | ||||||
| { | { | ||||||
| } | } | ||||||
| PlacefileText::~PlacefileText() = default; | PlacefileText::~PlacefileText() = default; | ||||||
|  |  | ||||||
|  | @ -74,7 +74,7 @@ public: | ||||||
| 
 | 
 | ||||||
| PlacefileTriangles::PlacefileTriangles( | PlacefileTriangles::PlacefileTriangles( | ||||||
|    const std::shared_ptr<GlContext>& context) : |    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; | PlacefileTriangles::~PlacefileTriangles() = default; | ||||||
|  | @ -96,8 +96,6 @@ void PlacefileTriangles::set_thresholded(bool thresholded) | ||||||
| 
 | 
 | ||||||
| void PlacefileTriangles::Initialize() | void PlacefileTriangles::Initialize() | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); |  | ||||||
| 
 |  | ||||||
|    p->shaderProgram_ = p->context_->GetShaderProgram( |    p->shaderProgram_ = p->context_->GetShaderProgram( | ||||||
|       {{GL_VERTEX_SHADER, ":/gl/map_color.vert"}, |       {{GL_VERTEX_SHADER, ":/gl/map_color.vert"}, | ||||||
|        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, |        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, | ||||||
|  | @ -112,58 +110,58 @@ void PlacefileTriangles::Initialize() | ||||||
|    p->uSelectedTimeLocation_ = |    p->uSelectedTimeLocation_ = | ||||||
|       p->shaderProgram_->GetUniformLocation("uSelectedTime"); |       p->shaderProgram_->GetUniformLocation("uSelectedTime"); | ||||||
| 
 | 
 | ||||||
|    gl.glGenVertexArrays(1, &p->vao_); |    glGenVertexArrays(1, &p->vao_); | ||||||
|    gl.glGenBuffers(2, p->vbo_.data()); |    glGenBuffers(2, p->vbo_.data()); | ||||||
| 
 | 
 | ||||||
|    gl.glBindVertexArray(p->vao_); |    glBindVertexArray(p->vao_); | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); |    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); |    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|    // aScreenCoord
 |    // aScreenCoord
 | ||||||
|    gl.glVertexAttribPointer(0, |    glVertexAttribPointer(0, | ||||||
|                          2, |                          2, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          static_cast<void*>(0)); |                          static_cast<void*>(0)); | ||||||
|    gl.glEnableVertexAttribArray(0); |    glEnableVertexAttribArray(0); | ||||||
| 
 | 
 | ||||||
|    // aXYOffset
 |    // aXYOffset
 | ||||||
|    gl.glVertexAttribPointer(1, |    glVertexAttribPointer(1, | ||||||
|                          2, |                          2, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          reinterpret_cast<void*>(2 * sizeof(float))); |                          reinterpret_cast<void*>(2 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(1); |    glEnableVertexAttribArray(1); | ||||||
| 
 | 
 | ||||||
|    // aColor
 |    // aColor
 | ||||||
|    gl.glVertexAttribPointer(2, |    glVertexAttribPointer(2, | ||||||
|                          4, |                          4, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          kPointsPerVertex * sizeof(float), |                          kPointsPerVertex * sizeof(float), | ||||||
|                          reinterpret_cast<void*>(4 * sizeof(float))); |                          reinterpret_cast<void*>(4 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(2); |    glEnableVertexAttribArray(2); | ||||||
| 
 | 
 | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); |    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); |    glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|    // aThreshold
 |    // aThreshold
 | ||||||
|    gl.glVertexAttribIPointer(3, //
 |    glVertexAttribIPointer(3, //
 | ||||||
|                           1, |                           1, | ||||||
|                           GL_INT, |                           GL_INT, | ||||||
|                           kIntegersPerVertex_ * sizeof(GLint), |                           kIntegersPerVertex_ * sizeof(GLint), | ||||||
|                           static_cast<void*>(0)); |                           static_cast<void*>(0)); | ||||||
|    gl.glEnableVertexAttribArray(3); |    glEnableVertexAttribArray(3); | ||||||
| 
 | 
 | ||||||
|    // aTimeRange
 |    // aTimeRange
 | ||||||
|    gl.glVertexAttribIPointer(4, //
 |    glVertexAttribIPointer(4, //
 | ||||||
|                           2, |                           2, | ||||||
|                           GL_INT, |                           GL_INT, | ||||||
|                           kIntegersPerVertex_ * sizeof(GLint), |                           kIntegersPerVertex_ * sizeof(GLint), | ||||||
|                           reinterpret_cast<void*>(1 * sizeof(GLint))); |                           reinterpret_cast<void*>(1 * sizeof(GLint))); | ||||||
|    gl.glEnableVertexAttribArray(4); |    glEnableVertexAttribArray(4); | ||||||
| 
 | 
 | ||||||
|    p->dirty_ = true; |    p->dirty_ = true; | ||||||
| } | } | ||||||
|  | @ -173,9 +171,7 @@ void PlacefileTriangles::Render( | ||||||
| { | { | ||||||
|    if (!p->currentBuffer_.empty()) |    if (!p->currentBuffer_.empty()) | ||||||
|    { |    { | ||||||
|       gl::OpenGLFunctions& gl = p->context_->gl(); |       glBindVertexArray(p->vao_); | ||||||
| 
 |  | ||||||
|       gl.glBindVertexArray(p->vao_); |  | ||||||
| 
 | 
 | ||||||
|       p->Update(); |       p->Update(); | ||||||
|       p->shaderProgram_->Use(); |       p->shaderProgram_->Use(); | ||||||
|  | @ -188,12 +184,12 @@ void PlacefileTriangles::Render( | ||||||
|          // If thresholding is enabled, set the map distance
 |          // If thresholding is enabled, set the map distance
 | ||||||
|          units::length::nautical_miles<float> mapDistance = |          units::length::nautical_miles<float> mapDistance = | ||||||
|             util::maplibre::GetMapDistance(params); |             util::maplibre::GetMapDistance(params); | ||||||
|          gl.glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); |          glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); | ||||||
|       } |       } | ||||||
|       else |       else | ||||||
|       { |       { | ||||||
|          // If thresholding is disabled, set the map distance to 0
 |          // If thresholding is disabled, set the map distance to 0
 | ||||||
|          gl.glUniform1f(p->uMapDistanceLocation_, 0.0f); |          glUniform1f(p->uMapDistanceLocation_, 0.0f); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       // Selected time
 |       // Selected time
 | ||||||
|  | @ -201,23 +197,21 @@ void PlacefileTriangles::Render( | ||||||
|          (p->selectedTime_ == std::chrono::system_clock::time_point {}) ? |          (p->selectedTime_ == std::chrono::system_clock::time_point {}) ? | ||||||
|             std::chrono::system_clock::now() : |             std::chrono::system_clock::now() : | ||||||
|             p->selectedTime_; |             p->selectedTime_; | ||||||
|       gl.glUniform1i( |       glUniform1i( | ||||||
|          p->uSelectedTimeLocation_, |          p->uSelectedTimeLocation_, | ||||||
|          static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>( |          static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>( | ||||||
|                                selectedTime.time_since_epoch()) |                                selectedTime.time_since_epoch()) | ||||||
|                                .count())); |                                .count())); | ||||||
| 
 | 
 | ||||||
|       // Draw icons
 |       // Draw icons
 | ||||||
|       gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); |       glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||||
|    } |    } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void PlacefileTriangles::Deinitialize() | void PlacefileTriangles::Deinitialize() | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); |    glDeleteVertexArrays(1, &p->vao_); | ||||||
| 
 |    glDeleteBuffers(2, p->vbo_.data()); | ||||||
|    gl.glDeleteVertexArrays(1, &p->vao_); |  | ||||||
|    gl.glDeleteBuffers(2, p->vbo_.data()); |  | ||||||
| 
 | 
 | ||||||
|    std::unique_lock lock {p->bufferMutex_}; |    std::unique_lock lock {p->bufferMutex_}; | ||||||
| 
 | 
 | ||||||
|  | @ -320,20 +314,18 @@ void PlacefileTriangles::Impl::Update() | ||||||
| { | { | ||||||
|    if (dirty_) |    if (dirty_) | ||||||
|    { |    { | ||||||
|       gl::OpenGLFunctions& gl = context_->gl(); |  | ||||||
| 
 |  | ||||||
|       std::unique_lock lock {bufferMutex_}; |       std::unique_lock lock {bufferMutex_}; | ||||||
| 
 | 
 | ||||||
|       // Buffer vertex data
 |       // Buffer vertex data
 | ||||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); |       glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); | ||||||
|       gl.glBufferData(GL_ARRAY_BUFFER, |       glBufferData(GL_ARRAY_BUFFER, | ||||||
|                    sizeof(GLfloat) * currentBuffer_.size(), |                    sizeof(GLfloat) * currentBuffer_.size(), | ||||||
|                    currentBuffer_.data(), |                    currentBuffer_.data(), | ||||||
|                    GL_DYNAMIC_DRAW); |                    GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|       // Buffer threshold data
 |       // Buffer threshold data
 | ||||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); |       glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]); | ||||||
|       gl.glBufferData(GL_ARRAY_BUFFER, |       glBufferData(GL_ARRAY_BUFFER, | ||||||
|                    sizeof(GLint) * currentIntegerBuffer_.size(), |                    sizeof(GLint) * currentIntegerBuffer_.size(), | ||||||
|                    currentIntegerBuffer_.data(), |                    currentIntegerBuffer_.data(), | ||||||
|                    GL_DYNAMIC_DRAW); |                    GL_DYNAMIC_DRAW); | ||||||
|  |  | ||||||
|  | @ -73,7 +73,7 @@ public: | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Rectangle::Rectangle(std::shared_ptr<GlContext> context) : | 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; | Rectangle::~Rectangle() = default; | ||||||
|  | @ -83,41 +83,39 @@ Rectangle& Rectangle::operator=(Rectangle&&) noexcept = default; | ||||||
| 
 | 
 | ||||||
| void Rectangle::Initialize() | void Rectangle::Initialize() | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); |  | ||||||
| 
 |  | ||||||
|    p->shaderProgram_ = |    p->shaderProgram_ = | ||||||
|       p->context_->GetShaderProgram(":/gl/color.vert", ":/gl/color.frag"); |       p->context_->GetShaderProgram(":/gl/color.vert", ":/gl/color.frag"); | ||||||
| 
 | 
 | ||||||
|    p->uMVPMatrixLocation_ = |    p->uMVPMatrixLocation_ = | ||||||
|       gl.glGetUniformLocation(p->shaderProgram_->id(), "uMVPMatrix"); |       glGetUniformLocation(p->shaderProgram_->id(), "uMVPMatrix"); | ||||||
|    if (p->uMVPMatrixLocation_ == -1) |    if (p->uMVPMatrixLocation_ == -1) | ||||||
|    { |    { | ||||||
|       logger_->warn("Could not find uMVPMatrix"); |       logger_->warn("Could not find uMVPMatrix"); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    gl.glGenVertexArrays(1, &p->vao_); |    glGenVertexArrays(1, &p->vao_); | ||||||
|    gl.glGenBuffers(1, &p->vbo_); |    glGenBuffers(1, &p->vbo_); | ||||||
| 
 | 
 | ||||||
|    gl.glBindVertexArray(p->vao_); |    glBindVertexArray(p->vao_); | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_); |    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_); | ||||||
|    gl.glBufferData( |    glBufferData( | ||||||
|       GL_ARRAY_BUFFER, sizeof(float) * BUFFER_LENGTH, nullptr, GL_DYNAMIC_DRAW); |       GL_ARRAY_BUFFER, sizeof(float) * BUFFER_LENGTH, nullptr, GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|    gl.glVertexAttribPointer(0, |    glVertexAttribPointer(0, | ||||||
|                          3, |                          3, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          POINTS_PER_VERTEX * sizeof(float), |                          POINTS_PER_VERTEX * sizeof(float), | ||||||
|                          static_cast<void*>(0)); |                          static_cast<void*>(0)); | ||||||
|    gl.glEnableVertexAttribArray(0); |    glEnableVertexAttribArray(0); | ||||||
| 
 | 
 | ||||||
|    gl.glVertexAttribPointer(1, |    glVertexAttribPointer(1, | ||||||
|                          4, |                          4, | ||||||
|                          GL_FLOAT, |                          GL_FLOAT, | ||||||
|                          GL_FALSE, |                          GL_FALSE, | ||||||
|                          POINTS_PER_VERTEX * sizeof(float), |                          POINTS_PER_VERTEX * sizeof(float), | ||||||
|                          reinterpret_cast<void*>(3 * sizeof(float))); |                          reinterpret_cast<void*>(3 * sizeof(float))); | ||||||
|    gl.glEnableVertexAttribArray(1); |    glEnableVertexAttribArray(1); | ||||||
| 
 | 
 | ||||||
|    p->dirty_ = true; |    p->dirty_ = true; | ||||||
| } | } | ||||||
|  | @ -126,10 +124,8 @@ void Rectangle::Render(const QMapLibre::CustomLayerRenderParameters& params) | ||||||
| { | { | ||||||
|    if (p->visible_) |    if (p->visible_) | ||||||
|    { |    { | ||||||
|       gl::OpenGLFunctions& gl = p->context_->gl(); |       glBindVertexArray(p->vao_); | ||||||
| 
 |       glBindBuffer(GL_ARRAY_BUFFER, p->vbo_); | ||||||
|       gl.glBindVertexArray(p->vao_); |  | ||||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_); |  | ||||||
| 
 | 
 | ||||||
|       p->Update(); |       p->Update(); | ||||||
|       p->shaderProgram_->Use(); |       p->shaderProgram_->Use(); | ||||||
|  | @ -138,23 +134,21 @@ void Rectangle::Render(const QMapLibre::CustomLayerRenderParameters& params) | ||||||
|       if (p->fillColor_.has_value()) |       if (p->fillColor_.has_value()) | ||||||
|       { |       { | ||||||
|          // Draw fill
 |          // Draw fill
 | ||||||
|          gl.glDrawArrays(GL_TRIANGLES, 24, 6); |          glDrawArrays(GL_TRIANGLES, 24, 6); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       if (p->borderWidth_ > 0.0f) |       if (p->borderWidth_ > 0.0f) | ||||||
|       { |       { | ||||||
|          // Draw border
 |          // Draw border
 | ||||||
|          gl.glDrawArrays(GL_TRIANGLES, 0, 24); |          glDrawArrays(GL_TRIANGLES, 0, 24); | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Rectangle::Deinitialize() | void Rectangle::Deinitialize() | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); |    glDeleteVertexArrays(1, &p->vao_); | ||||||
| 
 |    glDeleteBuffers(1, &p->vbo_); | ||||||
|    gl.glDeleteVertexArrays(1, &p->vao_); |  | ||||||
|    gl.glDeleteBuffers(1, &p->vbo_); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Rectangle::SetBorder(float width, boost::gil::rgba8_pixel_t color) | void Rectangle::SetBorder(float width, boost::gil::rgba8_pixel_t color) | ||||||
|  | @ -206,8 +200,6 @@ void Rectangle::Impl::Update() | ||||||
| { | { | ||||||
|    if (dirty_) |    if (dirty_) | ||||||
|    { |    { | ||||||
|       gl::OpenGLFunctions& gl = context_->gl(); |  | ||||||
| 
 |  | ||||||
|       const float lox = x_; |       const float lox = x_; | ||||||
|       const float rox = x_ + width_; |       const float rox = x_ + width_; | ||||||
|       const float boy = y_; |       const float boy = y_; | ||||||
|  | @ -289,7 +281,7 @@ void Rectangle::Impl::Update() | ||||||
|              {lox, toy, z_, fc0, fc1, fc2, fc3}  // TL
 |              {lox, toy, z_, fc0, fc1, fc2, fc3}  // TL
 | ||||||
|           }}; |           }}; | ||||||
| 
 | 
 | ||||||
|       gl.glBufferData(GL_ARRAY_BUFFER, |       glBufferData(GL_ARRAY_BUFFER, | ||||||
|                    sizeof(float) * BUFFER_LENGTH, |                    sizeof(float) * BUFFER_LENGTH, | ||||||
|                    buffer, |                    buffer, | ||||||
|                    GL_DYNAMIC_DRAW); |                    GL_DYNAMIC_DRAW); | ||||||
|  |  | ||||||
|  | @ -1,25 +1,12 @@ | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <QOpenGLFunctions_3_3_Core> | #include <GL/glew.h> | ||||||
| 
 | 
 | ||||||
| #define SCWX_GL_CHECK_ERROR()                                                  \ | #define SCWX_GL_CHECK_ERROR()                                                  \ | ||||||
|    {                                                                           \ |    {                                                                           \ | ||||||
|       GLenum err;                                                              \ |       GLenum err;                                                              \ | ||||||
|       while ((err = gl.glGetError()) != GL_NO_ERROR)                           \ |       while ((err = glGetError()) != GL_NO_ERROR)                              \ | ||||||
|       {                                                                        \ |       {                                                                        \ | ||||||
|          logger_->error("GL Error: {}, {}: {}", err, __FILE__, __LINE__);      \ |          logger_->error("GL Error: {}, {}: {}", err, __FILE__, __LINE__);      \ | ||||||
|       }                                                                        \ |       }                                                                        \ | ||||||
|    } |    } | ||||||
| 
 |  | ||||||
| namespace scwx |  | ||||||
| { |  | ||||||
| namespace qt |  | ||||||
| { |  | ||||||
| namespace gl |  | ||||||
| { |  | ||||||
| 
 |  | ||||||
| using OpenGLFunctions = QOpenGLFunctions_3_3_Core; |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| } // namespace qt
 |  | ||||||
| } // namespace scwx
 |  | ||||||
|  |  | ||||||
|  | @ -30,9 +30,6 @@ public: | ||||||
|    static std::size_t |    static std::size_t | ||||||
|    GetShaderKey(std::initializer_list<std::pair<GLenum, std::string>> shaders); |    GetShaderKey(std::initializer_list<std::pair<GLenum, std::string>> shaders); | ||||||
| 
 | 
 | ||||||
|    gl::OpenGLFunctions*  gl_ {nullptr}; |  | ||||||
|    QOpenGLFunctions_3_0* gl30_ {nullptr}; |  | ||||||
| 
 |  | ||||||
|    bool glInitialized_ {false}; |    bool glInitialized_ {false}; | ||||||
| 
 | 
 | ||||||
|    std::unordered_map<std::size_t, std::shared_ptr<gl::ShaderProgram>> |    std::unordered_map<std::size_t, std::shared_ptr<gl::ShaderProgram>> | ||||||
|  | @ -51,18 +48,6 @@ GlContext::~GlContext() = default; | ||||||
| GlContext::GlContext(GlContext&&) noexcept            = default; | GlContext::GlContext(GlContext&&) noexcept            = default; | ||||||
| GlContext& GlContext::operator=(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 | std::uint64_t GlContext::texture_buffer_count() const | ||||||
| { | { | ||||||
|    return p->textureBufferCount_; |    return p->textureBufferCount_; | ||||||
|  | @ -75,26 +60,21 @@ void GlContext::Impl::InitializeGL() | ||||||
|       return; |       return; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    // QOpenGLFunctions objects will not be freed. Since "destruction" takes
 |    GLenum error = glewInit(); | ||||||
|    // place at the end of program execution, it is OK to intentionally leak
 |    if (error != GLEW_OK) | ||||||
|    // these.
 |    { | ||||||
| 
 |       logger_->error("glewInit failed: {}", | ||||||
|    // NOLINTBEGIN(cppcoreguidelines-owning-memory)
 |                      reinterpret_cast<const char*>(glewGetErrorString(error))); | ||||||
|    gl_   = new gl::OpenGLFunctions(); |    } | ||||||
|    gl30_ = new QOpenGLFunctions_3_0(); |  | ||||||
|    // NOLINTEND(cppcoreguidelines-owning-memory)
 |  | ||||||
| 
 |  | ||||||
|    gl_->initializeOpenGLFunctions(); |  | ||||||
|    gl30_->initializeOpenGLFunctions(); |  | ||||||
| 
 | 
 | ||||||
|    logger_->info("OpenGL Version: {}", |    logger_->info("OpenGL Version: {}", | ||||||
|                  reinterpret_cast<const char*>(gl_->glGetString(GL_VERSION))); |                  reinterpret_cast<const char*>(glGetString(GL_VERSION))); | ||||||
|    logger_->info("OpenGL Vendor: {}", |    logger_->info("OpenGL Vendor: {}", | ||||||
|                  reinterpret_cast<const char*>(gl_->glGetString(GL_VENDOR))); |                  reinterpret_cast<const char*>(glGetString(GL_VENDOR))); | ||||||
|    logger_->info("OpenGL Renderer: {}", |    logger_->info("OpenGL Renderer: {}", | ||||||
|                  reinterpret_cast<const char*>(gl_->glGetString(GL_RENDERER))); |                  reinterpret_cast<const char*>(glGetString(GL_RENDERER))); | ||||||
| 
 | 
 | ||||||
|    gl_->glGenTextures(1, &textureAtlas_); |    glGenTextures(1, &textureAtlas_); | ||||||
| 
 | 
 | ||||||
|    glInitialized_ = true; |    glInitialized_ = true; | ||||||
| } | } | ||||||
|  | @ -119,7 +99,7 @@ std::shared_ptr<gl::ShaderProgram> GlContext::GetShaderProgram( | ||||||
| 
 | 
 | ||||||
|    if (it == p->shaderProgramMap_.end()) |    if (it == p->shaderProgramMap_.end()) | ||||||
|    { |    { | ||||||
|       shaderProgram = std::make_shared<gl::ShaderProgram>(*p->gl_); |       shaderProgram = std::make_shared<gl::ShaderProgram>(); | ||||||
|       shaderProgram->Load(shaders); |       shaderProgram->Load(shaders); | ||||||
|       p->shaderProgramMap_[key] = shaderProgram; |       p->shaderProgramMap_[key] = shaderProgram; | ||||||
|    } |    } | ||||||
|  | @ -142,7 +122,7 @@ GLuint GlContext::GetTextureAtlas() | ||||||
|    if (p->textureBufferCount_ != textureAtlas.BuildCount()) |    if (p->textureBufferCount_ != textureAtlas.BuildCount()) | ||||||
|    { |    { | ||||||
|       p->textureBufferCount_ = textureAtlas.BuildCount(); |       p->textureBufferCount_ = textureAtlas.BuildCount(); | ||||||
|       textureAtlas.BufferAtlas(*p->gl_, p->textureAtlas_); |       textureAtlas.BufferAtlas(p->textureAtlas_); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    return p->textureAtlas_; |    return p->textureAtlas_; | ||||||
|  | @ -155,10 +135,8 @@ void GlContext::Initialize() | ||||||
| 
 | 
 | ||||||
| void GlContext::StartFrame() | void GlContext::StartFrame() | ||||||
| { | { | ||||||
|    auto& gl = p->gl_; |    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | ||||||
| 
 |    glClear(GL_COLOR_BUFFER_BIT); | ||||||
|    gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |  | ||||||
|    gl->glClear(GL_COLOR_BUFFER_BIT); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::size_t GlContext::Impl::GetShaderKey( | std::size_t GlContext::Impl::GetShaderKey( | ||||||
|  |  | ||||||
|  | @ -3,8 +3,6 @@ | ||||||
| #include <scwx/qt/gl/gl.hpp> | #include <scwx/qt/gl/gl.hpp> | ||||||
| #include <scwx/qt/gl/shader_program.hpp> | #include <scwx/qt/gl/shader_program.hpp> | ||||||
| 
 | 
 | ||||||
| #include <QOpenGLFunctions_3_0> |  | ||||||
| 
 |  | ||||||
| namespace scwx | namespace scwx | ||||||
| { | { | ||||||
| namespace qt | namespace qt | ||||||
|  | @ -24,12 +22,6 @@ public: | ||||||
|    GlContext(GlContext&&) noexcept; |    GlContext(GlContext&&) noexcept; | ||||||
|    GlContext& operator=(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::uint64_t texture_buffer_count() const; | ||||||
| 
 | 
 | ||||||
|    std::shared_ptr<gl::ShaderProgram> |    std::shared_ptr<gl::ShaderProgram> | ||||||
|  |  | ||||||
|  | @ -2,6 +2,7 @@ | ||||||
| #include <scwx/util/logger.hpp> | #include <scwx/util/logger.hpp> | ||||||
| 
 | 
 | ||||||
| #include <QFile> | #include <QFile> | ||||||
|  | #include <QTextStream> | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx | ||||||
| { | { | ||||||
|  | @ -23,29 +24,24 @@ static const std::unordered_map<GLenum, std::string> kShaderNames_ { | ||||||
| class ShaderProgram::Impl | class ShaderProgram::Impl | ||||||
| { | { | ||||||
| public: | public: | ||||||
|    explicit Impl(OpenGLFunctions& gl) : gl_(gl), id_ {GL_INVALID_INDEX} |    explicit Impl() : id_ {GL_INVALID_INDEX} | ||||||
|    { |    { | ||||||
|       // Create shader program
 |       // Create shader program
 | ||||||
|       id_ = gl_.glCreateProgram(); |       id_ = glCreateProgram(); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    ~Impl() |    ~Impl() | ||||||
|    { |    { | ||||||
|       // Delete shader program
 |       // Delete shader program
 | ||||||
|       gl_.glDeleteProgram(id_); |       glDeleteProgram(id_); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    static std::string ShaderName(GLenum type); |    static std::string ShaderName(GLenum type); | ||||||
| 
 | 
 | ||||||
|    OpenGLFunctions& gl_; |  | ||||||
| 
 |  | ||||||
|    GLuint id_; |    GLuint id_; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| ShaderProgram::ShaderProgram(OpenGLFunctions& gl) : | ShaderProgram::ShaderProgram() : p(std::make_unique<Impl>()) {} | ||||||
|     p(std::make_unique<Impl>(gl)) |  | ||||||
| { |  | ||||||
| } |  | ||||||
| ShaderProgram::~ShaderProgram() = default; | ShaderProgram::~ShaderProgram() = default; | ||||||
| 
 | 
 | ||||||
| ShaderProgram::ShaderProgram(ShaderProgram&&) noexcept            = default; | ShaderProgram::ShaderProgram(ShaderProgram&&) noexcept            = default; | ||||||
|  | @ -58,7 +54,7 @@ GLuint ShaderProgram::id() const | ||||||
| 
 | 
 | ||||||
| GLint ShaderProgram::GetUniformLocation(const std::string& name) | GLint ShaderProgram::GetUniformLocation(const std::string& name) | ||||||
| { | { | ||||||
|    GLint location = p->gl_.glGetUniformLocation(p->id_, name.c_str()); |    GLint location = glGetUniformLocation(p->id_, name.c_str()); | ||||||
|    if (location == -1) |    if (location == -1) | ||||||
|    { |    { | ||||||
|       logger_->warn("Could not find {}", name); |       logger_->warn("Could not find {}", name); | ||||||
|  | @ -88,8 +84,6 @@ bool ShaderProgram::Load( | ||||||
| { | { | ||||||
|    logger_->debug("Load()"); |    logger_->debug("Load()"); | ||||||
| 
 | 
 | ||||||
|    OpenGLFunctions& gl = p->gl_; |  | ||||||
| 
 |  | ||||||
|    GLint   glSuccess; |    GLint   glSuccess; | ||||||
|    bool    success = true; |    bool    success = true; | ||||||
|    char    infoLog[kInfoLogBufSize]; |    char    infoLog[kInfoLogBufSize]; | ||||||
|  | @ -120,16 +114,16 @@ bool ShaderProgram::Load( | ||||||
|       const char* shaderSourceC = shaderSource.c_str(); |       const char* shaderSourceC = shaderSource.c_str(); | ||||||
| 
 | 
 | ||||||
|       // Create a shader
 |       // Create a shader
 | ||||||
|       GLuint shaderId = gl.glCreateShader(shader.first); |       GLuint shaderId = glCreateShader(shader.first); | ||||||
|       shaderIds.push_back(shaderId); |       shaderIds.push_back(shaderId); | ||||||
| 
 | 
 | ||||||
|       // Attach the shader source code and compile the shader
 |       // Attach the shader source code and compile the shader
 | ||||||
|       gl.glShaderSource(shaderId, 1, &shaderSourceC, NULL); |       glShaderSource(shaderId, 1, &shaderSourceC, NULL); | ||||||
|       gl.glCompileShader(shaderId); |       glCompileShader(shaderId); | ||||||
| 
 | 
 | ||||||
|       // Check for errors
 |       // Check for errors
 | ||||||
|       gl.glGetShaderiv(shaderId, GL_COMPILE_STATUS, &glSuccess); |       glGetShaderiv(shaderId, GL_COMPILE_STATUS, &glSuccess); | ||||||
|       gl.glGetShaderInfoLog(shaderId, kInfoLogBufSize, &logLength, infoLog); |       glGetShaderInfoLog(shaderId, kInfoLogBufSize, &logLength, infoLog); | ||||||
|       if (!glSuccess) |       if (!glSuccess) | ||||||
|       { |       { | ||||||
|          logger_->error("Shader compilation failed: {}", infoLog); |          logger_->error("Shader compilation failed: {}", infoLog); | ||||||
|  | @ -146,13 +140,13 @@ bool ShaderProgram::Load( | ||||||
|    { |    { | ||||||
|       for (auto& shaderId : shaderIds) |       for (auto& shaderId : shaderIds) | ||||||
|       { |       { | ||||||
|          gl.glAttachShader(p->id_, shaderId); |          glAttachShader(p->id_, shaderId); | ||||||
|       } |       } | ||||||
|       gl.glLinkProgram(p->id_); |       glLinkProgram(p->id_); | ||||||
| 
 | 
 | ||||||
|       // Check for errors
 |       // Check for errors
 | ||||||
|       gl.glGetProgramiv(p->id_, GL_LINK_STATUS, &glSuccess); |       glGetProgramiv(p->id_, GL_LINK_STATUS, &glSuccess); | ||||||
|       gl.glGetProgramInfoLog(p->id_, kInfoLogBufSize, &logLength, infoLog); |       glGetProgramInfoLog(p->id_, kInfoLogBufSize, &logLength, infoLog); | ||||||
|       if (!glSuccess) |       if (!glSuccess) | ||||||
|       { |       { | ||||||
|          logger_->error("Shader program link failed: {}", infoLog); |          logger_->error("Shader program link failed: {}", infoLog); | ||||||
|  | @ -167,7 +161,7 @@ bool ShaderProgram::Load( | ||||||
|    // Delete shaders
 |    // Delete shaders
 | ||||||
|    for (auto& shaderId : shaderIds) |    for (auto& shaderId : shaderIds) | ||||||
|    { |    { | ||||||
|       gl.glDeleteShader(shaderId); |       glDeleteShader(shaderId); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    return success; |    return success; | ||||||
|  | @ -175,7 +169,7 @@ bool ShaderProgram::Load( | ||||||
| 
 | 
 | ||||||
| void ShaderProgram::Use() const | void ShaderProgram::Use() const | ||||||
| { | { | ||||||
|    p->gl_.glUseProgram(p->id_); |    glUseProgram(p->id_); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace gl
 | } // namespace gl
 | ||||||
|  |  | ||||||
|  | @ -19,7 +19,7 @@ namespace gl | ||||||
| class ShaderProgram | class ShaderProgram | ||||||
| { | { | ||||||
| public: | public: | ||||||
|    explicit ShaderProgram(OpenGLFunctions& gl); |    explicit ShaderProgram(); | ||||||
|    virtual ~ShaderProgram(); |    virtual ~ShaderProgram(); | ||||||
| 
 | 
 | ||||||
|    ShaderProgram(const ShaderProgram&)            = delete; |    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 const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | ||||||
| 
 | 
 | ||||||
| static void ConfigureTheme(const std::vector<std::string>& args); | static void ConfigureTheme(const std::vector<std::string>& args); | ||||||
|  | static void InitializeOpenGL(); | ||||||
| static void OverrideDefaultStyle(const std::vector<std::string>& args); | static void OverrideDefaultStyle(const std::vector<std::string>& args); | ||||||
| static void OverridePlatform(); | static void OverridePlatform(); | ||||||
| 
 | 
 | ||||||
|  | @ -66,17 +67,7 @@ int main(int argc, char* argv[]) | ||||||
|                  scwx::qt::main::kBuildNumber_, |                  scwx::qt::main::kBuildNumber_, | ||||||
|                  scwx::qt::main::kCommitString_); |                  scwx::qt::main::kCommitString_); | ||||||
| 
 | 
 | ||||||
|    QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true); |    InitializeOpenGL(); | ||||||
| 
 |  | ||||||
| #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 |  | ||||||
| 
 | 
 | ||||||
|    QApplication a(argc, argv); |    QApplication a(argc, argv); | ||||||
| 
 | 
 | ||||||
|  | @ -234,6 +225,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 | static void | ||||||
| OverrideDefaultStyle([[maybe_unused]] const std::vector<std::string>& args) | 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, | void AlertLayer::Render(const std::shared_ptr<MapContext>& mapContext, | ||||||
|                         const QMapLibre::CustomLayerRenderParameters& params) |                         const QMapLibre::CustomLayerRenderParameters& params) | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = gl_context()->gl(); |  | ||||||
| 
 |  | ||||||
|    for (auto alertActive : {false, true}) |    for (auto alertActive : {false, true}) | ||||||
|    { |    { | ||||||
|       p->geoLines_.at(alertActive)->set_selected_time(p->selectedTime_); |       p->geoLines_.at(alertActive)->set_selected_time(p->selectedTime_); | ||||||
|  |  | ||||||
|  | @ -55,38 +55,36 @@ void ColorTableLayer::Initialize(const std::shared_ptr<MapContext>& mapContext) | ||||||
| 
 | 
 | ||||||
|    auto glContext = gl_context(); |    auto glContext = gl_context(); | ||||||
| 
 | 
 | ||||||
|    gl::OpenGLFunctions& gl = glContext->gl(); |  | ||||||
| 
 |  | ||||||
|    // Load and configure overlay shader
 |    // Load and configure overlay shader
 | ||||||
|    p->shaderProgram_ = |    p->shaderProgram_ = | ||||||
|       glContext->GetShaderProgram(":/gl/texture1d.vert", ":/gl/texture1d.frag"); |       glContext->GetShaderProgram(":/gl/texture1d.vert", ":/gl/texture1d.frag"); | ||||||
| 
 | 
 | ||||||
|    p->uMVPMatrixLocation_ = |    p->uMVPMatrixLocation_ = | ||||||
|       gl.glGetUniformLocation(p->shaderProgram_->id(), "uMVPMatrix"); |       glGetUniformLocation(p->shaderProgram_->id(), "uMVPMatrix"); | ||||||
|    if (p->uMVPMatrixLocation_ == -1) |    if (p->uMVPMatrixLocation_ == -1) | ||||||
|    { |    { | ||||||
|       logger_->warn("Could not find uMVPMatrix"); |       logger_->warn("Could not find uMVPMatrix"); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    gl.glGenTextures(1, &p->texture_); |    glGenTextures(1, &p->texture_); | ||||||
| 
 | 
 | ||||||
|    p->shaderProgram_->Use(); |    p->shaderProgram_->Use(); | ||||||
| 
 | 
 | ||||||
|    // Generate a vertex array object
 |    // Generate a vertex array object
 | ||||||
|    gl.glGenVertexArrays(1, &p->vao_); |    glGenVertexArrays(1, &p->vao_); | ||||||
| 
 | 
 | ||||||
|    // Generate vertex buffer objects
 |    // Generate vertex buffer objects
 | ||||||
|    gl.glGenBuffers(2, p->vbo_.data()); |    glGenBuffers(2, p->vbo_.data()); | ||||||
| 
 | 
 | ||||||
|    gl.glBindVertexArray(p->vao_); |    glBindVertexArray(p->vao_); | ||||||
| 
 | 
 | ||||||
|    // Bottom panel
 |    // Bottom panel
 | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); |    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||||
|    gl.glBufferData( |    glBufferData( | ||||||
|       GL_ARRAY_BUFFER, sizeof(float) * 6 * 2, nullptr, GL_DYNAMIC_DRAW); |       GL_ARRAY_BUFFER, sizeof(float) * 6 * 2, nullptr, GL_DYNAMIC_DRAW); | ||||||
| 
 | 
 | ||||||
|    gl.glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, static_cast<void*>(0)); |    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, static_cast<void*>(0)); | ||||||
|    gl.glEnableVertexAttribArray(0); |    glEnableVertexAttribArray(0); | ||||||
| 
 | 
 | ||||||
|    // Color table panel texture coordinates
 |    // Color table panel texture coordinates
 | ||||||
|    const float textureCoords[6][1] = {{0.0f}, // TL
 |    const float textureCoords[6][1] = {{0.0f}, // TL
 | ||||||
|  | @ -96,12 +94,12 @@ void ColorTableLayer::Initialize(const std::shared_ptr<MapContext>& mapContext) | ||||||
|                                       {0.0f},  // BL
 |                                       {0.0f},  // BL
 | ||||||
|                                       {1.0f},  // TR
 |                                       {1.0f},  // TR
 | ||||||
|                                       {1.0f}}; // BR
 |                                       {1.0f}}; // BR
 | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); |    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||||
|    gl.glBufferData( |    glBufferData( | ||||||
|       GL_ARRAY_BUFFER, sizeof(textureCoords), textureCoords, GL_STATIC_DRAW); |       GL_ARRAY_BUFFER, sizeof(textureCoords), textureCoords, GL_STATIC_DRAW); | ||||||
| 
 | 
 | ||||||
|    gl.glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, static_cast<void*>(0)); |    glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, static_cast<void*>(0)); | ||||||
|    gl.glEnableVertexAttribArray(1); |    glEnableVertexAttribArray(1); | ||||||
| 
 | 
 | ||||||
|    connect(mapContext->radar_product_view().get(), |    connect(mapContext->radar_product_view().get(), | ||||||
|            &view::RadarProductView::ColorTableLutUpdated, |            &view::RadarProductView::ColorTableLutUpdated, | ||||||
|  | @ -113,7 +111,6 @@ void ColorTableLayer::Render( | ||||||
|    const std::shared_ptr<MapContext>&            mapContext, |    const std::shared_ptr<MapContext>&            mapContext, | ||||||
|    const QMapLibre::CustomLayerRenderParameters& params) |    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()) |    if (radarProductView == nullptr || !radarProductView->IsInitialized()) | ||||||
|  | @ -130,18 +127,18 @@ void ColorTableLayer::Render( | ||||||
|    p->shaderProgram_->Use(); |    p->shaderProgram_->Use(); | ||||||
| 
 | 
 | ||||||
|    // Set OpenGL blend mode for transparency
 |    // 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)); |       p->uMVPMatrixLocation_, 1, GL_FALSE, glm::value_ptr(projection)); | ||||||
| 
 | 
 | ||||||
|    if (p->colorTableNeedsUpdate_) |    if (p->colorTableNeedsUpdate_) | ||||||
|    { |    { | ||||||
|       p->colorTable_ = radarProductView->color_table_lut(); |       p->colorTable_ = radarProductView->color_table_lut(); | ||||||
| 
 | 
 | ||||||
|       gl.glActiveTexture(GL_TEXTURE0); |       glActiveTexture(GL_TEXTURE0); | ||||||
|       gl.glBindTexture(GL_TEXTURE_1D, p->texture_); |       glBindTexture(GL_TEXTURE_1D, p->texture_); | ||||||
|       gl.glTexImage1D(GL_TEXTURE_1D, |       glTexImage1D(GL_TEXTURE_1D, | ||||||
|                    0, |                    0, | ||||||
|                    GL_RGBA, |                    GL_RGBA, | ||||||
|                    (GLsizei) p->colorTable_.size(), |                    (GLsizei) p->colorTable_.size(), | ||||||
|  | @ -149,9 +146,9 @@ void ColorTableLayer::Render( | ||||||
|                    GL_RGBA, |                    GL_RGBA, | ||||||
|                    GL_UNSIGNED_BYTE, |                    GL_UNSIGNED_BYTE, | ||||||
|                    p->colorTable_.data()); |                    p->colorTable_.data()); | ||||||
|       gl.glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |       glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||||||
|       gl.glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |       glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||||||
|       gl.glGenerateMipmap(GL_TEXTURE_1D); |       glGenerateMipmap(GL_TEXTURE_1D); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    if (p->colorTable_.size() > 0 && radarProductView->sweep_time() != |    if (p->colorTable_.size() > 0 && radarProductView->sweep_time() != | ||||||
|  | @ -171,10 +168,10 @@ void ColorTableLayer::Render( | ||||||
|                                     {vertexRX, vertexBY}}; // BR
 |                                     {vertexRX, vertexBY}}; // BR
 | ||||||
| 
 | 
 | ||||||
|       // Draw vertices
 |       // Draw vertices
 | ||||||
|       gl.glBindVertexArray(p->vao_); |       glBindVertexArray(p->vao_); | ||||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); |       glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||||
|       gl.glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); |       glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); | ||||||
|       gl.glDrawArrays(GL_TRIANGLES, 0, 6); |       glDrawArrays(GL_TRIANGLES, 0, 6); | ||||||
| 
 | 
 | ||||||
|       static constexpr int kLeftMargin_   = 0; |       static constexpr int kLeftMargin_   = 0; | ||||||
|       static constexpr int kTopMargin_    = 0; |       static constexpr int kTopMargin_    = 0; | ||||||
|  | @ -196,11 +193,9 @@ void ColorTableLayer::Deinitialize() | ||||||
| { | { | ||||||
|    logger_->debug("Deinitialize()"); |    logger_->debug("Deinitialize()"); | ||||||
| 
 | 
 | ||||||
|    gl::OpenGLFunctions& gl = gl_context()->gl(); |    glDeleteVertexArrays(1, &p->vao_); | ||||||
| 
 |    glDeleteBuffers(2, p->vbo_.data()); | ||||||
|    gl.glDeleteVertexArrays(1, &p->vao_); |    glDeleteTextures(1, &p->texture_); | ||||||
|    gl.glDeleteBuffers(2, p->vbo_.data()); |  | ||||||
|    gl.glDeleteTextures(1, &p->texture_); |  | ||||||
| 
 | 
 | ||||||
|    p->uMVPMatrixLocation_ = GL_INVALID_INDEX; |    p->uMVPMatrixLocation_ = GL_INVALID_INDEX; | ||||||
|    p->vao_                = GL_INVALID_INDEX; |    p->vao_                = GL_INVALID_INDEX; | ||||||
|  |  | ||||||
|  | @ -127,7 +127,6 @@ void DrawLayer::RenderWithoutImGui( | ||||||
| { | { | ||||||
|    auto& glContext = p->glContext_; |    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
 |    // Determine if the texture atlas changed since last render
 | ||||||
|  | @ -137,10 +136,10 @@ void DrawLayer::RenderWithoutImGui( | ||||||
|       newTextureAtlasBuildCount != p->textureAtlasBuildCount_; |       newTextureAtlasBuildCount != p->textureAtlasBuildCount_; | ||||||
| 
 | 
 | ||||||
|    // Set OpenGL blend mode for transparency
 |    // 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); |    glActiveTexture(GL_TEXTURE0); | ||||||
|    gl.glBindTexture(GL_TEXTURE_2D_ARRAY, p->textureAtlas_); |    glBindTexture(GL_TEXTURE_2D_ARRAY, p->textureAtlas_); | ||||||
| 
 | 
 | ||||||
|    for (auto& item : p->drawList_) |    for (auto& item : p->drawList_) | ||||||
|    { |    { | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ | ||||||
| #include <scwx/common/geographic.hpp> | #include <scwx/common/geographic.hpp> | ||||||
| #include <scwx/common/products.hpp> | #include <scwx/common/products.hpp> | ||||||
| #include <scwx/qt/config/radar_site.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/map_types.hpp> | ||||||
| #include <scwx/qt/types/radar_product_record.hpp> | #include <scwx/qt/types/radar_product_record.hpp> | ||||||
| #include <scwx/qt/types/text_event_key.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, | void MarkerLayer::Render(const std::shared_ptr<MapContext>& mapContext, | ||||||
|                          const QMapLibre::CustomLayerRenderParameters& params) |                          const QMapLibre::CustomLayerRenderParameters& params) | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = gl_context()->gl(); |  | ||||||
| 
 |  | ||||||
|    DrawLayer::Render(mapContext, params); |    DrawLayer::Render(mapContext, params); | ||||||
| 
 | 
 | ||||||
|    SCWX_GL_CHECK_ERROR(); |    SCWX_GL_CHECK_ERROR(); | ||||||
|  |  | ||||||
|  | @ -338,7 +338,6 @@ void OverlayLayer::Render(const std::shared_ptr<MapContext>& mapContext, | ||||||
| { | { | ||||||
|    const std::unique_lock lock {p->renderMutex_}; |    const std::unique_lock lock {p->renderMutex_}; | ||||||
| 
 | 
 | ||||||
|    gl::OpenGLFunctions& gl               = gl_context()->gl(); |  | ||||||
|    auto        radarProductView = mapContext->radar_product_view(); |    auto        radarProductView = mapContext->radar_product_view(); | ||||||
|    auto&       settings         = mapContext->settings(); |    auto&       settings         = mapContext->settings(); | ||||||
|    const float pixelRatio       = mapContext->pixel_ratio(); |    const float pixelRatio       = mapContext->pixel_ratio(); | ||||||
|  |  | ||||||
|  | @ -142,8 +142,6 @@ void OverlayProductLayer::Render( | ||||||
|    const std::shared_ptr<MapContext>&            mapContext, |    const std::shared_ptr<MapContext>&            mapContext, | ||||||
|    const QMapLibre::CustomLayerRenderParameters& params) |    const QMapLibre::CustomLayerRenderParameters& params) | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = gl_context()->gl(); |  | ||||||
| 
 |  | ||||||
|    if (p->stiNeedsUpdate_) |    if (p->stiNeedsUpdate_) | ||||||
|    { |    { | ||||||
|       p->UpdateStormTrackingInformation(mapContext); |       p->UpdateStormTrackingInformation(mapContext); | ||||||
|  |  | ||||||
|  | @ -132,8 +132,6 @@ void PlacefileLayer::Render( | ||||||
|    const std::shared_ptr<MapContext>&            mapContext, |    const std::shared_ptr<MapContext>&            mapContext, | ||||||
|    const QMapLibre::CustomLayerRenderParameters& params) |    const QMapLibre::CustomLayerRenderParameters& params) | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = gl_context()->gl(); |  | ||||||
| 
 |  | ||||||
|    std::shared_ptr<manager::PlacefileManager> placefileManager = |    std::shared_ptr<manager::PlacefileManager> placefileManager = | ||||||
|       manager::PlacefileManager::Instance(); |       manager::PlacefileManager::Instance(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -78,42 +78,40 @@ void RadarProductLayer::Initialize( | ||||||
| 
 | 
 | ||||||
|    auto glContext = gl_context(); |    auto glContext = gl_context(); | ||||||
| 
 | 
 | ||||||
|    gl::OpenGLFunctions& gl = glContext->gl(); |  | ||||||
| 
 |  | ||||||
|    // Load and configure radar shader
 |    // Load and configure radar shader
 | ||||||
|    p->shaderProgram_ = |    p->shaderProgram_ = | ||||||
|       glContext->GetShaderProgram(":/gl/radar.vert", ":/gl/radar.frag"); |       glContext->GetShaderProgram(":/gl/radar.vert", ":/gl/radar.frag"); | ||||||
| 
 | 
 | ||||||
|    p->uMVPMatrixLocation_ = |    p->uMVPMatrixLocation_ = | ||||||
|       gl.glGetUniformLocation(p->shaderProgram_->id(), "uMVPMatrix"); |       glGetUniformLocation(p->shaderProgram_->id(), "uMVPMatrix"); | ||||||
|    if (p->uMVPMatrixLocation_ == -1) |    if (p->uMVPMatrixLocation_ == -1) | ||||||
|    { |    { | ||||||
|       logger_->warn("Could not find uMVPMatrix"); |       logger_->warn("Could not find uMVPMatrix"); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    p->uMapScreenCoordLocation_ = |    p->uMapScreenCoordLocation_ = | ||||||
|       gl.glGetUniformLocation(p->shaderProgram_->id(), "uMapScreenCoord"); |       glGetUniformLocation(p->shaderProgram_->id(), "uMapScreenCoord"); | ||||||
|    if (p->uMapScreenCoordLocation_ == -1) |    if (p->uMapScreenCoordLocation_ == -1) | ||||||
|    { |    { | ||||||
|       logger_->warn("Could not find uMapScreenCoord"); |       logger_->warn("Could not find uMapScreenCoord"); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    p->uDataMomentOffsetLocation_ = |    p->uDataMomentOffsetLocation_ = | ||||||
|       gl.glGetUniformLocation(p->shaderProgram_->id(), "uDataMomentOffset"); |       glGetUniformLocation(p->shaderProgram_->id(), "uDataMomentOffset"); | ||||||
|    if (p->uDataMomentOffsetLocation_ == -1) |    if (p->uDataMomentOffsetLocation_ == -1) | ||||||
|    { |    { | ||||||
|       logger_->warn("Could not find uDataMomentOffset"); |       logger_->warn("Could not find uDataMomentOffset"); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    p->uDataMomentScaleLocation_ = |    p->uDataMomentScaleLocation_ = | ||||||
|       gl.glGetUniformLocation(p->shaderProgram_->id(), "uDataMomentScale"); |       glGetUniformLocation(p->shaderProgram_->id(), "uDataMomentScale"); | ||||||
|    if (p->uDataMomentScaleLocation_ == -1) |    if (p->uDataMomentScaleLocation_ == -1) | ||||||
|    { |    { | ||||||
|       logger_->warn("Could not find uDataMomentScale"); |       logger_->warn("Could not find uDataMomentScale"); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    p->uCFPEnabledLocation_ = |    p->uCFPEnabledLocation_ = | ||||||
|       gl.glGetUniformLocation(p->shaderProgram_->id(), "uCFPEnabled"); |       glGetUniformLocation(p->shaderProgram_->id(), "uCFPEnabled"); | ||||||
|    if (p->uCFPEnabledLocation_ == -1) |    if (p->uCFPEnabledLocation_ == -1) | ||||||
|    { |    { | ||||||
|       logger_->warn("Could not find uCFPEnabled"); |       logger_->warn("Could not find uCFPEnabled"); | ||||||
|  | @ -122,22 +120,22 @@ void RadarProductLayer::Initialize( | ||||||
|    p->shaderProgram_->Use(); |    p->shaderProgram_->Use(); | ||||||
| 
 | 
 | ||||||
|    // Generate a vertex array object
 |    // Generate a vertex array object
 | ||||||
|    gl.glGenVertexArrays(1, &p->vao_); |    glGenVertexArrays(1, &p->vao_); | ||||||
| 
 | 
 | ||||||
|    // Generate vertex buffer objects
 |    // Generate vertex buffer objects
 | ||||||
|    gl.glGenBuffers(3, p->vbo_.data()); |    glGenBuffers(3, p->vbo_.data()); | ||||||
| 
 | 
 | ||||||
|    // Update radar sweep
 |    // Update radar sweep
 | ||||||
|    p->sweepNeedsUpdate_ = true; |    p->sweepNeedsUpdate_ = true; | ||||||
|    UpdateSweep(mapContext); |    UpdateSweep(mapContext); | ||||||
| 
 | 
 | ||||||
|    // Create color table
 |    // Create color table
 | ||||||
|    gl.glGenTextures(1, &p->texture_); |    glGenTextures(1, &p->texture_); | ||||||
|    p->colorTableNeedsUpdate_ = true; |    p->colorTableNeedsUpdate_ = true; | ||||||
|    UpdateColorTable(mapContext); |    UpdateColorTable(mapContext); | ||||||
|    gl.glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||||||
|    gl.glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |    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_WRAP_S, GL_CLAMP_TO_EDGE); | ||||||
| 
 | 
 | ||||||
|    auto radarProductView = mapContext->radar_product_view(); |    auto radarProductView = mapContext->radar_product_view(); | ||||||
|    connect(radarProductView.get(), |    connect(radarProductView.get(), | ||||||
|  | @ -153,8 +151,6 @@ void RadarProductLayer::Initialize( | ||||||
| void RadarProductLayer::UpdateSweep( | void RadarProductLayer::UpdateSweep( | ||||||
|    const std::shared_ptr<MapContext>& mapContext) |    const std::shared_ptr<MapContext>& mapContext) | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = gl_context()->gl(); |  | ||||||
| 
 |  | ||||||
|    boost::timer::cpu_timer timer; |    boost::timer::cpu_timer timer; | ||||||
| 
 | 
 | ||||||
|    std::shared_ptr<view::RadarProductView> radarProductView = |    std::shared_ptr<view::RadarProductView> radarProductView = | ||||||
|  | @ -174,20 +170,20 @@ void RadarProductLayer::UpdateSweep( | ||||||
|    const std::vector<float>& vertices = radarProductView->vertices(); |    const std::vector<float>& vertices = radarProductView->vertices(); | ||||||
| 
 | 
 | ||||||
|    // Bind a vertex array object
 |    // Bind a vertex array object
 | ||||||
|    gl.glBindVertexArray(p->vao_); |    glBindVertexArray(p->vao_); | ||||||
| 
 | 
 | ||||||
|    // Buffer vertices
 |    // Buffer vertices
 | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); |    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||||
|    timer.start(); |    timer.start(); | ||||||
|    gl.glBufferData(GL_ARRAY_BUFFER, |    glBufferData(GL_ARRAY_BUFFER, | ||||||
|                 vertices.size() * sizeof(GLfloat), |                 vertices.size() * sizeof(GLfloat), | ||||||
|                 vertices.data(), |                 vertices.data(), | ||||||
|                 GL_STATIC_DRAW); |                 GL_STATIC_DRAW); | ||||||
|    timer.stop(); |    timer.stop(); | ||||||
|    logger_->debug("Vertices buffered in {}", timer.format(6, "%ws")); |    logger_->debug("Vertices buffered in {}", timer.format(6, "%ws")); | ||||||
| 
 | 
 | ||||||
|    gl.glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, static_cast<void*>(0)); |    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, static_cast<void*>(0)); | ||||||
|    gl.glEnableVertexAttribArray(0); |    glEnableVertexAttribArray(0); | ||||||
| 
 | 
 | ||||||
|    // Buffer data moments
 |    // Buffer data moments
 | ||||||
|    const GLvoid* data; |    const GLvoid* data; | ||||||
|  | @ -206,14 +202,14 @@ void RadarProductLayer::UpdateSweep( | ||||||
|       type = GL_UNSIGNED_SHORT; |       type = GL_UNSIGNED_SHORT; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); |    glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||||
|    timer.start(); |    timer.start(); | ||||||
|    gl.glBufferData(GL_ARRAY_BUFFER, dataSize, data, GL_STATIC_DRAW); |    glBufferData(GL_ARRAY_BUFFER, dataSize, data, GL_STATIC_DRAW); | ||||||
|    timer.stop(); |    timer.stop(); | ||||||
|    logger_->debug("Data moments buffered in {}", timer.format(6, "%ws")); |    logger_->debug("Data moments buffered in {}", timer.format(6, "%ws")); | ||||||
| 
 | 
 | ||||||
|    gl.glVertexAttribIPointer(1, 1, type, 0, static_cast<void*>(0)); |    glVertexAttribIPointer(1, 1, type, 0, static_cast<void*>(0)); | ||||||
|    gl.glEnableVertexAttribArray(1); |    glEnableVertexAttribArray(1); | ||||||
| 
 | 
 | ||||||
|    // Buffer CFP data
 |    // Buffer CFP data
 | ||||||
|    const GLvoid* cfpData; |    const GLvoid* cfpData; | ||||||
|  | @ -235,18 +231,18 @@ void RadarProductLayer::UpdateSweep( | ||||||
|          cfpType = GL_UNSIGNED_SHORT; |          cfpType = GL_UNSIGNED_SHORT; | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[2]); |       glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[2]); | ||||||
|       timer.start(); |       timer.start(); | ||||||
|       gl.glBufferData(GL_ARRAY_BUFFER, cfpDataSize, cfpData, GL_STATIC_DRAW); |       glBufferData(GL_ARRAY_BUFFER, cfpDataSize, cfpData, GL_STATIC_DRAW); | ||||||
|       timer.stop(); |       timer.stop(); | ||||||
|       logger_->debug("CFP moments buffered in {}", timer.format(6, "%ws")); |       logger_->debug("CFP moments buffered in {}", timer.format(6, "%ws")); | ||||||
| 
 | 
 | ||||||
|       gl.glVertexAttribIPointer(2, 1, cfpType, 0, static_cast<void*>(0)); |       glVertexAttribIPointer(2, 1, cfpType, 0, static_cast<void*>(0)); | ||||||
|       gl.glEnableVertexAttribArray(2); |       glEnableVertexAttribArray(2); | ||||||
|    } |    } | ||||||
|    else |    else | ||||||
|    { |    { | ||||||
|       gl.glDisableVertexAttribArray(2); |       glDisableVertexAttribArray(2); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    p->numVertices_ = vertices.size() / 2; |    p->numVertices_ = vertices.size() / 2; | ||||||
|  | @ -256,18 +252,17 @@ void RadarProductLayer::Render( | ||||||
|    const std::shared_ptr<MapContext>&            mapContext, |    const std::shared_ptr<MapContext>&            mapContext, | ||||||
|    const QMapLibre::CustomLayerRenderParameters& params) |    const QMapLibre::CustomLayerRenderParameters& params) | ||||||
| { | { | ||||||
|    gl::OpenGLFunctions& gl = gl_context()->gl(); |  | ||||||
| 
 | 
 | ||||||
|    p->shaderProgram_->Use(); |    p->shaderProgram_->Use(); | ||||||
| 
 | 
 | ||||||
|    // Set OpenGL blend mode for transparency
 |    // 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_; |    const bool wireframeEnabled = mapContext->settings().radarWireframeEnabled_; | ||||||
|    if (wireframeEnabled) |    if (wireframeEnabled) | ||||||
|    { |    { | ||||||
|       // Set polygon mode to draw wireframe
 |       // Set polygon mode to draw wireframe
 | ||||||
|       gl.glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); |       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    if (p->colorTableNeedsUpdate_) |    if (p->colorTableNeedsUpdate_) | ||||||
|  | @ -291,28 +286,28 @@ void RadarProductLayer::Render( | ||||||
|                             glm::radians<float>(params.bearing), |                             glm::radians<float>(params.bearing), | ||||||
|                             glm::vec3(0.0f, 0.0f, 1.0f)); |                             glm::vec3(0.0f, 0.0f, 1.0f)); | ||||||
| 
 | 
 | ||||||
|    gl.glUniform2fv(p->uMapScreenCoordLocation_, |    glUniform2fv(p->uMapScreenCoordLocation_, | ||||||
|                 1, |                 1, | ||||||
|                 glm::value_ptr(util::maplibre::LatLongToScreenCoordinate( |                 glm::value_ptr(util::maplibre::LatLongToScreenCoordinate( | ||||||
|                    {params.latitude, params.longitude}))); |                    {params.latitude, params.longitude}))); | ||||||
| 
 | 
 | ||||||
|    gl.glUniformMatrix4fv( |    glUniformMatrix4fv( | ||||||
|       p->uMVPMatrixLocation_, 1, GL_FALSE, glm::value_ptr(uMVPMatrix)); |       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_); |    glUniform1ui(p->uDataMomentOffsetLocation_, p->rangeMin_); | ||||||
|    gl.glUniform1f(p->uDataMomentScaleLocation_, p->scale_); |    glUniform1f(p->uDataMomentScaleLocation_, p->scale_); | ||||||
| 
 | 
 | ||||||
|    gl.glActiveTexture(GL_TEXTURE0); |    glActiveTexture(GL_TEXTURE0); | ||||||
|    gl.glBindTexture(GL_TEXTURE_1D, p->texture_); |    glBindTexture(GL_TEXTURE_1D, p->texture_); | ||||||
|    gl.glBindVertexArray(p->vao_); |    glBindVertexArray(p->vao_); | ||||||
|    gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); |    glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||||
| 
 | 
 | ||||||
|    if (wireframeEnabled) |    if (wireframeEnabled) | ||||||
|    { |    { | ||||||
|       // Restore polygon mode to default
 |       // Restore polygon mode to default
 | ||||||
|       gl.glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); |       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    SCWX_GL_CHECK_ERROR(); |    SCWX_GL_CHECK_ERROR(); | ||||||
|  | @ -322,10 +317,8 @@ void RadarProductLayer::Deinitialize() | ||||||
| { | { | ||||||
|    logger_->debug("Deinitialize()"); |    logger_->debug("Deinitialize()"); | ||||||
| 
 | 
 | ||||||
|    gl::OpenGLFunctions& gl = gl_context()->gl(); |    glDeleteVertexArrays(1, &p->vao_); | ||||||
| 
 |    glDeleteBuffers(3, p->vbo_.data()); | ||||||
|    gl.glDeleteVertexArrays(1, &p->vao_); |  | ||||||
|    gl.glDeleteBuffers(3, p->vbo_.data()); |  | ||||||
| 
 | 
 | ||||||
|    p->uMVPMatrixLocation_        = GL_INVALID_INDEX; |    p->uMVPMatrixLocation_        = GL_INVALID_INDEX; | ||||||
|    p->uMapScreenCoordLocation_   = GL_INVALID_INDEX; |    p->uMapScreenCoordLocation_   = GL_INVALID_INDEX; | ||||||
|  | @ -536,7 +529,6 @@ void RadarProductLayer::UpdateColorTable( | ||||||
| 
 | 
 | ||||||
|    p->colorTableNeedsUpdate_ = false; |    p->colorTableNeedsUpdate_ = false; | ||||||
| 
 | 
 | ||||||
|    gl::OpenGLFunctions&                    gl = gl_context()->gl(); |  | ||||||
|    std::shared_ptr<view::RadarProductView> radarProductView = |    std::shared_ptr<view::RadarProductView> radarProductView = | ||||||
|       mapContext->radar_product_view(); |       mapContext->radar_product_view(); | ||||||
| 
 | 
 | ||||||
|  | @ -547,9 +539,9 @@ void RadarProductLayer::UpdateColorTable( | ||||||
| 
 | 
 | ||||||
|    const float scale = rangeMax - rangeMin; |    const float scale = rangeMax - rangeMin; | ||||||
| 
 | 
 | ||||||
|    gl.glActiveTexture(GL_TEXTURE0); |    glActiveTexture(GL_TEXTURE0); | ||||||
|    gl.glBindTexture(GL_TEXTURE_1D, p->texture_); |    glBindTexture(GL_TEXTURE_1D, p->texture_); | ||||||
|    gl.glTexImage1D(GL_TEXTURE_1D, |    glTexImage1D(GL_TEXTURE_1D, | ||||||
|                 0, |                 0, | ||||||
|                 GL_RGBA, |                 GL_RGBA, | ||||||
|                 (GLsizei) colorTable.size(), |                 (GLsizei) colorTable.size(), | ||||||
|  | @ -557,7 +549,7 @@ void RadarProductLayer::UpdateColorTable( | ||||||
|                 GL_RGBA, |                 GL_RGBA, | ||||||
|                 GL_UNSIGNED_BYTE, |                 GL_UNSIGNED_BYTE, | ||||||
|                 colorTable.data()); |                 colorTable.data()); | ||||||
|    gl.glGenerateMipmap(GL_TEXTURE_1D); |    glGenerateMipmap(GL_TEXTURE_1D); | ||||||
| 
 | 
 | ||||||
|    p->rangeMin_ = rangeMin; |    p->rangeMin_ = rangeMin; | ||||||
|    p->scale_    = scale; |    p->scale_    = scale; | ||||||
|  |  | ||||||
|  | @ -107,8 +107,6 @@ void RadarSiteLayer::Render( | ||||||
|       return; |       return; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    gl::OpenGLFunctions& gl = gl_context()->gl(); |  | ||||||
| 
 |  | ||||||
|    // Update map screen coordinate and scale information
 |    // Update map screen coordinate and scale information
 | ||||||
|    p->mapScreenCoordLocation_ = util::maplibre::LatLongToScreenCoordinate( |    p->mapScreenCoordLocation_ = util::maplibre::LatLongToScreenCoordinate( | ||||||
|       {params.latitude, params.longitude}); |       {params.latitude, params.longitude}); | ||||||
|  |  | ||||||
|  | @ -1,5 +1,4 @@ | ||||||
| #include <scwx/qt/ui/imgui_debug_widget.hpp> | #include <scwx/qt/ui/imgui_debug_widget.hpp> | ||||||
| #include <scwx/qt/gl/gl.hpp> |  | ||||||
| #include <scwx/qt/manager/font_manager.hpp> | #include <scwx/qt/manager/font_manager.hpp> | ||||||
| #include <scwx/qt/model/imgui_context_model.hpp> | #include <scwx/qt/model/imgui_context_model.hpp> | ||||||
| 
 | 
 | ||||||
|  | @ -60,8 +59,6 @@ public: | ||||||
| 
 | 
 | ||||||
|    ImGuiContext* currentContext_; |    ImGuiContext* currentContext_; | ||||||
| 
 | 
 | ||||||
|    gl::OpenGLFunctions gl_; |  | ||||||
| 
 |  | ||||||
|    std::set<ImGuiContext*> renderedSet_ {}; |    std::set<ImGuiContext*> renderedSet_ {}; | ||||||
|    bool                    imGuiRendererInitialized_ {false}; |    bool                    imGuiRendererInitialized_ {false}; | ||||||
|    std::uint64_t           imGuiFontsBuildCount_ {}; |    std::uint64_t           imGuiFontsBuildCount_ {}; | ||||||
|  | @ -106,9 +103,6 @@ void ImGuiDebugWidget::initializeGL() | ||||||
| { | { | ||||||
|    makeCurrent(); |    makeCurrent(); | ||||||
| 
 | 
 | ||||||
|    // Initialize OpenGL Functions
 |  | ||||||
|    p->gl_.initializeOpenGLFunctions(); |  | ||||||
| 
 |  | ||||||
|    // Initialize ImGui OpenGL3 backend
 |    // Initialize ImGui OpenGL3 backend
 | ||||||
|    ImGui::SetCurrentContext(p->context_); |    ImGui::SetCurrentContext(p->context_); | ||||||
|    ImGui_ImplOpenGL3_Init(); |    ImGui_ImplOpenGL3_Init(); | ||||||
|  | @ -119,8 +113,8 @@ void ImGuiDebugWidget::initializeGL() | ||||||
| 
 | 
 | ||||||
| void ImGuiDebugWidget::paintGL() | void ImGuiDebugWidget::paintGL() | ||||||
| { | { | ||||||
|    p->gl_.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | ||||||
|    p->gl_.glClear(GL_COLOR_BUFFER_BIT); |    glClear(GL_COLOR_BUFFER_BIT); | ||||||
| 
 | 
 | ||||||
|    ImGui::SetCurrentContext(p->currentContext_); |    ImGui::SetCurrentContext(p->currentContext_); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,5 +1,7 @@ | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
|  | #include <scwx/qt/gl/gl.hpp> | ||||||
|  | 
 | ||||||
| #include <QOpenGLWidget> | #include <QOpenGLWidget> | ||||||
| 
 | 
 | ||||||
| struct ImGuiContext; | 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")); |    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_); |    std::shared_lock lock(p->atlasMutex_); | ||||||
| 
 | 
 | ||||||
|  | @ -343,16 +343,14 @@ void TextureAtlas::BufferAtlas(gl::OpenGLFunctions& gl, GLuint texture) | ||||||
| 
 | 
 | ||||||
|       lock.unlock(); |       lock.unlock(); | ||||||
| 
 | 
 | ||||||
|       gl.glBindTexture(GL_TEXTURE_2D_ARRAY, texture); |       glBindTexture(GL_TEXTURE_2D_ARRAY, texture); | ||||||
| 
 | 
 | ||||||
|       gl.glTexParameteri( |       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||||||
|          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); | ||||||
|       gl.glTexParameteri( |       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||||||
|          GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||||||
|       gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |  | ||||||
|       gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |  | ||||||
| 
 | 
 | ||||||
|       gl.glTexImage3D(GL_TEXTURE_2D_ARRAY, |       glTexImage3D(GL_TEXTURE_2D_ARRAY, | ||||||
|                    0, |                    0, | ||||||
|                    GL_RGBA, |                    GL_RGBA, | ||||||
|                    static_cast<GLsizei>(width), |                    static_cast<GLsizei>(width), | ||||||
|  |  | ||||||
|  | @ -77,7 +77,7 @@ public: | ||||||
|    std::shared_ptr<boost::gil::rgba8_image_t> CacheTexture( |    std::shared_ptr<boost::gil::rgba8_image_t> CacheTexture( | ||||||
|       const std::string& name, const std::string& path, double scale = 1); |       const std::string& name, const std::string& path, double scale = 1); | ||||||
|    void BuildAtlas(std::size_t width, std::size_t height); |    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); |    TextureAttributes GetTextureAttributes(const std::string& name); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat