From bf8ed99fb5a474aa6a56d61c9e3a1b5e44d6b6cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomi=20Korpip=C3=A4=C3=A4?= Date: Wed, 16 Apr 2014 12:25:14 +0300 Subject: Add custom item support, part 2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTRD-2866 + Added custom item rendering Change-Id: If24400fed7c0467d8ebbd554d6e4df3ec5a205f3 Reviewed-by: Tomi Korpipää --- src/datavisualization/data/customdataitem_p.h | 9 +- .../engine/abstract3dcontroller.cpp | 26 +++- .../engine/abstract3dcontroller_p.h | 1 + .../engine/abstract3drenderer.cpp | 120 +++++++++++++++++- .../engine/abstract3drenderer_p.h | 14 +- src/datavisualization/engine/bars3drenderer.cpp | 48 +++---- src/datavisualization/engine/bars3drenderer_p.h | 6 +- src/datavisualization/engine/engine.qrc | 1 + src/datavisualization/engine/qabstract3dgraph.cpp | 19 +++ src/datavisualization/engine/qabstract3dgraph.h | 1 + src/datavisualization/engine/scatter3drenderer.cpp | 141 +++------------------ src/datavisualization/engine/scatter3drenderer_p.h | 9 +- src/datavisualization/engine/shaders/texture.vert | 26 ++++ src/datavisualization/engine/surface3drenderer.cpp | 73 ++++++----- src/datavisualization/engine/surface3drenderer_p.h | 9 +- src/datavisualization/utils/texturehelper.cpp | 6 +- 16 files changed, 296 insertions(+), 213 deletions(-) create mode 100644 src/datavisualization/engine/shaders/texture.vert (limited to 'src/datavisualization') diff --git a/src/datavisualization/data/customdataitem_p.h b/src/datavisualization/data/customdataitem_p.h index f607daba..c077a17a 100644 --- a/src/datavisualization/data/customdataitem_p.h +++ b/src/datavisualization/data/customdataitem_p.h @@ -42,10 +42,15 @@ public: virtual ~CustomDataItem(); inline void setMeshFile(const QString &meshFile) { m_meshFile = meshFile; } + inline QString meshFile() { return m_meshFile;} void setTextureImage(const QImage &textureImage); + inline GLuint texture() { return m_texture; } inline void setPosition(const QVector3D &position) { m_position = position; } + inline QVector3D position() { return m_position; } inline void setScaling(const QVector3D &scaling) { m_scaling = scaling; } + inline QVector3D scaling() { return m_scaling; } inline void setRotation(const QQuaternion &rotation) { m_rotation = rotation; } + inline QQuaternion rotation() { return m_rotation; } private: TextureHelper *m_textureHelper; @@ -54,10 +59,6 @@ private: QVector3D m_position; QVector3D m_scaling; QQuaternion m_rotation; - - friend class Bars3DRenderer; - friend class Scatter3DRenderer; - friend class Surface3DRenderer; }; QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp index e10069ff..4c66ad76 100644 --- a/src/datavisualization/engine/abstract3dcontroller.cpp +++ b/src/datavisualization/engine/abstract3dcontroller.cpp @@ -841,10 +841,28 @@ int Abstract3DController::addCustomItem(const QString &meshFile, const QVector3D void Abstract3DController::deleteCustomItem(int index) { - delete m_customItems[index]; - m_customItems.removeAt(index); - m_isCustomDataDirty = true; - emitNeedRender(); + if (m_customItems.size() > index) { + delete m_customItems[index]; + m_customItems.removeAt(index); + m_isCustomDataDirty = true; + emitNeedRender(); + } +} + +void Abstract3DController::deleteCustomItem(const QVector3D &position) +{ + int index = -1; + int counter = 0; + // Get the index for the item at position + foreach (CustomDataItem *item, m_customItems) { + if (item->position() == position) { + index = counter; + break; + } + counter++; + } + if (index >= 0) + deleteCustomItem(index); } void Abstract3DController::handleAxisTitleChanged(const QString &title) diff --git a/src/datavisualization/engine/abstract3dcontroller_p.h b/src/datavisualization/engine/abstract3dcontroller_p.h index 98df8fda..ba91796e 100644 --- a/src/datavisualization/engine/abstract3dcontroller_p.h +++ b/src/datavisualization/engine/abstract3dcontroller_p.h @@ -233,6 +233,7 @@ public: int addCustomItem(const QString &meshFile, const QVector3D &position, const QVector3D &scaling, const QQuaternion &rotation, const QImage &textureImage); void deleteCustomItem(int index); + void deleteCustomItem(const QVector3D &position); void emitNeedRender(); diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp index 1cb4bdba..d18a1fc3 100644 --- a/src/datavisualization/engine/abstract3drenderer.cpp +++ b/src/datavisualization/engine/abstract3drenderer.cpp @@ -227,7 +227,7 @@ void Abstract3DRenderer::reInitShaders() QStringLiteral(":/shaders/fragment")); initBackgroundShaders(QStringLiteral(":/shaders/vertex"), QStringLiteral(":/shaders/fragment")); - initCustomItemShaders(QStringLiteral(":/shaders/vertexShadow"), + initCustomItemShaders(QStringLiteral(":/shaders/vertexTexture"), QStringLiteral(":/shaders/fragmentTexture")); } #else @@ -237,7 +237,7 @@ 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 + initCustomItemShaders(QStringLiteral(":/shaders/vertexTexture"), QStringLiteral(":/shaders/fragmentTextureES2")); #endif } @@ -393,6 +393,19 @@ void Abstract3DRenderer::updateSeries(const QList &seriesLi } } +void Abstract3DRenderer::updateCustomData(const QList &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 *Abstract3DRenderer::createNewCache(QAbstract3DSeries *series) { return new SeriesRenderCache(series, this); @@ -502,4 +515,107 @@ QString &Abstract3DRenderer::selectionLabel() return m_selectionLabel; } +QVector4D Abstract3DRenderer::indexToSelectionColor(GLint index) +{ + GLubyte idxRed = index & 0xff; + GLubyte idxGreen = (index & 0xff00) >> 8; + GLubyte idxBlue = (index & 0xff0000) >> 16; + + return QVector4D(idxRed, idxGreen, idxBlue, 0); +} + +void Abstract3DRenderer::addCustomItem(CustomDataItem *item) { + CustomRenderItem *newItem = new CustomRenderItem(); + newItem->setMesh(item->meshFile()); + newItem->setScaling(item->scaling()); + newItem->setRotation(item->rotation()); + newItem->setTexture(item->texture()); + QVector3D translation = convertPositionToTranslation(item->position()); + newItem->setTranslation(translation); + m_customRenderCache.append(newItem); +} + +void Abstract3DRenderer::drawCustomItems(RenderingState state, + ShaderHelper *shader, + const QMatrix4x4 &viewMatrix, + const QMatrix4x4 &projectionViewMatrix, + const QMatrix4x4 &depthProjectionViewMatrix, + GLuint depthTexture, + GLfloat shadowQuality) +{ + if (m_customRenderCache.isEmpty()) + return; + + int itemIndex = 0; + + 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; + QMatrix4x4 MVPMatrix; + + modelMatrix.translate(item->translation()); + modelMatrix.rotate(item->rotation()); + modelMatrix.scale(item->scaling()); + itModelMatrix.rotate(item->rotation()); + itModelMatrix.scale(item->scaling()); + MVPMatrix = projectionViewMatrix * modelMatrix; + + if (RenderingNormal == state) { + // Normal render + shader->setUniformValue(shader->model(), modelMatrix); + shader->setUniformValue(shader->MVP(), MVPMatrix); + 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(), shadowQuality); + shader->setUniformValue(shader->depth(), depthProjectionViewMatrix * modelMatrix); + shader->setUniformValue(shader->lightS(), m_cachedTheme->lightStrength() / 10.0f); + m_drawer->drawObject(shader, item->mesh(), item->texture(), depthTexture); + } else +#else + Q_UNUSED(depthTexture) + Q_UNUSED(shadowQuality) +#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 + shader->setUniformValue(shader->MVP(), MVPMatrix); + 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); + } +} + QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/abstract3drenderer_p.h b/src/datavisualization/engine/abstract3drenderer_p.h index 884c0f39..967a41a9 100644 --- a/src/datavisualization/engine/abstract3drenderer_p.h +++ b/src/datavisualization/engine/abstract3drenderer_p.h @@ -69,7 +69,7 @@ public: virtual void updateData() = 0; virtual void updateSeries(const QList &seriesList); - virtual void updateCustomData(const QList &customItems) = 0; + virtual void updateCustomData(const QList &customItems); virtual SeriesRenderCache *createNewCache(QAbstract3DSeries *series); virtual void cleanCache(SeriesRenderCache *cache); virtual void render(GLuint defaultFboHandle); @@ -110,6 +110,11 @@ public: virtual void modifiedSeriesList(const QVector &seriesList); virtual void fixMeshFileName(QString &fileName, QAbstract3DSeries::Mesh mesh); + + virtual void addCustomItem(CustomDataItem *item); + + virtual QVector3D convertPositionToTranslation(const QVector3D &position) = 0; + void generateBaseColorTexture(const QColor &color, GLuint *texture); void fixGradientAndGenerateTexture(QLinearGradient *gradient, GLuint *gradientTexture); @@ -122,6 +127,13 @@ public: void setSelectionLabel(const QString &label); QString &selectionLabel(); + void drawCustomItems(RenderingState state, ShaderHelper *shader, + const QMatrix4x4 &viewMatrix, + const QMatrix4x4 &projectionViewMatrix, + const QMatrix4x4 &depthProjectionViewMatrix, + GLuint depthTexture, GLfloat shadowQuality); + QVector4D indexToSelectionColor(GLint index); + signals: void needRender(); // Emit this if something in renderer causes need for another render pass. void requestShadowQuality(QAbstract3DGraph::ShadowQuality quality); // For automatic quality adjustments diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp index f02b9910..e2feefac 100644 --- a/src/datavisualization/engine/bars3drenderer.cpp +++ b/src/datavisualization/engine/bars3drenderer.cpp @@ -299,11 +299,6 @@ void Bars3DRenderer::updateSeries(const QList &seriesList) m_selectionLabelDirty = true; } -void Bars3DRenderer::updateCustomData(const QList &customItems) -{ - // TODO -} - SeriesRenderCache *Bars3DRenderer::createNewCache(QAbstract3DSeries *series) { return new BarSeriesRenderCache(series, this); @@ -575,7 +570,6 @@ void Bars3DRenderer::drawSlicedScene() else barShader = m_barGradientShader; barShader->bind(); - } if (!colorStyleIsUniform && (previousColorStyle != colorStyle) @@ -992,8 +986,9 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) } } - drawCustomItems(RenderingDepth, m_depthShader, activeCamera, projectionMatrix, - depthProjectionMatrix); + Abstract3DRenderer::drawCustomItems(RenderingDepth, m_depthShader, viewMatrix, + projectionViewMatrix, depthProjectionViewMatrix, + m_depthTexture, m_shadowQualityToShader); // Disable drawing to depth framebuffer (= enable drawing to screen) glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle); @@ -1011,7 +1006,8 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) // Skip selection mode drawing if we're slicing or have no selection mode if (!m_cachedIsSlicingActivated && m_cachedSelectionMode > QAbstract3DGraph::SelectionNone - && m_selectionState == SelectOnScene && m_visibleSeriesCount > 0) { + && m_selectionState == SelectOnScene + && (m_visibleSeriesCount > 0 || !m_customRenderCache.isEmpty())) { // Bind selection shader m_selectionShader->bind(); @@ -1075,8 +1071,9 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) } } glCullFace(GL_BACK); - drawCustomItems(RenderingSelection, m_selectionShader, activeCamera, projectionMatrix, - depthProjectionMatrix); + Abstract3DRenderer::drawCustomItems(RenderingSelection, m_selectionShader, viewMatrix, + projectionViewMatrix, depthProjectionViewMatrix, + m_depthTexture, m_shadowQualityToShader); drawLabels(true, activeCamera, viewMatrix, projectionMatrix, rowScaleFactor, columnScaleFactor); glEnable(GL_DITHER); @@ -1373,15 +1370,16 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) glDisable(GL_POLYGON_OFFSET_FILL); - drawCustomItems(RenderingNormal, m_customItemShader, activeCamera, projectionMatrix, - depthProjectionMatrix); + // Reset culling + glCullFace(GL_BACK); + + Abstract3DRenderer::drawCustomItems(RenderingNormal, m_customItemShader, viewMatrix, + projectionViewMatrix, depthProjectionViewMatrix, + m_depthTexture, m_shadowQualityToShader); // Bind background shader m_backgroundShader->bind(); - // Reset culling - glCullFace(GL_BACK); - // Draw background if (m_cachedTheme->isBackgroundEnabled() && m_backgroundObj) { QMatrix4x4 modelMatrix; @@ -1745,14 +1743,6 @@ 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) { @@ -2337,4 +2327,14 @@ void Bars3DRenderer::initLabelShaders(const QString &vertexShader, const QString m_labelShader->initialize(); } +QVector3D Bars3DRenderer::convertPositionToTranslation(const QVector3D &position) { + // Convert row and column to translation on graph + float xTrans = (((position.x() + 0.5f) * m_cachedBarSpacing.width()) - m_rowWidth) + / m_scaleFactor; + float zTrans = (m_columnDepth - ((position.z() + 0.5f) * m_cachedBarSpacing.height())) + / m_scaleFactor; + float yTrans = m_axisCacheY.positionAt(position.y()); + return QVector3D(xTrans, yTrans, zTrans); +} + QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/bars3drenderer_p.h b/src/datavisualization/engine/bars3drenderer_p.h index efe84d39..ca0e690e 100644 --- a/src/datavisualization/engine/bars3drenderer_p.h +++ b/src/datavisualization/engine/bars3drenderer_p.h @@ -115,11 +115,12 @@ public: void updateData(); void updateSeries(const QList &seriesList); - void updateCustomData(const QList &customItems); SeriesRenderCache *createNewCache(QAbstract3DSeries *series); void updateScene(Q3DScene *scene); void render(GLuint defaultFboHandle = 0); + QVector3D convertPositionToTranslation(const QVector3D &position); + protected: virtual void initializeOpenGL(); @@ -146,9 +147,6 @@ 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 38a9e651..4d95f030 100644 --- a/src/datavisualization/engine/engine.qrc +++ b/src/datavisualization/engine/engine.qrc @@ -56,5 +56,6 @@ shaders/surfaceShadowFlat.vert shaders/texture.frag shaders/texture_ES2.frag + shaders/texture.vert diff --git a/src/datavisualization/engine/qabstract3dgraph.cpp b/src/datavisualization/engine/qabstract3dgraph.cpp index 0d1bdfc9..1c46427d 100644 --- a/src/datavisualization/engine/qabstract3dgraph.cpp +++ b/src/datavisualization/engine/qabstract3dgraph.cpp @@ -389,6 +389,9 @@ void QAbstract3DGraph::clearSelection() * * \return index to the added item. * + * \note No validity checks are made for the position of the item, so it is up to the user to + * provide a valid position. Items positioned outside axis ranges are still rendered. + * * \sa removeCustomItemAt() * * \since Qt Data Visualization 1.1 @@ -404,6 +407,9 @@ int QAbstract3DGraph::addCustomItem(const QString &meshFile, const QVector3D &po /*! * Removes the custom item at \a {index}. Deletes the resource allocated to it. * + * \note The index of the remaining items will change if the item removed is other than + * the last. + * * \since Qt Data Visualization 1.1 */ void QAbstract3DGraph::removeCustomItemAt(int index) @@ -411,6 +417,19 @@ void QAbstract3DGraph::removeCustomItemAt(int index) d_ptr->m_visualController->deleteCustomItem(index); } +/*! + * Removes the custom item at \a {position}. Deletes the resource allocated to it. + * + * \note The index of the remaining items will change if an item is removed from a position that + * is not at the last index. + * + * \since Qt Data Visualization 1.1 + */ +void QAbstract3DGraph::removeCustomItemAt(const QVector3D &position) +{ + d_ptr->m_visualController->deleteCustomItem(position); +} + /*! * 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 2e909b1d..dc0bf6f0 100644 --- a/src/datavisualization/engine/qabstract3dgraph.h +++ b/src/datavisualization/engine/qabstract3dgraph.h @@ -111,6 +111,7 @@ public: const QVector3D &scaling, const QQuaternion &rotation, const QImage &textureImage = QImage()); void removeCustomItemAt(int index); + void removeCustomItemAt(const QVector3D &position); QImage renderToImage(int msaaSamples = 0, const QSize &imageSize = QSize()); diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp index b1c5e903..9d5696a0 100644 --- a/src/datavisualization/engine/scatter3drenderer.cpp +++ b/src/datavisualization/engine/scatter3drenderer.cpp @@ -267,19 +267,6 @@ void Scatter3DRenderer::updateSeries(const QList &seriesLis m_selectionLabelDirty = true; } -void Scatter3DRenderer::updateCustomData(const QList &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); @@ -482,8 +469,9 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) } } - drawCustomItems(RenderingDepth, m_depthShader, activeCamera, projectionMatrix, - depthProjectionMatrix); + Abstract3DRenderer::drawCustomItems(RenderingDepth, m_depthShader, viewMatrix, + projectionViewMatrix, depthProjectionViewMatrix, + m_depthTexture, m_shadowQualityToShader); // Disable drawing to framebuffer (= enable drawing to screen) glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle); @@ -506,7 +494,8 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) // Skip selection mode drawing if we have no selection mode if (m_cachedSelectionMode > QAbstract3DGraph::SelectionNone - && SelectOnScene == m_selectionState && m_visibleSeriesCount > 0) { + && SelectOnScene == m_selectionState + && (m_visibleSeriesCount > 0 || !m_customRenderCache.isEmpty())) { // Draw dots to selection buffer glBindFramebuffer(GL_FRAMEBUFFER, m_selectionFrameBuffer); glViewport(0, 0, @@ -582,8 +571,9 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) } } - drawCustomItems(RenderingSelection, m_selectionShader, activeCamera, projectionMatrix, - depthProjectionMatrix); + Abstract3DRenderer::drawCustomItems(RenderingSelection, m_selectionShader, viewMatrix, + projectionViewMatrix, depthProjectionViewMatrix, + m_depthTexture, m_shadowQualityToShader); drawLabels(true, activeCamera, viewMatrix, projectionMatrix); @@ -813,8 +803,9 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) } #endif - drawCustomItems(RenderingNormal, m_customItemShader, activeCamera, projectionMatrix, - depthProjectionMatrix); + Abstract3DRenderer::drawCustomItems(RenderingNormal, m_customItemShader, viewMatrix, + projectionViewMatrix, depthProjectionViewMatrix, + m_depthTexture, m_shadowQualityToShader); // Bind background shader m_backgroundShader->bind(); @@ -1327,87 +1318,6 @@ 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) { @@ -1849,22 +1759,12 @@ void Scatter3DRenderer::initLabelShaders(const QString &vertexShader, const QStr m_labelShader->initialize(); } -QVector4D Scatter3DRenderer::indexToSelectionColor(GLint index) -{ - GLubyte dotIdxRed = index & 0xff; - GLubyte dotIdxGreen = (index & 0xff00) >> 8; - GLubyte dotIdxBlue = (index & 0xff0000) >> 16; - - return QVector4D(dotIdxRed, dotIdxGreen, dotIdxBlue, 0); -} - void Scatter3DRenderer::selectionColorToSeriesAndIndex(const QVector4D &color, int &index, QAbstract3DSeries *&series) { m_clickedType = QAbstract3DGraph::ElementNone; if (color != selectionSkipColor) { - qDebug() << __FUNCTION__ << color.w(); if (color.w() == labelRowAlpha) { // Row selection index = Scatter3DController::invalidSelectionIndex(); @@ -1881,7 +1781,6 @@ void Scatter3DRenderer::selectionColorToSeriesAndIndex(const QVector4D &color, // Custom item selection index = Scatter3DController::invalidSelectionIndex(); m_clickedType = QAbstract3DGraph::ElementCustomItem; - qDebug() << "custom item selected"; } else { int totalIndex = int(color.x()) + (int(color.y()) << 8) @@ -1909,19 +1808,11 @@ 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(); +QVector3D Scatter3DRenderer::convertPositionToTranslation(const QVector3D &position) { + float xTrans = m_axisCacheX.positionAt(position.x()); + float yTrans = m_axisCacheY.positionAt(position.y()); + float zTrans = m_axisCacheZ.positionAt(position.z()); + return QVector3D(xTrans, yTrans, zTrans); } QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/scatter3drenderer_p.h b/src/datavisualization/engine/scatter3drenderer_p.h index 3aad8788..172d0c46 100644 --- a/src/datavisualization/engine/scatter3drenderer_p.h +++ b/src/datavisualization/engine/scatter3drenderer_p.h @@ -104,10 +104,11 @@ public: void updateData(); void updateSeries(const QList &seriesList); - void updateCustomData(const QList &customItems); SeriesRenderCache *createNewCache(QAbstract3DSeries *series); void updateScene(Q3DScene *scene); + QVector3D convertPositionToTranslation(const QVector3D &position); + inline int clickedIndex() const { return m_clickedIndex; } void resetClickedStatus(); @@ -124,9 +125,6 @@ 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); @@ -146,8 +144,6 @@ private: void calculateTranslation(ScatterRenderItem &item); void calculateSceneScalingFactors(); - void addCustomItem(CustomDataItem *item); - Q_DISABLE_COPY(Scatter3DRenderer) friend class ScatterRenderItem; @@ -156,7 +152,6 @@ public slots: void updateSelectedItem(int index, QScatter3DSeries *series); private: - QVector4D indexToSelectionColor(GLint index); void selectionColorToSeriesAndIndex(const QVector4D &color, int &index, QAbstract3DSeries *&series); }; diff --git a/src/datavisualization/engine/shaders/texture.vert b/src/datavisualization/engine/shaders/texture.vert new file mode 100644 index 00000000..7d98b053 --- /dev/null +++ b/src/datavisualization/engine/shaders/texture.vert @@ -0,0 +1,26 @@ +uniform highp mat4 MVP; +uniform highp mat4 V; +uniform highp mat4 M; +uniform highp mat4 itM; +uniform highp vec3 lightPosition_wrld; + +attribute highp vec3 vertexPosition_mdl; +attribute highp vec2 vertexUV; +attribute highp vec3 vertexNormal_mdl; + +varying highp vec2 UV; +varying highp vec3 position_wrld; +varying highp vec3 normal_cmr; +varying highp vec3 eyeDirection_cmr; +varying highp vec3 lightDirection_cmr; + +void main() { + gl_Position = MVP * vec4(vertexPosition_mdl, 1.0); + 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 = 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; +} diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp index eeeaaf0d..bdcb8871 100644 --- a/src/datavisualization/engine/surface3drenderer.cpp +++ b/src/datavisualization/engine/surface3drenderer.cpp @@ -48,6 +48,8 @@ const GLfloat labelMargin = 0.05f; const GLfloat gridLineWidth = 0.005f; const GLfloat sliceZScale = 0.1f; const GLfloat sliceUnits = 2.5f; +const uint greenMultiplier = 256; +const uint blueMultiplier = 65536; const uint alphaMultiplier = 16777216; Surface3DRenderer::Surface3DRenderer(Surface3DController *controller) @@ -294,11 +296,6 @@ void Surface3DRenderer::updateSeries(const QList &seriesLis } } -void Surface3DRenderer::updateCustomData(const QList &customItems) -{ - // TODO -} - SeriesRenderCache *Surface3DRenderer::createNewCache(QAbstract3DSeries *series) { m_selectionTexturesDirty = true; @@ -749,7 +746,7 @@ void Surface3DRenderer::drawSlicedScene() GLfloat scaleXBackground = 0.0f; - if (m_renderCacheList.size()) { + if (!m_renderCacheList.isEmpty()) { bool drawGrid = false; foreach (SeriesRenderCache *baseCache, m_renderCacheList) { @@ -1045,8 +1042,9 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) // Draw depth buffer #if !defined(QT_OPENGL_ES_2) - GLfloat adjustedLightStrength = m_cachedTheme->lightStrength() / 10.0f; - if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone && m_renderCacheList.size()) { + GLfloat adjustedLightStrength = m_cachedTheme->lightStrength() / 10.0f; + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone && + (!m_renderCacheList.isEmpty() || !m_customRenderCache.isEmpty())) { // Render scene into a depth texture for using with shadow mapping // Enable drawing to depth framebuffer glBindFramebuffer(GL_FRAMEBUFFER, m_depthFrameBuffer); @@ -1107,6 +1105,10 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); + Abstract3DRenderer::drawCustomItems(RenderingDepth, m_depthShader, viewMatrix, + projectionViewMatrix, depthProjectionViewMatrix, + m_depthTexture, m_shadowQualityToShader); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthModelTexture, 0); glClear(GL_DEPTH_BUFFER_BIT); @@ -1139,8 +1141,9 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) glDisableVertexAttribArray(m_depthShader->posAtt()); - drawCustomItems(RenderingDepth, m_depthShader, activeCamera, projectionMatrix, - depthProjectionMatrix); + Abstract3DRenderer::drawCustomItems(RenderingDepth, m_depthShader, viewMatrix, + projectionViewMatrix, depthProjectionViewMatrix, + m_depthTexture, m_shadowQualityToShader); // Disable drawing to depth framebuffer (= enable drawing to screen) glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle); @@ -1160,7 +1163,9 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) glEnable(GL_TEXTURE_2D); // Draw selection buffer - if (!m_cachedIsSlicingActivated && m_renderCacheList.size() && m_selectionState == SelectOnScene + if (!m_cachedIsSlicingActivated && !m_renderCacheList.isEmpty() + && !m_customRenderCache.isEmpty() + && m_selectionState == SelectOnScene && m_cachedSelectionMode > QAbstract3DGraph::SelectionNone) { m_selectionShader->bind(); glBindFramebuffer(GL_FRAMEBUFFER, m_selectionFrameBuffer); @@ -1189,24 +1194,23 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) cache->selectionTexture()); } } - drawCustomItems(RenderingSelection, m_selectionShader, activeCamera, projectionMatrix, - depthProjectionMatrix); + m_surfaceGridShader->bind(); + Abstract3DRenderer::drawCustomItems(RenderingSelection, m_surfaceGridShader, viewMatrix, + projectionViewMatrix, depthProjectionViewMatrix, + m_depthTexture, m_shadowQualityToShader); drawLabels(true, activeCamera, viewMatrix, projectionMatrix); glEnable(GL_DITHER); - GLubyte pixel[4] = {0, 0, 0, 0}; - glReadPixels(m_inputPosition.x(), m_viewport.height() - m_inputPosition.y(), - 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void *)pixel); + QVector4D clickedColor = Utils::getSelection(m_inputPosition, m_viewport.height()); glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle); // Put the RGBA value back to uint -#if !defined(QT_OPENGL_ES_2) - uint selectionId = pixel[0] + pixel[1] * 256 + pixel[2] * 65536 + pixel[3] * alphaMultiplier; -#else - uint selectionId = pixel[0] + pixel[1] * 256 + pixel[2] * 65536; -#endif + uint selectionId = clickedColor.x() + + clickedColor.y() * greenMultiplier + + clickedColor.z() * blueMultiplier + + clickedColor.w() * alphaMultiplier; m_clickedPosition = selectionIdToSurfacePoint(selectionId); @@ -1220,7 +1224,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) } // Draw the surface - if (m_renderCacheList.size()) { + if (!m_renderCacheList.isEmpty()) { // For surface we can see climpses from underneath glDisable(GL_CULL_FACE); @@ -1321,8 +1325,9 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) } } - drawCustomItems(RenderingNormal, m_customItemShader, activeCamera, projectionMatrix, - depthProjectionMatrix); + Abstract3DRenderer::drawCustomItems(RenderingNormal, m_customItemShader, viewMatrix, + projectionViewMatrix, depthProjectionViewMatrix, + m_depthTexture, m_shadowQualityToShader); // Bind background shader m_backgroundShader->bind(); @@ -1377,7 +1382,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) m_backgroundShader->setUniformValue(m_backgroundShader->lightS(), adjustedLightStrength); // Draw the object - if (noShadows) + if (noShadows && m_customRenderCache.isEmpty()) m_drawer->drawObject(m_backgroundShader, m_backgroundObj, 0, m_noShadowTexture); else m_drawer->drawObject(m_backgroundShader, m_backgroundObj, 0, m_depthTexture); @@ -1767,14 +1772,6 @@ 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) { @@ -1786,12 +1783,11 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa shader = m_surfaceGridShader; } else { shader = m_labelShader; - + shader->bind(); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } - shader->bind(); glEnable(GL_POLYGON_OFFSET_FILL); @@ -2509,4 +2505,11 @@ void Surface3DRenderer::updateDepthBuffer() } #endif +QVector3D Surface3DRenderer::convertPositionToTranslation(const QVector3D &position) { + float xTrans = m_axisCacheX.positionAt(position.x()); + float yTrans = m_axisCacheY.positionAt(position.y()); + float zTrans = m_axisCacheZ.positionAt(position.z()); + return QVector3D(xTrans, yTrans, zTrans); +} + QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h index 98968dd5..0cd4502a 100644 --- a/src/datavisualization/engine/surface3drenderer_p.h +++ b/src/datavisualization/engine/surface3drenderer_p.h @@ -106,7 +106,6 @@ public: void updateData(); void updateSeries(const QList &seriesList); - void updateCustomData(const QList &customItems); SeriesRenderCache *createNewCache(QAbstract3DSeries *series); void cleanCache(SeriesRenderCache *cache); void updateSelectionMode(QAbstract3DGraph::SelectionFlags mode); @@ -117,8 +116,8 @@ public: void updateSelectedPoint(const QPoint &position, QSurface3DSeries *series); inline QPoint clickedPosition() const { return m_clickedPosition; } void resetClickedStatus(); + QVector3D convertPositionToTranslation(const QVector3D &position); - void drawSlicedScene(); void render(GLuint defaultFboHandle = 0); protected: @@ -141,12 +140,12 @@ private: QRect calculateSampleRect(const QSurfaceDataArray &array); void loadBackgroundMesh(); void loadLabelMesh(); + + 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); + void calculateSceneScalingFactors(); void initBackgroundShaders(const QString &vertexShader, const QString &fragmentShader); void initLabelShaders(const QString &vertexShader, const QString &fragmentShader); diff --git a/src/datavisualization/utils/texturehelper.cpp b/src/datavisualization/utils/texturehelper.cpp index ee1d51a6..07130d7e 100644 --- a/src/datavisualization/utils/texturehelper.cpp +++ b/src/datavisualization/utils/texturehelper.cpp @@ -193,7 +193,8 @@ GLuint TextureHelper::createDepthTexture(const QSize &size, GLuint textureSize) #endif #if !defined(QT_OPENGL_ES_2) -GLuint TextureHelper::createDepthTextureFrameBuffer(const QSize &size, GLuint &frameBuffer, GLuint textureSize) +GLuint TextureHelper::createDepthTextureFrameBuffer(const QSize &size, GLuint &frameBuffer, + GLuint textureSize) { GLuint depthtextureid = createDepthTexture(size, textureSize); @@ -223,7 +224,8 @@ GLuint TextureHelper::createDepthTextureFrameBuffer(const QSize &size, GLuint &f #endif #if !defined(QT_OPENGL_ES_2) -void TextureHelper::fillDepthTexture(GLuint texture,const QSize &size, GLuint textureSize, GLfloat value) +void TextureHelper::fillDepthTexture(GLuint texture,const QSize &size, GLuint textureSize, + GLfloat value) { int nItems = size.width() * textureSize * size.height() * textureSize; GLfloat *bits = new GLfloat[nItems]; -- cgit v1.2.3