mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 19:50:06 +00:00 
			
		
		
		
	Draw a radial. This needs some cleanup, and some MVP matrix tweaking.
This commit is contained in:
		
							parent
							
								
									ace3aeb460
								
							
						
					
					
						commit
						516983ab09
					
				
					 10 changed files with 506 additions and 4 deletions
				
			
		
							
								
								
									
										215
									
								
								scwx-qt/source/scwx/qt/map/radar_layer.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								scwx-qt/source/scwx/qt/map/radar_layer.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,215 @@ | |||
| #define _USE_MATH_DEFINES | ||||
| 
 | ||||
| #include <scwx/qt/map/radar_layer.hpp> | ||||
| #include <scwx/qt/util/shader_program.hpp> | ||||
| 
 | ||||
| #include <QOpenGLFunctions_3_3_Core> | ||||
| 
 | ||||
| #include <boost/log/trivial.hpp> | ||||
| 
 | ||||
| #include <glm/glm.hpp> | ||||
| #include <glm/gtc/matrix_transform.hpp> | ||||
| #include <glm/gtc/type_ptr.hpp> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
| { | ||||
| 
 | ||||
| static const std::string logPrefix_ = "[scwx::qt::map::radar_layer] "; | ||||
| 
 | ||||
| class RadarLayerImpl | ||||
| { | ||||
| public: | ||||
|    explicit RadarLayerImpl() : | ||||
|        gl_(), | ||||
|        shaderProgram_(), | ||||
|        uMVPMatrixLocation_(GL_INVALID_INDEX), | ||||
|        vbo_ {GL_INVALID_INDEX}, | ||||
|        vao_ {GL_INVALID_INDEX}, | ||||
|        numVertices_ {0} | ||||
|    { | ||||
|       gl_.initializeOpenGLFunctions(); | ||||
|    } | ||||
|    ~RadarLayerImpl() = default; | ||||
| 
 | ||||
|    QOpenGLFunctions_3_3_Core gl_; | ||||
| 
 | ||||
|    ShaderProgram shaderProgram_; | ||||
|    GLint         uMVPMatrixLocation_; | ||||
|    GLuint        vbo_; | ||||
|    GLuint        vao_; | ||||
| 
 | ||||
|    GLsizeiptr numVertices_; | ||||
| }; | ||||
| 
 | ||||
| RadarLayer::RadarLayer() : p(std::make_unique<RadarLayerImpl>()) {} | ||||
| RadarLayer::~RadarLayer() = default; | ||||
| 
 | ||||
| RadarLayer::RadarLayer(RadarLayer&&) noexcept = default; | ||||
| RadarLayer& RadarLayer::operator=(RadarLayer&&) noexcept = default; | ||||
| 
 | ||||
| void RadarLayer::initialize() | ||||
| { | ||||
|    BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "initialize()"; | ||||
| 
 | ||||
|    QOpenGLFunctions_3_3_Core& gl = p->gl_; | ||||
| 
 | ||||
|    p->shaderProgram_.Load(":/gl/radar.vert", ":/gl/radar.frag"); | ||||
| 
 | ||||
|    p->uMVPMatrixLocation_ = | ||||
|       gl.glGetUniformLocation(p->shaderProgram_.id(), "uMVPMatrix"); | ||||
|    if (p->uMVPMatrixLocation_ == -1) | ||||
|    { | ||||
|       BOOST_LOG_TRIVIAL(warning) << logPrefix_ << "Could not find uMVPMatrix"; | ||||
|    } | ||||
|    constexpr uint16_t MAX_RADIALS           = 720; | ||||
|    constexpr uint16_t MAX_DATA_MOMENT_GATES = 1840; | ||||
| 
 | ||||
|    static std::array<GLfloat, MAX_RADIALS * MAX_DATA_MOMENT_GATES * 6 * 2> | ||||
|       vertices; | ||||
| 
 | ||||
|    constexpr float angleDelta = 0.5f * static_cast<float>(M_PI) / 180.0f; | ||||
| 
 | ||||
|    float angle1 = 0; | ||||
|    float angle2 = angleDelta; | ||||
| 
 | ||||
|    GLsizeiptr index = 0; | ||||
| 
 | ||||
|    for (uint16_t azimuth = 0; azimuth < 720; ++azimuth) | ||||
|    { | ||||
|       const float dataMomentRange     = 2.125f; | ||||
|       const float dataMomentInterval  = 0.25f; | ||||
|       const float dataMomentIntervalH = dataMomentInterval * 0.5f; | ||||
|       const float snrThreshold        = 2.0f; | ||||
| 
 | ||||
|       const uint16_t numberOfDataMomentGates = 1832; | ||||
| 
 | ||||
|       float range1 = dataMomentRange - dataMomentIntervalH; | ||||
|       float range2 = range1 + dataMomentInterval; | ||||
| 
 | ||||
|       float sinTheta1 = std::sinf(angle1); | ||||
|       float sinTheta2 = std::sinf(angle2); | ||||
|       float cosTheta1 = std::cosf(angle1); | ||||
|       float cosTheta2 = std::cosf(angle2); | ||||
| 
 | ||||
|       for (uint16_t gate = 0; gate < numberOfDataMomentGates; ++gate) | ||||
|       { | ||||
|          float r1SinTheta1 = range1 * sinTheta1; | ||||
|          float r1SinTheta2 = range1 * sinTheta2; | ||||
|          float r2SinTheta1 = range2 * sinTheta1; | ||||
|          float r2SinTheta2 = range2 * sinTheta2; | ||||
| 
 | ||||
|          float r1CosTheta1 = range1 * cosTheta1; | ||||
|          float r1CosTheta2 = range1 * cosTheta2; | ||||
|          float r2CosTheta1 = range2 * cosTheta1; | ||||
|          float r2CosTheta2 = range2 * cosTheta2; | ||||
| 
 | ||||
|          vertices[index++] = r1SinTheta1; | ||||
|          vertices[index++] = r1CosTheta1; | ||||
| 
 | ||||
|          vertices[index++] = r2SinTheta1; | ||||
|          vertices[index++] = r2CosTheta1; | ||||
| 
 | ||||
|          vertices[index++] = r1SinTheta2; | ||||
|          vertices[index++] = r1CosTheta2; | ||||
| 
 | ||||
|          vertices[index++] = r1SinTheta2; | ||||
|          vertices[index++] = r1CosTheta2; | ||||
| 
 | ||||
|          vertices[index++] = r2SinTheta2; | ||||
|          vertices[index++] = r2CosTheta2; | ||||
| 
 | ||||
|          vertices[index++] = r2SinTheta1; | ||||
|          vertices[index++] = r2CosTheta1; | ||||
| 
 | ||||
|          range1 += dataMomentInterval; | ||||
|          range2 += dataMomentInterval; | ||||
|       } | ||||
| 
 | ||||
|       angle1 += angleDelta; | ||||
|       angle2 += angleDelta; | ||||
|       break; | ||||
|    } | ||||
| 
 | ||||
|    // Generate a vertex buffer object
 | ||||
|    gl.glGenBuffers(1, &p->vbo_); | ||||
| 
 | ||||
|    // Generate a vertex array object
 | ||||
|    gl.glGenVertexArrays(1, &p->vao_); | ||||
| 
 | ||||
|    // Bind vertex array object
 | ||||
|    gl.glBindVertexArray(p->vao_); | ||||
| 
 | ||||
|    // Copy vertices array in a buffer for OpenGL to use
 | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_); | ||||
|    gl.glBufferData(GL_ARRAY_BUFFER, | ||||
|                    index * sizeof(GLfloat), | ||||
|                    vertices.data(), | ||||
|                    GL_STATIC_DRAW); | ||||
| 
 | ||||
|    // Set the vertex attributes pointers
 | ||||
|    gl.glVertexAttribPointer( | ||||
|       0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(0); | ||||
| 
 | ||||
|    p->numVertices_ = index; | ||||
| } | ||||
| 
 | ||||
| void RadarLayer::render(const QMapbox::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    QOpenGLFunctions_3_3_Core& gl = p->gl_; | ||||
| 
 | ||||
|    p->shaderProgram_.Use(); | ||||
| 
 | ||||
|    float metersPerPixel = | ||||
|       QMapbox::metersPerPixelAtLatitude(params.latitude, params.zoom); | ||||
| 
 | ||||
|    const float scale  = 1000.0f / metersPerPixel * 2.0f; | ||||
|    const float xScale = scale / params.width; | ||||
|    const float yScale = scale / params.height; | ||||
| 
 | ||||
|    const QMapbox::Coordinate radar(38.6986, -90.6828); | ||||
| 
 | ||||
|    const QMapbox::ProjectedMeters radarMeters = | ||||
|       QMapbox::projectedMetersForCoordinate(radar); | ||||
|    const QMapbox::ProjectedMeters mapMeters = | ||||
|       QMapbox::projectedMetersForCoordinate( | ||||
|          {params.latitude, params.longitude}); | ||||
| 
 | ||||
|    const float yTranslate = (radarMeters.first - mapMeters.first) * 0.001f; | ||||
|    const float xTranslate = (radarMeters.second - mapMeters.second) * 0.001f; | ||||
| 
 | ||||
|    glm::mat4 uMVPMatrix(1.0f); | ||||
|    uMVPMatrix = glm::scale(uMVPMatrix, glm::vec3(xScale, yScale, 1.0f)); | ||||
|    uMVPMatrix = | ||||
|       glm::translate(uMVPMatrix, glm::vec3(xTranslate, yTranslate, 0.0f)); | ||||
|    uMVPMatrix = glm::rotate(uMVPMatrix, | ||||
|                             glm::radians<float>(params.bearing), | ||||
|                             glm::vec3(0.0f, 0.0f, 1.0f)); | ||||
| 
 | ||||
|    gl.glUniformMatrix4fv( | ||||
|       p->uMVPMatrixLocation_, 1, GL_FALSE, glm::value_ptr(uMVPMatrix)); | ||||
| 
 | ||||
|    gl.glBindVertexArray(p->vao_); | ||||
|    gl.glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | ||||
|    gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_); | ||||
|    gl.glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | ||||
| } | ||||
| 
 | ||||
| void RadarLayer::deinitialize() | ||||
| { | ||||
|    QOpenGLFunctions_3_3_Core& gl = p->gl_; | ||||
| 
 | ||||
|    BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "deinitialize()"; | ||||
| 
 | ||||
|    gl.glDeleteVertexArrays(1, &p->vao_); | ||||
|    gl.glDeleteBuffers(1, &p->vbo_); | ||||
| 
 | ||||
|    p->uMVPMatrixLocation_ = GL_INVALID_INDEX; | ||||
|    p->vao_                = GL_INVALID_INDEX; | ||||
|    p->vbo_                = GL_INVALID_INDEX; | ||||
| } | ||||
| 
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat