Texture to surface

API for setting a texture to surface.

Task-number: QTRD-3232
Change-Id: Icd9de61882b54b9c1fc84a742e49980926ca681d
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@digia.com>
This commit is contained in:
Mika Salmela 2014-07-04 09:58:12 +03:00
parent 6264a2ff15
commit 6e4fb23270
23 changed files with 436 additions and 42 deletions

View File

@ -299,6 +299,54 @@ QSurface3DSeries::DrawFlags QSurface3DSeries::drawMode() const
return dptrc()->m_drawMode;
}
/*!
* Set the \a texture as a QImage for the surface. To clear the texture, set empty
* QImage as texture.
*/
void QSurface3DSeries::setTexture(const QImage &texture)
{
if (dptr()->m_texture != texture) {
dptr()->setTexture(texture);
emit textureChanged(texture);
dptr()->m_textureFile.clear();
}
}
QImage QSurface3DSeries::texture() const
{
return dptrc()->m_texture;
}
/*! \property QSurface3DSeries::textureFile
*
* Holds the texture file name for the surface texture. To clear the texture, set empty
* file name.
*/
void QSurface3DSeries::setTextureFile(const QString &filename)
{
if (dptr()->m_textureFile != filename) {
if (filename.isEmpty()) {
setTexture(QImage());
} else {
QImage image(filename);
if (image.isNull()) {
qWarning() << "Warning: Tried to set invalid image file as surface texture.";
return;
}
setTexture(image);
}
dptr()->m_textureFile = filename;
emit textureFileChanged(filename);
}
}
QString QSurface3DSeries::textureFile() const
{
return dptrc()->m_textureFile;
}
/*!
* \internal
*/
@ -445,4 +493,11 @@ void QSurface3DSeriesPrivate::setDrawMode(QSurface3DSeries::DrawFlags mode)
}
}
void QSurface3DSeriesPrivate::setTexture(const QImage &texture)
{
m_texture = texture;
if (static_cast<Surface3DController *>(m_controller))
static_cast<Surface3DController *>(m_controller)->updateSurfaceTexture(qptr());
}
QT_END_NAMESPACE_DATAVISUALIZATION

View File

@ -35,6 +35,8 @@ class QT_DATAVISUALIZATION_EXPORT QSurface3DSeries : public QAbstract3DSeries
Q_PROPERTY(bool flatShadingEnabled READ isFlatShadingEnabled WRITE setFlatShadingEnabled NOTIFY flatShadingEnabledChanged)
Q_PROPERTY(bool flatShadingSupported READ isFlatShadingSupported NOTIFY flatShadingSupportedChanged)
Q_PROPERTY(DrawFlags drawMode READ drawMode WRITE setDrawMode NOTIFY drawModeChanged)
Q_PROPERTY(QImage texture READ texture WRITE setTexture NOTIFY textureChanged)
Q_PROPERTY(QString textureFile READ textureFile WRITE setTextureFile NOTIFY textureFileChanged)
public:
enum DrawFlag {
@ -63,12 +65,19 @@ public:
bool isFlatShadingSupported() const;
void setTexture(const QImage &texture);
QImage texture() const;
void setTextureFile(const QString &filename);
QString textureFile() const;
signals:
void dataProxyChanged(QSurfaceDataProxy *proxy);
void selectedPointChanged(const QPoint &position);
void flatShadingEnabledChanged(bool enable);
void flatShadingSupportedChanged(bool enable);
void drawModeChanged(QSurface3DSeries::DrawFlags mode);
void textureChanged(const QImage &image);
void textureFileChanged(const QString &filename);
protected:
explicit QSurface3DSeries(QSurface3DSeriesPrivate *d, QObject *parent = 0);

View File

@ -48,6 +48,7 @@ public:
void setSelectedPoint(const QPoint &position);
void setFlatShadingEnabled(bool enabled);
void setDrawMode(QSurface3DSeries::DrawFlags mode);
void setTexture(const QImage &texture);
private:
QSurface3DSeries *qptr();
@ -55,6 +56,8 @@ private:
QPoint m_selectedPoint;
bool m_flatShadingEnabled;
QSurface3DSeries::DrawFlags m_drawMode;
QImage m_texture;
QString m_textureFile;
private:
friend class QSurface3DSeries;

View File

@ -57,5 +57,7 @@
<file alias="fragmentTexture">shaders/texture.frag</file>
<file alias="fragmentTextureES2">shaders/texture_ES2.frag</file>
<file alias="vertexTexture">shaders/texture.vert</file>
<file alias="fragmentTexturedSurfaceShadowFlat">shaders/surfaceTexturedShadowFlat.frag</file>
<file alias="fragmentSurfaceTexturedFlat">shaders/surfaceTexturedFlat.frag</file>
</qresource>
</RCC>

View File

@ -2062,10 +2062,10 @@ void Scatter3DRenderer::calculateSceneScalingFactors()
m_axisCacheX.setScale(m_scaleX * 2.0f);
m_axisCacheY.setScale(m_scaleY * 2.0f);
m_axisCacheZ.setScale(m_scaleZ * 2.0f);
m_axisCacheZ.setScale(-m_scaleZ * 2.0f);
m_axisCacheX.setTranslate(-m_scaleX);
m_axisCacheY.setTranslate(-m_scaleY);
m_axisCacheZ.setTranslate(-m_scaleZ);
m_axisCacheZ.setTranslate(m_scaleZ);
}
void Scatter3DRenderer::initShaders(const QString &vertexShader, const QString &fragmentShader)

View File

@ -4,6 +4,7 @@
attribute highp vec3 vertexPosition_mdl;
attribute highp vec3 vertexNormal_mdl;
attribute highp vec2 vertexUV;
uniform highp mat4 MVP;
uniform highp mat4 V;
@ -11,6 +12,7 @@ uniform highp mat4 M;
uniform highp mat4 itM;
uniform highp vec3 lightPosition_wrld;
varying highp vec2 UV;
varying highp vec3 position_wrld;
flat varying highp vec3 normal_cmr;
varying highp vec3 eyeDirection_cmr;
@ -26,4 +28,5 @@ void main() {
vec3 lightPosition_cmr = vec4(V * vec4(lightPosition_wrld, 1.0)).xyz;
lightDirection_cmr = lightPosition_cmr + eyeDirection_cmr;
normal_cmr = vec4(V * itM * vec4(vertexNormal_mdl, 0.0)).xyz;
UV = vertexUV;
}

View File

@ -4,6 +4,7 @@
attribute highp vec3 vertexPosition_mdl;
attribute highp vec3 vertexNormal_mdl;
attribute highp vec2 vertexUV;
uniform highp mat4 MVP;
uniform highp mat4 V;
@ -12,6 +13,7 @@ uniform highp mat4 itM;
uniform highp mat4 depthMVP;
uniform highp vec3 lightPosition_wrld;
varying highp vec2 UV;
varying highp vec3 position_wrld;
flat varying highp vec3 normal_cmr;
varying highp vec3 eyeDirection_cmr;
@ -34,4 +36,5 @@ void main() {
vec3 lightPosition_cmr = vec4(V * vec4(lightPosition_wrld, 1.0)).xyz;
lightDirection_cmr = lightPosition_cmr + eyeDirection_cmr;
normal_cmr = vec4(V * itM * vec4(vertexNormal_mdl, 0.0)).xyz;
UV = vertexUV;
}

View File

@ -0,0 +1,39 @@
#version 120
#extension GL_EXT_gpu_shader4 : require
varying highp vec3 coords_mdl;
varying highp vec3 position_wrld;
flat varying highp vec3 normal_cmr;
varying highp vec3 eyeDirection_cmr;
varying highp vec3 lightDirection_cmr;
varying highp vec2 UV;
uniform sampler2D textureSampler;
uniform highp vec3 lightPosition_wrld;
uniform highp float lightStrength;
uniform highp float ambientStrength;
uniform highp vec4 lightColor;
void main() {
highp vec3 materialDiffuseColor = texture2D(textureSampler, UV).xyz;
highp vec3 materialAmbientColor = lightColor.rgb * ambientStrength * materialDiffuseColor;
highp vec3 materialSpecularColor = lightColor.rgb;
highp float distance = length(lightPosition_wrld - position_wrld);
highp vec3 n = normalize(normal_cmr);
highp vec3 l = normalize(lightDirection_cmr);
highp float cosTheta = clamp(dot(n, l), 0.0, 1.0);
highp vec3 E = normalize(eyeDirection_cmr);
highp vec3 R = reflect(-l, n);
highp float cosAlpha = clamp(dot(E, R), 0.0, 1.0);
gl_FragColor.rgb =
materialAmbientColor +
materialDiffuseColor * lightStrength * pow(cosTheta, 2) / distance +
materialSpecularColor * lightStrength * pow(cosAlpha, 10) / distance;
gl_FragColor.a = 1.0;
}

View File

@ -0,0 +1,72 @@
#version 120
#extension GL_EXT_gpu_shader4 : require
varying highp vec3 coords_mdl;
varying highp vec3 position_wrld;
flat varying highp vec3 normal_cmr;
varying highp vec3 eyeDirection_cmr;
varying highp vec3 lightDirection_cmr;
varying highp vec2 UV;
uniform highp sampler2DShadow shadowMap;
uniform sampler2D textureSampler;
varying highp vec4 shadowCoord;
uniform highp vec3 lightPosition_wrld;
uniform highp float lightStrength;
uniform highp float ambientStrength;
uniform highp float shadowQuality;
uniform highp vec4 lightColor;
highp vec2 poissonDisk[16] = vec2[16](vec2(-0.94201624, -0.39906216),
vec2(0.94558609, -0.76890725),
vec2(-0.094184101, -0.92938870),
vec2(0.34495938, 0.29387760),
vec2(-0.91588581, 0.45771432),
vec2(-0.81544232, -0.87912464),
vec2(-0.38277543, 0.27676845),
vec2(0.97484398, 0.75648379),
vec2(0.44323325, -0.97511554),
vec2(0.53742981, -0.47373420),
vec2(-0.26496911, -0.41893023),
vec2(0.79197514, 0.19090188),
vec2(-0.24188840, 0.99706507),
vec2(-0.81409955, 0.91437590),
vec2(0.19984126, 0.78641367),
vec2(0.14383161, -0.14100790));
void main() {
highp vec3 materialDiffuseColor = texture2D(textureSampler, UV).xyz;
highp vec3 materialAmbientColor = lightColor.rgb * ambientStrength * materialDiffuseColor;
highp vec3 materialSpecularColor = lightColor.rgb;
highp vec3 n = normalize(normal_cmr);
highp vec3 l = normalize(lightDirection_cmr);
highp float cosTheta = clamp(dot(n, l), 0.0, 1.0);
highp vec3 E = normalize(eyeDirection_cmr);
highp vec3 R = reflect(-l, n);
highp float cosAlpha = clamp(dot(E, R), 0.0, 1.0);
highp float bias = 0.005 * tan(acos(cosTheta));
bias = clamp(bias, 0.0, 0.01);
vec4 shadCoords = shadowCoord;
shadCoords.z -= bias;
highp float visibility = 0.6;
for (int i = 0; i < 15; i++) {
vec4 shadCoordsPD = shadCoords;
shadCoordsPD.x += cos(poissonDisk[i].x) / shadowQuality;
shadCoordsPD.y += sin(poissonDisk[i].y) / shadowQuality;
visibility += 0.025 * shadow2DProj(shadowMap, shadCoordsPD).r;
}
gl_FragColor.rgb =
(materialAmbientColor +
materialDiffuseColor * lightStrength * cosTheta +
materialSpecularColor * lightStrength * pow(cosAlpha, 10));
gl_FragColor.a = 1.0;
gl_FragColor.rgb = visibility * clamp(gl_FragColor.rgb, 0.0, 1.0);
}

View File

@ -85,6 +85,12 @@ void Surface3DController::synchDataToRenderer()
m_renderer->updateFlipHorizontalGrid(m_flipHorizontalGrid);
m_changeTracker.flipHorizontalGridChanged = false;
}
if (m_changeTracker.surfaceTextureChanged) {
m_renderer->updateSurfaceTextures(m_changedTextures);
m_changeTracker.surfaceTextureChanged = false;
m_changedTextures.clear();
}
}
void Surface3DController::handleAxisAutoAdjustRangeChangedInOrientation(
@ -146,6 +152,9 @@ void Surface3DController::addSeries(QAbstract3DSeries *series)
QSurface3DSeries *surfaceSeries = static_cast<QSurface3DSeries *>(series);
if (surfaceSeries->selectedPoint() != invalidSelectionPosition())
setSelectedPoint(surfaceSeries->selectedPoint(), surfaceSeries, false);
if (!surfaceSeries->texture().isNull())
updateSurfaceTexture(surfaceSeries);
}
void Surface3DController::removeSeries(QAbstract3DSeries *series)
@ -450,6 +459,16 @@ void Surface3DController::handleRowsRemoved(int startIndex, int count)
emitNeedRender();
}
void Surface3DController::updateSurfaceTexture(QSurface3DSeries *series)
{
m_changeTracker.surfaceTextureChanged = true;
if (!m_changedTextures.contains(series))
m_changedTextures.append(series);
emitNeedRender();
}
void Surface3DController::adjustAxisRanges()
{
QValue3DAxis *valueAxisX = static_cast<QValue3DAxis *>(m_axisX);

View File

@ -42,12 +42,14 @@ struct Surface3DChangeBitField {
bool rowsChanged : 1;
bool itemChanged : 1;
bool flipHorizontalGridChanged : 1;
bool surfaceTextureChanged : 1;
Surface3DChangeBitField() :
selectedPointChanged(true),
rowsChanged(false),
itemChanged(false),
flipHorizontalGridChanged(true)
flipHorizontalGridChanged(true),
surfaceTextureChanged(true)
{
}
};
@ -76,6 +78,7 @@ private:
QVector<ChangeItem> m_changedItems;
QVector<ChangeRow> m_changedRows;
bool m_flipHorizontalGrid;
QVector<QSurface3DSeries *> m_changedTextures;
public:
explicit Surface3DController(QRect rect, Q3DScene *scene = 0);
@ -107,6 +110,8 @@ public:
void setFlipHorizontalGrid(bool flip);
bool flipHorizontalGrid() const;
void updateSurfaceTexture(QSurface3DSeries *series);
public slots:
void handleArrayReset();
void handleRowsAdded(int startIndex, int count);

View File

@ -43,6 +43,8 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller)
m_backgroundShader(0),
m_surfaceFlatShader(0),
m_surfaceSmoothShader(0),
m_surfaceTexturedSmoothShader(0),
m_surfaceTexturedFlatShader(0),
m_surfaceGridShader(0),
m_surfaceSliceFlatShader(0),
m_surfaceSliceSmoothShader(0),
@ -104,6 +106,8 @@ Surface3DRenderer::~Surface3DRenderer()
delete m_selectionShader;
delete m_surfaceFlatShader;
delete m_surfaceSmoothShader;
delete m_surfaceTexturedSmoothShader;
delete m_surfaceTexturedFlatShader;
delete m_surfaceGridShader;
delete m_surfaceSliceFlatShader;
delete m_surfaceSliceSmoothShader;
@ -257,6 +261,33 @@ void Surface3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesLis
}
}
void Surface3DRenderer::updateSurfaceTextures(QVector<QSurface3DSeries *> seriesList)
{
foreach (QSurface3DSeries *series, seriesList) {
SurfaceSeriesRenderCache *cache =
static_cast<SurfaceSeriesRenderCache *>(m_renderCacheList.value(series));
if (cache) {
GLuint oldTexture = cache->surfaceTexture();
m_textureHelper->deleteTexture(&oldTexture);
cache->setSurfaceTexture(0);
const QSurface3DSeries *currentSeries = cache->series();
QSurfaceDataProxy *dataProxy = currentSeries->dataProxy();
const QSurfaceDataArray &array = *dataProxy->array();
if (!series->texture().isNull()) {
cache->setSurfaceTexture(m_textureHelper->create2DTexture(
series->texture(), true, true, true));
if (cache->isFlatShadingEnabled())
cache->surfaceObject()->coarseUVs(array, cache->dataArray());
else
cache->surfaceObject()->smoothUVs(array, cache->dataArray());
}
}
}
}
SeriesRenderCache *Surface3DRenderer::createNewCache(QAbstract3DSeries *series)
{
m_selectionTexturesDirty = true;
@ -1191,6 +1222,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
glCullFace(GL_BACK);
}
#endif
// Draw selection buffer
if (!m_cachedIsSlicingActivated && (!m_renderCacheList.isEmpty()
|| !m_customRenderCache.isEmpty())
@ -1220,6 +1252,8 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
MVPMatrix = projectionViewMatrix * modelMatrix;
m_selectionShader->setUniformValue(m_selectionShader->MVP(), MVPMatrix);
cache->surfaceObject()->activateSurfaceTexture(false);
m_drawer->drawObject(m_selectionShader, cache->surfaceObject(),
cache->selectionTexture());
}
@ -1285,8 +1319,13 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
if (cache->surfaceVisible()) {
ShaderHelper *shader = m_surfaceFlatShader;
if (!cache->isFlatShadingEnabled())
if (cache->surfaceTexture())
shader = m_surfaceTexturedFlatShader;
if (!cache->isFlatShadingEnabled()) {
shader = m_surfaceSmoothShader;
if (cache->surfaceTexture())
shader = m_surfaceTexturedSmoothShader;
}
shader->bind();
// Set shader bindings
@ -1300,23 +1339,30 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
m_cachedTheme->ambientLightStrength());
shader->setUniformValue(shader->lightColor(), lightColor);
GLuint gradientTexture;
if (cache->colorStyle() == Q3DTheme::ColorStyleUniform) {
gradientTexture = cache->baseUniformTexture();
shader->setUniformValue(shader->gradientMin(), 0.0f);
shader->setUniformValue(shader->gradientHeight(), 0.0f);
// Set the surface texturing
cache->surfaceObject()->activateSurfaceTexture(false);
GLuint texture;
if (cache->surfaceTexture()) {
texture = cache->surfaceTexture();
cache->surfaceObject()->activateSurfaceTexture(true);
} else {
gradientTexture = cache->baseGradientTexture();
if (cache->colorStyle() == Q3DTheme::ColorStyleObjectGradient) {
float objMin = cache->surfaceObject()->minYValue();
float objMax = cache->surfaceObject()->maxYValue();
float objRange = objMax - objMin;
shader->setUniformValue(shader->gradientMin(), -(objMin / objRange));
shader->setUniformValue(shader->gradientHeight(), 1.0f / objRange);
if (cache->colorStyle() == Q3DTheme::ColorStyleUniform) {
texture = cache->baseUniformTexture();
shader->setUniformValue(shader->gradientMin(), 0.0f);
shader->setUniformValue(shader->gradientHeight(), 0.0f);
} else {
shader->setUniformValue(shader->gradientMin(), 0.5f);
shader->setUniformValue(shader->gradientHeight(),
1.0f / (m_scaleY * 2.0f));
texture = cache->baseGradientTexture();
if (cache->colorStyle() == Q3DTheme::ColorStyleObjectGradient) {
float objMin = cache->surfaceObject()->minYValue();
float objMax = cache->surfaceObject()->maxYValue();
float objRange = objMax - objMin;
shader->setUniformValue(shader->gradientMin(), -(objMin / objRange));
shader->setUniformValue(shader->gradientHeight(), 1.0f / objRange);
} else {
shader->setUniformValue(shader->gradientMin(), 0.5f);
shader->setUniformValue(shader->gradientHeight(),
1.0f / (m_scaleY * 2.0f));
}
}
}
@ -1329,7 +1375,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
shader->setUniformValue(shader->lightS(), adjustedLightStrength);
// Draw the objects
m_drawer->drawObject(shader, cache->surfaceObject(), gradientTexture,
m_drawer->drawObject(shader, cache->surfaceObject(), texture,
m_depthModelTexture);
} else
#endif
@ -1339,7 +1385,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
m_cachedTheme->lightStrength());
// Draw the objects
m_drawer->drawObject(shader, cache->surfaceObject(), gradientTexture);
m_drawer->drawObject(shader, cache->surfaceObject(), texture);
}
}
}
@ -2448,10 +2494,10 @@ void Surface3DRenderer::calculateSceneScalingFactors()
m_axisCacheX.setScale(m_scaleX * 2.0f);
m_axisCacheY.setScale(m_scaleY * 2.0f);
m_axisCacheZ.setScale(m_scaleZ * 2.0f);
m_axisCacheZ.setScale(-m_scaleZ * 2.0f);
m_axisCacheX.setTranslate(-m_scaleX);
m_axisCacheY.setTranslate(-m_scaleY);
m_axisCacheZ.setTranslate(-m_scaleZ);
m_axisCacheZ.setTranslate(m_scaleZ);
}
void Surface3DRenderer::checkFlatSupport(SurfaceSeriesRenderCache *cache)
@ -2470,11 +2516,19 @@ void Surface3DRenderer::updateObjects(SurfaceSeriesRenderCache *cache, bool dime
QSurfaceDataArray &dataArray = cache->dataArray();
const QRect &sampleSpace = cache->sampleSpace();
const QSurface3DSeries *currentSeries = cache->series();
QSurfaceDataProxy *dataProxy = currentSeries->dataProxy();
const QSurfaceDataArray &array = *dataProxy->array();
if (cache->isFlatShadingEnabled()) {
cache->surfaceObject()->setUpData(dataArray, sampleSpace, dimensionChanged, m_polarGraph);
if (cache->surfaceTexture())
cache->surfaceObject()->coarseUVs(array, dataArray);
} else {
cache->surfaceObject()->setUpSmoothData(dataArray, sampleSpace, dimensionChanged,
m_polarGraph);
if (cache->surfaceTexture())
cache->surfaceObject()->smoothUVs(array, dataArray);
}
}
@ -2736,6 +2790,10 @@ void Surface3DRenderer::initShaders(const QString &vertexShader, const QString &
delete m_surfaceFlatShader;
if (m_surfaceSmoothShader)
delete m_surfaceSmoothShader;
if (m_surfaceTexturedSmoothShader)
delete m_surfaceTexturedSmoothShader;
if (m_surfaceTexturedFlatShader)
delete m_surfaceTexturedFlatShader;
if (m_surfaceSliceFlatShader)
delete m_surfaceSliceFlatShader;
if (m_surfaceSliceSmoothShader)
@ -2745,9 +2803,13 @@ void Surface3DRenderer::initShaders(const QString &vertexShader, const QString &
if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
m_surfaceSmoothShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexShadow"),
QStringLiteral(":/shaders/fragmentSurfaceShadowNoTex"));
m_surfaceTexturedSmoothShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexShadow"),
QStringLiteral(":/shaders/fragmentShadow"));
} else {
m_surfaceSmoothShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertex"),
QStringLiteral(":/shaders/fragmentSurface"));
m_surfaceTexturedSmoothShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexTexture"),
QStringLiteral(":/shaders/fragmentTexture"));
}
m_surfaceSliceSmoothShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertex"),
QStringLiteral(":/shaders/fragmentSurface"));
@ -2755,9 +2817,13 @@ void Surface3DRenderer::initShaders(const QString &vertexShader, const QString &
if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
m_surfaceFlatShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSurfaceShadowFlat"),
QStringLiteral(":/shaders/fragmentSurfaceShadowFlat"));
m_surfaceTexturedFlatShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSurfaceShadowFlat"),
QStringLiteral(":/shaders/fragmentTexturedSurfaceShadowFlat"));
} else {
m_surfaceFlatShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSurfaceFlat"),
QStringLiteral(":/shaders/fragmentSurfaceFlat"));
m_surfaceTexturedFlatShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSurfaceFlat"),
QStringLiteral(":/shaders/fragmentSurfaceTexturedFlat"));
}
m_surfaceSliceFlatShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSurfaceFlat"),
QStringLiteral(":/shaders/fragmentSurfaceFlat"));
@ -2770,6 +2836,10 @@ void Surface3DRenderer::initShaders(const QString &vertexShader, const QString &
QStringLiteral(":/shaders/fragmentSurfaceES2"));
m_surfaceFlatShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertex"),
QStringLiteral(":/shaders/fragmentSurfaceES2"));
m_surfaceTexturedSmoothShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexTexture"),
QStringLiteral(":/shaders/fragmentTextureES2"));
m_surfaceTexturedFlatShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexTexture"),
QStringLiteral(":/shaders/fragmentTextureES2"));
m_surfaceSliceSmoothShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertex"),
QStringLiteral(":/shaders/fragmentSurfaceES2"));
m_surfaceSliceFlatShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertex"),
@ -2777,9 +2847,11 @@ void Surface3DRenderer::initShaders(const QString &vertexShader, const QString &
#endif
m_surfaceSmoothShader->initialize();
m_surfaceSliceSmoothShader->initialize();
m_surfaceTexturedSmoothShader->initialize();
if (m_flatSupported) {
m_surfaceFlatShader->initialize();
m_surfaceSliceFlatShader->initialize();
m_surfaceTexturedFlatShader->initialize();
}
}

View File

@ -51,6 +51,8 @@ private:
ShaderHelper *m_backgroundShader;
ShaderHelper *m_surfaceFlatShader;
ShaderHelper *m_surfaceSmoothShader;
ShaderHelper *m_surfaceTexturedSmoothShader;
ShaderHelper *m_surfaceTexturedFlatShader;
ShaderHelper *m_surfaceGridShader;
ShaderHelper *m_surfaceSliceFlatShader;
ShaderHelper *m_surfaceSliceSmoothShader;
@ -87,6 +89,7 @@ public:
void updateData();
void updateSeries(const QList<QAbstract3DSeries *> &seriesList);
void updateSurfaceTextures(QVector<QSurface3DSeries *> seriesList);
SeriesRenderCache *createNewCache(QAbstract3DSeries *series);
void cleanCache(SeriesRenderCache *cache);
void updateSelectionMode(QAbstract3DGraph::SelectionFlags mode);

View File

@ -39,7 +39,8 @@ SurfaceSeriesRenderCache::SurfaceSeriesRenderCache(QAbstract3DSeries *series,
m_sliceSelectionPointer(0),
m_mainSelectionPointer(0),
m_slicePointerActive(false),
m_mainPointerActive(false)
m_mainPointerActive(false),
m_surfaceTexture(0)
{
}
@ -62,8 +63,10 @@ void SurfaceSeriesRenderCache::populate(bool newSeries)
void SurfaceSeriesRenderCache::cleanup(TextureHelper *texHelper)
{
if (QOpenGLContext::currentContext())
if (QOpenGLContext::currentContext()) {
texHelper->deleteTexture(&m_selectionTexture);
texHelper->deleteTexture(&m_surfaceTexture);
}
delete m_surfaceObj;
delete m_sliceSurfaceObj;

View File

@ -85,6 +85,8 @@ public:
inline bool slicePointerActive() const { return m_slicePointerActive; }
inline void setMainPointerActivity(bool activity) { m_mainPointerActive = activity; }
inline bool mainPointerActive() const { return m_mainPointerActive; }
inline void setSurfaceTexture(GLuint texture) { m_surfaceTexture = texture; }
inline GLuint surfaceTexture() const { return m_surfaceTexture; }
protected:
bool m_surfaceVisible;
@ -105,6 +107,7 @@ protected:
SelectionPointer *m_mainSelectionPointer;
bool m_slicePointerActive;
bool m_mainPointerActive;
GLuint m_surfaceTexture;
};
QT_END_NAMESPACE_DATAVISUALIZATION

View File

@ -42,7 +42,7 @@ public:
GLuint vertexBuf();
GLuint normalBuf();
GLuint uvBuf();
virtual GLuint uvBuf();
GLuint elementBuf();
GLuint indexCount();
GLuint indicesType();

View File

@ -31,8 +31,8 @@ SurfaceObject::SurfaceObject(Surface3DRenderer *renderer)
m_axisCacheX(renderer->m_axisCacheX),
m_axisCacheY(renderer->m_axisCacheY),
m_axisCacheZ(renderer->m_axisCacheZ),
m_renderer(renderer)
m_renderer(renderer),
m_returnTextureBuffer(false)
{
m_indicesType = GL_UNSIGNED_INT;
initializeOpenGLFunctions();
@ -41,12 +41,15 @@ SurfaceObject::SurfaceObject(Surface3DRenderer *renderer)
glGenBuffers(1, &m_uvbuffer);
glGenBuffers(1, &m_elementbuffer);
glGenBuffers(1, &m_gridElementbuffer);
glGenBuffers(1, &m_uvTextureBuffer);
}
SurfaceObject::~SurfaceObject()
{
if (QOpenGLContext::currentContext())
if (QOpenGLContext::currentContext()) {
glDeleteBuffers(1, &m_gridElementbuffer);
glDeleteBuffers(1, &m_uvTextureBuffer);
}
}
void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QRect &space,
@ -135,6 +138,37 @@ void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QR
createBuffers(m_vertices, uvs, m_normals, 0, changeGeometry);
}
void SurfaceObject::smoothUVs(const QSurfaceDataArray &dataArray,
const QSurfaceDataArray &modelArray)
{
int columns = dataArray.at(0)->size();
int rows = dataArray.size();
float xRangeNormalizer = dataArray.at(0)->at(columns - 1).x() - dataArray.at(0)->at(0).x();
float zRangeNormalizer = dataArray.at(rows - 1)->at(0).z() - dataArray.at(0)->at(0).z();
float xMin = dataArray.at(0)->at(0).x();
float zMin = dataArray.at(0)->at(0).z();
QVector<QVector2D> uvs;
uvs.resize(m_rows * m_columns);
int index = 0;
for (int i = 0; i < m_rows; i++) {
float y = (modelArray.at(i)->at(0).z() - zMin) / zRangeNormalizer;
const QSurfaceDataRow &p = *modelArray.at(i);
for (int j = 0; j < m_columns; j++) {
float x = (p.at(j).x() - xMin) / xRangeNormalizer;
uvs[index] = QVector2D(x, y);
index++;
}
}
glBindBuffer(GL_ARRAY_BUFFER, m_uvTextureBuffer);
glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(QVector2D),
&uvs.at(0), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
m_returnTextureBuffer = true;
}
void SurfaceObject::updateSmoothRow(const QSurfaceDataArray &dataArray, int rowIndex, bool polar)
{
// Update vertices
@ -426,6 +460,42 @@ void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &s
delete[] indices;
}
void SurfaceObject::coarseUVs(const QSurfaceDataArray &dataArray,
const QSurfaceDataArray &modelArray)
{
int columns = dataArray.at(0)->size();
int rows = dataArray.size();
float xRangeNormalizer = dataArray.at(0)->at(columns - 1).x() - dataArray.at(0)->at(0).x();
float zRangeNormalizer = dataArray.at(rows - 1)->at(0).z() - dataArray.at(0)->at(0).z();
float xMin = dataArray.at(0)->at(0).x();
float zMin = dataArray.at(0)->at(0).z();
QVector<QVector2D> uvs;
uvs.resize(m_rows * m_columns * 2);
int index = 0;
int colLimit = m_columns - 1;
for (int i = 0; i < m_rows; i++) {
float y = (modelArray.at(i)->at(0).z() - zMin) / zRangeNormalizer;
const QSurfaceDataRow &p = *modelArray.at(i);
for (int j = 0; j < m_columns; j++) {
float x = (p.at(j).x() - xMin) / xRangeNormalizer;
uvs[index] = QVector2D(x, y);
index++;
if (j > 0 && j < colLimit) {
uvs[index] = uvs[index - 1];
index++;
}
}
}
glBindBuffer(GL_ARRAY_BUFFER, m_uvTextureBuffer);
glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(QVector2D),
&uvs.at(0), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
m_returnTextureBuffer = true;
}
void SurfaceObject::updateCoarseRow(const QSurfaceDataArray &dataArray, int rowIndex, bool polar)
{
int colLimit = m_columns - 1;
@ -684,6 +754,17 @@ GLuint SurfaceObject::gridElementBuf()
return m_gridElementbuffer;
}
GLuint SurfaceObject::uvBuf()
{
if (!m_meshDataLoaded)
qFatal("No loaded object");
if (m_returnTextureBuffer)
return m_uvTextureBuffer;
else
return m_uvbuffer;
}
GLuint SurfaceObject::gridIndexCount()
{
return m_gridIndexCount;

View File

@ -57,6 +57,8 @@ public:
bool changeGeometry, bool polar, bool flipXZ = false);
void setUpSmoothData(const QSurfaceDataArray &dataArray, const QRect &space,
bool changeGeometry, bool polar, bool flipXZ = false);
void smoothUVs(const QSurfaceDataArray &dataArray, const QSurfaceDataArray &modelArray);
void coarseUVs(const QSurfaceDataArray &dataArray, const QSurfaceDataArray &modelArray);
void updateCoarseRow(const QSurfaceDataArray &dataArray, int rowIndex, bool polar);
void updateSmoothRow(const QSurfaceDataArray &dataArray, int startRow, bool polar);
void updateSmoothItem(const QSurfaceDataArray &dataArray, int row, int column, bool polar);
@ -67,11 +69,13 @@ public:
void createCoarseGridlineIndices(int x, int y, int endX, int endY);
void uploadBuffers();
GLuint gridElementBuf();
GLuint uvBuf();
GLuint gridIndexCount();
QVector3D vertexAt(int column, int row);
void clear();
float minYValue() const { return m_minY; }
float maxYValue() const { return m_maxY; }
inline void activateSurfaceTexture(bool value) { m_returnTextureBuffer = value; }
private:
QVector3D normal(const QVector3D &a, const QVector3D &b, const QVector3D &c, bool flipNormal);
@ -97,6 +101,8 @@ private:
Surface3DRenderer *m_renderer;
float m_minY;
float m_maxY;
GLuint m_uvTextureBuffer;
bool m_returnTextureBuffer;
};
QT_END_NAMESPACE_DATAVISUALIZATION

View File

@ -48,12 +48,12 @@ GraphModifier::GraphModifier(Q3DSurface *graph)
m_zCount(24),
m_activeSample(0),
m_fontSize(40),
m_rangeX(16.0),
m_rangeX(34.0),
m_rangeY(16.0),
m_rangeZ(16.0),
m_minX(-8.0),
m_rangeZ(34.0),
m_minX(-17.0),
m_minY(-8.0),
m_minZ(-8.0),
m_minZ(-17.0),
m_addRowCounter(m_zCount),
m_insertTestZPos(0),
m_insertTestIndexPos(1),
@ -1244,12 +1244,12 @@ void GraphModifier::resetArray()
void GraphModifier::resetArrayEmpty()
{
QSurfaceDataArray *emptryArray = new QSurfaceDataArray;
QSurfaceDataArray *emptyArray = new QSurfaceDataArray;
#ifdef MULTI_SERIES
int series = rand() % 4;
m_multiseries[series]->dataProxy()->resetArray(emptryArray);
m_multiseries[series]->dataProxy()->resetArray(emptyArray);
#else
m_theSeries->dataProxy()->resetArray(emptryArray);
m_theSeries->dataProxy()->resetArray(emptyArray);
#endif
}
@ -1594,3 +1594,11 @@ void GraphModifier::setHorizontalAspectRatio(int ratio)
qreal aspectRatio = qreal(ratio) / 100.0;
m_graph->setHorizontalAspectRatio(aspectRatio);
}
void GraphModifier::setSurfaceTexture(bool enabled)
{
if (enabled)
m_multiseries[3]->setTexture(QImage(":/maps/mapimage"));
else
m_multiseries[3]->setTexture(QImage());
}

View File

@ -112,9 +112,9 @@ public:
void massiveTestAppendAndScroll();
void testAxisReverse();
void testDataOrdering();
void setAspectRatio(int ratio);
void setHorizontalAspectRatio(int ratio);
void setSurfaceTexture(bool enabled);
public slots:
void changeShadowQuality(int quality);

View File

@ -56,7 +56,7 @@ int main(int argc, char *argv[])
surfaceGraph->activeTheme()->setType(Q3DTheme::Theme(initialTheme));
QWidget *container = QWidget::createWindowContainer(surfaceGraph);
container->setMinimumSize(QSize(screenSize.width() / 4, screenSize.height() / 4));
container->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 4));
container->setMaximumSize(screenSize);
container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
container->setFocusPolicy(Qt::StrongFocus);
@ -183,7 +183,7 @@ int main(int argc, char *argv[])
QSlider *axisRangeSliderX = new QSlider(Qt::Horizontal, widget);
axisRangeSliderX->setTickInterval(1);
axisRangeSliderX->setMinimum(1);
axisRangeSliderX->setValue(16);
axisRangeSliderX->setValue(34);
axisRangeSliderX->setMaximum(100);
axisRangeSliderX->setEnabled(true);
QSlider *axisRangeSliderY = new QSlider(Qt::Horizontal, widget);
@ -195,14 +195,14 @@ int main(int argc, char *argv[])
QSlider *axisRangeSliderZ = new QSlider(Qt::Horizontal, widget);
axisRangeSliderZ->setTickInterval(1);
axisRangeSliderZ->setMinimum(1);
axisRangeSliderZ->setValue(16);
axisRangeSliderZ->setValue(34);
axisRangeSliderZ->setMaximum(100);
axisRangeSliderZ->setEnabled(true);
QSlider *axisMinSliderX = new QSlider(Qt::Horizontal, widget);
axisMinSliderX->setTickInterval(1);
axisMinSliderX->setMinimum(-100);
axisMinSliderX->setValue(-8);
axisMinSliderX->setValue(-17);
axisMinSliderX->setMaximum(100);
axisMinSliderX->setEnabled(true);
QSlider *axisMinSliderY = new QSlider(Qt::Horizontal, widget);
@ -214,7 +214,7 @@ int main(int argc, char *argv[])
QSlider *axisMinSliderZ = new QSlider(Qt::Horizontal, widget);
axisMinSliderZ->setTickInterval(1);
axisMinSliderZ->setMinimum(-100);
axisMinSliderZ->setValue(-8);
axisMinSliderZ->setValue(-17);
axisMinSliderZ->setMaximum(100);
axisMinSliderZ->setEnabled(true);
@ -402,6 +402,10 @@ int main(int argc, char *argv[])
polarCB->setText(QStringLiteral("Polar"));
polarCB->setChecked(false);
QCheckBox *surfaceTextureCB = new QCheckBox(widget);
surfaceTextureCB->setText(QStringLiteral("Map texture"));
surfaceTextureCB->setChecked(false);
// Add controls to the layout
#ifdef MULTI_SERIES
vLayout->addWidget(series1CB);
@ -429,6 +433,7 @@ int main(int argc, char *argv[])
vLayout->addWidget(surfaceGridS4CB);
vLayout->addWidget(surfaceS4CB);
vLayout->addWidget(series4VisibleCB);
vLayout->addWidget(surfaceTextureCB);
#endif
#ifndef MULTI_SERIES
vLayout->addWidget(new QLabel(QStringLiteral("Select surface sample")));
@ -669,6 +674,8 @@ int main(int argc, char *argv[])
modifier, &GraphModifier::setAspectRatio);
QObject::connect(horizontalAspectRatioSlider, &QSlider::valueChanged,
modifier, &GraphModifier::setHorizontalAspectRatio);
QObject::connect(surfaceTextureCB, &QCheckBox::stateChanged,
modifier, &GraphModifier::setSurfaceTexture);
#ifdef MULTI_SERIES
modifier->setSeries1CB(series1CB);

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

View File

@ -1,5 +1,6 @@
<RCC>
<qresource prefix="/maps">
<file alias="map">Heightmap.png</file>
<file alias="mapimage">mapimage.png</file>
</qresource>
</RCC>