Commit 43e2eb43 authored by Marc R.'s avatar Marc R.

skew-T: profile interpolation implemented on the CPU, first simplified draw...

skew-T: profile interpolation implemented on the CPU, first simplified draw routine for revised diagram architecture
parent 7bdbc0cb
......@@ -423,7 +423,7 @@ void MSkewTActor::loadConfiguration(QSettings *settings)
{
var->variable = dynamic_cast<MNWPSkewTActorVariable*>(
variables.at(index - 1));
properties->mColor()->setValue(var->variable->colorProperty, color);
properties->mColor()->setValue(var->variable->profileColourProperty, color);
}
}
......@@ -452,6 +452,7 @@ void MSkewTActor::loadConfiguration(QSettings *settings)
settings->endGroup();
copyDiagramConfigurationFromQtProperties();
updateVerticalProfiles();
enableActorUpdates(true);
}
......@@ -860,14 +861,18 @@ void MSkewTActor::onQtPropertyChanged(QtProperty *property)
labelBBoxColour = properties->mColor()->value(labelBBoxColourProperty);
emitActorChangedSignal();
}
else if (property == geoPositionProperty
|| property == perspectiveRenderingProperty)
else if (property == geoPositionProperty)
{
diagramConfiguration.drawInPerspective
= properties->mBool()->value(perspectiveRenderingProperty);
diagramConfiguration.geoPosition = QVector2D(
float(properties->mPointF()->value(geoPositionProperty).x()),
float(properties->mPointF()->value(geoPositionProperty).y()));
updateVerticalProfiles();
emitActorChangedSignal();
}
else if (property == perspectiveRenderingProperty)
{
diagramConfiguration.drawInPerspective
= properties->mBool()->value(perspectiveRenderingProperty);
emitActorChangedSignal();
}
else if (property == drawDryAdiabatesProperty)
......@@ -944,13 +949,13 @@ void MSkewTActor::onQtPropertyChanged(QtProperty *property)
continue;
}
if (property == var->property
|| property == var->variable->colorProperty
|| property == var->variable->thicknessProperty)
|| property == var->variable->profileColourProperty
|| property == var->variable->lineThicknessProperty)
{
var->variable = dynamic_cast<MNWPSkewTActorVariable*>(
variables.at(var->index - 1));
var->color = var->variable->color;
var->thickness = var->variable->thickness;
var->color = var->variable->profileColour;
var->thickness = var->variable->lineThickness;
emitActorChangedSignal();
return;
}
......@@ -1532,8 +1537,8 @@ void MSkewTActor::drawDiagram(MSceneViewGLWidget *sceneView,
skewTShader->setUniformValue("drawHumidity" , false);
skewTShader->setUniformValue("drawTemperature", true);
}
skewTShader->setUniformValue("colour", var->color);
glLineWidth(float(var->thickness));
skewTShader->setUniformValue("colour", var->profileColour);
glLineWidth(float(var->lineThickness));
config->layer -= 0.001f;
skewTShader->setUniformValue("layer",
config->layer);
......@@ -1591,7 +1596,7 @@ void MSkewTActor::drawDiagram(MSceneViewGLWidget *sceneView,
"numberOfLevels", grid->getNumLevels());
skewTShader->setUniformValue(
"numberOfLats" , grid->getNumLats());
glLineWidth(float(var->thickness));
glLineWidth(float(var->lineThickness));
if (var->transferFunction != nullptr)
{
......@@ -1615,7 +1620,7 @@ void MSkewTActor::drawDiagram(MSceneViewGLWidget *sceneView,
"useTransferFunction", true);
skewTShader->setUniformValue("scalarMinimum", 0.f);
skewTShader->setUniformValue("scalarMaximum", 0.f);
skewTShader->setUniformValue("colour", var->color);
skewTShader->setUniformValue("colour", var->profileColour);
}
// To avoid z fighting first render all spaghetti contours
// into the stencil buffer and updating the depth buffer
......@@ -1720,6 +1725,35 @@ void MSkewTActor::drawDiagram(MSceneViewGLWidget *sceneView,
}
void MSkewTActor::drawDiagram2(
MSceneViewGLWidget *sceneView,
GL::MVertexBuffer *vbDiagramVertices,
MSkewTActor::ModeSpecificDiagramConfiguration *config)
{
skewTShader->bindProgram("DiagramData");
setShaderGeneralVars(sceneView, config);
skewTShader->setUniformValue("tlogp2xyMatrix", transformationMatrixTlogp2xy);
for (MNWPActorVariable* avar : variables)
{
MNWPSkewTActorVariable* var =
static_cast<MNWPSkewTActorVariable*> (avar);
if ( !var->hasData() ) continue;
var->profileVertexBuffer->attachToVertexAttribute(
SHADER_VERTEX_ATTRIBUTE, 2,
GL_FALSE, 0, (const GLvoid *)(0 * sizeof(float)));
skewTShader->setUniformValue("colour", var->profileColour);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glLineWidth(float(var->lineThickness));
glDrawArrays(GL_LINE_STRIP, 0, var->profile.getScalarPressureData().size());
}
}
void MSkewTActor::drawProbabilityTube(
MNWPSkewTActorVariable *max, MNWPSkewTActorVariable *min, bool isHumidity,
QColor color)
......@@ -2729,7 +2763,7 @@ void MSkewTActor::drawDiagramFullScreen(MSceneViewGLWidget* sceneView)
glClear(GL_DEPTH_BUFFER_BIT);
fullscreenDiagrammConfiguration.layer = -0.005f;
drawDiagramGeometryAndLabelsFullScreen(sceneView);
drawDiagram(sceneView, vbDiagramVerticesFS, &fullscreenDiagrammConfiguration);
drawDiagram2(sceneView, vbDiagramVerticesFS, &fullscreenDiagrammConfiguration);
}
......@@ -2787,4 +2821,18 @@ QVector2D MSkewTActor::transformTp2xy(QVector2D tpCoordinate_K_hPa)
}
void MSkewTActor::updateVerticalProfiles()
{
// Tell all actor variables to update their vertical profile data to the
// current geographical location.
for (MNWPActorVariable* avar : variables)
{
MNWPSkewTActorVariable* var =
static_cast<MNWPSkewTActorVariable*> (avar);
var->updateProfile(diagramConfiguration.geoPosition);
}
}
} // namespace Met3D
......@@ -438,6 +438,10 @@ private:
GL::MVertexBuffer *vbDiagramVertices,
ModeSpecificDiagramConfiguration *config);
void drawDiagram2(MSceneViewGLWidget* sceneView,
GL::MVertexBuffer *vbDiagramVertices,
ModeSpecificDiagramConfiguration *config);
void loadObservationalDataFromUWyoming(int stationNum);
void loadListOfAvailableObservationsFromUWyoming();
......@@ -475,6 +479,12 @@ private:
@ref computeTlogp2xyTransformationMatrix().
*/
QVector2D transformTp2xy(QVector2D tpCoordinate_K_hPa);
/**
Updates (recomputes) the vertical profiles of the actor variables, e.g.
after the position of the diagram handle has been changed.
*/
void updateVerticalProfiles();
};
......
/******************************************************************************
**
** This file is part of Met.3D -- a research environment for the
** three-dimensional visual exploration of numerical ensemble weather
** prediction data.
**
** Copyright 2019 Marc Rautenhaus
**
** Regional Computing Center, Visualization
** Universitaet Hamburg, Hamburg, Germany
**
** Met.3D is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Met.3D is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Met.3D. If not, see <http://www.gnu.org/licenses/>.
**
*******************************************************************************/
#include "verticalprofile.h"
// standard library imports
// related third party imports
#include <log4cplus/loggingmacros.h>
// local application imports
#include "gxfw/mglresourcesmanager.h"
#include "gxfw/gl/typedvertexbuffer.h"
namespace Met3D
{
/******************************************************************************
*** CONSTRUCTOR / DESTRUCTOR ***
*******************************************************************************/
MVerticalProfile::MVerticalProfile()
: MAbstractDataItem()
{
}
MVerticalProfile::~MVerticalProfile()
{
// Make sure the corresponding data is removed from GPU memory as well.
MGLResourcesManager::getInstance()->releaseAllGPUItemReferences(getID());
}
/******************************************************************************
*** PUBLIC METHODS ***
*******************************************************************************/
unsigned int MVerticalProfile::getMemorySize_kb()
{
return (profileData.size() * sizeof(QVector2D));
}
GL::MVertexBuffer *MVerticalProfile::getVertexBuffer(
QGLWidget *currentGLContext)
{
MGLResourcesManager *glRM = MGLResourcesManager::getInstance();
// Check if a vertex buffer already exists in GPU memory.
GL::MVertexBuffer *vb = static_cast<GL::MVertexBuffer*>(
glRM->getGPUItem(getID()));
if (vb) return vb;
// No vertex buffer exists. Create a new one.
GL::MVector2DVertexBuffer *newVB = new GL::MVector2DVertexBuffer(
getID(), profileData.size());
if (glRM->tryStoreGPUItem(newVB))
{
newVB->upload(profileData, currentGLContext);
}
else
{
delete newVB;
}
return static_cast<GL::MVertexBuffer*>(glRM->getGPUItem(getID()));
}
void MVerticalProfile::releaseVertexBuffer()
{
MGLResourcesManager::getInstance()->releaseGPUItem(getID());
}
void MVerticalProfile::updateData(
QVector2D lonLatLocation, QVector<QVector2D> &profile)
{
// Update CPU-side memory.
this->lonLatLocation = lonLatLocation;
this->profileData = profile;
// If a vertex buffer exists, update that as well.
MGLResourcesManager* glRM = MGLResourcesManager::getInstance();
GL::MVertexBuffer* vb = static_cast<GL::MVertexBuffer*>(
glRM->getGPUItem(getID()));
if (vb)
{
GL::MVector2DVertexBuffer* vb2D =
dynamic_cast<GL::MVector2DVertexBuffer*>(vb);
// Reallocate buffer if size has changed.
vb2D->reallocate(nullptr, profile.size(), 0, false);
vb2D->update(profile, 0, 0);
}
}
} // namespace Met3D
/******************************************************************************
**
** This file is part of Met.3D -- a research environment for the
** three-dimensional visual exploration of numerical ensemble weather
** prediction data.
**
** Copyright 2019 Marc Rautenhaus
**
** Regional Computing Center, Visualization
** Universitaet Hamburg, Hamburg, Germany
**
** Met.3D is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Met.3D is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Met.3D. If not, see <http://www.gnu.org/licenses/>.
**
*******************************************************************************/
#ifndef VERTICALPROFILE_H
#define VERTICALPROFILE_H
// standard library imports
// related third party imports
#include <QVector>
#include <QVector2D>
// local application imports
#include "data/abstractdataitem.h"
#include "gxfw/gl/vertexbuffer.h"
namespace Met3D
{
/**
@brief MVerticalProfile ...
*/
class MVerticalProfile : public MAbstractDataItem
{
public:
MVerticalProfile();
~MVerticalProfile();
unsigned int getMemorySize_kb();
const QVector<QVector2D>& getScalarPressureData() { return profileData; }
const QVector2D& getLonLatLocation() { return lonLatLocation; }
/**
Return a vertex buffer object that contains the profile data. The
vertex buffer is created (and data uploaded) on the first call to this
method.
The @p currentGLContext argument is necessary as a GPU upload can switch
the currently active OpenGL context. If this method is called
from a render method, it should switch back to the current render context
(given by @p currentGLContext).
*/
GL::MVertexBuffer *getVertexBuffer(QGLWidget *currentGLContext = 0);
void releaseVertexBuffer();
void updateData(QVector2D lonLatLocation, QVector<QVector2D> &profile);
protected:
private:
QVector<QVector2D> profileData;
QVector2D lonLatLocation;
};
} // namespace Met3D
#endif // VERTICALPROFILE_H
......@@ -79,6 +79,7 @@ uniform float topPressure;
uniform float bottomPressure;
uniform struct Area area; // diagram outline
uniform mat4 mvpMatrix; // model-view-projection
uniform mat4 tlogp2xyMatrix;
uniform vec2 pToWorldZParams; // convert pressure to y axis
uniform vec2 pToWorldZParams2; // convert pressure to y axis
uniform vec4 colour;
......@@ -496,6 +497,21 @@ shader VSDiagramXYtoFullscreen(in vec2 vertex : 0)
}
shader VSTPtoFullscreen(in vec2 vertex : 0)
{
vec4 tlogp = vec4(vertex.x, log(vertex.y), 0, 1);
vec4 vertexDiagramXY = tlogp2xyMatrix * tlogp;
//TODO (mr, 10Jan2019) -- replace by matrix multiplication.
float hPad = 0.1;
float vPad = 0.1;
vec2 vertexClipSpace = vec2(vertexDiagramXY.x * (2.-2.*hPad) - 1.+hPad,
vertexDiagramXY.y * (2.-2.*vPad) - 1.+vPad);
gl_Position = vec4(vertexClipSpace.x, vertexClipSpace.y, layer, 1.);
}
shader VS2DVertexYInPressure(in vec2 vertexCoord : 0, out vec2 worldPos)
{
worldPos.x = vertexCoord.x;
......@@ -989,6 +1005,13 @@ program DiagramVertices
// fs(400)=FSColourWithAreaTest();
};
program DiagramData
{
vs(400)=VSTPtoFullscreen();
fs(400)=FSColour();
};
program MeasurementPoint
{
vs(400)=VSWorld();
......
......@@ -3957,8 +3957,9 @@ bool MNWP3DVolumeActorVariable::setTransferFunctionFromProperty()
MNWPSkewTActorVariable::MNWPSkewTActorVariable(MNWPMultiVarActor *actor)
: MNWPActorVariable(actor),
color(QColor(0, 0, 0, 255)),
thickness(2.)
profileColour(QColor(0, 0, 0, 255)),
lineThickness(2.),
profileVertexBuffer(nullptr)
{
assert(actor != nullptr);
MQtProperties *properties = actor->getQtProperties();
......@@ -3970,17 +3971,27 @@ MNWPSkewTActorVariable::MNWPSkewTActorVariable(MNWPMultiVarActor *actor)
QtProperty* renderGroup = getPropertyGroup("rendering");
assert(renderGroup != nullptr);
colorProperty = actor->addProperty(COLOR_PROPERTY, "colour", renderGroup);
properties->mColor()->setValue(colorProperty, color);
profileColourProperty = actor->addProperty(
COLOR_PROPERTY, "line colour", renderGroup);
properties->mColor()->setValue(profileColourProperty, profileColour);
thicknessProperty = actor->addProperty(DOUBLE_PROPERTY, "line thickness",
renderGroup);
properties->setDouble(thicknessProperty, thickness, 0., 10., 2, 0.1);
lineThicknessProperty = actor->addProperty(
DOUBLE_PROPERTY, "line thickness", renderGroup);
properties->setDouble(lineThicknessProperty, lineThickness, 0., 10., 2, 0.1);
actor->endInitialiseQtProperties();
}
MNWPSkewTActorVariable::~MNWPSkewTActorVariable()
{
if (profileVertexBuffer != nullptr)
{
profile.releaseVertexBuffer();
}
}
/******************************************************************************
*** PUBLIC METHODS ***
*******************************************************************************/
......@@ -3992,14 +4003,14 @@ bool MNWPSkewTActorVariable::onQtPropertyChanged(QtProperty *property)
MQtProperties *properties = actor->getQtProperties();
if (property == colorProperty)
if (property == profileColourProperty)
{
color = properties->mColor()->value(colorProperty);
profileColour = properties->mColor()->value(profileColourProperty);
return true;
}
else if (property == thicknessProperty)
else if (property == lineThicknessProperty)
{
thickness = properties->mDouble()->value(thicknessProperty);
lineThickness = properties->mDouble()->value(lineThicknessProperty);
return true;
}
......@@ -4011,8 +4022,8 @@ void MNWPSkewTActorVariable::saveConfiguration(QSettings *settings)
{
MNWPActorVariable::saveConfiguration(settings);
settings->setValue("colour", color);
settings->setValue("thickness", thickness);
settings->setValue("lineColour", profileColour);
settings->setValue("lineThickness", lineThickness);
}
......@@ -4022,10 +4033,35 @@ void MNWPSkewTActorVariable::loadConfiguration(QSettings *settings)
MQtProperties *properties = actor->getQtProperties();
properties->mColor()->setValue(colorProperty,
settings->value("colour").value<QColor>());
properties->mDouble()->setValue(thicknessProperty,
settings->value("thickness", 2.).toDouble());
properties->mColor()->setValue(
profileColourProperty,
settings->value("lineColour").value<QColor>());
properties->mDouble()->setValue(
lineThicknessProperty,
settings->value("lineThickness", 2.).toDouble());
}
void MNWPSkewTActorVariable::dataFieldChangedEvent()
{
updateProfile(profile.getLonLatLocation());
}
void MNWPSkewTActorVariable::updateProfile(QVector2D lonLatLocation)
{
QVector<QVector2D> profileData;
if (grid != nullptr)
{
profileData = grid->extractVerticalProfile(
lonLatLocation.x(), lonLatLocation.y());
}
profile.updateData(lonLatLocation, profileData);
if (profileVertexBuffer == nullptr)
{
profileVertexBuffer = profile.getVertexBuffer();
}
}
......
......@@ -47,6 +47,7 @@
#include "actors/transferfunction1d.h"
#include "actors/spatial1dtransferfunction.h"
#include "util/mstopwatch.h"
#include "data/verticalprofile.h"
#define MSTOPWATCH_ENABLED
......@@ -780,17 +781,30 @@ class MNWPSkewTActorVariable : public MNWPActorVariable
public:
MNWPSkewTActorVariable(MNWPMultiVarActor *actor);
~MNWPSkewTActorVariable();
bool onQtPropertyChanged(QtProperty *property) override;
void saveConfiguration(QSettings *settings);
void loadConfiguration(QSettings *settings);
QtProperty *colorProperty;
QtProperty *thicknessProperty;
protected:
friend class MSkewTActor;
void dataFieldChangedEvent() override;
/* Rendering properties. **/
QColor profileColour;
QtProperty *profileColourProperty;
double lineThickness;
QtProperty *lineThicknessProperty;
/* Profile data (CPU and vertex buffer). */
MVerticalProfile profile;
GL::MVertexBuffer *profileVertexBuffer;
QColor color;
double thickness;
void updateProfile(QVector2D lonLatLocation);
};
} // namespace Met3D
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment