mirror of https://github.com/qt/qtdatavis3d.git
Reflection API added
Task-number: QTRD-3287 Change-Id: I6c06b8fe025e0f1f87be00be906cab0e1f18a19f Reviewed-by: Miikka Heikkinen <miikka.heikkinen@digia.com>
This commit is contained in:
parent
5a51d06ec8
commit
fcac33d0ee
|
|
@ -340,7 +340,7 @@
|
|||
|
||||
/*!
|
||||
* \qmlproperty AbstractGraph3D.OptimizationHints AbstractGraph3D::optimizationHints
|
||||
* \since Qt Data Visualization 1.1
|
||||
* \since QtDataVisualization 1.1
|
||||
*
|
||||
* Defines if the rendering optimization is default or static. Default mode provides the full feature set at
|
||||
* reasonable performance. Static is a beta level feature and currently supports only a subset of the
|
||||
|
|
@ -351,3 +351,26 @@
|
|||
* with massive data sets is not advisable.
|
||||
* Defaults to \c{OptimizationDefault}
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \qmlproperty bool AbstractGraph3D::reflection
|
||||
* \since QtDataVisualization 1.2
|
||||
*
|
||||
* Sets floor reflections on or off. Defaults to \c{false}.
|
||||
*
|
||||
* \note Affects only Bars3D.
|
||||
*
|
||||
* \sa reflectivity
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \qmlproperty real AbstractGraph3D::reflectivity
|
||||
* \since QtDataVisualization 1.2
|
||||
*
|
||||
* Adjusts floor reflectivity, larger number being more reflective. Valid range is \c{[0...1]}.
|
||||
* Defaults to \c{0.5}.
|
||||
*
|
||||
* \note Affects only Bars3D.
|
||||
*
|
||||
* \sa reflection
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ Abstract3DController::Abstract3DController(QRect initialViewport, Q3DScene *scen
|
|||
m_aspectRatio(2.0),
|
||||
m_horizontalAspectRatio(0.0),
|
||||
m_optimizationHints(QAbstract3DGraph::OptimizationDefault),
|
||||
m_reflectionEnabled(false),
|
||||
m_reflectivity(0.5),
|
||||
m_scene(scene),
|
||||
m_activeInputHandler(0),
|
||||
m_axisX(0),
|
||||
|
|
@ -215,6 +217,17 @@ void Abstract3DController::synchDataToRenderer()
|
|||
m_changeTracker.optimizationHintChanged = false;
|
||||
}
|
||||
|
||||
if (m_changeTracker.reflectionChanged) {
|
||||
m_renderer->m_reflectionEnabled = m_reflectionEnabled;
|
||||
m_changeTracker.reflectionChanged = false;
|
||||
}
|
||||
|
||||
if (m_changeTracker.reflectivityChanged) {
|
||||
// Invert value to match functionality to the property description
|
||||
m_renderer->m_reflectivity = -(m_reflectivity - 1.0);
|
||||
m_changeTracker.reflectivityChanged = false;
|
||||
}
|
||||
|
||||
if (m_changeTracker.axisXFormatterChanged) {
|
||||
m_changeTracker.axisXFormatterChanged = false;
|
||||
if (m_axisX->type() & QAbstract3DAxis::AxisTypeValue) {
|
||||
|
|
@ -1558,6 +1571,36 @@ qreal Abstract3DController::horizontalAspectRatio() const
|
|||
return m_horizontalAspectRatio;
|
||||
}
|
||||
|
||||
void Abstract3DController::setReflection(bool enable)
|
||||
{
|
||||
if (m_reflectionEnabled != enable) {
|
||||
m_reflectionEnabled = enable;
|
||||
m_changeTracker.reflectionChanged = true;
|
||||
emit reflectionChanged(m_reflectionEnabled);
|
||||
emitNeedRender();
|
||||
}
|
||||
}
|
||||
|
||||
bool Abstract3DController::reflection() const
|
||||
{
|
||||
return m_reflectionEnabled;
|
||||
}
|
||||
|
||||
void Abstract3DController::setReflectivity(qreal reflectivity)
|
||||
{
|
||||
if (m_reflectivity != reflectivity) {
|
||||
m_reflectivity = reflectivity;
|
||||
m_changeTracker.reflectivityChanged = true;
|
||||
emit reflectivityChanged(m_reflectivity);
|
||||
emitNeedRender();
|
||||
}
|
||||
}
|
||||
|
||||
qreal Abstract3DController::reflectivity() const
|
||||
{
|
||||
return m_reflectivity;
|
||||
}
|
||||
|
||||
void Abstract3DController::setPolar(bool enable)
|
||||
{
|
||||
if (enable != m_isPolar) {
|
||||
|
|
|
|||
|
|
@ -93,6 +93,8 @@ struct Abstract3DChangeBitField {
|
|||
bool axisZTitleFixedChanged : 1;
|
||||
bool polarChanged : 1;
|
||||
bool radialLabelOffsetChanged : 1;
|
||||
bool reflectionChanged : 1;
|
||||
bool reflectivityChanged : 1;
|
||||
|
||||
Abstract3DChangeBitField() :
|
||||
themeChanged(true),
|
||||
|
|
@ -139,7 +141,9 @@ struct Abstract3DChangeBitField {
|
|||
axisYTitleFixedChanged(true),
|
||||
axisZTitleFixedChanged(true),
|
||||
polarChanged(true),
|
||||
radialLabelOffsetChanged(true)
|
||||
radialLabelOffsetChanged(true),
|
||||
reflectionChanged(true),
|
||||
reflectivityChanged(true)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
|
@ -165,6 +169,8 @@ private:
|
|||
qreal m_aspectRatio;
|
||||
qreal m_horizontalAspectRatio;
|
||||
QAbstract3DGraph::OptimizationHints m_optimizationHints;
|
||||
bool m_reflectionEnabled;
|
||||
qreal m_reflectivity;
|
||||
|
||||
protected:
|
||||
Q3DScene *m_scene;
|
||||
|
|
@ -281,6 +287,11 @@ public:
|
|||
void setHorizontalAspectRatio(qreal ratio);
|
||||
qreal horizontalAspectRatio() const;
|
||||
|
||||
void setReflection(bool enable);
|
||||
bool reflection() const;
|
||||
void setReflectivity(qreal reflectivity);
|
||||
qreal reflectivity() const;
|
||||
|
||||
void setPolar(bool enable);
|
||||
bool isPolar() const;
|
||||
void setRadialLabelOffset(float offset);
|
||||
|
|
@ -365,6 +376,8 @@ signals:
|
|||
void optimizationHintsChanged(QAbstract3DGraph::OptimizationHints hints);
|
||||
void polarChanged(bool enabled);
|
||||
void radialLabelOffsetChanged(float offset);
|
||||
void reflectionChanged(bool enabled);
|
||||
void reflectivityChanged(qreal reflectivity);
|
||||
|
||||
protected:
|
||||
virtual QAbstract3DAxis *createDefaultAxis(QAbstract3DAxis::AxisOrientation orientation);
|
||||
|
|
|
|||
|
|
@ -83,7 +83,9 @@ Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller)
|
|||
m_zFlipRotation(QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, -180.0f)),
|
||||
m_vBackgroundMargin(0.1f),
|
||||
m_hBackgroundMargin(0.1f),
|
||||
m_oldCameraTarget(QVector3D(2000.0f, 2000.0f, 2000.0f)) // Just random invalid target
|
||||
m_oldCameraTarget(QVector3D(2000.0f, 2000.0f, 2000.0f)), // Just random invalid target
|
||||
m_reflectionEnabled(false),
|
||||
m_reflectivity(0.5)
|
||||
{
|
||||
QObject::connect(m_drawer, &Drawer::drawerChanged, this, &Abstract3DRenderer::updateTextures);
|
||||
QObject::connect(this, &Abstract3DRenderer::needRender, controller,
|
||||
|
|
@ -1049,7 +1051,7 @@ void Abstract3DRenderer::updateCustomItem(CustomRenderItem *renderItem)
|
|||
}
|
||||
} else
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
if (!item->d_ptr->m_isVolumeItem)
|
||||
if (!item->d_ptr->m_isVolumeItem)
|
||||
#endif
|
||||
{
|
||||
renderItem->setBlendNeeded(textureImage.hasAlphaChannel());
|
||||
|
|
@ -1097,10 +1099,10 @@ void Abstract3DRenderer::updateCustomItem(CustomRenderItem *renderItem)
|
|||
GLuint oldTexture = renderItem->texture();
|
||||
m_textureHelper->deleteTexture(&oldTexture);
|
||||
GLuint texture = m_textureHelper->create3DTexture(volumeItem->textureData(),
|
||||
volumeItem->textureWidth(),
|
||||
volumeItem->textureHeight(),
|
||||
volumeItem->textureDepth(),
|
||||
volumeItem->textureFormat());
|
||||
volumeItem->textureWidth(),
|
||||
volumeItem->textureHeight(),
|
||||
volumeItem->textureDepth(),
|
||||
volumeItem->textureFormat());
|
||||
renderItem->setTexture(texture);
|
||||
renderItem->setTextureWidth(volumeItem->textureWidth());
|
||||
renderItem->setTextureHeight(volumeItem->textureHeight());
|
||||
|
|
@ -1134,7 +1136,6 @@ void Abstract3DRenderer::updateCustomItemPositions()
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef USE_REFLECTIONS
|
||||
void Abstract3DRenderer::drawCustomItems(RenderingState state,
|
||||
ShaderHelper *regularShader,
|
||||
ShaderHelper *volumeShader,
|
||||
|
|
@ -1145,17 +1146,6 @@ void Abstract3DRenderer::drawCustomItems(RenderingState state,
|
|||
GLuint depthTexture,
|
||||
GLfloat shadowQuality,
|
||||
GLfloat reflection)
|
||||
#else
|
||||
void Abstract3DRenderer::drawCustomItems(RenderingState state,
|
||||
ShaderHelper *regularShader,
|
||||
ShaderHelper *volumeShader,
|
||||
ShaderHelper *volumeSliceShader,
|
||||
const QMatrix4x4 &viewMatrix,
|
||||
const QMatrix4x4 &projectionViewMatrix,
|
||||
const QMatrix4x4 &depthProjectionViewMatrix,
|
||||
GLuint depthTexture,
|
||||
GLfloat shadowQuality)
|
||||
#endif
|
||||
{
|
||||
#if defined(QT_OPENGL_ES_2)
|
||||
Q_UNUSED(volumeShader)
|
||||
|
|
@ -1205,36 +1195,36 @@ void Abstract3DRenderer::drawCustomItems(RenderingState state,
|
|||
* QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, -camRotationY);
|
||||
}
|
||||
|
||||
#ifdef USE_REFLECTIONS
|
||||
if (reflection < 0.0f) {
|
||||
if (item->itemPointer()->d_ptr->m_isLabelItem)
|
||||
continue;
|
||||
else
|
||||
glCullFace(GL_FRONT);
|
||||
} else {
|
||||
glCullFace(GL_BACK);
|
||||
}
|
||||
QVector3D trans = item->translation();
|
||||
trans.setY(reflection * trans.y());
|
||||
modelMatrix.translate(trans);
|
||||
if (reflection < 0.0f) {
|
||||
QQuaternion mirror = QQuaternion(rotation.scalar(),
|
||||
-rotation.x(), rotation.y(), -rotation.z());
|
||||
modelMatrix.rotate(mirror);
|
||||
itModelMatrix.rotate(mirror);
|
||||
if (m_reflectionEnabled) {
|
||||
if (reflection < 0.0f) {
|
||||
if (item->itemPointer()->d_ptr->m_isLabelItem)
|
||||
continue;
|
||||
else
|
||||
glCullFace(GL_FRONT);
|
||||
} else {
|
||||
glCullFace(GL_BACK);
|
||||
}
|
||||
QVector3D trans = item->translation();
|
||||
trans.setY(reflection * trans.y());
|
||||
modelMatrix.translate(trans);
|
||||
if (reflection < 0.0f) {
|
||||
QQuaternion mirror = QQuaternion(rotation.scalar(),
|
||||
-rotation.x(), rotation.y(), -rotation.z());
|
||||
modelMatrix.rotate(mirror);
|
||||
itModelMatrix.rotate(mirror);
|
||||
} else {
|
||||
modelMatrix.rotate(rotation);
|
||||
itModelMatrix.rotate(rotation);
|
||||
}
|
||||
QVector3D scale = item->scaling();
|
||||
scale.setY(reflection * scale.y());
|
||||
modelMatrix.scale(scale);
|
||||
} else {
|
||||
modelMatrix.translate(item->translation());
|
||||
modelMatrix.rotate(rotation);
|
||||
modelMatrix.scale(item->scaling());
|
||||
itModelMatrix.rotate(rotation);
|
||||
}
|
||||
QVector3D scale = item->scaling();
|
||||
scale.setY(reflection * scale.y());
|
||||
modelMatrix.scale(scale);
|
||||
#else
|
||||
modelMatrix.translate(item->translation());
|
||||
modelMatrix.rotate(rotation);
|
||||
modelMatrix.scale(item->scaling());
|
||||
itModelMatrix.rotate(rotation);
|
||||
#endif
|
||||
if (!item->isFacingCamera())
|
||||
itModelMatrix.scale(item->scaling());
|
||||
MVPMatrix = projectionViewMatrix * modelMatrix;
|
||||
|
|
|
|||
|
|
@ -29,8 +29,6 @@
|
|||
#ifndef ABSTRACT3DRENDERER_P_H
|
||||
#define ABSTRACT3DRENDERER_P_H
|
||||
|
||||
//#define USE_REFLECTIONS // Bars only test version (only floor reflects)
|
||||
|
||||
#include <QtGui/QOpenGLFunctions>
|
||||
|
||||
#include "datavisualizationglobal_p.h"
|
||||
|
|
@ -147,21 +145,13 @@ public:
|
|||
void setSelectionLabel(const QString &label);
|
||||
QString &selectionLabel();
|
||||
|
||||
#ifdef USE_REFLECTIONS
|
||||
void drawCustomItems(RenderingState state, ShaderHelper *regularShader,
|
||||
ShaderHelper *volumeShader, ShaderHelper *volumeSliceShader,
|
||||
const QMatrix4x4 &viewMatrix,
|
||||
const QMatrix4x4 &projectionViewMatrix,
|
||||
const QMatrix4x4 &depthProjectionViewMatrix,
|
||||
GLuint depthTexture, GLfloat shadowQuality, GLfloat reflection = 1.0f);
|
||||
#else
|
||||
void drawCustomItems(RenderingState state, ShaderHelper *regularShader,
|
||||
ShaderHelper *volumeShader, ShaderHelper *volumeSliceShader,
|
||||
const QMatrix4x4 &viewMatrix,
|
||||
const QMatrix4x4 &projectionViewMatrix,
|
||||
const QMatrix4x4 &depthProjectionViewMatrix,
|
||||
GLuint depthTexture, GLfloat shadowQuality);
|
||||
#endif
|
||||
|
||||
QVector4D indexToSelectionColor(GLint index);
|
||||
void calculatePolarXZ(const QVector3D &dataPos, float &x, float &z) const;
|
||||
|
||||
|
|
@ -285,6 +275,9 @@ protected:
|
|||
|
||||
QVector3D m_oldCameraTarget;
|
||||
|
||||
bool m_reflectionEnabled;
|
||||
qreal m_reflectivity;
|
||||
|
||||
private:
|
||||
friend class Abstract3DController;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1043,12 +1043,11 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
|
|||
shadowOffset = -0.015f;
|
||||
}
|
||||
|
||||
#ifdef USE_REFLECTIONS
|
||||
if (m_yFlipped && item.height() > 0.0
|
||||
|| !m_yFlipped && item.height() < 0.0) {
|
||||
if (m_reflectionEnabled && (m_yFlipped && item.height() > 0.0
|
||||
|| !m_yFlipped && item.height() < 0.0)) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
QMatrix4x4 modelMatrix;
|
||||
QMatrix4x4 MVPMatrix;
|
||||
|
||||
|
|
@ -1205,61 +1204,65 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
|
|||
m_primarySubViewport.height());
|
||||
}
|
||||
|
||||
#ifdef USE_REFLECTIONS
|
||||
//
|
||||
// Draw reflections
|
||||
//
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
|
||||
glStencilFunc(GL_ALWAYS, 1, 0xffffffff);
|
||||
if (m_reflectionEnabled) {
|
||||
//
|
||||
// Draw reflections
|
||||
//
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
|
||||
glStencilFunc(GL_ALWAYS, 1, 0xffffffff);
|
||||
|
||||
// Draw background stencil
|
||||
drawBackground(backgroundRotation, depthProjectionViewMatrix, projectionViewMatrix, viewMatrix);
|
||||
// Draw background stencil
|
||||
drawBackground(backgroundRotation, depthProjectionViewMatrix, projectionViewMatrix,
|
||||
viewMatrix);
|
||||
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glStencilFunc(GL_EQUAL, 1, 0xffffffff);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
glStencilFunc(GL_EQUAL, 1, 0xffffffff);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
|
||||
// Set light
|
||||
QVector3D reflectionLightPos = lightPos;
|
||||
reflectionLightPos.setY(-(lightPos.y()));
|
||||
m_cachedScene->activeLight()->setPosition(reflectionLightPos);
|
||||
// Set light
|
||||
QVector3D reflectionLightPos = lightPos;
|
||||
reflectionLightPos.setY(-(lightPos.y()));
|
||||
m_cachedScene->activeLight()->setPosition(reflectionLightPos);
|
||||
|
||||
// Draw bar reflections
|
||||
(void)drawBars(&selectedBar, depthProjectionViewMatrix,
|
||||
projectionViewMatrix, viewMatrix,
|
||||
startRow, stopRow, stepRow,
|
||||
startBar, stopBar, stepBar, -1.0f);
|
||||
// Draw bar reflections
|
||||
(void)drawBars(&selectedBar, depthProjectionViewMatrix,
|
||||
projectionViewMatrix, viewMatrix,
|
||||
startRow, stopRow, stepRow,
|
||||
startBar, stopBar, stepBar, -1.0f);
|
||||
|
||||
Abstract3DRenderer::drawCustomItems(RenderingNormal, m_customItemShader, viewMatrix,
|
||||
projectionViewMatrix, depthProjectionViewMatrix,
|
||||
m_depthTexture, m_shadowQualityToShader, -1.0f);
|
||||
Abstract3DRenderer::drawCustomItems(RenderingNormal, m_customItemShader,
|
||||
m_volumeTextureShader, m_volumeTextureSliceShader,
|
||||
viewMatrix, projectionViewMatrix,
|
||||
depthProjectionViewMatrix, m_depthTexture,
|
||||
m_shadowQualityToShader, -1.0f);
|
||||
|
||||
// Reset light
|
||||
m_cachedScene->activeLight()->setPosition(lightPos);
|
||||
// Reset light
|
||||
m_cachedScene->activeLight()->setPosition(lightPos);
|
||||
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
|
||||
glCullFace(GL_BACK);
|
||||
#endif
|
||||
glCullFace(GL_BACK);
|
||||
}
|
||||
|
||||
//
|
||||
// Draw the real scene
|
||||
//
|
||||
// Draw background
|
||||
#ifdef USE_REFLECTIONS
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
drawBackground(backgroundRotation, depthProjectionViewMatrix, projectionViewMatrix, viewMatrix,
|
||||
0.5f);
|
||||
glDisable(GL_BLEND);
|
||||
#else
|
||||
drawBackground(backgroundRotation, depthProjectionViewMatrix, projectionViewMatrix, viewMatrix);
|
||||
#endif
|
||||
if (m_reflectionEnabled) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
drawBackground(backgroundRotation, depthProjectionViewMatrix, projectionViewMatrix,
|
||||
viewMatrix, true);
|
||||
glDisable(GL_BLEND);
|
||||
} else {
|
||||
drawBackground(backgroundRotation, depthProjectionViewMatrix, projectionViewMatrix,
|
||||
viewMatrix);
|
||||
}
|
||||
|
||||
// Draw bars
|
||||
bool barSelectionFound = drawBars(&selectedBar, depthProjectionViewMatrix,
|
||||
|
|
@ -1320,19 +1323,11 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
|
|||
m_selectionDirty = false;
|
||||
}
|
||||
|
||||
#ifdef USE_REFLECTIONS
|
||||
bool Bars3DRenderer::drawBars(BarRenderItem **selectedBar,
|
||||
const QMatrix4x4 &depthProjectionViewMatrix,
|
||||
const QMatrix4x4 &projectionViewMatrix, const QMatrix4x4 &viewMatrix,
|
||||
GLint startRow, GLint stopRow, GLint stepRow,
|
||||
GLint startBar, GLint stopBar, GLint stepBar, GLfloat reflection)
|
||||
#else
|
||||
bool Bars3DRenderer::drawBars(BarRenderItem **selectedBar,
|
||||
const QMatrix4x4 &depthProjectionViewMatrix,
|
||||
const QMatrix4x4 &projectionViewMatrix, const QMatrix4x4 &viewMatrix,
|
||||
GLint startRow, GLint stopRow, GLint stepRow,
|
||||
GLint startBar, GLint stopBar, GLint stepBar)
|
||||
#endif
|
||||
{
|
||||
QVector3D lightPos = m_cachedScene->activeLight()->position();
|
||||
QVector4D lightColor = Utils::vectorFromColor(m_cachedTheme->lightColor());
|
||||
|
|
@ -1437,11 +1432,8 @@ bool Bars3DRenderer::drawBars(BarRenderItem **selectedBar,
|
|||
BarRenderItemRow &renderRow = renderArray[row];
|
||||
for (int bar = startBar; bar != stopBar; bar += stepBar) {
|
||||
BarRenderItem &item = renderRow[bar];
|
||||
#ifdef USE_REFLECTIONS
|
||||
if (reflection * item.height() < 0)
|
||||
#else
|
||||
if (item.height() < 0)
|
||||
#endif
|
||||
float adjustedHeight = reflection * item.height();
|
||||
if (adjustedHeight < 0)
|
||||
glCullFace(GL_FRONT);
|
||||
else
|
||||
glCullFace(GL_BACK);
|
||||
|
|
@ -1453,17 +1445,10 @@ bool Bars3DRenderer::drawBars(BarRenderItem **selectedBar,
|
|||
GLfloat colPos = (bar + seriesPos) * (m_cachedBarSpacing.width());
|
||||
GLfloat rowPos = (row + 0.5f) * (m_cachedBarSpacing.height());
|
||||
|
||||
#ifdef USE_REFLECTIONS
|
||||
modelMatrix.translate((colPos - m_rowWidth) / m_scaleFactor,
|
||||
reflection * item.height(),
|
||||
adjustedHeight,
|
||||
(m_columnDepth - rowPos) / m_scaleFactor);
|
||||
modelScaler.setY(reflection * item.height());
|
||||
#else
|
||||
modelMatrix.translate((colPos - m_rowWidth) / m_scaleFactor,
|
||||
item.height(),
|
||||
(m_columnDepth - rowPos) / m_scaleFactor);
|
||||
modelScaler.setY(item.height());
|
||||
#endif
|
||||
modelScaler.setY(adjustedHeight);
|
||||
if (!seriesRotation.isIdentity() || !item.rotation().isIdentity()) {
|
||||
QQuaternion totalRotation = seriesRotation * item.rotation();
|
||||
modelMatrix.rotate(totalRotation);
|
||||
|
|
@ -1579,16 +1564,15 @@ bool Bars3DRenderer::drawBars(BarRenderItem **selectedBar,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef USE_REFLECTIONS
|
||||
// Skip drawing of 0-height bars and reflections of bars on the "wrong side"
|
||||
if (item.height() != 0
|
||||
&& (reflection == 1.0f || (reflection != 1.0f
|
||||
&& (m_yFlipped && item.height() < 0.0)
|
||||
|| (!m_yFlipped && item.height() > 0.0)))) {
|
||||
#else
|
||||
// Skip drawing of 0-height bars
|
||||
if (item.height() != 0) {
|
||||
#endif
|
||||
if (item.height() == 0) {
|
||||
continue;
|
||||
} else if ((m_reflectionEnabled
|
||||
&& (reflection == 1.0f
|
||||
|| (reflection != 1.0f
|
||||
&& (m_yFlipped && item.height() < 0.0)
|
||||
|| (!m_yFlipped && item.height() > 0.0))))
|
||||
|| !m_reflectionEnabled) {
|
||||
// Skip drawing of 0-height bars and reflections of bars on the "wrong side"
|
||||
// Set shader bindings
|
||||
barShader->setUniformValue(barShader->model(), modelMatrix);
|
||||
barShader->setUniformValue(barShader->nModel(),
|
||||
|
|
@ -1602,12 +1586,9 @@ bool Bars3DRenderer::drawBars(BarRenderItem **selectedBar,
|
|||
}
|
||||
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
#ifdef USE_REFLECTIONS
|
||||
if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone
|
||||
&& reflection == 1.0f) {
|
||||
#else
|
||||
if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
|
||||
#endif
|
||||
if ((m_reflectionEnabled && reflection == 1.0f
|
||||
&& m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone)
|
||||
|| m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
|
||||
// Set shadow shader bindings
|
||||
QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
|
||||
barShader->setUniformValue(barShader->shadowQ(),
|
||||
|
|
@ -1626,14 +1607,11 @@ bool Bars3DRenderer::drawBars(BarRenderItem **selectedBar,
|
|||
#endif
|
||||
{
|
||||
// Set shadowless shader bindings
|
||||
#ifdef USE_REFLECTIONS
|
||||
if (reflection != 1.0f
|
||||
if (m_reflectionEnabled && reflection != 1.0f
|
||||
&& m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
|
||||
barShader->setUniformValue(barShader->lightS(),
|
||||
adjustedLightStrength);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
} else {
|
||||
barShader->setUniformValue(barShader->lightS(), lightStrength);
|
||||
}
|
||||
|
||||
|
|
@ -1653,17 +1631,10 @@ bool Bars3DRenderer::drawBars(BarRenderItem **selectedBar,
|
|||
return barSelectionFound;
|
||||
}
|
||||
|
||||
#ifdef USE_REFLECTIONS
|
||||
void Bars3DRenderer::drawBackground(GLfloat backgroundRotation,
|
||||
const QMatrix4x4 &depthProjectionViewMatrix,
|
||||
const QMatrix4x4 &projectionViewMatrix,
|
||||
const QMatrix4x4 &viewMatrix, GLfloat reflection)
|
||||
#else
|
||||
void Bars3DRenderer::drawBackground(GLfloat backgroundRotation,
|
||||
const QMatrix4x4 &depthProjectionViewMatrix,
|
||||
const QMatrix4x4 &projectionViewMatrix,
|
||||
const QMatrix4x4 &viewMatrix)
|
||||
#endif
|
||||
const QMatrix4x4 &viewMatrix, bool reflectingDraw)
|
||||
{
|
||||
QVector3D lightPos = m_cachedScene->activeLight()->position();
|
||||
QVector4D lightColor = Utils::vectorFromColor(m_cachedTheme->lightColor());
|
||||
|
|
@ -1680,9 +1651,8 @@ void Bars3DRenderer::drawBackground(GLfloat backgroundRotation,
|
|||
|
||||
QVector3D backgroundScaler(m_xScaleFactor, 1.0f, m_zScaleFactor);
|
||||
QVector4D backgroundColor = Utils::vectorFromColor(m_cachedTheme->backgroundColor());
|
||||
#ifdef USE_REFLECTIONS
|
||||
backgroundColor.setW(backgroundColor.w() * reflection);
|
||||
#endif
|
||||
if (m_reflectionEnabled)
|
||||
backgroundColor.setW(backgroundColor.w() * m_reflectivity);
|
||||
|
||||
// Set shader bindings
|
||||
m_backgroundShader->setUniformValue(m_backgroundShader->lightP(), lightPos);
|
||||
|
|
@ -1748,9 +1718,7 @@ void Bars3DRenderer::drawBackground(GLfloat backgroundRotation,
|
|||
m_backgroundShader->setUniformValue(m_backgroundShader->nModel(),
|
||||
itModelMatrix.inverted().transposed());
|
||||
m_backgroundShader->setUniformValue(m_backgroundShader->MVP(), MVPMatrix);
|
||||
#ifdef USE_REFLECTIONS
|
||||
if (reflection != 1.0f) {
|
||||
#endif
|
||||
if (!m_reflectionEnabled || (m_reflectionEnabled && reflectingDraw)) {
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
|
||||
// Set shadow shader bindings
|
||||
|
|
@ -1776,9 +1744,7 @@ void Bars3DRenderer::drawBackground(GLfloat backgroundRotation,
|
|||
// Draw the object
|
||||
m_drawer->drawObject(m_backgroundShader, m_backgroundObj);
|
||||
}
|
||||
#ifdef USE_REFLECTIONS
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2539,6 +2505,10 @@ void Bars3DRenderer::updateShadowQuality(QAbstract3DGraph::ShadowQuality quality
|
|||
// Re-init depth buffer
|
||||
updateDepthBuffer();
|
||||
#endif
|
||||
|
||||
// Redraw to handle both reflections and shadows on background
|
||||
if (m_reflectionEnabled)
|
||||
needRender();
|
||||
}
|
||||
|
||||
void Bars3DRenderer::loadBackgroundMesh()
|
||||
|
|
|
|||
|
|
@ -149,22 +149,13 @@ private:
|
|||
void drawLabels(bool drawSelection, const Q3DCamera *activeCamera,
|
||||
const QMatrix4x4 &viewMatrix, const QMatrix4x4 &projectionMatrix);
|
||||
|
||||
#ifdef USE_REFLECTIONS
|
||||
bool drawBars(BarRenderItem **selectedBar, const QMatrix4x4 &depthProjectionViewMatrix,
|
||||
const QMatrix4x4 &projectionViewMatrix, const QMatrix4x4 &viewMatrix,
|
||||
GLint startRow, GLint stopRow, GLint stepRow,
|
||||
GLint startBar, GLint stopBar, GLint stepBar, GLfloat reflection = 1.0f);
|
||||
void drawBackground(GLfloat backgroundRotation, const QMatrix4x4 &depthProjectionViewMatrix,
|
||||
const QMatrix4x4 &projectionViewMatrix, const QMatrix4x4 &viewMatrix,
|
||||
GLfloat reflection = 1.0f);
|
||||
#else
|
||||
bool drawBars(BarRenderItem **selectedBar, const QMatrix4x4 &depthProjectionViewMatrix,
|
||||
const QMatrix4x4 &projectionViewMatrix, const QMatrix4x4 &viewMatrix,
|
||||
GLint startRow, GLint stopRow, GLint stepRow,
|
||||
GLint startBar, GLint stopBar, GLint stepBar);
|
||||
void drawBackground(GLfloat backgroundRotation, const QMatrix4x4 &depthProjectionViewMatrix,
|
||||
const QMatrix4x4 &projectionViewMatrix, const QMatrix4x4 &viewMatrix);
|
||||
#endif
|
||||
bool reflectingDraw = false);
|
||||
void drawGridLines(const QMatrix4x4 &depthProjectionViewMatrix,
|
||||
const QMatrix4x4 &projectionViewMatrix,
|
||||
const QMatrix4x4 &viewMatrix);
|
||||
|
|
|
|||
|
|
@ -722,6 +722,47 @@ qreal QAbstract3DGraph::horizontalAspectRatio() const
|
|||
return d_ptr->m_visualController->horizontalAspectRatio();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \property QAbstract3DGraph::reflection
|
||||
* \since QtDataVisualization 1.2
|
||||
*
|
||||
* Sets floor reflections on or off. Defaults to \c{false}.
|
||||
*
|
||||
* \note Affects only Q3DBars.
|
||||
*
|
||||
* \sa reflectivity
|
||||
*/
|
||||
void QAbstract3DGraph::setReflection(bool enable)
|
||||
{
|
||||
d_ptr->m_visualController->setReflection(enable);
|
||||
}
|
||||
|
||||
bool QAbstract3DGraph::isReflection() const
|
||||
{
|
||||
return d_ptr->m_visualController->reflection();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \property QAbstract3DGraph::reflectivity
|
||||
* \since QtDataVisualization 1.2
|
||||
*
|
||||
* Adjusts floor reflectivity, larger number being more reflective. Valid range is \c{[0...1]}.
|
||||
* Defaults to \c{0.5}.
|
||||
*
|
||||
* \note Affects only Q3DBars.
|
||||
*
|
||||
* \sa reflection
|
||||
*/
|
||||
void QAbstract3DGraph::setReflectivity(qreal reflectivity)
|
||||
{
|
||||
d_ptr->m_visualController->setReflectivity(reflectivity);
|
||||
}
|
||||
|
||||
qreal QAbstract3DGraph::reflectivity() const
|
||||
{
|
||||
return d_ptr->m_visualController->reflectivity();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
|
|
@ -878,6 +919,11 @@ void QAbstract3DGraphPrivate::setVisualController(Abstract3DController *controll
|
|||
&QAbstract3DGraph::radialLabelOffsetChanged);
|
||||
QObject::connect(m_visualController, &Abstract3DController::horizontalAspectRatioChanged, q_ptr,
|
||||
&QAbstract3DGraph::horizontalAspectRatioChanged);
|
||||
|
||||
QObject::connect(m_visualController, &Abstract3DController::reflectionChanged, q_ptr,
|
||||
&QAbstract3DGraph::reflectionChanged);
|
||||
QObject::connect(m_visualController, &Abstract3DController::reflectivityChanged, q_ptr,
|
||||
&QAbstract3DGraph::reflectivityChanged);
|
||||
}
|
||||
|
||||
void QAbstract3DGraphPrivate::handleDevicePixelRatioChange()
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@ class QT_DATAVISUALIZATION_EXPORT QAbstract3DGraph : public QWindow, protected Q
|
|||
Q_PROPERTY(bool polar READ isPolar WRITE setPolar NOTIFY polarChanged)
|
||||
Q_PROPERTY(float radialLabelOffset READ radialLabelOffset WRITE setRadialLabelOffset NOTIFY radialLabelOffsetChanged)
|
||||
Q_PROPERTY(qreal horizontalAspectRatio READ horizontalAspectRatio WRITE setHorizontalAspectRatio NOTIFY horizontalAspectRatioChanged)
|
||||
Q_PROPERTY(bool reflection READ isReflection WRITE setReflection NOTIFY reflectionChanged)
|
||||
Q_PROPERTY(qreal reflectivity READ reflectivity WRITE setReflectivity NOTIFY reflectivityChanged)
|
||||
|
||||
protected:
|
||||
explicit QAbstract3DGraph(QAbstract3DGraphPrivate *d, const QSurfaceFormat *format,
|
||||
|
|
@ -162,6 +164,12 @@ public:
|
|||
void setHorizontalAspectRatio(qreal ratio);
|
||||
qreal horizontalAspectRatio() const;
|
||||
|
||||
void setReflection(bool enable);
|
||||
bool isReflection() const;
|
||||
|
||||
void setReflectivity(qreal reflectivity);
|
||||
qreal reflectivity() const;
|
||||
|
||||
protected:
|
||||
bool event(QEvent *event);
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
|
|
@ -188,6 +196,8 @@ signals:
|
|||
void polarChanged(bool enabled);
|
||||
void radialLabelOffsetChanged(float offset);
|
||||
void horizontalAspectRatioChanged(qreal ratio);
|
||||
void reflectionChanged(bool enabled);
|
||||
void reflectivityChanged(qreal reflectivity);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QAbstract3DGraph)
|
||||
|
|
|
|||
|
|
@ -760,6 +760,26 @@ qreal AbstractDeclarative::horizontalAspectRatio() const
|
|||
return m_controller->horizontalAspectRatio();
|
||||
}
|
||||
|
||||
void AbstractDeclarative::setReflection(bool enable)
|
||||
{
|
||||
m_controller->setReflection(enable);
|
||||
}
|
||||
|
||||
bool AbstractDeclarative::isReflection() const
|
||||
{
|
||||
return m_controller->reflection();
|
||||
}
|
||||
|
||||
void AbstractDeclarative::setReflectivity(qreal reflectivity)
|
||||
{
|
||||
m_controller->setReflectivity(reflectivity);
|
||||
}
|
||||
|
||||
qreal AbstractDeclarative::reflectivity() const
|
||||
{
|
||||
return m_controller->reflectivity();
|
||||
}
|
||||
|
||||
void AbstractDeclarative::windowDestroyed(QObject *obj)
|
||||
{
|
||||
// Remove destroyed window from window lists
|
||||
|
|
|
|||
|
|
@ -75,6 +75,8 @@ class AbstractDeclarative : public QQuickItem
|
|||
Q_PROPERTY(bool polar READ isPolar WRITE setPolar NOTIFY polarChanged REVISION 2)
|
||||
Q_PROPERTY(float radialLabelOffset READ radialLabelOffset WRITE setRadialLabelOffset NOTIFY radialLabelOffsetChanged REVISION 2)
|
||||
Q_PROPERTY(qreal horizontalAspectRatio READ horizontalAspectRatio WRITE setHorizontalAspectRatio NOTIFY horizontalAspectRatioChanged REVISION 2)
|
||||
Q_PROPERTY(bool reflection READ isReflection WRITE setReflection NOTIFY reflectionChanged REVISION 2)
|
||||
Q_PROPERTY(qreal reflectivity READ reflectivity WRITE setReflectivity NOTIFY reflectivityChanged REVISION 2)
|
||||
|
||||
public:
|
||||
enum SelectionFlag {
|
||||
|
|
@ -205,6 +207,12 @@ public:
|
|||
void setHorizontalAspectRatio(qreal ratio);
|
||||
qreal horizontalAspectRatio() const;
|
||||
|
||||
void setReflection(bool enable);
|
||||
bool isReflection() const;
|
||||
|
||||
void setReflectivity(qreal reflectivity);
|
||||
qreal reflectivity() const;
|
||||
|
||||
public slots:
|
||||
virtual void handleAxisXChanged(QAbstract3DAxis *axis) = 0;
|
||||
virtual void handleAxisYChanged(QAbstract3DAxis *axis) = 0;
|
||||
|
|
@ -245,6 +253,8 @@ signals:
|
|||
Q_REVISION(2) void polarChanged(bool enabled);
|
||||
Q_REVISION(2) void radialLabelOffsetChanged(float offset);
|
||||
Q_REVISION(2) void horizontalAspectRatioChanged(qreal ratio);
|
||||
Q_REVISION(2) void reflectionChanged(bool enabled);
|
||||
Q_REVISION(2) void reflectivityChanged(qreal reflectivity);
|
||||
|
||||
private:
|
||||
QPointer<Abstract3DController> m_controller;
|
||||
|
|
|
|||
|
|
@ -1712,3 +1712,14 @@ void GraphModifier::toggleMultiseriesScaling()
|
|||
{
|
||||
m_graph->setMultiSeriesUniform(!m_graph->isMultiSeriesUniform());
|
||||
}
|
||||
|
||||
void GraphModifier::setReflection(bool enabled)
|
||||
{
|
||||
m_graph->setReflection(enabled);
|
||||
}
|
||||
|
||||
void GraphModifier::setReflectivity(int value)
|
||||
{
|
||||
qreal reflectivity = (qreal)value / 100.0;
|
||||
m_graph->setReflectivity(reflectivity);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,6 +97,8 @@ public:
|
|||
void setInputHandlerRotationEnabled(int enabled);
|
||||
void setInputHandlerZoomEnabled(int enabled);
|
||||
void setInputHandlerSelectionEnabled(int enabled);
|
||||
void setReflection(bool enabled);
|
||||
void setReflectivity(int value);
|
||||
|
||||
public slots:
|
||||
void flipViews();
|
||||
|
|
|
|||
|
|
@ -253,6 +253,15 @@ int main(int argc, char **argv)
|
|||
ratioSlider->setValue(30);
|
||||
ratioSlider->setMaximum(100);
|
||||
|
||||
QCheckBox *reflectionCheckBox = new QCheckBox(widget);
|
||||
reflectionCheckBox->setText(QStringLiteral("Show reflections"));
|
||||
reflectionCheckBox->setChecked(false);
|
||||
|
||||
QSlider *reflectivitySlider = new QSlider(Qt::Horizontal, widget);
|
||||
reflectivitySlider->setMinimum(0);
|
||||
reflectivitySlider->setValue(50);
|
||||
reflectivitySlider->setMaximum(100);
|
||||
|
||||
QSlider *spacingSliderX = new QSlider(Qt::Horizontal, widget);
|
||||
spacingSliderX->setTickInterval(1);
|
||||
spacingSliderX->setMinimum(0);
|
||||
|
|
@ -420,8 +429,9 @@ int main(int argc, char **argv)
|
|||
vLayout3->addWidget(new QLabel(QStringLiteral("Camera target")), 0, Qt::AlignTop);
|
||||
vLayout3->addWidget(cameraTargetSliderX, 0, Qt::AlignTop);
|
||||
vLayout3->addWidget(cameraTargetSliderY, 0, Qt::AlignTop);
|
||||
vLayout3->addWidget(cameraTargetSliderZ, 1, Qt::AlignTop);
|
||||
// TODO: Add example for setMeshFileName
|
||||
vLayout3->addWidget(cameraTargetSliderZ, 0, Qt::AlignTop);
|
||||
vLayout3->addWidget(reflectionCheckBox, 0, Qt::AlignTop);
|
||||
vLayout3->addWidget(reflectivitySlider, 1, Qt::AlignTop);
|
||||
|
||||
widget->show();
|
||||
|
||||
|
|
@ -550,6 +560,11 @@ int main(int argc, char **argv)
|
|||
QObject::connect(rotationCheckBox, &QCheckBox::stateChanged, rotationSliderY,
|
||||
&QSlider::setValue);
|
||||
|
||||
QObject::connect(reflectionCheckBox, &QCheckBox::stateChanged, modifier,
|
||||
&GraphModifier::setReflection);
|
||||
QObject::connect(reflectivitySlider, &QSlider::valueChanged, modifier,
|
||||
&GraphModifier::setReflectivity);
|
||||
|
||||
QObject::connect(staticCheckBox, &QCheckBox::stateChanged, addDataButton,
|
||||
&QPushButton::setEnabled);
|
||||
QObject::connect(staticCheckBox, &QCheckBox::stateChanged, addMultiDataButton,
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ Rectangle {
|
|||
xRotation: camControlArea.xValue
|
||||
yRotation: camControlArea.yValue
|
||||
zoomLevel: zoomSlider.value
|
||||
target: Qt.vector3d(1.0, 1.0, 1.0)
|
||||
target: Qt.vector3d(0.5, 0.5, 0.5)
|
||||
}
|
||||
|
||||
Item {
|
||||
|
|
@ -214,4 +214,20 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: reflectionToggle
|
||||
anchors.bottom: shuttleAdd.top
|
||||
width: camControlArea.width
|
||||
text: "Show reflections"
|
||||
onClicked: {
|
||||
if (testChart.reflection === true) {
|
||||
text = "Show reflections"
|
||||
testChart.reflection = false
|
||||
} else {
|
||||
text = "Hide reflections"
|
||||
testChart.reflection = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue