mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 09:00:05 +00:00 
			
		
		
		
	Adding color table layer
This commit is contained in:
		
							parent
							
								
									5bbfb1ecd9
								
							
						
					
					
						commit
						1c093d01f4
					
				
					 12 changed files with 324 additions and 25 deletions
				
			
		
							
								
								
									
										191
									
								
								scwx-qt/source/scwx/qt/map/color_table_layer.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								scwx-qt/source/scwx/qt/map/color_table_layer.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,191 @@ | |||
| #include <scwx/qt/map/color_table_layer.hpp> | ||||
| #include <scwx/qt/gl/shader_program.hpp> | ||||
| 
 | ||||
| #include <boost/log/trivial.hpp> | ||||
| #include <glm/glm.hpp> | ||||
| #include <glm/gtc/type_ptr.hpp> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
| { | ||||
| namespace map | ||||
| { | ||||
| 
 | ||||
| static const std::string logPrefix_ = "[scwx::qt::map::color_table_layer] "; | ||||
| 
 | ||||
| class ColorTableLayerImpl | ||||
| { | ||||
| public: | ||||
|    explicit ColorTableLayerImpl( | ||||
|       std::shared_ptr<view::RadarProductView> radarProductView, | ||||
|       gl::OpenGLFunctions&                    gl) : | ||||
|        radarProductView_(radarProductView), | ||||
|        gl_(gl), | ||||
|        shaderProgram_(gl), | ||||
|        uMVPMatrixLocation_(GL_INVALID_INDEX), | ||||
|        vbo_ {GL_INVALID_INDEX}, | ||||
|        vao_ {GL_INVALID_INDEX}, | ||||
|        texture_ {GL_INVALID_INDEX}, | ||||
|        colorTableNeedsUpdate_ {true} | ||||
|    { | ||||
|    } | ||||
|    ~ColorTableLayerImpl() = default; | ||||
| 
 | ||||
|    std::shared_ptr<view::RadarProductView> radarProductView_; | ||||
|    gl::OpenGLFunctions&                    gl_; | ||||
| 
 | ||||
|    gl::ShaderProgram     shaderProgram_; | ||||
|    GLint                 uMVPMatrixLocation_; | ||||
|    std::array<GLuint, 2> vbo_; | ||||
|    GLuint                vao_; | ||||
|    GLuint                texture_; | ||||
| 
 | ||||
|    std::vector<boost::gil::rgba8_pixel_t> colorTable_; | ||||
| 
 | ||||
|    bool colorTableNeedsUpdate_; | ||||
| }; | ||||
| 
 | ||||
| ColorTableLayer::ColorTableLayer( | ||||
|    std::shared_ptr<view::RadarProductView> radarProductView, | ||||
|    gl::OpenGLFunctions&                    gl) : | ||||
|     p(std::make_unique<ColorTableLayerImpl>(radarProductView, gl)) | ||||
| { | ||||
| } | ||||
| ColorTableLayer::~ColorTableLayer() = default; | ||||
| 
 | ||||
| void ColorTableLayer::initialize() | ||||
| { | ||||
|    BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "initialize()"; | ||||
| 
 | ||||
|    gl::OpenGLFunctions& gl = p->gl_; | ||||
| 
 | ||||
|    // Load and configure overlay shader
 | ||||
|    p->shaderProgram_.Load(":/gl/texture1d.vert", ":/gl/texture1d.frag"); | ||||
| 
 | ||||
|    p->uMVPMatrixLocation_ = | ||||
|       gl.glGetUniformLocation(p->shaderProgram_.id(), "uMVPMatrix"); | ||||
|    if (p->uMVPMatrixLocation_ == -1) | ||||
|    { | ||||
|       BOOST_LOG_TRIVIAL(warning) << logPrefix_ << "Could not find uMVPMatrix"; | ||||
|    } | ||||
| 
 | ||||
|    gl.glGenTextures(1, &p->texture_); | ||||
| 
 | ||||
|    p->shaderProgram_.Use(); | ||||
| 
 | ||||
|    // Generate a vertex array object
 | ||||
|    gl.glGenVertexArrays(1, &p->vao_); | ||||
| 
 | ||||
|    // Generate vertex buffer objects
 | ||||
|    gl.glGenBuffers(2, p->vbo_.data()); | ||||
| 
 | ||||
|    gl.glBindVertexArray(p->vao_); | ||||
| 
 | ||||
|    // Bottom panel
 | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|    gl.glBufferData( | ||||
|       GL_ARRAY_BUFFER, sizeof(float) * 6 * 2, nullptr, GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|    gl.glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(0); | ||||
| 
 | ||||
|    // Color table panel texture coordinates
 | ||||
|    const float textureCoords[6][1] = {{0.0f}, // TL
 | ||||
|                                       {0.0f}, // BL
 | ||||
|                                       {1.0f}, // TR
 | ||||
|                                       //
 | ||||
|                                       {0.0f},  // BL
 | ||||
|                                       {1.0f},  // TR
 | ||||
|                                       {1.0f}}; // BR
 | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||
|    gl.glBufferData( | ||||
|       GL_ARRAY_BUFFER, sizeof(textureCoords), textureCoords, GL_STATIC_DRAW); | ||||
| 
 | ||||
|    gl.glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(1); | ||||
| 
 | ||||
|    connect(p->radarProductView_.get(), | ||||
|            &view::RadarProductView::ColorTableUpdated, | ||||
|            this, | ||||
|            [=]() { p->colorTableNeedsUpdate_ = true; }); | ||||
| } | ||||
| 
 | ||||
| void ColorTableLayer::render(const QMapbox::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = p->gl_; | ||||
| 
 | ||||
|    glm::mat4 projection = glm::ortho(0.0f, | ||||
|                                      static_cast<float>(params.width), | ||||
|                                      0.0f, | ||||
|                                      static_cast<float>(params.height)); | ||||
| 
 | ||||
|    p->shaderProgram_.Use(); | ||||
| 
 | ||||
|    gl.glUniformMatrix4fv( | ||||
|       p->uMVPMatrixLocation_, 1, GL_FALSE, glm::value_ptr(projection)); | ||||
| 
 | ||||
|    if (p->colorTableNeedsUpdate_) | ||||
|    { | ||||
|       p->colorTable_ = p->radarProductView_->color_table(); | ||||
| 
 | ||||
|       gl.glActiveTexture(GL_TEXTURE0); | ||||
|       gl.glBindTexture(GL_TEXTURE_1D, p->texture_); | ||||
|       gl.glTexImage1D(GL_TEXTURE_1D, | ||||
|                       0, | ||||
|                       GL_RGBA, | ||||
|                       (GLsizei) p->colorTable_.size(), | ||||
|                       0, | ||||
|                       GL_RGBA, | ||||
|                       GL_UNSIGNED_BYTE, | ||||
|                       p->colorTable_.data()); | ||||
|       gl.glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||||
|       gl.glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||||
|       gl.glGenerateMipmap(GL_TEXTURE_1D); | ||||
|    } | ||||
| 
 | ||||
|    if (p->colorTable_.size() > 0 && p->radarProductView_->sweep_time() != | ||||
|                                        std::chrono::system_clock::time_point()) | ||||
|    { | ||||
|       // Color table panel vertices
 | ||||
|       const float vertexLX       = 0.0f; | ||||
|       const float vertexRX       = static_cast<float>(params.width); | ||||
|       const float vertexTY       = 10.0f; | ||||
|       const float vertexBY       = 0.0f; | ||||
|       const float vertices[6][2] = {{vertexLX, vertexTY}, // TL
 | ||||
|                                     {vertexLX, vertexBY}, // BL
 | ||||
|                                     {vertexRX, vertexTY}, // TR
 | ||||
|                                     //
 | ||||
|                                     {vertexLX, vertexBY},  // BL
 | ||||
|                                     {vertexRX, vertexTY},  // TR
 | ||||
|                                     {vertexRX, vertexBY}}; // BR
 | ||||
| 
 | ||||
|       // Draw vertices
 | ||||
|       gl.glBindVertexArray(p->vao_); | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|       gl.glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); | ||||
|       gl.glDrawArrays(GL_TRIANGLES, 0, 6); | ||||
|    } | ||||
| 
 | ||||
|    SCWX_GL_CHECK_ERROR(); | ||||
| } | ||||
| 
 | ||||
| void ColorTableLayer::deinitialize() | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = p->gl_; | ||||
| 
 | ||||
|    BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "deinitialize()"; | ||||
| 
 | ||||
|    gl.glDeleteVertexArrays(1, &p->vao_); | ||||
|    gl.glDeleteBuffers(2, p->vbo_.data()); | ||||
|    gl.glDeleteTextures(1, &p->texture_); | ||||
| 
 | ||||
|    p->uMVPMatrixLocation_ = GL_INVALID_INDEX; | ||||
|    p->vao_                = GL_INVALID_INDEX; | ||||
|    p->vbo_                = {GL_INVALID_INDEX}; | ||||
|    p->texture_            = GL_INVALID_INDEX; | ||||
| } | ||||
| 
 | ||||
| } // namespace map
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
							
								
								
									
										37
									
								
								scwx-qt/source/scwx/qt/map/color_table_layer.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								scwx-qt/source/scwx/qt/map/color_table_layer.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,37 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <scwx/qt/gl/gl.hpp> | ||||
| #include <scwx/qt/view/radar_product_view.hpp> | ||||
| 
 | ||||
| #include <QMapboxGL> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
| { | ||||
| namespace map | ||||
| { | ||||
| 
 | ||||
| class ColorTableLayerImpl; | ||||
| 
 | ||||
| class ColorTableLayer : public QObject, public QMapbox::CustomLayerHostInterface | ||||
| { | ||||
|    Q_OBJECT | ||||
| 
 | ||||
| public: | ||||
|    explicit ColorTableLayer( | ||||
|       std::shared_ptr<view::RadarProductView> radarProductView, | ||||
|       gl::OpenGLFunctions&                    gl); | ||||
|    ~ColorTableLayer(); | ||||
| 
 | ||||
|    void initialize() override final; | ||||
|    void render(const QMapbox::CustomLayerRenderParameters&) override final; | ||||
|    void deinitialize() override final; | ||||
| 
 | ||||
| private: | ||||
|    std::unique_ptr<ColorTableLayerImpl> p; | ||||
| }; | ||||
| 
 | ||||
| } // namespace map
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
|  | @ -2,6 +2,7 @@ | |||
| #include <scwx/qt/gl/gl.hpp> | ||||
| #include <scwx/qt/manager/radar_product_manager.hpp> | ||||
| #include <scwx/qt/manager/settings_manager.hpp> | ||||
| #include <scwx/qt/map/color_table_layer.hpp> | ||||
| #include <scwx/qt/map/overlay_layer.hpp> | ||||
| #include <scwx/qt/map/radar_product_layer.hpp> | ||||
| #include <scwx/qt/map/radar_range_layer.hpp> | ||||
|  | @ -180,12 +181,18 @@ void MapWidget::AddLayers() | |||
|    { | ||||
|       p->map_->removeLayer("overlay"); | ||||
|    } | ||||
|    if (p->map_->layerExists("colorTable")) | ||||
|    { | ||||
|       p->map_->removeLayer("colorTable"); | ||||
|    } | ||||
| 
 | ||||
|    // QMapboxGL::addCustomLayer will take ownership of the QScopedPointer
 | ||||
|    QScopedPointer<QMapbox::CustomLayerHostInterface> pHost( | ||||
|       new RadarProductLayer(p->radarProductView_, p->gl_)); | ||||
|    QScopedPointer<QMapbox::CustomLayerHostInterface> pOverlayHost( | ||||
|       new OverlayLayer(p->radarProductView_, p->gl_)); | ||||
|    QScopedPointer<QMapbox::CustomLayerHostInterface> pColorTableHost( | ||||
|       new ColorTableLayer(p->radarProductView_, p->gl_)); | ||||
| 
 | ||||
|    QString before = "ferry"; | ||||
| 
 | ||||
|  | @ -203,6 +210,7 @@ void MapWidget::AddLayers() | |||
|    p->map_->addCustomLayer("radar", pHost, before); | ||||
|    RadarRangeLayer::Add(p->map_, p->radarProductView_->range(), before); | ||||
|    p->map_->addCustomLayer("overlay", pOverlayHost); | ||||
|    p->map_->addCustomLayer("colorTable", pColorTableHost); | ||||
| } | ||||
| 
 | ||||
| void MapWidget::keyPressEvent(QKeyEvent* ev) | ||||
|  |  | |||
|  | @ -318,18 +318,16 @@ void RadarProductLayer::UpdateColorTable() | |||
| { | ||||
|    BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "UpdateColorTable()"; | ||||
| 
 | ||||
|    uint16_t rangeMin; | ||||
|    uint16_t rangeMax; | ||||
|    float    scale; | ||||
| 
 | ||||
|    p->colorTableNeedsUpdate_ = false; | ||||
| 
 | ||||
|    gl::OpenGLFunctions& gl = p->gl_; | ||||
| 
 | ||||
|    const std::vector<boost::gil::rgba8_pixel_t>& colorTable = | ||||
|       p->radarProductView_->color_table(rangeMin, rangeMax); | ||||
|       p->radarProductView_->color_table(); | ||||
|    const uint16_t rangeMin = p->radarProductView_->color_table_min(); | ||||
|    const uint16_t rangeMax = p->radarProductView_->color_table_max(); | ||||
| 
 | ||||
|    scale = rangeMax - rangeMin; | ||||
|    const float scale = rangeMax - rangeMin; | ||||
| 
 | ||||
|    gl.glActiveTexture(GL_TEXTURE0); | ||||
|    gl.glBindTexture(GL_TEXTURE_1D, p->texture_); | ||||
|  |  | |||
|  | @ -122,20 +122,42 @@ Level2ProductView::Level2ProductView( | |||
| Level2ProductView::~Level2ProductView() = default; | ||||
| 
 | ||||
| const std::vector<boost::gil::rgba8_pixel_t>& | ||||
| Level2ProductView::color_table(uint16_t& minValue, uint16_t& maxValue) const | ||||
| Level2ProductView::color_table() const | ||||
| { | ||||
|    if (p->colorTableLut_.size() == 0) | ||||
|    { | ||||
|       return RadarProductView::color_table(minValue, maxValue); | ||||
|       return RadarProductView::color_table(); | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       minValue = p->colorTableMin_; | ||||
|       maxValue = p->colorTableMax_; | ||||
|       return p->colorTableLut_; | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| uint16_t Level2ProductView::color_table_min() const | ||||
| { | ||||
|    if (p->colorTableLut_.size() == 0) | ||||
|    { | ||||
|       return RadarProductView::color_table_min(); | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       return p->colorTableMin_; | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| uint16_t Level2ProductView::color_table_max() const | ||||
| { | ||||
|    if (p->colorTableLut_.size() == 0) | ||||
|    { | ||||
|       return RadarProductView::color_table_max(); | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       return p->colorTableMax_; | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| float Level2ProductView::elevation() const | ||||
| { | ||||
|    return p->elevationCut_; | ||||
|  | @ -306,7 +328,6 @@ void Level2ProductView::ComputeSweep() | |||
|       return; | ||||
|    } | ||||
| 
 | ||||
|    float                                       elevation; | ||||
|    std::shared_ptr<wsr88d::rda::ElevationScan> radarData; | ||||
|    std::tie(radarData, p->elevationCut_, p->elevationCuts_) = | ||||
|       p->radarProductManager_->GetLevel2Data(p->dataBlockType_, | ||||
|  |  | |||
|  | @ -29,10 +29,11 @@ public: | |||
|       std::shared_ptr<manager::RadarProductManager> radarProductManager); | ||||
|    ~Level2ProductView(); | ||||
| 
 | ||||
|    const std::vector<boost::gil::rgba8_pixel_t>& | ||||
|          color_table(uint16_t& minValue, uint16_t& maxValue) const override; | ||||
|    float elevation() const override; | ||||
|    float range() const override; | ||||
|    const std::vector<boost::gil::rgba8_pixel_t>& color_table() const override; | ||||
|    uint16_t                              color_table_min() const override; | ||||
|    uint16_t                              color_table_max() const override; | ||||
|    float                                 elevation() const override; | ||||
|    float                                 range() const override; | ||||
|    std::chrono::system_clock::time_point sweep_time() const override; | ||||
|    const std::vector<float>&             vertices() const override; | ||||
| 
 | ||||
|  |  | |||
|  | @ -33,13 +33,21 @@ RadarProductView::RadarProductView() : | |||
| RadarProductView::~RadarProductView() = default; | ||||
| 
 | ||||
| const std::vector<boost::gil::rgba8_pixel_t>& | ||||
| RadarProductView::color_table(uint16_t& minValue, uint16_t& maxValue) const | ||||
| RadarProductView::color_table() const | ||||
| { | ||||
|    minValue = DEFAULT_COLOR_TABLE_MIN; | ||||
|    maxValue = DEFAULT_COLOR_TABLE_MAX; | ||||
|    return DEFAULT_COLOR_TABLE; | ||||
| } | ||||
| 
 | ||||
| uint16_t RadarProductView::color_table_min() const | ||||
| { | ||||
|    return DEFAULT_COLOR_TABLE_MIN; | ||||
| } | ||||
| 
 | ||||
| uint16_t RadarProductView::color_table_max() const | ||||
| { | ||||
|    return DEFAULT_COLOR_TABLE_MAX; | ||||
| } | ||||
| 
 | ||||
| float RadarProductView::elevation() const | ||||
| { | ||||
|    return 0.0f; | ||||
|  |  | |||
|  | @ -25,10 +25,11 @@ public: | |||
|    explicit RadarProductView(); | ||||
|    ~RadarProductView(); | ||||
| 
 | ||||
|    virtual const std::vector<boost::gil::rgba8_pixel_t>& | ||||
|                  color_table(uint16_t& minValue, uint16_t& maxValue) const; | ||||
|    virtual float elevation() const; | ||||
|    virtual float range() const; | ||||
|    virtual const std::vector<boost::gil::rgba8_pixel_t>& color_table() const; | ||||
|    virtual uint16_t                              color_table_min() const; | ||||
|    virtual uint16_t                              color_table_max() const; | ||||
|    virtual float                                 elevation() const; | ||||
|    virtual float                                 range() const; | ||||
|    virtual std::chrono::system_clock::time_point sweep_time() const; | ||||
|    virtual const std::vector<float>&             vertices() const = 0; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat