Commit 31aedbe7 authored by Marc R.'s avatar Marc R.

Merge branch 'devel_1_5_skewt' into devel_1_5

parents e475b505 33e2d93c
......@@ -118,6 +118,7 @@ HEADERS += \
src/system/pipelineconfiguration.h \
src/data/probabltrajectoriessource.h \
src/gxfw/gl/shaderstoragebufferobject.h \
src/actors/skewtactor.h \
src/gxfw/memberselectiondialog.h \
src/gxfw/adddatasetdialog.h \
src/data/derivedmetvarsdatasource.h \
......@@ -222,6 +223,7 @@ SOURCES += \
src/system/pipelineconfiguration.cpp \
src/data/probabltrajectoriessource.cpp \
src/gxfw/gl/shaderstoragebufferobject.cpp \
src/actors/skewtactor.cpp \
src/gxfw/memberselectiondialog.cpp \
src/gxfw/adddatasetdialog.cpp \
src/data/derivedmetvarsdatasource.cpp \
......@@ -302,6 +304,7 @@ OTHER_FILES += \
src/glsl/vsec_marching_squares.fx.glsl \
src/glsl/volume_normalcurves_initpoints.fx.glsl \
src/glsl/hsec_texturedcontours.fx.glsl \
src/glsl/skewtrendering.fx.glsl \
config/cf_stdnames.dat \
config/log4cplus.properties \
src/glsl/north_arrow.fx.glsl \
......
......@@ -48,6 +48,7 @@ namespace Met3D
MMovablePoleActor::MMovablePoleActor()
: MActor(),
tickLength(0.8),
ticksOnRightSide(true),
lineColour(QColor(0, 104, 139, 255)),
bottomPressure_hPa(1050.f),
topPressure_hPa(100.f),
......@@ -109,6 +110,11 @@ MMovablePoleActor::MMovablePoleActor()
properties->setDDouble(tickLengthProperty, tickLength,
0.05, 20., 2, 0.05, " (world space)");
ticksOnRightSideProperty = addProperty(BOOL_PROPERTY,
"ticks on right side",
ticksGroupProperty);
properties->mBool()->setValue(ticksOnRightSideProperty, ticksOnRightSide);
tickPressureThresholdProperty = addProperty(DECORATEDDOUBLE_PROPERTY,
"tick interval threshold",
ticksGroupProperty);
......@@ -140,6 +146,14 @@ MMovablePoleActor::MMovablePoleActor()
MMovablePoleActor::~MMovablePoleActor()
{
// Release all vertex buffers.
MGLResourcesManager *glRM = MGLResourcesManager::getInstance();
const QString axisRequestKey = "axis_vertices_actor#"
+ QString::number(getID());
glRM->releaseAllGPUItemReferences(axisRequestKey);
const QString poleRequestKey = "pole_vertices_actor#"
+ QString::number(getID());
glRM->releaseAllGPUItemReferences(poleRequestKey);
}
......@@ -246,6 +260,9 @@ void MMovablePoleActor::saveConfiguration(QSettings *settings)
settings->setValue("tickLength",
properties->mDDouble()->value(tickLengthProperty));
settings->setValue("ticksOnRightSide",
properties->mBool()->value(ticksOnRightSideProperty));
settings->setValue("lineColour",
properties->mColor()->value(colourProperty));
......@@ -300,6 +317,10 @@ void MMovablePoleActor::loadConfiguration(QSettings *settings)
properties->mDDouble()->setValue(tickLengthProperty,
settings->value("tickLength", 0.8).toDouble());
properties->mBool()->setValue(
ticksOnRightSideProperty,
settings->value("ticksOnRightSide", true).toBool());
properties->mColor()->setValue(
colourProperty,
settings->value("lineColour", QColor(Qt::black)).value<QColor>());
......@@ -416,6 +437,9 @@ void MMovablePoleActor::renderToCurrentContext(MSceneViewGLWidget *sceneView)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); CHECK_GL_ERROR;
glDrawArrays(GL_LINES, 0, poleVertices.size()); CHECK_GL_ERROR;
// Unbind VBO.
glBindBuffer(GL_ARRAY_BUFFER, 0); CHECK_GL_ERROR;
// B) Render tick marks and adjust label positions.
// ================================================
......@@ -448,7 +472,8 @@ void MMovablePoleActor::renderToCurrentContext(MSceneViewGLWidget *sceneView)
// Offset for the "other end" of the tick line and anchor offset for
// the labels.
QVector3D anchorOffset = tickLength * sceneView->getCamera()->getXAxis();
QVector3D anchorOffset = (ticksOnRightSide ? 1 : -1) *
tickLength * sceneView->getCamera()->getXAxis();
simpleGeometryEffect->setUniformValue(
"offsetDirection", anchorOffset);
......@@ -457,7 +482,8 @@ void MMovablePoleActor::renderToCurrentContext(MSceneViewGLWidget *sceneView)
for (int i = 0; i < labels.size(); i++)
{
labels[i]->anchorOffset = anchorOffset
+ tubeRadius * sceneView->getCamera()->getXAxis();
+ ((ticksOnRightSide ? 1 : -1) * tubeRadius)
* sceneView->getCamera()->getXAxis();
}
// Render tick marks.
......@@ -478,7 +504,7 @@ void MMovablePoleActor::renderToCurrentContext(MSceneViewGLWidget *sceneView)
if (sceneView->interactionModeEnabled() && movementEnabled)
{
// Bind shader program.
positionSpheresShader->bind();
positionSpheresShader->bindProgram("Normal");
// Set MVP-matrix and parameters to map pressure to world space in the
// vertex shader.
......@@ -745,11 +771,13 @@ void MMovablePoleActor::dragEvent(MSceneViewGLWidget *sceneView,
const QString poleRequestKey = "pole_vertices_actor#"
+ QString::number(getID());
// NOTE: needs to be released in destructor.
uploadVec3ToVertexBuffer(poleVertices, poleRequestKey, &poleVertexBuffer,
sceneView);
const QString axisRequestKey = "axis_vertices_actor#"
+ QString::number(getID());
// NOTE: needs to be released in destructor.
uploadVec3ToVertexBuffer(axisTicks, axisRequestKey, &axisVertexBuffer,
sceneView);
......@@ -807,6 +835,51 @@ void MMovablePoleActor::setMovement(bool enabled)
}
void MMovablePoleActor::enablePoleProperties(bool enabled)
{
addPoleProperty->setEnabled(enabled);
individualPoleHeightsProperty->setEnabled(enabled);
bottomPressureProperty->setEnabled(enabled);
topPressureProperty->setEnabled(enabled);
for (int i = 0; i < poles.size(); i++)
{
poles.at(i)->groupProperty->setEnabled(enabled);
}
}
void MMovablePoleActor::setTubeRadius(float radius)
{
properties->mDouble()->setValue(tubeRadiusProperty, radius);
}
void MMovablePoleActor::setVerticalExtent(float pbot_hPa, float ptop_hPa)
{
enableActorUpdates(false);
properties->mDDouble()->setValue(bottomPressureProperty, pbot_hPa);
enableActorUpdates(true);
properties->mDDouble()->setValue(topPressureProperty, ptop_hPa);
}
void MMovablePoleActor::setPolePosition(int index, QPointF lonlatPos)
{
if (index < poles.size())
{
properties->mPointF()->setValue(poles[index]->positionProperty,
lonlatPos);
}
}
void MMovablePoleActor::setTicksOnRightSide(bool rightSide)
{
properties->mBool()->setValue(ticksOnRightSideProperty, rightSide);
}
/******************************************************************************
*** PUBLIC SLOTS ***
*******************************************************************************/
......@@ -849,14 +922,25 @@ void MMovablePoleActor::onQtPropertyChanged(QtProperty *property)
emitActorChangedSignal();
}
else if (property == addPoleProperty)
else if (property == ticksOnRightSideProperty)
{
generatePole();
ticksOnRightSide = properties->mBool()->value(ticksOnRightSideProperty);
if (suppressActorUpdates()) return;
generateGeometry();
emitActorChangedSignal();
}
else if (property == addPoleProperty)
{
if (addPoleProperty->isEnabled())
{
generatePole();
if (suppressActorUpdates()) return;
generateGeometry();
emitActorChangedSignal();
}
}
else if (property == tickPressureThresholdProperty
|| property == tickIntervalAboveThreshold
|| property == tickIntervalBelowThreshold
......@@ -1039,7 +1123,9 @@ void MMovablePoleActor::generateGeometry()
QString("%1").arg(p),
MTextManager::LONLATP,
polePos.x(), polePos.y(), p,
labelsize, labelColour, MTextManager::MIDDLELEFT,
labelsize, labelColour, (ticksOnRightSide ?
MTextManager::MIDDLELEFT :
MTextManager::MIDDLERIGHT),
labelbbox, labelBBoxColour)
);
}
......@@ -1056,10 +1142,12 @@ void MMovablePoleActor::generateGeometry()
const QString poleRequestKey = "pole_vertices_actor#"
+ QString::number(getID());
// NOTE: needs to be released in destructor.
uploadVec3ToVertexBuffer(poleVertices, poleRequestKey, &poleVertexBuffer);
const QString axisRequestKey = "axis_vertices_actor#"
+ QString::number(getID());
// NOTE: needs to be released in destructor.
uploadVec3ToVertexBuffer(axisTicks, axisRequestKey, &axisVertexBuffer);
}
......
......@@ -99,6 +99,24 @@ public:
void setMovement(bool enabled);
/**
Programatically enable/disable the "add pole" property and the properties
that control position and vertical extent of a pole. Used e.g. by the
SkewT-Actor that keep a pole as a subactor that should only have exactly
one pole.
*/
void enablePoleProperties(bool enabled);
void setTubeRadius(float radius);
void setVerticalExtent(float pbot_hPa, float ptop_hPa);
void setPolePosition(int index, QPointF lonlatPos);
void setTicksOnRightSide(bool rightSide);
const QVector<QVector3D>& getAxisTicks() { return axisTicks; }
protected:
void initializeActorResources();
......@@ -125,6 +143,8 @@ protected:
QtProperty *ticksGroupProperty;
QtProperty *tickLengthProperty;
float tickLength;
QtProperty *ticksOnRightSideProperty;
bool ticksOnRightSide;
QtProperty *colourProperty;
QColor lineColour;
......
This diff is collapsed.
This diff is collapsed.
......@@ -69,6 +69,7 @@ MDerivedMetVarsDataSource::MDerivedMetVarsDataSource()
registerDerivedDataFieldProcessor(new MEquivalentPotentialTemperatureProcessor());
registerDerivedDataFieldProcessor(new MGeopotentialHeightProcessor());
registerDerivedDataFieldProcessor(new MGeopotentialHeightFromGeopotentialProcessor());
registerDerivedDataFieldProcessor(new MDewPointTemperatureProcessor());
registerDerivedDataFieldProcessor(
new MMagnitudeOfVerticallyIntegratedMoistureFluxProcessor(
......@@ -915,6 +916,43 @@ void MGeopotentialHeightFromGeopotentialProcessor::compute(
}
// Dew point temperature
// =====================
MDewPointTemperatureProcessor::MDewPointTemperatureProcessor()
: MDerivedDataFieldProcessor(
"dew_point_temperature",
QStringList() << "specific_humidity")
{}
void MDewPointTemperatureProcessor::compute(
QList<MStructuredGrid *> &inputGrids, MStructuredGrid *derivedGrid)
{
// input 0 = "specific_humidity"
// Requires nested k/j/i loops to access pressure at grid point.
for (unsigned int k = 0; k < derivedGrid->getNumLevels(); k++)
for (unsigned int j = 0; j < derivedGrid->getNumLats(); j++)
for (unsigned int i = 0; i < derivedGrid->getNumLons(); i++)
{
float q_kgkg = inputGrids.at(0)->getValue(k, j, i);
if (q_kgkg == M_MISSING_VALUE)
{
derivedGrid->setValue(k, j, i, M_MISSING_VALUE);
}
else
{
float dewPoint_K = dewPointTemperature_K_Bolton(
inputGrids.at(0)->getPressure(k, j, i) * 100.,
q_kgkg);
derivedGrid->setValue(k, j, i, dewPoint_K);
}
}
}
// Total precipitation per time interval
// =====================================
......
......@@ -251,6 +251,17 @@ public:
};
class MDewPointTemperatureProcessor
: public MDerivedDataFieldProcessor
{
public:
MDewPointTemperatureProcessor();
void compute(QList<MStructuredGrid*>& inputGrids,
MStructuredGrid *derivedGrid);
};
class MTHourlyTotalPrecipitationProcessor
: public MDerivedDataFieldProcessor
{
......
......@@ -4,10 +4,13 @@
** three-dimensional visual exploration of numerical ensemble weather
** prediction data.
**
** Copyright 2015-2018 Marc Rautenhaus
** Copyright 2017-2018 Bianca Tost
** Copyright 2015-2019 Marc Rautenhaus [*, previously +]
** Copyright 2017-2018 Bianca Tost [+]
**
** Computer Graphics and Visualization Group
** * Regional Computing Center, Visualization
** Universitaet Hamburg, Hamburg, Germany
**
** + Computer Graphics and Visualization Group
** Technische Universitaet Muenchen, Garching, Germany
**
** Met.3D is free software: you can redistribute it and/or modify
......@@ -315,17 +318,27 @@ void MStructuredGrid::setToValue(float val)
}
float MStructuredGrid::interpolateValue(float lon, float lat, float p_hPa)
void MStructuredGrid::findEnclosingHorizontalIndices(
float lon, float lat, int *i, int *j, int *i1, int *j1,
float *mixI, float *mixJ)
{
// Find horizontal indices i,i+1 and j,j+1 that enclose lon, lat.
float mixI = MMOD(lon - lons[0], 360.) / abs(lons[1]-lons[0]);
float mixJ = (lats[0] - lat) / abs(lats[1]-lats[0]);
int i = int(mixI);
int j = int(mixJ);
*mixI = MMOD(lon - lons[0], 360.) / abs(lons[1]-lons[0]);
*mixJ = (lats[0] - lat) / abs(lats[1]-lats[0]);
*i = int(*mixI);
*j = int(*mixJ);
*i1 = (*i)+1;
if (gridIsCyclicInLongitude()) *i1 %= nlons;
*j1 = (*j)+1;
}
int i1 = i+1;
if (gridIsCyclicInLongitude()) i1 %= nlons;
int j1 = j+1;
float MStructuredGrid::interpolateValue(float lon, float lat, float p_hPa)
{
int i, j, i1, j1;
float mixI, mixJ;
findEnclosingHorizontalIndices(lon, lat, &i, &j, &i1, &j1, &mixI, &mixJ);
if ((i < 0) || (j < 0) || (i1 >= int(nlons)) || (j1 >= int(nlats)))
return M_MISSING_VALUE;
......@@ -355,19 +368,56 @@ float MStructuredGrid::interpolateValue(QVector3D vec3_lonLatP)
}
float MStructuredGrid::interpolateValueOnLevel(
float lon, float lat, unsigned int k)
{
int i, j, i1, j1;
float mixI, mixJ;
findEnclosingHorizontalIndices(lon, lat, &i, &j, &i1, &j1, &mixI, &mixJ);
if ((i < 0) || (j < 0) || (i1 >= int(nlons)) || (j1 >= int(nlats)))
return M_MISSING_VALUE;
// Get scalar values at the four surrounding grid points of the level.
float scalar_i0j0 = getValue(k, j , i);
float scalar_i1j0 = getValue(k, j , i1);
float scalar_i0j1 = getValue(k, j1, i);
float scalar_i1j1 = getValue(k, j1, i1);
// Interpolate horizontally.
mixJ = MFRACT(mixJ); // fract(mixJ) in GLSL
float scalar_i0 = MMIX(scalar_i0j0, scalar_i0j1, mixJ);
float scalar_i1 = MMIX(scalar_i1j0, scalar_i1j1, mixJ);
mixI = MFRACT(mixI);
float scalar = MMIX(scalar_i0, scalar_i1, mixI);
return scalar;
}
QVector<QVector2D> MStructuredGrid::extractVerticalProfile(float lon, float lat)
{
QVector<QVector2D> profile;
for (unsigned int k = 0; k < nlevs; k++)
{
float scalar = interpolateValueOnLevel(lon, lat, k);
float pressure_hPa = levelPressureAtLonLat_hPa(lon, lat, k);
profile.append(QVector2D(scalar, pressure_hPa));
}
return profile;
}
bool MStructuredGrid::findTopGridIndices(
float lon, float lat, float p_hPa,
MIndex3D *nw, MIndex3D *ne, MIndex3D *sw, MIndex3D *se)
{
// Find horizontal indices i,i+1 and j,j+1 that enclose lon, lat.
float mixI = MMOD(lon - lons[0], 360.) / abs(lons[1]-lons[0]);
float mixJ = (lats[0] - lat) / abs(lats[1]-lats[0]);
int i = int(mixI);
int j = int(mixJ);
int i1 = i+1;
if (gridIsCyclicInLongitude()) i1 %= nlons;
int j1 = j+1;
int i, j, i1, j1;
float mixI, mixJ;
findEnclosingHorizontalIndices(lon, lat, &i, &j, &i1, &j1, &mixI, &mixJ);
nw->i = i; nw->j = j; nw->k = findLevel(nw->j, nw->i, p_hPa);
ne->i = i1; ne->j = j; ne->k = findLevel(ne->j, ne->i, p_hPa);
......@@ -1100,6 +1150,15 @@ float MRegularLonLatLnPGrid::interpolateGridColumnToPressure(
}
float MRegularLonLatLnPGrid::levelPressureAtLonLat_hPa(
float lon, float lat, unsigned int k)
{
Q_UNUSED(lon);
Q_UNUSED(lat);
return exp(levels[k]);
}
int MRegularLonLatLnPGrid::findLevel(
unsigned int j, unsigned int i, float p_hPa)
{
......@@ -1305,6 +1364,15 @@ float MRegularLonLatStructuredPressureGrid::interpolateGridColumnToPressure(
}
float MRegularLonLatStructuredPressureGrid::levelPressureAtLonLat_hPa(
float lon, float lat, unsigned int k)
{
Q_UNUSED(lon);
Q_UNUSED(lat);
return levels[k];
}
int MRegularLonLatStructuredPressureGrid::findLevel(
unsigned int j, unsigned int i, float p_hPa)
{
......@@ -1837,6 +1905,18 @@ float MLonLatHybridSigmaPressureGrid::interpolateGridColumnToPressure(
}
float MLonLatHybridSigmaPressureGrid::levelPressureAtLonLat_hPa(
float lon, float lat, unsigned int k)
{
// Interpolate surface pressure to lon/lat position (pressure value is
// ignored by interpolateValue() since surface pressure is a 2D field), ..
float psfc_hPa = surfacePressure->interpolateValue(lon, lat, 0.) / 100.;
// .. then compute pressure of level.
float p_hPa = ak_hPa[k] + bk[k] * psfc_hPa;
return p_hPa;
}
int MLonLatHybridSigmaPressureGrid::findLevel(
unsigned int j, unsigned int i, float p_hPa)
{
......@@ -2143,6 +2223,13 @@ float MLonLatAuxiliaryPressureGrid::interpolateGridColumnToPressure(
}
float MLonLatAuxiliaryPressureGrid::levelPressureAtLonLat_hPa(
float lon, float lat, unsigned int k)
{
return auxPressureField_hPa->interpolateValueOnLevel(lon, lat, k);
}
int MLonLatAuxiliaryPressureGrid::findLevel(
unsigned int j, unsigned int i, float p_hPa)
{
......
......@@ -4,10 +4,13 @@
** three-dimensional visual exploration of numerical ensemble weather
** prediction data.
**
** Copyright 2015-2018 Marc Rautenhaus
** Copyright 2017-2018 Bianca Tost
** Copyright 2015-2019 Marc Rautenhaus [*, previously +]
** Copyright 2017-2018 Bianca Tost [+]
**
** Computer Graphics and Visualization Group
** * Regional Computing Center, Visualization
** Universitaet Hamburg, Hamburg, Germany
**
** + Computer Graphics and Visualization Group
** Technische Universitaet Muenchen, Garching, Germany
**
** Met.3D is free software: you can redistribute it and/or modify
......@@ -275,8 +278,17 @@ public:
inline float getSouthInterfaceLat(unsigned int j)
{ return lats[j] - getDeltaLat()/2.; }
/**
Determine the horizontal grid indices @p i, @p j, @p i1, @p j1 that
enclose the position given by @p lon, @p lat.
*/
void findEnclosingHorizontalIndices(float lon, float lat, int *i, int *j,
int *i1, int *j1, float *mixI, float *mixJ);
/**
Sample the data grid at lon, lat and p, using trilinear interpolation.
Uses @ref interpolateGridColumnToPressure(). For derived grid classes
that are only two-dimensional, the @p p_hPa parameter is ignored.
*/
float interpolateValue(float lon, float lat, float p_hPa);
......@@ -284,12 +296,34 @@ public:
/**
Implement this method in derived classes that know about their vertical
coordinate. It is used by @ref interpolateValue().
coordinate. It is used by @ref interpolateValue(). If the derived class
is two-dimensional, the @p p_hPa parameter can be ignored.
*/
virtual float interpolateGridColumnToPressure(
unsigned int j, unsigned int i, float p_hPa)
{ Q_UNUSED(j); Q_UNUSED(i); Q_UNUSED(p_hPa); return M_MISSING_VALUE; }
/**
Computes the pressure on grid level @p k at position (@p lon, @p lat).
Implement this method in derived classes.
*/
virtual float levelPressureAtLonLat_hPa(float lon, float lat, unsigned int k)
{ Q_UNUSED(lon); Q_UNUSED(lat); Q_UNUSED(k); return M_MISSING_VALUE; }
/**
Samples the data grid on vertical level k and at position (@p lon, @p lat)
using bi-linear interpolation.
*/
float interpolateValueOnLevel(float lon, float lat, unsigned int k);
/**
Extracts a vertical profile of (scalar, p_hPa) tuples from the data
field at position (@p lon, @p lat). Uses @ref interpolateValueOnLevel()
and @ref levelPressureAtLonLat_hPa().
*/
QVector<QVector2D> extractVerticalProfile(float lon, float lat);
/**
Determine the four grid indices that horizontally bound the grid cell
that contains the position specified by @p lon, @p lat, @p p_hPa. In the
......@@ -612,6 +646,8 @@ public:
float interpolateGridColumnToPressure(unsigned int j, unsigned int i,
float p_hPa);
float levelPressureAtLonLat_hPa(float lon, float lat, unsigned int k) override;
int findLevel(unsigned int j, unsigned int i, float p_hPa);
float getPressure(unsigned int k, unsigned int j, unsigned int i);
......@@ -652,6 +688,8 @@ public:
float interpolateGridColumnToPressure(unsigned int j, unsigned int i,
float p_hPa);
float levelPressureAtLonLat_hPa(float lon, float lat, unsigned int k) override;
int findLevel(unsigned int j, unsigned int i, float p_hPa);
float getPressure(unsigned int k, unsigned int j, unsigned int i);
......@@ -687,6 +725,14 @@ public:
inline float getValue(unsigned int j, unsigned int i) const
{ return data[INDEX2yx(j, i, nlons)]; }
/**
2D special case: ignore @p p_hPa parameter and simply map to getValue().
Implementation required for @ref MStructuredGrid::interpolateValue().
*/
float interpolateGridColumnToPressure(unsigned int j, unsigned int i,
float p_hPa)
{ Q_UNUSED(p_hPa); return getValue(j, i); }
GL::MTexture* getTexture(QGLWidget *currentGLContext = nullptr,
bool nullTexture = false);
......@@ -733,6 +779,8 @@ public:
float interpolateGridColumnToPressure(unsigned int j, unsigned int i,
float p_hPa);
float levelPressureAtLonLat_hPa(float lon, float lat, unsigned int k) override;
int findLevel(unsigned int j, unsigned int i, float p_hPa);
float getPressure(unsigned int k, unsigned int j, unsigned int i);
......@@ -801,6 +849,8 @@ public:
float interpolateGridColumnToPressure(unsigned int j, unsigned int i,
float p_hPa);
float levelPressureAtLonLat_hPa(float lon, float lat, unsigned int k) override;
int findLevel(unsigned int j, unsigned int i, float p_hPa);
float getPressure(unsigned int k, unsigned int j, unsigned int i);
......
/******************************************************************************
**
** 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);
}