diff options
author | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2014-09-25 15:04:44 +0300 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2014-09-26 10:06:52 +0300 |
commit | 0ab45b018fa98e9ef6cffd70178f208eb4f16550 (patch) | |
tree | 77d324f47ccb52cc543df9e8990153b82ead2688 /src/datavisualization/engine/abstract3drenderer.cpp | |
parent | 36bc54f5720bddb9899e64d665117ac1e1b5bc94 (diff) |
Implement zooming to cursor
Zooming to cursor is now default operating mode of
the default input handler.
Task-number: QTRD-3263
Change-Id: I5699fc0ce7393059538972cd52f31f06d87e3d8d
Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
Diffstat (limited to 'src/datavisualization/engine/abstract3drenderer.cpp')
-rw-r--r-- | src/datavisualization/engine/abstract3drenderer.cpp | 124 |
1 files changed, 115 insertions, 9 deletions
diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp index d0f3c04b..a5e1bc9b 100644 --- a/src/datavisualization/engine/abstract3drenderer.cpp +++ b/src/datavisualization/engine/abstract3drenderer.cpp @@ -54,8 +54,11 @@ Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller) m_devicePixelRatio(1.0f), m_selectionLabelDirty(true), m_clickPending(false), + m_graphPositionQueryPending(false), m_clickedSeries(0), m_clickedType(QAbstract3DGraph::ElementNone), + m_selectedLabelIndex(-1), + m_selectedCustomItemIndex(-1), m_selectionLabelItem(0), m_visibleSeriesCount(0), m_customItemShader(0), @@ -64,6 +67,9 @@ Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller) m_volumeTextureSliceShader(0), m_volumeSliceFrameShader(0), m_labelShader(0), + m_cursorPositionShader(0), + m_cursorPositionFrameBuffer(0), + m_cursorPositionTexture(0), m_useOrthoProjection(false), m_xFlipped(false), m_yFlipped(false), @@ -72,6 +78,7 @@ Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller) m_backgroundObj(0), m_gridLineObj(0), m_labelObj(0), + m_positionMapperObj(0), m_graphAspectRatio(2.0f), m_graphHorizontalAspectRatio(0.0f), m_polarGraph(false), @@ -110,6 +117,7 @@ Abstract3DRenderer::~Abstract3DRenderer() delete m_volumeSliceFrameShader; delete m_volumeTextureSliceShader; delete m_labelShader; + delete m_cursorPositionShader; foreach (SeriesRenderCache *cache, m_renderCacheList) { cache->cleanup(m_textureHelper); @@ -127,9 +135,15 @@ Abstract3DRenderer::~Abstract3DRenderer() ObjectHelper::releaseObjectHelper(this, m_backgroundObj); ObjectHelper::releaseObjectHelper(this, m_gridLineObj); ObjectHelper::releaseObjectHelper(this, m_labelObj); + ObjectHelper::releaseObjectHelper(this, m_positionMapperObj); if (m_textureHelper) { m_textureHelper->deleteTexture(&m_depthTexture); + m_textureHelper->deleteTexture(&m_cursorPositionTexture); + + if (QOpenGLContext::currentContext()) + m_textureHelper->glDeleteFramebuffers(1, &m_cursorPositionFrameBuffer); + delete m_textureHelper; } } @@ -157,6 +171,12 @@ void Abstract3DRenderer::initializeOpenGL() initLabelShaders(QStringLiteral(":/shaders/vertexLabel"), QStringLiteral(":/shaders/fragmentLabel")); + + initCursorPositionShaders(QStringLiteral(":/shaders/vertexPosition"), + QStringLiteral(":/shaders/fragmentPositionMap")); + + loadLabelMesh(); + loadPositionMapperMesh(); } void Abstract3DRenderer::render(const GLuint defaultFboHandle) @@ -191,11 +211,6 @@ void Abstract3DRenderer::updateSelectionState(SelectionState state) m_selectionState = state; } -void Abstract3DRenderer::updateInputPosition(const QPoint &position) -{ - m_inputPosition = position; -} - void Abstract3DRenderer::initGradientShaders(const QString &vertexShader, const QString &fragmentShader) { @@ -244,6 +259,27 @@ void Abstract3DRenderer::initLabelShaders(const QString &vertexShader, const QSt m_labelShader->initialize(); } +void Abstract3DRenderer::initCursorPositionShaders(const QString &vertexShader, + const QString &fragmentShader) +{ + // Init the shader + delete m_cursorPositionShader; + m_cursorPositionShader = new ShaderHelper(this, vertexShader, fragmentShader); + m_cursorPositionShader->initialize(); +} + +void Abstract3DRenderer::initCursorPositionBuffer() +{ + m_textureHelper->deleteTexture(&m_cursorPositionTexture); + + if (m_primarySubViewport.size().isEmpty()) + return; + + m_cursorPositionTexture = + m_textureHelper->createCursorPositionTexture(m_primarySubViewport.size(), + m_cursorPositionFrameBuffer); +} + void Abstract3DRenderer::updateTheme(Q3DTheme *theme) { // Synchronize the controller theme with renderer @@ -270,8 +306,12 @@ void Abstract3DRenderer::updateScene(Q3DScene *scene) } QPoint logicalPixelPosition = scene->selectionQueryPosition(); - updateInputPosition(QPoint(logicalPixelPosition.x() * m_devicePixelRatio, - logicalPixelPosition.y() * m_devicePixelRatio)); + m_inputPosition = QPoint(logicalPixelPosition.x() * m_devicePixelRatio, + logicalPixelPosition.y() * m_devicePixelRatio); + + QPoint logicalGraphPosition = scene->graphPositionQuery(); + m_graphPositionQuery = QPoint(logicalGraphPosition.x() * m_devicePixelRatio, + logicalGraphPosition.y() * m_devicePixelRatio); // Synchronize the renderer scene to controller scene scene->d_ptr->sync(*m_cachedScene->d_ptr); @@ -296,6 +336,11 @@ void Abstract3DRenderer::updateScene(Q3DScene *scene) updateSelectionState(SelectOnScene); } } + + if (Q3DScene::invalidSelectionPoint() != logicalGraphPosition) { + m_graphPositionQueryPending = true; + scene->setGraphPositionQuery(Q3DScene::invalidSelectionPoint()); + } } void Abstract3DRenderer::updateTextures() @@ -347,7 +392,7 @@ void Abstract3DRenderer::reInitShaders() QStringLiteral(":/shaders/fragmentTexture3D"), QStringLiteral(":/shaders/fragmentTexture3DLowDef"), QStringLiteral(":/shaders/fragmentTexture3DSlice"), - QStringLiteral(":/shaders/colorAndPosition"), + QStringLiteral(":/shaders/vertexPosition"), QStringLiteral(":/shaders/fragment3DSliceFrames")); #else if (m_cachedOptimizationHint.testFlag(QAbstract3DGraph::OptimizationStatic) @@ -434,6 +479,8 @@ void Abstract3DRenderer::handleResize() // Re-init depth buffer updateDepthBuffer(); #endif + + initCursorPositionBuffer(); } void Abstract3DRenderer::calculateZoomLevel() @@ -929,6 +976,12 @@ void Abstract3DRenderer::loadLabelMesh() QStringLiteral(":/defaultMeshes/plane")); } +void Abstract3DRenderer::loadPositionMapperMesh() +{ + ObjectHelper::resetObjectHelper(this, m_positionMapperObj, + QStringLiteral(":/defaultMeshes/barFull")); +} + void Abstract3DRenderer::generateBaseColorTexture(const QColor &color, GLuint *texture) { m_textureHelper->deleteTexture(texture); @@ -1305,7 +1358,7 @@ void Abstract3DRenderer::drawCustomItems(RenderingState state, // Check that the render item is visible, and skip drawing if not // Also check if reflected item is on the "wrong" side, and skip drawing if it is if (!item->isVisible() || ((m_reflectionEnabled && reflection < 0.0f) - && (m_yFlipped == item->translation().y() >= 0.0))) { + && (m_yFlipped == (item->translation().y() >= 0.0)))) { continue; } if (loopCount == 0) { @@ -1627,6 +1680,59 @@ void Abstract3DRenderer::drawVolumeSliceFrame(const CustomRenderItem *item, Qt:: } +void Abstract3DRenderer::queriedGraphPosition(const QMatrix4x4 &projectionViewMatrix, + const QVector3D &scaling, + GLuint defaultFboHandle) +{ + m_cursorPositionShader->bind(); + + // Set up mapper framebuffer + glBindFramebuffer(GL_FRAMEBUFFER, m_cursorPositionFrameBuffer); + glViewport(0, 0, + m_primarySubViewport.width(), + m_primarySubViewport.height()); + glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_DITHER); // Dither may affect colors if enabled + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + + // Draw a cube scaled to the graph dimensions + QMatrix4x4 modelMatrix; + QMatrix4x4 MVPMatrix; + + modelMatrix.scale(scaling); + + MVPMatrix = projectionViewMatrix * modelMatrix; + m_cursorPositionShader->setUniformValue(m_cursorPositionShader->MVP(), MVPMatrix); + m_drawer->drawObject(m_cursorPositionShader, m_positionMapperObj); + + QVector4D dataColor = Utils::getSelection(m_graphPositionQuery, + m_primarySubViewport.height()); + if (dataColor.w() > 0.0f) { + // If position is outside the graph, set the position well outside the graph boundaries + dataColor = QVector4D(-10000.0f, -10000.0f, -10000.0f, 0.0f); + } else { + // Normalize to range [0.0, 1.0] + dataColor /= 255.0f; + } + + // Restore state + glEnable(GL_DITHER); + glCullFace(GL_BACK); + glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle); + glViewport(m_primarySubViewport.x(), + m_primarySubViewport.y(), + m_primarySubViewport.width(), + m_primarySubViewport.height()); + + QVector3D normalizedValues = dataColor.toVector3D() * 2.0f; + normalizedValues -= oneVector; + m_queriedGraphPosition = QVector3D(normalizedValues.x(), + normalizedValues.y(), + normalizedValues.z()); +} + void Abstract3DRenderer::calculatePolarXZ(const QVector3D &dataPos, float &x, float &z) const { // x is angular, z is radial |