Adding reflectivity declutter capability

This commit is contained in:
Dan Paulat 2021-11-14 00:25:17 -06:00
parent e58b1f5b57
commit 77ba92ce7f
7 changed files with 130 additions and 6 deletions

View file

@ -7,7 +7,10 @@ uniform sampler1D uTexture;
uniform uint uDataMomentOffset; uniform uint uDataMomentOffset;
uniform float uDataMomentScale; uniform float uDataMomentScale;
uniform bool uCFPEnabled;
flat in uint dataMoment; flat in uint dataMoment;
flat in uint cfpMoment;
layout (location = 0) out vec4 fragColor; layout (location = 0) out vec4 fragColor;
@ -15,5 +18,10 @@ void main()
{ {
float texCoord = float(dataMoment - uDataMomentOffset) / uDataMomentScale; float texCoord = float(dataMoment - uDataMomentOffset) / uDataMomentScale;
if (uCFPEnabled && cfpMoment > 8u)
{
texCoord = texCoord - float(cfpMoment - 8u) / 2.0f;
}
fragColor = texture(uTexture, texCoord); fragColor = texture(uTexture, texCoord);
} }

View file

@ -8,11 +8,13 @@
layout (location = 0) in vec2 aLatLong; layout (location = 0) in vec2 aLatLong;
layout (location = 1) in uint aDataMoment; layout (location = 1) in uint aDataMoment;
layout (location = 2) in uint aCfpMoment;
uniform mat4 uMVPMatrix; uniform mat4 uMVPMatrix;
uniform vec2 uMapScreenCoord; uniform vec2 uMapScreenCoord;
flat out uint dataMoment; flat out uint dataMoment;
flat out uint cfpMoment;
vec2 latLngToScreenCoordinate(in vec2 latLng) vec2 latLngToScreenCoordinate(in vec2 latLng)
{ {
@ -27,6 +29,7 @@ void main()
{ {
// Pass the coded data moment to the fragment shader // Pass the coded data moment to the fragment shader
dataMoment = aDataMoment; dataMoment = aDataMoment;
cfpMoment = aCfpMoment;
vec2 p = latLngToScreenCoordinate(aLatLong) - uMapScreenCoord; vec2 p = latLngToScreenCoordinate(aLatLong) - uMapScreenCoord;

View file

@ -37,10 +37,14 @@ public:
shaderProgram_(gl), shaderProgram_(gl),
uMVPMatrixLocation_(GL_INVALID_INDEX), uMVPMatrixLocation_(GL_INVALID_INDEX),
uMapScreenCoordLocation_(GL_INVALID_INDEX), uMapScreenCoordLocation_(GL_INVALID_INDEX),
uDataMomentOffsetLocation_(GL_INVALID_INDEX),
uDataMomentScaleLocation_(GL_INVALID_INDEX),
uCFPEnabledLocation_(GL_INVALID_INDEX),
vbo_ {GL_INVALID_INDEX}, vbo_ {GL_INVALID_INDEX},
vao_ {GL_INVALID_INDEX}, vao_ {GL_INVALID_INDEX},
texture_ {GL_INVALID_INDEX}, texture_ {GL_INVALID_INDEX},
numVertices_ {0}, numVertices_ {0},
cfpEnabled_ {false},
colorTableNeedsUpdate_ {false}, colorTableNeedsUpdate_ {false},
sweepNeedsUpdate_ {false} sweepNeedsUpdate_ {false}
{ {
@ -55,12 +59,15 @@ public:
GLint uMapScreenCoordLocation_; GLint uMapScreenCoordLocation_;
GLint uDataMomentOffsetLocation_; GLint uDataMomentOffsetLocation_;
GLint uDataMomentScaleLocation_; GLint uDataMomentScaleLocation_;
std::array<GLuint, 2> vbo_; GLint uCFPEnabledLocation_;
std::array<GLuint, 3> vbo_;
GLuint vao_; GLuint vao_;
GLuint texture_; GLuint texture_;
GLsizeiptr numVertices_; GLsizeiptr numVertices_;
bool cfpEnabled_;
bool colorTableNeedsUpdate_; bool colorTableNeedsUpdate_;
bool sweepNeedsUpdate_; bool sweepNeedsUpdate_;
}; };
@ -113,6 +120,13 @@ void RadarProductLayer::initialize()
<< logPrefix_ << "Could not find uDataMomentScale"; << logPrefix_ << "Could not find uDataMomentScale";
} }
p->uCFPEnabledLocation_ =
gl.glGetUniformLocation(p->shaderProgram_.id(), "uCFPEnabled");
if (p->uCFPEnabledLocation_ == -1)
{
BOOST_LOG_TRIVIAL(warning) << logPrefix_ << "Could not find uCFPEnabled";
}
p->shaderProgram_.Use(); p->shaderProgram_.Use();
// Generate a vertex array object // Generate a vertex array object
@ -155,7 +169,7 @@ void RadarProductLayer::UpdateSweep()
gl.glBindVertexArray(p->vao_); gl.glBindVertexArray(p->vao_);
// Generate vertex buffer objects // Generate vertex buffer objects
gl.glGenBuffers(2, p->vbo_.data()); gl.glGenBuffers(3, p->vbo_.data());
// Buffer vertices // Buffer vertices
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]);
@ -199,6 +213,41 @@ void RadarProductLayer::UpdateSweep()
gl.glVertexAttribIPointer(1, 1, type, 0, static_cast<void*>(0)); gl.glVertexAttribIPointer(1, 1, type, 0, static_cast<void*>(0));
gl.glEnableVertexAttribArray(1); gl.glEnableVertexAttribArray(1);
// Buffer CFP data
const GLvoid* cfpData;
GLsizeiptr cfpDataSize;
size_t cfpComponentSize;
GLenum cfpType;
std::tie(cfpData, cfpDataSize, cfpComponentSize) =
p->radarProductView_->GetCfpMomentData();
if (cfpData != nullptr)
{
if (cfpComponentSize == 1)
{
cfpType = GL_UNSIGNED_BYTE;
}
else
{
cfpType = GL_UNSIGNED_SHORT;
}
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[2]);
timer.start();
gl.glBufferData(GL_ARRAY_BUFFER, cfpDataSize, cfpData, GL_STATIC_DRAW);
timer.stop();
BOOST_LOG_TRIVIAL(debug)
<< logPrefix_ << "CFP moments buffered in " << timer.format(6, "%ws");
gl.glVertexAttribIPointer(2, 1, cfpType, 0, static_cast<void*>(0));
gl.glEnableVertexAttribArray(2);
}
else
{
gl.glDisableVertexAttribArray(2);
}
p->numVertices_ = vertices.size() / 2; p->numVertices_ = vertices.size() / 2;
} }
@ -238,6 +287,8 @@ void RadarProductLayer::render(
gl.glUniformMatrix4fv( gl.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);
gl.glActiveTexture(GL_TEXTURE0); gl.glActiveTexture(GL_TEXTURE0);
gl.glBindTexture(GL_TEXTURE_1D, p->texture_); gl.glBindTexture(GL_TEXTURE_1D, p->texture_);
gl.glBindVertexArray(p->vao_); gl.glBindVertexArray(p->vao_);
@ -253,10 +304,14 @@ void RadarProductLayer::deinitialize()
gl.glDeleteVertexArrays(1, &p->vao_); gl.glDeleteVertexArrays(1, &p->vao_);
gl.glDeleteBuffers(2, p->vbo_.data()); gl.glDeleteBuffers(2, p->vbo_.data());
p->uMVPMatrixLocation_ = GL_INVALID_INDEX; p->uMVPMatrixLocation_ = GL_INVALID_INDEX;
p->vao_ = GL_INVALID_INDEX; p->uMapScreenCoordLocation_ = GL_INVALID_INDEX;
p->vbo_ = {GL_INVALID_INDEX}; p->uDataMomentOffsetLocation_ = GL_INVALID_INDEX;
p->texture_ = GL_INVALID_INDEX; p->uDataMomentScaleLocation_ = GL_INVALID_INDEX;
p->uCFPEnabledLocation_ = GL_INVALID_INDEX;
p->vao_ = GL_INVALID_INDEX;
p->vbo_ = {GL_INVALID_INDEX};
p->texture_ = GL_INVALID_INDEX;
disconnect(p->radarProductView_.get(), disconnect(p->radarProductView_.get(),
&view::RadarProductView::ColorTableUpdated, &view::RadarProductView::ColorTableUpdated,

View file

@ -76,6 +76,7 @@ public:
std::vector<float> vertices_; std::vector<float> vertices_;
std::vector<uint8_t> dataMoments8_; std::vector<uint8_t> dataMoments8_;
std::vector<uint16_t> dataMoments16_; std::vector<uint16_t> dataMoments16_;
std::vector<uint8_t> cfpMoments_;
float latitude_; float latitude_;
float longitude_; float longitude_;
@ -151,6 +152,22 @@ std::tuple<const void*, size_t, size_t> Level2ProductView::GetMomentData() const
return std::tie(data, dataSize, componentSize); return std::tie(data, dataSize, componentSize);
} }
std::tuple<const void*, size_t, size_t>
Level2ProductView::GetCfpMomentData() const
{
const void* data = nullptr;
size_t dataSize = 0;
size_t componentSize = 1;
if (p->cfpMoments_.size() > 0)
{
data = p->cfpMoments_.data();
dataSize = p->cfpMoments_.size() * sizeof(uint8_t);
}
return std::tie(data, dataSize, componentSize);
}
void Level2ProductView::LoadColorTable( void Level2ProductView::LoadColorTable(
std::shared_ptr<common::ColorTable> colorTable) std::shared_ptr<common::ColorTable> colorTable)
{ {
@ -297,6 +314,7 @@ void Level2ProductView::ComputeSweep()
// Setup data moment vector // Setup data moment vector
std::vector<uint8_t>& dataMoments8 = p->dataMoments8_; std::vector<uint8_t>& dataMoments8 = p->dataMoments8_;
std::vector<uint16_t>& dataMoments16 = p->dataMoments16_; std::vector<uint16_t>& dataMoments16 = p->dataMoments16_;
std::vector<uint8_t>& cfpMoments = p->cfpMoments_;
size_t mIndex = 0; size_t mIndex = 0;
if (momentData0->data_word_size() == 8) if (momentData0->data_word_size() == 8)
@ -314,6 +332,16 @@ void Level2ProductView::ComputeSweep()
dataMoments16.resize(radials * gates * VERTICES_PER_BIN); dataMoments16.resize(radials * gates * VERTICES_PER_BIN);
} }
if (p->dataBlockType_ == wsr88d::rda::DataBlockType::MomentRef)
{
cfpMoments.resize(radials * gates * VERTICES_PER_BIN);
}
else
{
cfpMoments.resize(0);
cfpMoments.shrink_to_fit();
}
// Compute threshold at which to display an individual bin // Compute threshold at which to display an individual bin
const float scale = momentData0->scale(); const float scale = momentData0->scale();
const float offset = momentData0->offset(); const float offset = momentData0->offset();
@ -361,6 +389,7 @@ void Level2ProductView::ComputeSweep()
const uint8_t* dataMomentsArray8 = nullptr; const uint8_t* dataMomentsArray8 = nullptr;
const uint16_t* dataMomentsArray16 = nullptr; const uint16_t* dataMomentsArray16 = nullptr;
const uint8_t* cfpMomentsArray = nullptr;
if (momentData->data_word_size() == 8) if (momentData->data_word_size() == 8)
{ {
@ -373,6 +402,13 @@ void Level2ProductView::ComputeSweep()
reinterpret_cast<const uint16_t*>(momentData->data_moments()); reinterpret_cast<const uint16_t*>(momentData->data_moments());
} }
if (cfpMoments.size() > 0)
{
cfpMomentsArray = reinterpret_cast<const uint8_t*>(
radialData->moment_data_block(wsr88d::rda::DataBlockType::MomentCfp)
->data_moments());
}
for (uint16_t gate = startGate, i = 0; gate + gateSize <= endGate; for (uint16_t gate = startGate, i = 0; gate + gateSize <= endGate;
gate += gateSize, ++i) gate += gateSize, ++i)
{ {
@ -390,6 +426,11 @@ void Level2ProductView::ComputeSweep()
for (size_t m = 0; m < vertexCount; m++) for (size_t m = 0; m < vertexCount; m++)
{ {
dataMoments8[mIndex++] = dataMomentsArray8[i]; dataMoments8[mIndex++] = dataMomentsArray8[i];
if (cfpMomentsArray != nullptr)
{
cfpMoments[mIndex - 1] = cfpMomentsArray[i];
}
} }
} }
else else
@ -481,6 +522,11 @@ void Level2ProductView::ComputeSweep()
dataMoments16.resize(mIndex); dataMoments16.resize(mIndex);
} }
if (cfpMoments.size() > 0)
{
cfpMoments.resize(mIndex);
}
timer.stop(); timer.stop();
BOOST_LOG_TRIVIAL(debug) BOOST_LOG_TRIVIAL(debug)
<< logPrefix_ << "Vertices calculated in " << timer.format(6, "%ws"); << logPrefix_ << "Vertices calculated in " << timer.format(6, "%ws");

View file

@ -36,6 +36,7 @@ public:
void LoadColorTable(std::shared_ptr<common::ColorTable> colorTable) override; void LoadColorTable(std::shared_ptr<common::ColorTable> colorTable) override;
std::tuple<const void*, size_t, size_t> GetMomentData() const override; std::tuple<const void*, size_t, size_t> GetMomentData() const override;
std::tuple<const void*, size_t, size_t> GetCfpMomentData() const override;
static std::shared_ptr<Level2ProductView> static std::shared_ptr<Level2ProductView>
Create(common::Level2Product product, Create(common::Level2Product product,

View file

@ -50,6 +50,16 @@ void RadarProductView::Initialize()
ComputeSweep(); ComputeSweep();
} }
std::tuple<const void*, size_t, size_t>
RadarProductView::GetCfpMomentData() const
{
const void* data = nullptr;
size_t dataSize = 0;
size_t componentSize = 0;
return std::tie(data, dataSize, componentSize);
}
void RadarProductView::ComputeSweep() void RadarProductView::ComputeSweep()
{ {
BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "ComputeSweep()"; BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "ComputeSweep()";

View file

@ -35,6 +35,7 @@ public:
LoadColorTable(std::shared_ptr<common::ColorTable> colorTable) = 0; LoadColorTable(std::shared_ptr<common::ColorTable> colorTable) = 0;
virtual std::tuple<const void*, size_t, size_t> GetMomentData() const = 0; virtual std::tuple<const void*, size_t, size_t> GetMomentData() const = 0;
virtual std::tuple<const void*, size_t, size_t> GetCfpMomentData() const;
protected: protected:
virtual void UpdateColorTable() = 0; virtual void UpdateColorTable() = 0;