summaryrefslogtreecommitdiffstats
path: root/src/datavisualization/engine
diff options
context:
space:
mode:
authorTomi Korpipää <tomi.korpipaa@digia.com>2014-04-15 10:32:03 +0300
committerTomi Korpipää <tomi.korpipaa@digia.com>2014-04-15 10:40:38 +0300
commita30c0c304e55ffe30545ab0838e4dbe11a99b8da (patch)
treece6ccc0e4de8e350aebec466ff0a70c0fd7710bc /src/datavisualization/engine
parent79646ac9664745701667104c19bbae8cba8fd2e3 (diff)
Add custom item support, part 1
Task-number: QTRD-2866 + Added API for adding and removing custom items + Added custom data and custom render items + Added shaders for textured objects + Added custom item rendering draft to scatter + Fixed some shaders - to be continued in part 2 Change-Id: I9735fd02fc9e86ae486cca4c06f6d7f2a4b0b7da Reviewed-by: Mika Salmela <mika.salmela@digia.com>
Diffstat (limited to 'src/datavisualization/engine')
-rw-r--r--src/datavisualization/engine/abstract3dcontroller.cpp39
-rw-r--r--src/datavisualization/engine/abstract3dcontroller_p.h8
-rw-r--r--src/datavisualization/engine/abstract3drenderer.cpp20
-rw-r--r--src/datavisualization/engine/abstract3drenderer_p.h15
-rw-r--r--src/datavisualization/engine/bars3drenderer.cpp25
-rw-r--r--src/datavisualization/engine/bars3drenderer_p.h4
-rw-r--r--src/datavisualization/engine/engine.qrc2
-rw-r--r--src/datavisualization/engine/qabstract3dgraph.cpp32
-rw-r--r--src/datavisualization/engine/qabstract3dgraph.h8
-rw-r--r--src/datavisualization/engine/scatter3drenderer.cpp124
-rw-r--r--src/datavisualization/engine/scatter3drenderer_p.h6
-rw-r--r--src/datavisualization/engine/shaders/default.vert8
-rw-r--r--src/datavisualization/engine/shaders/shadow.vert8
-rw-r--r--src/datavisualization/engine/shaders/surfaceFlat.vert8
-rw-r--r--src/datavisualization/engine/shaders/surfaceShadowFlat.vert8
-rw-r--r--src/datavisualization/engine/shaders/texture.frag37
-rw-r--r--src/datavisualization/engine/shaders/texture_ES2.frag40
-rw-r--r--src/datavisualization/engine/surface3drenderer.cpp32
-rw-r--r--src/datavisualization/engine/surface3drenderer_p.h4
19 files changed, 403 insertions, 25 deletions
diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp
index 885904d4..e10069ff 100644
--- a/src/datavisualization/engine/abstract3dcontroller.cpp
+++ b/src/datavisualization/engine/abstract3dcontroller.cpp
@@ -50,6 +50,7 @@ Abstract3DController::Abstract3DController(QRect initialViewport, Q3DScene *scen
m_axisZ(0),
m_renderer(0),
m_isDataDirty(true),
+ m_isCustomDataDirty(true),
m_isSeriesVisualsDirty(true),
m_renderPending(false),
m_measureFps(false),
@@ -87,6 +88,9 @@ Abstract3DController::~Abstract3DController()
destroyRenderer();
delete m_scene;
delete m_themeManager;
+ foreach (CustomDataItem *item, m_customItems)
+ delete item;
+ m_customItems.clear();
}
void Abstract3DController::destroyRenderer()
@@ -369,6 +373,11 @@ void Abstract3DController::synchDataToRenderer()
m_renderer->updateData();
m_isDataDirty = false;
}
+
+ if (m_isCustomDataDirty) {
+ m_renderer->updateCustomData(m_customItems);
+ m_isCustomDataDirty = false;
+ }
}
void Abstract3DController::render(const GLuint defaultFboHandle)
@@ -814,6 +823,30 @@ void Abstract3DController::requestRender(QOpenGLFramebufferObject *fbo)
m_renderer->render(fbo->handle());
}
+int Abstract3DController::addCustomItem(const QString &meshFile, const QVector3D &position,
+ const QVector3D &scaling, const QQuaternion &rotation,
+ const QImage &textureImage)
+{
+ CustomDataItem *newItem = new CustomDataItem();
+ newItem->setMeshFile(meshFile);
+ newItem->setPosition(position);
+ newItem->setScaling(scaling);
+ newItem->setRotation(rotation);
+ newItem->setTextureImage(textureImage);
+ m_customItems.append(newItem);
+ m_isCustomDataDirty = true;
+ emitNeedRender();
+ return m_customItems.count() - 1;
+}
+
+void Abstract3DController::deleteCustomItem(int index)
+{
+ delete m_customItems[index];
+ m_customItems.removeAt(index);
+ m_isCustomDataDirty = true;
+ emitNeedRender();
+}
+
void Abstract3DController::handleAxisTitleChanged(const QString &title)
{
Q_UNUSED(title)
@@ -974,9 +1007,9 @@ void Abstract3DController::setMeasureFps(bool enable)
m_currentFps = 0.0;
if (enable) {
- m_frameTimer.start();
- m_numFrames = -1;
- emitNeedRender();
+ m_frameTimer.start();
+ m_numFrames = -1;
+ emitNeedRender();
}
emit measureFpsChanged(enable);
}
diff --git a/src/datavisualization/engine/abstract3dcontroller_p.h b/src/datavisualization/engine/abstract3dcontroller_p.h
index 4f597769..98df8fda 100644
--- a/src/datavisualization/engine/abstract3dcontroller_p.h
+++ b/src/datavisualization/engine/abstract3dcontroller_p.h
@@ -35,6 +35,7 @@
#include "qabstract3dinputhandler.h"
#include "qabstractdataproxy.h"
#include "q3dscene_p.h"
+#include "customdataitem_p.h"
#include <QtGui/QLinearGradient>
#include <QtCore/QTime>
@@ -155,6 +156,7 @@ protected:
QList<QAbstract3DAxis *> m_axes; // List of all added axes
Abstract3DRenderer *m_renderer;
bool m_isDataDirty;
+ bool m_isCustomDataDirty;
bool m_isSeriesVisualsDirty;
bool m_renderPending;
@@ -167,6 +169,8 @@ protected:
QVector<QAbstract3DSeries *> m_changedSeriesList;
+ QList<CustomDataItem *> m_customItems;
+
explicit Abstract3DController(QRect initialViewport, Q3DScene *scene, QObject *parent = 0);
public:
@@ -226,6 +230,10 @@ public:
void requestRender(QOpenGLFramebufferObject *fbo);
+ int addCustomItem(const QString &meshFile, const QVector3D &position, const QVector3D &scaling,
+ const QQuaternion &rotation, const QImage &textureImage);
+ void deleteCustomItem(int index);
+
void emitNeedRender();
virtual void clearSelection() = 0;
diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp
index f70d128b..1cb4bdba 100644
--- a/src/datavisualization/engine/abstract3drenderer.cpp
+++ b/src/datavisualization/engine/abstract3drenderer.cpp
@@ -27,6 +27,7 @@
#include "q3dtheme_p.h"
#include "objecthelper_p.h"
#include "qvalue3daxisformatter_p.h"
+#include "shaderhelper_p.h"
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -48,7 +49,8 @@ Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller)
m_clickedSeries(0),
m_clickedType(QAbstract3DGraph::ElementNone),
m_selectionLabelItem(0),
- m_visibleSeriesCount(0)
+ m_visibleSeriesCount(0),
+ m_customItemShader(0)
{
QObject::connect(m_drawer, &Drawer::drawerChanged, this, &Abstract3DRenderer::updateTextures);
@@ -65,6 +67,7 @@ Abstract3DRenderer::~Abstract3DRenderer()
delete m_cachedScene;
delete m_cachedTheme;
delete m_selectionLabelItem;
+ delete m_customItemShader;
foreach (SeriesRenderCache *cache, m_renderCacheList) {
cache->cleanup(m_textureHelper);
@@ -140,6 +143,15 @@ void Abstract3DRenderer::initGradientShaders(const QString &vertexShader,
Q_UNUSED(fragmentShader)
}
+void Abstract3DRenderer::initCustomItemShaders(const QString &vertexShader,
+ const QString &fragmentShader)
+{
+ if (m_customItemShader)
+ delete m_customItemShader;
+ m_customItemShader = new ShaderHelper(this, vertexShader, fragmentShader);
+ m_customItemShader->initialize();
+}
+
void Abstract3DRenderer::updateTheme(Q3DTheme *theme)
{
// Synchronize the controller theme with renderer
@@ -206,6 +218,8 @@ void Abstract3DRenderer::reInitShaders()
QStringLiteral(":/shaders/fragmentShadowNoTex"));
initBackgroundShaders(QStringLiteral(":/shaders/vertexShadow"),
QStringLiteral(":/shaders/fragmentShadowNoTex"));
+ initCustomItemShaders(QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentShadow"));
} else {
initGradientShaders(QStringLiteral(":/shaders/vertex"),
QStringLiteral(":/shaders/fragmentColorOnY"));
@@ -213,6 +227,8 @@ void Abstract3DRenderer::reInitShaders()
QStringLiteral(":/shaders/fragment"));
initBackgroundShaders(QStringLiteral(":/shaders/vertex"),
QStringLiteral(":/shaders/fragment"));
+ initCustomItemShaders(QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentTexture"));
}
#else
initGradientShaders(QStringLiteral(":/shaders/vertex"),
@@ -221,6 +237,8 @@ void Abstract3DRenderer::reInitShaders()
QStringLiteral(":/shaders/fragmentES2"));
initBackgroundShaders(QStringLiteral(":/shaders/vertex"),
QStringLiteral(":/shaders/fragmentES2"));
+ initCustomItemShaders(QStringLiteral(":/shaders/vertex"), // TODO: Need new shader? At least this one doesn't work
+ QStringLiteral(":/shaders/fragmentTextureES2"));
#endif
}
diff --git a/src/datavisualization/engine/abstract3drenderer_p.h b/src/datavisualization/engine/abstract3drenderer_p.h
index ce21deff..884c0f39 100644
--- a/src/datavisualization/engine/abstract3drenderer_p.h
+++ b/src/datavisualization/engine/abstract3drenderer_p.h
@@ -36,6 +36,7 @@
#include "axisrendercache_p.h"
#include "qabstractdataproxy.h"
#include "seriesrendercache_p.h"
+#include "customrenderitem_p.h"
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -55,13 +56,20 @@ protected:
SelectOnSlice
};
-// QString generateValueLabel(const QString &format, float value);
+ enum RenderingState {
+ RenderingNormal = 0,
+ RenderingSelection,
+ RenderingDepth
+ };
+
+ // QString generateValueLabel(const QString &format, float value);
public:
virtual ~Abstract3DRenderer();
virtual void updateData() = 0;
virtual void updateSeries(const QList<QAbstract3DSeries *> &seriesList);
+ virtual void updateCustomData(const QList<CustomDataItem *> &customItems) = 0;
virtual SeriesRenderCache *createNewCache(QAbstract3DSeries *series);
virtual void cleanCache(SeriesRenderCache *cache);
virtual void render(GLuint defaultFboHandle);
@@ -82,6 +90,8 @@ public:
virtual void initGradientShaders(const QString &vertexShader, const QString &fragmentShader);
virtual void initBackgroundShaders(const QString &vertexShader,
const QString &fragmentShader) = 0;
+ virtual void initCustomItemShaders(const QString &vertexShader,
+ const QString &fragmentShader);
virtual void updateAxisType(QAbstract3DAxis::AxisOrientation orientation,
QAbstract3DAxis::AxisType type);
virtual void updateAxisTitle(QAbstract3DAxis::AxisOrientation orientation,
@@ -150,6 +160,7 @@ protected:
SelectionState m_selectionState;
QPoint m_inputPosition;
QHash<QAbstract3DSeries *, SeriesRenderCache *> m_renderCacheList;
+ CustomRenderItemArray m_customRenderCache;
QRect m_primarySubViewport;
QRect m_secondarySubViewport;
float m_devicePixelRatio;
@@ -161,6 +172,8 @@ protected:
QString m_selectionLabel;
LabelItem *m_selectionLabelItem;
int m_visibleSeriesCount;
+
+ ShaderHelper *m_customItemShader;
};
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp
index c8b25463..f02b9910 100644
--- a/src/datavisualization/engine/bars3drenderer.cpp
+++ b/src/datavisualization/engine/bars3drenderer.cpp
@@ -299,6 +299,11 @@ void Bars3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesList)
m_selectionLabelDirty = true;
}
+void Bars3DRenderer::updateCustomData(const QList<CustomDataItem *> &customItems)
+{
+ // TODO
+}
+
SeriesRenderCache *Bars3DRenderer::createNewCache(QAbstract3DSeries *series)
{
return new BarSeriesRenderCache(series, this);
@@ -987,6 +992,9 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
}
}
+ drawCustomItems(RenderingDepth, m_depthShader, activeCamera, projectionMatrix,
+ depthProjectionMatrix);
+
// Disable drawing to depth framebuffer (= enable drawing to screen)
glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle);
@@ -1067,6 +1075,8 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
}
}
glCullFace(GL_BACK);
+ drawCustomItems(RenderingSelection, m_selectionShader, activeCamera, projectionMatrix,
+ depthProjectionMatrix);
drawLabels(true, activeCamera, viewMatrix, projectionMatrix, rowScaleFactor,
columnScaleFactor);
glEnable(GL_DITHER);
@@ -1363,6 +1373,9 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
glDisable(GL_POLYGON_OFFSET_FILL);
+ drawCustomItems(RenderingNormal, m_customItemShader, activeCamera, projectionMatrix,
+ depthProjectionMatrix);
+
// Bind background shader
m_backgroundShader->bind();
@@ -1732,6 +1745,14 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
m_selectionDirty = false;
}
+void Bars3DRenderer::drawCustomItems(RenderingState state, ShaderHelper *shader,
+ const Q3DCamera *activeCamera,
+ const QMatrix4x4 &projectionMatrix,
+ const QMatrix4x4 &depthProjectionMatrix)
+{
+ // TODO
+}
+
void Bars3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCamera,
const QMatrix4x4 &viewMatrix, const QMatrix4x4 &projectionMatrix,
GLfloat rowScaleFactor, GLfloat columnScaleFactor) {
@@ -2189,6 +2210,10 @@ QPoint Bars3DRenderer::selectionColorToArrayPosition(const QVector4D &selectionC
position = Bars3DController::invalidSelectionPosition();
// Pass label clicked info to input handler
m_clickedType = QAbstract3DGraph::ElementAxisYLabel;
+ } else if (selectionColor.w() == customItemAlpha) {
+ // Custom item selection
+ position = Bars3DController::invalidSelectionPosition();
+ m_clickedType = QAbstract3DGraph::ElementCustomItem;
}
return position;
}
diff --git a/src/datavisualization/engine/bars3drenderer_p.h b/src/datavisualization/engine/bars3drenderer_p.h
index 549a63f6..efe84d39 100644
--- a/src/datavisualization/engine/bars3drenderer_p.h
+++ b/src/datavisualization/engine/bars3drenderer_p.h
@@ -115,6 +115,7 @@ public:
void updateData();
void updateSeries(const QList<QAbstract3DSeries *> &seriesList);
+ void updateCustomData(const QList<CustomDataItem *> &customItems);
SeriesRenderCache *createNewCache(QAbstract3DSeries *series);
void updateScene(Q3DScene *scene);
void render(GLuint defaultFboHandle = 0);
@@ -145,6 +146,9 @@ private:
void drawSlicedScene();
void drawScene(GLuint defaultFboHandle);
+ void drawCustomItems(RenderingState state, ShaderHelper *shader, const Q3DCamera *activeCamera,
+ const QMatrix4x4 &projectionMatrix,
+ const QMatrix4x4 &depthProjectionMatrix);
void drawLabels(bool drawSelection, const Q3DCamera *activeCamera,
const QMatrix4x4 &viewMatrix, const QMatrix4x4 &projectionMatrix,
GLfloat rowScaleFactor, GLfloat columnScaleFactor);
diff --git a/src/datavisualization/engine/engine.qrc b/src/datavisualization/engine/engine.qrc
index 18cba7fe..38a9e651 100644
--- a/src/datavisualization/engine/engine.qrc
+++ b/src/datavisualization/engine/engine.qrc
@@ -54,5 +54,7 @@
<file alias="fragmentSurfaceShadowNoTex">shaders/surfaceShadowNoTex.frag</file>
<file alias="fragmentSurfaceShadowFlat">shaders/surfaceShadowFlat.frag</file>
<file alias="vertexSurfaceShadowFlat">shaders/surfaceShadowFlat.vert</file>
+ <file alias="fragmentTexture">shaders/texture.frag</file>
+ <file alias="fragmentTextureES2">shaders/texture_ES2.frag</file>
</qresource>
</RCC>
diff --git a/src/datavisualization/engine/qabstract3dgraph.cpp b/src/datavisualization/engine/qabstract3dgraph.cpp
index 703cd18b..0d1bdfc9 100644
--- a/src/datavisualization/engine/qabstract3dgraph.cpp
+++ b/src/datavisualization/engine/qabstract3dgraph.cpp
@@ -135,6 +135,8 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
Z axis label.
\value ElementAxisYLabel
Y axis label.
+ \value ElementCustomItem
+ Custom item.
*/
/*!
@@ -380,6 +382,36 @@ void QAbstract3DGraph::clearSelection()
}
/*!
+ * Adds a custom mesh item located in \a meshFile to a graph at \a position with \a {scaling},
+ * \a rotation and optional \a textureImage. Item must be in Wavefront obj format and include
+ * vertices, normals and UVs. It also needs to be in triangles. Item position is given in data
+ * coordinates.
+ *
+ * \return index to the added item.
+ *
+ * \sa removeCustomItemAt()
+ *
+ * \since Qt Data Visualization 1.1
+ */
+int QAbstract3DGraph::addCustomItem(const QString &meshFile, const QVector3D &position,
+ const QVector3D &scaling, const QQuaternion &rotation,
+ const QImage &textureImage)
+{
+ return d_ptr->m_visualController->addCustomItem(meshFile, position, scaling, rotation,
+ textureImage);
+}
+
+/*!
+ * Removes the custom item at \a {index}. Deletes the resource allocated to it.
+ *
+ * \since Qt Data Visualization 1.1
+ */
+void QAbstract3DGraph::removeCustomItemAt(int index)
+{
+ d_ptr->m_visualController->deleteCustomItem(index);
+}
+
+/*!
* Renders current frame to an image of \a imageSize. Default size is the window size. Image is
* rendered with antialiasing level given in \a msaaSamples. Default level is \c{0}.
*
diff --git a/src/datavisualization/engine/qabstract3dgraph.h b/src/datavisualization/engine/qabstract3dgraph.h
index 2f417c2f..2e909b1d 100644
--- a/src/datavisualization/engine/qabstract3dgraph.h
+++ b/src/datavisualization/engine/qabstract3dgraph.h
@@ -77,7 +77,8 @@ public:
ElementSeries,
ElementAxisXLabel,
ElementAxisZLabel,
- ElementAxisYLabel
+ ElementAxisYLabel,
+ ElementCustomItem
};
public:
@@ -106,6 +107,11 @@ public:
void clearSelection();
+ int addCustomItem(const QString &meshFile, const QVector3D &position,
+ const QVector3D &scaling, const QQuaternion &rotation,
+ const QImage &textureImage = QImage());
+ void removeCustomItemAt(int index);
+
QImage renderToImage(int msaaSamples = 0, const QSize &imageSize = QSize());
void setMeasureFps(bool enable);
diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp
index ef39deba..b1c5e903 100644
--- a/src/datavisualization/engine/scatter3drenderer.cpp
+++ b/src/datavisualization/engine/scatter3drenderer.cpp
@@ -267,6 +267,19 @@ void Scatter3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesLis
m_selectionLabelDirty = true;
}
+void Scatter3DRenderer::updateCustomData(const QList<CustomDataItem *> &customItems)
+{
+ if (customItems.isEmpty() && m_customRenderCache.isEmpty())
+ return;
+
+ // There are probably not too many custom items, just recreate the array if something changes
+ foreach (CustomRenderItem *item, m_customRenderCache)
+ delete item;
+ m_customRenderCache.clear();
+ foreach (CustomDataItem *item, customItems)
+ addCustomItem(item);
+}
+
SeriesRenderCache *Scatter3DRenderer::createNewCache(QAbstract3DSeries *series)
{
return new ScatterSeriesRenderCache(series, this);
@@ -469,6 +482,9 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
}
}
+ drawCustomItems(RenderingDepth, m_depthShader, activeCamera, projectionMatrix,
+ depthProjectionMatrix);
+
// Disable drawing to framebuffer (= enable drawing to screen)
glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle);
@@ -566,6 +582,9 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
}
}
+ drawCustomItems(RenderingSelection, m_selectionShader, activeCamera, projectionMatrix,
+ depthProjectionMatrix);
+
drawLabels(true, activeCamera, viewMatrix, projectionMatrix);
glEnable(GL_DITHER);
@@ -794,6 +813,9 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
}
#endif
+ drawCustomItems(RenderingNormal, m_customItemShader, activeCamera, projectionMatrix,
+ depthProjectionMatrix);
+
// Bind background shader
m_backgroundShader->bind();
@@ -1305,6 +1327,87 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
m_selectionDirty = false;
}
+void Scatter3DRenderer::drawCustomItems(RenderingState state, ShaderHelper *shader,
+ const Q3DCamera *activeCamera,
+ const QMatrix4x4 &projectionMatrix,
+ const QMatrix4x4 &depthProjectionMatrix)
+{
+ if (m_customRenderCache.isEmpty())
+ return;
+
+ int itemIndex = 0;
+ QMatrix4x4 viewMatrix = activeCamera->d_ptr->viewMatrix();
+ QMatrix4x4 depthViewMatrix;
+ QMatrix4x4 projectionViewMatrix = projectionMatrix * viewMatrix;
+ QVector3D depthLightPos = activeCamera->d_ptr->calculatePositionRelativeToCamera(
+ zeroVector, 0.0f, 2.5f / m_autoScaleAdjustment);
+ depthViewMatrix.lookAt(depthLightPos, zeroVector, upVector);
+ QMatrix4x4 depthProjectionViewMatrix = depthProjectionMatrix * depthViewMatrix;
+
+ if (RenderingNormal == state) {
+ shader->bind();
+ shader->setUniformValue(shader->lightP(), m_cachedScene->activeLight()->position());
+ shader->setUniformValue(shader->ambientS(), m_cachedTheme->ambientLightStrength());
+ shader->setUniformValue(shader->lightColor(),
+ Utils::vectorFromColor(m_cachedTheme->lightColor()));
+ shader->setUniformValue(shader->view(), viewMatrix);
+
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+
+ // Draw custom items
+ foreach (CustomRenderItem *item, m_customRenderCache) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ modelMatrix.translate(item->translation());
+ modelMatrix.rotate(item->rotation());
+ modelMatrix.scale(item->scaling());
+ itModelMatrix.rotate(item->rotation());
+ itModelMatrix.scale(item->scaling());
+
+ if (RenderingNormal == state) {
+ // Normal render
+ shader->setUniformValue(shader->model(), modelMatrix);
+ shader->setUniformValue(shader->MVP(), projectionViewMatrix * modelMatrix);
+ shader->setUniformValue(shader->nModel(), itModelMatrix.inverted().transposed());
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
+ // Set shadow shader bindings
+ shader->setUniformValue(shader->shadowQ(), m_shadowQualityToShader);
+ shader->setUniformValue(shader->depth(), depthProjectionViewMatrix * modelMatrix);
+ shader->setUniformValue(shader->lightS(), m_cachedTheme->lightStrength() / 10.0f);
+ m_drawer->drawObject(shader, item->mesh(), item->texture(), m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ shader->setUniformValue(shader->lightS(), m_cachedTheme->lightStrength());
+ m_drawer->drawObject(shader, item->mesh(), item->texture());
+ }
+ } else if (RenderingSelection == state) {
+ // Selection render
+ QVector4D itemColor = indexToSelectionColor(itemIndex++);
+ itemColor.setW(customItemAlpha);
+ itemColor /= 255.0f;
+ shader->setUniformValue(shader->color(), itemColor);
+ m_drawer->drawObject(shader, item->mesh());
+ } else {
+ // Depth render
+ shader->setUniformValue(shader->MVP(), depthProjectionViewMatrix * modelMatrix);
+ m_drawer->drawObject(shader, item->mesh());
+ }
+ }
+
+ if (RenderingNormal == state) {
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+ }
+}
+
void Scatter3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCamera,
const QMatrix4x4 &viewMatrix,
const QMatrix4x4 &projectionMatrix) {
@@ -1761,6 +1864,7 @@ void Scatter3DRenderer::selectionColorToSeriesAndIndex(const QVector4D &color,
{
m_clickedType = QAbstract3DGraph::ElementNone;
if (color != selectionSkipColor) {
+ qDebug() << __FUNCTION__ << color.w();
if (color.w() == labelRowAlpha) {
// Row selection
index = Scatter3DController::invalidSelectionIndex();
@@ -1773,6 +1877,11 @@ void Scatter3DRenderer::selectionColorToSeriesAndIndex(const QVector4D &color,
// Value selection
index = Scatter3DController::invalidSelectionIndex();
m_clickedType = QAbstract3DGraph::ElementAxisYLabel;
+ } else if (color.w() == customItemAlpha) {
+ // Custom item selection
+ index = Scatter3DController::invalidSelectionIndex();
+ m_clickedType = QAbstract3DGraph::ElementCustomItem;
+ qDebug() << "custom item selected";
} else {
int totalIndex = int(color.x())
+ (int(color.y()) << 8)
@@ -1800,4 +1909,19 @@ void Scatter3DRenderer::selectionColorToSeriesAndIndex(const QVector4D &color,
series = 0;
}
+void Scatter3DRenderer::addCustomItem(CustomDataItem *item) {
+ CustomRenderItem *newItem = new CustomRenderItem();
+ newItem->setMesh(item->m_meshFile);
+ newItem->setScaling(item->m_scaling);
+ newItem->setRotation(item->m_rotation);
+ newItem->setTexture(item->m_texture);
+ const QVector3D &pos = item->m_position;
+ float xTrans = m_axisCacheX.positionAt(pos.x());
+ float yTrans = m_axisCacheY.positionAt(pos.y());
+ float zTrans = m_axisCacheZ.positionAt(pos.z());
+ newItem->setTranslation(QVector3D(xTrans, yTrans, zTrans));
+ m_customRenderCache.append(newItem);
+ qDebug() << __FUNCTION__ << item->m_meshFile << newItem->rotation() << newItem->scaling() << newItem->translation();
+}
+
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/engine/scatter3drenderer_p.h b/src/datavisualization/engine/scatter3drenderer_p.h
index ab45381e..3aad8788 100644
--- a/src/datavisualization/engine/scatter3drenderer_p.h
+++ b/src/datavisualization/engine/scatter3drenderer_p.h
@@ -104,6 +104,7 @@ public:
void updateData();
void updateSeries(const QList<QAbstract3DSeries *> &seriesList);
+ void updateCustomData(const QList<CustomDataItem *> &customItems);
SeriesRenderCache *createNewCache(QAbstract3DSeries *series);
void updateScene(Q3DScene *scene);
@@ -123,6 +124,9 @@ private:
virtual void fixMeshFileName(QString &fileName, QAbstract3DSeries::Mesh mesh);
void drawScene(GLuint defaultFboHandle);
+ void drawCustomItems(RenderingState state, ShaderHelper *shader, const Q3DCamera *activeCamera,
+ const QMatrix4x4 &projectionMatrix,
+ const QMatrix4x4 &depthProjectionMatrix);
void drawLabels(bool drawSelection, const Q3DCamera *activeCamera,
const QMatrix4x4 &viewMatrix, const QMatrix4x4 &projectionMatrix);
@@ -142,6 +146,8 @@ private:
void calculateTranslation(ScatterRenderItem &item);
void calculateSceneScalingFactors();
+ void addCustomItem(CustomDataItem *item);
+
Q_DISABLE_COPY(Scatter3DRenderer)
friend class ScatterRenderItem;
diff --git a/src/datavisualization/engine/shaders/default.vert b/src/datavisualization/engine/shaders/default.vert
index efb40862..e0718b20 100644
--- a/src/datavisualization/engine/shaders/default.vert
+++ b/src/datavisualization/engine/shaders/default.vert
@@ -17,10 +17,10 @@ varying highp vec2 coords_mdl;
void main() {
gl_Position = MVP * vec4(vertexPosition_mdl, 1.0);
coords_mdl = vertexPosition_mdl.xy;
- position_wrld = (M * vec4(vertexPosition_mdl, 1.0)).xyz;
- vec3 vertexPosition_cmr = (V * M * vec4(vertexPosition_mdl, 1.0)).xyz;
+ position_wrld = vec4(M * vec4(vertexPosition_mdl, 1.0)).xyz;
+ vec3 vertexPosition_cmr = vec4(V * M * vec4(vertexPosition_mdl, 1.0)).xyz;
eyeDirection_cmr = vec3(0.0, 0.0, 0.0) - vertexPosition_cmr;
- vec3 lightPosition_cmr = (V * vec4(lightPosition_wrld, 1.0)).xyz;
+ vec3 lightPosition_cmr = vec4(V * vec4(lightPosition_wrld, 1.0)).xyz;
lightDirection_cmr = lightPosition_cmr + eyeDirection_cmr;
- normal_cmr = (V * itM * vec4(vertexNormal_mdl, 0.0)).xyz;
+ normal_cmr = vec4(V * itM * vec4(vertexNormal_mdl, 0.0)).xyz;
}
diff --git a/src/datavisualization/engine/shaders/shadow.vert b/src/datavisualization/engine/shaders/shadow.vert
index e29a8a30..0adcd43c 100644
--- a/src/datavisualization/engine/shaders/shadow.vert
+++ b/src/datavisualization/engine/shaders/shadow.vert
@@ -28,10 +28,10 @@ void main() {
gl_Position = MVP * vec4(vertexPosition_mdl, 1.0);
coords_mdl = vertexPosition_mdl.xy;
shadowCoord = bias * depthMVP * vec4(vertexPosition_mdl, 1.0);
- position_wrld = (M * vec4(vertexPosition_mdl, 1.0)).xyz;
- vec3 vertexPosition_cmr = (V * M * vec4(vertexPosition_mdl, 1.0)).xyz;
+ position_wrld = vec4(M * vec4(vertexPosition_mdl, 1.0)).xyz;
+ vec3 vertexPosition_cmr = vec4(V * M * vec4(vertexPosition_mdl, 1.0)).xyz;
eyeDirection_cmr = vec3(0.0, 0.0, 0.0) - vertexPosition_cmr;
- lightDirection_cmr = (V * vec4(lightPosition_wrld, 0.0)).xyz;
- normal_cmr = (V * itM * vec4(vertexNormal_mdl, 0.0)).xyz;
+ lightDirection_cmr = vec4(V * vec4(lightPosition_wrld, 0.0)).xyz;
+ normal_cmr = vec4(V * itM * vec4(vertexNormal_mdl, 0.0)).xyz;
UV = vertexUV;
}
diff --git a/src/datavisualization/engine/shaders/surfaceFlat.vert b/src/datavisualization/engine/shaders/surfaceFlat.vert
index 0d39f6bc..102bea78 100644
--- a/src/datavisualization/engine/shaders/surfaceFlat.vert
+++ b/src/datavisualization/engine/shaders/surfaceFlat.vert
@@ -20,10 +20,10 @@ varying highp vec3 coords_mdl;
void main() {
gl_Position = MVP * vec4(vertexPosition_mdl, 1.0);
coords_mdl = vertexPosition_mdl;
- position_wrld = (M * vec4(vertexPosition_mdl, 1.0)).xyz;
- vec3 vertexPosition_cmr = (V * M * vec4(vertexPosition_mdl, 1.0)).xyz;
+ position_wrld = vec4(M * vec4(vertexPosition_mdl, 1.0)).xyz;
+ vec3 vertexPosition_cmr = vec4(V * M * vec4(vertexPosition_mdl, 1.0)).xyz;
eyeDirection_cmr = vec3(0.0, 0.0, 0.0) - vertexPosition_cmr;
- vec3 lightPosition_cmr = (V * vec4(lightPosition_wrld, 1.0)).xyz;
+ vec3 lightPosition_cmr = vec4(V * vec4(lightPosition_wrld, 1.0)).xyz;
lightDirection_cmr = lightPosition_cmr + eyeDirection_cmr;
- normal_cmr = (V * itM * vec4(vertexNormal_mdl, 0.0)).xyz;
+ normal_cmr = vec4(V * itM * vec4(vertexNormal_mdl, 0.0)).xyz;
}
diff --git a/src/datavisualization/engine/shaders/surfaceShadowFlat.vert b/src/datavisualization/engine/shaders/surfaceShadowFlat.vert
index 0a6e967f..8da7b196 100644
--- a/src/datavisualization/engine/shaders/surfaceShadowFlat.vert
+++ b/src/datavisualization/engine/shaders/surfaceShadowFlat.vert
@@ -28,10 +28,10 @@ void main() {
gl_Position = MVP * vec4(vertexPosition_mdl, 1.0);
coords_mdl = vertexPosition_mdl;
shadowCoord = bias * depthMVP * vec4(vertexPosition_mdl, 1.0);
- position_wrld = (M * vec4(vertexPosition_mdl, 1.0)).xyz;
- vec3 vertexPosition_cmr = (V * M * vec4(vertexPosition_mdl, 1.0)).xyz;
+ position_wrld = vec4(M * vec4(vertexPosition_mdl, 1.0)).xyz;
+ vec3 vertexPosition_cmr = vec4(V * M * vec4(vertexPosition_mdl, 1.0)).xyz;
eyeDirection_cmr = vec3(0.0, 0.0, 0.0) - vertexPosition_cmr;
- vec3 lightPosition_cmr = (V * vec4(lightPosition_wrld, 1.0)).xyz;
+ vec3 lightPosition_cmr = vec4(V * vec4(lightPosition_wrld, 1.0)).xyz;
lightDirection_cmr = lightPosition_cmr + eyeDirection_cmr;
- normal_cmr = (V * itM * vec4(vertexNormal_mdl, 0.0)).xyz;
+ normal_cmr = vec4(V * itM * vec4(vertexNormal_mdl, 0.0)).xyz;
}
diff --git a/src/datavisualization/engine/shaders/texture.frag b/src/datavisualization/engine/shaders/texture.frag
new file mode 100644
index 00000000..69509a3f
--- /dev/null
+++ b/src/datavisualization/engine/shaders/texture.frag
@@ -0,0 +1,37 @@
+#version 120
+
+varying highp vec2 UV;
+varying highp vec3 position_wrld;
+varying highp vec3 normal_cmr;
+varying highp vec3 eyeDirection_cmr;
+varying highp vec3 lightDirection_cmr;
+
+uniform highp vec3 lightPosition_wrld;
+uniform highp sampler2D textureSampler;
+uniform highp float lightStrength;
+uniform highp float ambientStrength;
+uniform highp vec3 lightColor;
+
+void main() {
+ highp vec3 materialDiffuseColor = texture2D(textureSampler, UV).rgb;
+ highp vec3 materialAmbientColor = lightColor * ambientStrength * materialDiffuseColor;
+ highp vec3 materialSpecularColor = lightColor;
+
+ 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 = texture2D(textureSampler, UV).a;
+ gl_FragColor.rgb = clamp(gl_FragColor.rgb, 0.0, 1.0);
+}
+
diff --git a/src/datavisualization/engine/shaders/texture_ES2.frag b/src/datavisualization/engine/shaders/texture_ES2.frag
new file mode 100644
index 00000000..e749d763
--- /dev/null
+++ b/src/datavisualization/engine/shaders/texture_ES2.frag
@@ -0,0 +1,40 @@
+varying highp vec2 UV;
+varying highp vec2 coords_mdl;
+varying highp vec3 position_wrld;
+varying highp vec3 normal_cmr;
+varying highp vec3 eyeDirection_cmr;
+varying highp vec3 lightDirection_cmr;
+
+uniform highp vec3 lightPosition_wrld;
+uniform highp sampler2D textureSampler;
+uniform highp float lightStrength;
+uniform highp float ambientStrength;
+uniform highp vec3 lightColor;
+
+void main() {
+ highp vec3 materialDiffuseColor = texture2D(textureSampler, UV).rgb;
+ highp vec3 materialAmbientColor = lightColor * ambientStrength * materialDiffuseColor;
+ highp vec3 materialSpecularColor = lightColor;
+
+ highp float distance = length(lightPosition_wrld - position_wrld);
+
+ highp vec3 n = normalize(normal_cmr);
+ highp vec3 l = normalize(lightDirection_cmr);
+ highp float cosTheta = dot(n, l);
+ if (cosTheta < 0.0) cosTheta = 0.0;
+ else if (cosTheta > 1.0) cosTheta = 1.0;
+
+ highp vec3 E = normalize(eyeDirection_cmr);
+ highp vec3 R = reflect(-l, n);
+ highp float cosAlpha = dot(E, R);
+ if (cosAlpha < 0.0) cosAlpha = 0.0;
+ else if (cosAlpha > 1.0) cosAlpha = 1.0;
+
+ gl_FragColor.rgb =
+ materialAmbientColor +
+ materialDiffuseColor * lightStrength * (cosTheta * cosTheta) / distance +
+ materialSpecularColor * lightStrength * (cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha) / distance;
+ gl_FragColor.a = texture2D(textureSampler, UV).a;
+ gl_FragColor.rgb = clamp(gl_FragColor.rgb, 0.0, 1.0);
+}
+
diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp
index 0d5536e2..eeeaaf0d 100644
--- a/src/datavisualization/engine/surface3drenderer.cpp
+++ b/src/datavisualization/engine/surface3drenderer.cpp
@@ -41,8 +41,9 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
//#define SHOW_DEPTH_TEXTURE_SCENE
const GLfloat aspectRatio = 2.0f; // Forced ratio of x and z to y. Dynamic will make it look odd.
-const GLfloat backgroundMargin = 1.1f; // Margin for background (1.10 make it 10% larger to avoid
- // selection ball being drawn inside background)
+// Margin for background (1.10 make it 10% larger to avoid
+// selection ball being drawn inside background)
+const GLfloat backgroundMargin = 1.1f;
const GLfloat labelMargin = 0.05f;
const GLfloat gridLineWidth = 0.005f;
const GLfloat sliceZScale = 0.1f;
@@ -293,6 +294,11 @@ void Surface3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesLis
}
}
+void Surface3DRenderer::updateCustomData(const QList<CustomDataItem *> &customItems)
+{
+ // TODO
+}
+
SeriesRenderCache *Surface3DRenderer::createNewCache(QAbstract3DSeries *series)
{
m_selectionTexturesDirty = true;
@@ -1133,6 +1139,9 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
glDisableVertexAttribArray(m_depthShader->posAtt());
+ drawCustomItems(RenderingDepth, m_depthShader, activeCamera, projectionMatrix,
+ depthProjectionMatrix);
+
// Disable drawing to depth framebuffer (= enable drawing to screen)
glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle);
@@ -1180,6 +1189,8 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
cache->selectionTexture());
}
}
+ drawCustomItems(RenderingSelection, m_selectionShader, activeCamera, projectionMatrix,
+ depthProjectionMatrix);
drawLabels(true, activeCamera, viewMatrix, projectionMatrix);
glEnable(GL_DITHER);
@@ -1310,6 +1321,9 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
}
}
+ drawCustomItems(RenderingNormal, m_customItemShader, activeCamera, projectionMatrix,
+ depthProjectionMatrix);
+
// Bind background shader
m_backgroundShader->bind();
glCullFace(GL_BACK);
@@ -1753,6 +1767,14 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
}
}
+void Surface3DRenderer::drawCustomItems(RenderingState state, ShaderHelper *shader,
+ const Q3DCamera *activeCamera,
+ const QMatrix4x4 &projectionMatrix,
+ const QMatrix4x4 &depthProjectionMatrix)
+{
+ // TODO
+}
+
void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCamera,
const QMatrix4x4 &viewMatrix,
const QMatrix4x4 &projectionMatrix) {
@@ -2235,7 +2257,7 @@ void Surface3DRenderer::updateSelectionPoint(SurfaceSeriesRenderCache *cache, co
QPoint Surface3DRenderer::selectionIdToSurfacePoint(uint id)
{
m_clickedType = QAbstract3DGraph::ElementNone;
- // Check for label selection
+ // Check for label and custom item selection
if (id / alphaMultiplier == labelRowAlpha) {
m_clickedType = QAbstract3DGraph::ElementAxisZLabel;
return Surface3DController::invalidSelectionPosition();
@@ -2245,6 +2267,10 @@ QPoint Surface3DRenderer::selectionIdToSurfacePoint(uint id)
} else if (id / alphaMultiplier == labelValueAlpha) {
m_clickedType = QAbstract3DGraph::ElementAxisYLabel;
return Surface3DController::invalidSelectionPosition();
+ } else if (id / alphaMultiplier == customItemAlpha) {
+ // Custom item selection
+ m_clickedType = QAbstract3DGraph::ElementCustomItem;
+ return Surface3DController::invalidSelectionPosition();
}
// Not a label selection
diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h
index e1147e3c..98968dd5 100644
--- a/src/datavisualization/engine/surface3drenderer_p.h
+++ b/src/datavisualization/engine/surface3drenderer_p.h
@@ -106,6 +106,7 @@ public:
void updateData();
void updateSeries(const QList<QAbstract3DSeries *> &seriesList);
+ void updateCustomData(const QList<CustomDataItem *> &customItems);
SeriesRenderCache *createNewCache(QAbstract3DSeries *series);
void cleanCache(SeriesRenderCache *cache);
void updateSelectionMode(QAbstract3DGraph::SelectionFlags mode);
@@ -141,6 +142,9 @@ private:
void loadBackgroundMesh();
void loadLabelMesh();
void drawScene(GLuint defaultFboHandle);
+ void drawCustomItems(RenderingState state, ShaderHelper *shader, const Q3DCamera *activeCamera,
+ const QMatrix4x4 &projectionMatrix,
+ const QMatrix4x4 &depthProjectionMatrix);
void drawLabels(bool drawSelection, const Q3DCamera *activeCamera,
const QMatrix4x4 &viewMatrix, const QMatrix4x4 &projectionMatrix);
void calculateSceneScalingFactors();