diff options
author | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2013-09-19 15:11:27 +0300 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2013-09-20 08:56:51 +0300 |
commit | d395b8a944b1dc7eea69c5d2b4501e71552d659e (patch) | |
tree | ee16bf4695d03e697e99819d34792c2ad37fc905 /src/datavisualization/engine | |
parent | 14c8349dc0999f07c50504e70c91a604722eebf2 (diff) |
Fix scaling of the surface
No longer will surface grid count cause scaling of the background
etc.
Task-number: QTRD-2267
Change-Id: I9dd62bcd6ed7b342abc8a52c7f88ed88d22ded69
Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
Diffstat (limited to 'src/datavisualization/engine')
-rw-r--r-- | src/datavisualization/engine/scatter3drenderer.cpp | 20 | ||||
-rw-r--r-- | src/datavisualization/engine/surface3drenderer.cpp | 595 | ||||
-rw-r--r-- | src/datavisualization/engine/surface3drenderer_p.h | 3 |
3 files changed, 391 insertions, 227 deletions
diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp index 3d385c02..38044bbe 100644 --- a/src/datavisualization/engine/scatter3drenderer.cpp +++ b/src/datavisualization/engine/scatter3drenderer.cpp @@ -572,20 +572,18 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) QMatrix4x4 depthMVPMatrix; QMatrix4x4 itModelMatrix; - modelMatrix.translate(0.0f, 0.0f, zComp); #ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z - modelMatrix.scale( - QVector3D( - (aspectRatio * backgroundMargin * m_areaSize.width()) / m_scaleFactor, - backgroundMargin, - (aspectRatio * backgroundMargin * m_areaSize.height()) / m_scaleFactor)); + QVector3D bgScale((aspectRatio * backgroundMargin * m_areaSize.width()) / m_scaleFactor, + backgroundMargin, + (aspectRatio * backgroundMargin * m_areaSize.height()) / m_scaleFactor); #else // ..and this if we want uniform scaling based on largest dimension - modelMatrix.scale(QVector3D((aspectRatio * backgroundMargin), - backgroundMargin, - (aspectRatio * backgroundMargin))); + QVector3D bgScale((aspectRatio * backgroundMargin), + backgroundMargin, + (aspectRatio * backgroundMargin)); #endif - // We can copy modelMatrix to itModelMatrix as it has not been translated - itModelMatrix = modelMatrix; + modelMatrix.translate(0.0f, 0.0f, zComp); + modelMatrix.scale(bgScale); + itModelMatrix.scale(bgScale); // If we're viewing from below, background object must be flipped if (m_yFlipped) { modelMatrix.rotate(180.0f, 1.0, 0.0, 0.0); diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp index e477fca3..e93b3a2c 100644 --- a/src/datavisualization/engine/surface3drenderer.cpp +++ b/src/datavisualization/engine/surface3drenderer.cpp @@ -43,6 +43,10 @@ static const int ID_TO_RGBA_MASK = 0xff; QT_DATAVISUALIZATION_BEGIN_NAMESPACE +// TODO Uniform scaling is broken on surface +//#define USE_UNIFORM_SCALING // Scale x and z uniformly, or based on autoscaled values + +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.1f = make it 10% larger to avoid items being drawn inside background) const GLfloat labelMargin = 0.05f; const GLfloat backgroundBottom = 1.0f; @@ -67,6 +71,8 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller) m_scaleFactor(0.0f), m_scaleX(0.0f), m_scaleZ(0.0f), + m_scaleXWithBackground(0.0f), + m_scaleZWithBackground(0.0f), m_backgroundObj(0), m_gridLineObj(0), m_labelObj(0), @@ -205,6 +211,8 @@ void Surface3DRenderer::updateDataModel(QSurfaceDataProxy *dataProxy) sampleSpace.setWidth(2); } + calculateSceneScalingFactors(); + if (m_dataArray.size() > 0) { if (!m_surfaceObj) loadSurfaceObj(); @@ -217,10 +225,6 @@ void Surface3DRenderer::updateDataModel(QSurfaceDataProxy *dataProxy) m_sampleSpace = sampleSpace; } - // TODO: Setting height bigger than biggest value on data works nicely, but smaller - // creates odd scaling. That's not going to be trivial to clip 'peaks' off - m_heightNormalizer = (GLfloat)qMax(qAbs(m_axisCacheY.max()), qAbs(m_axisCacheY.min())); - if (m_cachedSmoothSurface) m_surfaceObj->setUpSmoothData(m_dataArray, m_sampleSpace, m_heightNormalizer, dimensionChanged); else @@ -230,8 +234,6 @@ void Surface3DRenderer::updateDataModel(QSurfaceDataProxy *dataProxy) updateSelectionTexture(); } - calculateSceneScalingFactors(); - Abstract3DRenderer::updateDataModel(dataProxy); } @@ -293,7 +295,6 @@ void Surface3DRenderer::render(GLuint defaultFboHandle) void Surface3DRenderer::drawScene(GLuint defaultFboHandle) { - Q3DCamera *camera = m_cachedScene->activeCamera(); GLfloat backgroundRotation = 0; // Specify viewport @@ -308,6 +309,8 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) // Calculate view matrix QMatrix4x4 viewMatrix = m_cachedScene->activeCamera()->viewMatrix(); + QMatrix4x4 projectionViewMatrix = projectionMatrix * viewMatrix; + // Calculate flipping indicators if (viewMatrix.row(0).x() > 0) m_zFlipped = false; @@ -337,6 +340,10 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) depthViewMatrix.lookAt(lightPos, QVector3D(0.0f, 0.0f, zComp), QVector3D(0.0f, 1.0f, 0.0f)); // TODO: Move + QMatrix4x4 depthProjectionViewMatrix = depthProjectionMatrix * depthViewMatrix; + + GLfloat adjustedLightStrength = m_cachedTheme.m_lightStrength / 10.0f; + // Enable texturing glEnable(GL_TEXTURE_2D); @@ -360,7 +367,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) modelMatrix.translate(0.0f, 0.0f, zComp); modelMatrix.scale(QVector3D(m_scaleX, 1.0f, m_scaleZ)); - MVPMatrix = projectionMatrix * viewMatrix * modelMatrix; + MVPMatrix = projectionViewMatrix * modelMatrix; m_selectionShader->setUniformValue(m_selectionShader->MVP(), MVPMatrix); @@ -433,12 +440,12 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) itModelMatrix.scale(QVector3D(m_scaleX, 1.0f, m_scaleZ)); #ifdef SHOW_DEPTH_TEXTURE_SCENE - MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix; + MVPMatrix = depthProjectionViewMatrix * modelMatrix; #else - MVPMatrix = projectionMatrix * viewMatrix * modelMatrix; + MVPMatrix = projectionViewMatrix * modelMatrix; #endif // TODO Check the usage? - depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix; + depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; // Set shader bindings m_surfaceShader->setUniformValue(m_surfaceShader->lightP(), lightPos); @@ -502,16 +509,24 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) QMatrix4x4 itModelMatrix; modelMatrix.translate(0.0f, 0.0f, zComp); - modelMatrix.scale(QVector3D(m_scaleX * backgroundMargin, 1.0f, m_scaleZ * backgroundMargin)); - modelMatrix.rotate(backgroundRotation, 0.0f, 1.0f, 0.0f); - itModelMatrix.scale(QVector3D(m_scaleX * backgroundMargin, 1.0f, m_scaleZ * backgroundMargin)); + QVector3D bgScale(m_scaleXWithBackground, backgroundMargin, m_scaleZWithBackground); + modelMatrix.scale(bgScale); + itModelMatrix.scale(bgScale); + + // If we're viewing from below, background object must be flipped + if (m_yFlipped) { + modelMatrix.rotate(180.0f, 1.0, 0.0, 0.0); + modelMatrix.rotate(270.0f - backgroundRotation, 0.0f, 1.0f, 0.0f); + } else { + modelMatrix.rotate(backgroundRotation, 0.0f, 1.0f, 0.0f); + } #ifdef SHOW_DEPTH_TEXTURE_SCENE - MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix; + MVPMatrix = depthProjectionViewMatrix * modelMatrix; #else - MVPMatrix = projectionMatrix * viewMatrix * modelMatrix; + MVPMatrix = projectionViewMatrix * modelMatrix; #endif - depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix; + depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; QVector3D backgroundColor = Utils::vectorFromColor(m_cachedTheme.m_backgroundColor); @@ -533,7 +548,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) m_shadowQualityToShader); m_backgroundShader->setUniformValue(m_backgroundShader->depth(), depthMVPMatrix); m_backgroundShader->setUniformValue(m_backgroundShader->lightS(), - m_cachedTheme.m_lightStrength / 10.0f); + adjustedLightStrength); // Draw the object m_drawer->drawObject(m_backgroundShader, m_backgroundObj, 0, m_depthTexture); @@ -562,39 +577,49 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) } // Draw grid lines - if (m_cachedIsGridEnabled && m_surfaceObj /*&& m_heightNormalizer*/) { + QVector3D gridLineScaleX(m_scaleXWithBackground, gridLineWidth, gridLineWidth); + QVector3D gridLineScaleZ(gridLineWidth, gridLineWidth, m_scaleZWithBackground); + QVector3D gridLineScaleY(gridLineWidth, backgroundMargin, gridLineWidth); + + if (m_cachedIsGridEnabled && m_heightNormalizer) { ShaderHelper *lineShader = m_backgroundShader; - // Bind shader + // Bind line shader lineShader->bind(); // Set unchanging shader bindings - QVector3D color = Utils::vectorFromColor(m_cachedTheme.m_gridLine); + QVector3D lineColor = Utils::vectorFromColor(m_cachedTheme.m_gridLine); lineShader->setUniformValue(lineShader->lightP(), lightPos); lineShader->setUniformValue(lineShader->view(), viewMatrix); - lineShader->setUniformValue(lineShader->color(), color); + lineShader->setUniformValue(lineShader->color(), lineColor); lineShader->setUniformValue(lineShader->ambientS(), m_cachedTheme.m_ambientStrength); - GLfloat yPos = -backgroundBottom; - if (m_yFlipped) - yPos = backgroundBottom; - + // Rows (= Z) if (m_axisCacheZ.segmentCount() > 0) { - GLfloat lineStep = 2.0f / (m_axisCacheZ.segmentCount()); - GLfloat linePos = -1.0; + // Floor lines + GLfloat lineStep = 2.0f * aspectRatio * m_axisCacheZ.subSegmentStep() / m_scaleFactor; + GLfloat linePos = m_scaleZ + zComp; // Start line + int lastSegment = m_axisCacheZ.subSegmentCount() * m_axisCacheZ.segmentCount(); - for (int segment = 0; segment <= m_axisCacheZ.segmentCount(); segment++) { + for (int segment = 0; segment <= lastSegment; segment++) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; QMatrix4x4 depthMVPMatrix; QMatrix4x4 itModelMatrix; - modelMatrix.translate(0.0f, yPos, linePos * m_scaleZ + zComp); + if (m_yFlipped) + modelMatrix.translate(0.0f, backgroundMargin, linePos); + else + modelMatrix.translate(0.0f, -backgroundMargin, linePos); + + modelMatrix.scale(gridLineScaleX); + itModelMatrix.scale(gridLineScaleX); - modelMatrix.scale(QVector3D(m_scaleX * backgroundMargin, gridLineWidth, gridLineWidth)); - itModelMatrix.scale(QVector3D(m_scaleX * backgroundMargin, gridLineWidth, gridLineWidth)); + // If we're viewing from below, grid line object must be flipped + if (m_yFlipped) + modelMatrix.rotate(180.0f, 1.0, 0.0, 0.0); - MVPMatrix = projectionMatrix * viewMatrix * modelMatrix; - depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix; + MVPMatrix = projectionViewMatrix * modelMatrix; + depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; // Set the rest of the shader bindings lineShader->setUniformValue(lineShader->model(), modelMatrix); @@ -608,10 +633,10 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader); lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); lineShader->setUniformValue(lineShader->lightS(), - m_cachedTheme.m_lightStrength / 10.0f); + adjustedLightStrength); // Draw the object - m_drawer->drawObject(m_shader, m_gridLineObj, 0, m_depthTexture); + m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture); } else #endif { @@ -620,31 +645,88 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) m_cachedTheme.m_lightStrength); // Draw the object - m_drawer->drawObject(m_shader, m_gridLineObj); + m_drawer->drawObject(lineShader, m_gridLineObj); } + linePos -= lineStep; + } - linePos += lineStep; + // Side wall lines + GLfloat lineXTrans = m_scaleXWithBackground; + linePos = m_scaleZ + zComp; // Start line + + if (!m_xFlipped) + lineXTrans = -lineXTrans; + + for (int segment = 0; segment <= lastSegment; segment++) { + QMatrix4x4 modelMatrix; + QMatrix4x4 MVPMatrix; + QMatrix4x4 depthMVPMatrix; + QMatrix4x4 itModelMatrix; + + modelMatrix.translate(lineXTrans, 0.0f, linePos); + modelMatrix.scale(gridLineScaleY); + itModelMatrix.scale(gridLineScaleY); + + MVPMatrix = projectionViewMatrix * modelMatrix; + depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; + + // Set the rest of the shader bindings + lineShader->setUniformValue(lineShader->model(), modelMatrix); + lineShader->setUniformValue(lineShader->nModel(), + itModelMatrix.inverted().transposed()); + lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); + +#if !defined(QT_OPENGL_ES_2) + if (m_cachedShadowQuality > QDataVis::ShadowNone) { + // Set shadow shader bindings + lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader); + lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); + lineShader->setUniformValue(lineShader->lightS(), + adjustedLightStrength); + + // Draw the object + m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture); + } else +#endif + { + // Set shadowless shader bindings + lineShader->setUniformValue(lineShader->lightS(), + m_cachedTheme.m_lightStrength); + + // Draw the object + m_drawer->drawObject(lineShader, m_gridLineObj); + } + linePos -= lineStep; } } - // Floor lines: columns (= X) + // Columns (= X) if (m_axisCacheX.segmentCount() > 0) { - GLfloat lineStep = 2.0f / (m_axisCacheX.segmentCount()); - GLfloat linePos = -1.0; + // Floor lines + GLfloat lineStep = -2.0f * aspectRatio * m_axisCacheX.subSegmentStep() / m_scaleFactor; + GLfloat linePos = m_scaleX; + int lastSegment = m_axisCacheX.subSegmentCount() * m_axisCacheX.segmentCount(); - for (int segment = 0; segment <= m_axisCacheX.segmentCount(); segment++) { + for (int segment = 0; segment <= lastSegment; segment++) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; QMatrix4x4 depthMVPMatrix; QMatrix4x4 itModelMatrix; - modelMatrix.translate(linePos * m_scaleX, yPos, zComp); + if (m_yFlipped) + modelMatrix.translate(linePos, backgroundMargin, zComp); + else + modelMatrix.translate(linePos, -backgroundMargin, zComp); + + modelMatrix.scale(gridLineScaleZ); + itModelMatrix.scale(gridLineScaleZ); - modelMatrix.scale(QVector3D(gridLineWidth, gridLineWidth, m_scaleZ * backgroundMargin)); - itModelMatrix.scale(QVector3D(gridLineWidth, gridLineWidth, m_scaleZ * backgroundMargin)); + // If we're viewing from below, grid line object must be flipped + if (m_yFlipped) + modelMatrix.rotate(180.0f, 1.0, 0.0, 0.0); - MVPMatrix = projectionMatrix * viewMatrix * modelMatrix; - depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix; + MVPMatrix = projectionViewMatrix * modelMatrix; + depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; // Set the rest of the shader bindings lineShader->setUniformValue(lineShader->model(), modelMatrix); @@ -658,10 +740,10 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader); lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); lineShader->setUniformValue(lineShader->lightS(), - m_cachedTheme.m_lightStrength / 10.0f); + adjustedLightStrength); // Draw the object - m_drawer->drawObject(m_shader, m_gridLineObj, 0, m_depthTexture); + m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture); } else #endif { @@ -670,35 +752,86 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) m_cachedTheme.m_lightStrength); // Draw the object - m_drawer->drawObject(m_shader, m_gridLineObj); + m_drawer->drawObject(lineShader, m_gridLineObj); } + linePos += lineStep; + } + + // Back wall lines + GLfloat lineZTrans = m_scaleZWithBackground + zComp; + linePos = m_scaleX; + if (!m_zFlipped) + lineZTrans = -lineZTrans + zComp + zComp; + + for (int segment = 0; segment <= lastSegment; segment++) { + QMatrix4x4 modelMatrix; + QMatrix4x4 MVPMatrix; + QMatrix4x4 depthMVPMatrix; + QMatrix4x4 itModelMatrix; + + modelMatrix.translate(linePos, 0.0f, lineZTrans); + modelMatrix.scale(gridLineScaleY); + itModelMatrix.scale(gridLineScaleY); + + MVPMatrix = projectionViewMatrix * modelMatrix; + depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; + + // Set the rest of the shader bindings + lineShader->setUniformValue(lineShader->model(), modelMatrix); + lineShader->setUniformValue(lineShader->nModel(), + itModelMatrix.inverted().transposed()); + lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); + +#if !defined(QT_OPENGL_ES_2) + if (m_cachedShadowQuality > QDataVis::ShadowNone) { + // Set shadow shader bindings + lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader); + lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); + lineShader->setUniformValue(lineShader->lightS(), + adjustedLightStrength); + + // Draw the object + m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture); + } else +#endif + { + // Set shadowless shader bindings + lineShader->setUniformValue(lineShader->lightS(), + m_cachedTheme.m_lightStrength); + + // Draw the object + m_drawer->drawObject(lineShader, m_gridLineObj); + } linePos += lineStep; } } - // Wall lines: back wall + // Horizontal wall lines if (m_axisCacheY.segmentCount() > 0) { - GLfloat lineStep = 2.0f / (m_axisCacheY.segmentCount()); - GLfloat linePos = -1.0; - GLfloat zPos = -backgroundMargin; + // Back wall + GLfloat lineStep = 2.0f * m_axisCacheY.subSegmentStep() / m_heightNormalizer; + GLfloat linePos = -1.0f; + int lastSegment = m_axisCacheY.subSegmentCount() * m_axisCacheY.segmentCount(); + + GLfloat lineZTrans = m_scaleZWithBackground + zComp; - if (m_zFlipped) - zPos = backgroundMargin; + if (!m_zFlipped) + lineZTrans = -lineZTrans + zComp + zComp; - for (int segment = 0; segment <= m_axisCacheY.segmentCount(); segment++) { + for (int segment = 0; segment <= lastSegment; segment++) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; QMatrix4x4 depthMVPMatrix; QMatrix4x4 itModelMatrix; - modelMatrix.translate(0.0f, linePos, zPos * m_scaleZ + zComp); + modelMatrix.translate(0.0f, linePos, lineZTrans); - modelMatrix.scale(QVector3D(m_scaleX * backgroundMargin, gridLineWidth, gridLineWidth)); - itModelMatrix.scale(QVector3D(m_scaleX * backgroundMargin, gridLineWidth, gridLineWidth)); + modelMatrix.scale(gridLineScaleX); + itModelMatrix.scale(gridLineScaleX); - MVPMatrix = projectionMatrix * viewMatrix * modelMatrix; - depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix; + MVPMatrix = projectionViewMatrix * modelMatrix; + depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; // Set the rest of the shader bindings lineShader->setUniformValue(lineShader->model(), modelMatrix); @@ -712,10 +845,10 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader); lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); lineShader->setUniformValue(lineShader->lightS(), - m_cachedTheme.m_lightStrength / 10.0f); + adjustedLightStrength); // Draw the object - m_drawer->drawObject(m_shader, m_gridLineObj, 0, m_depthTexture); + m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture); } else #endif { @@ -724,32 +857,32 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) m_cachedTheme.m_lightStrength); // Draw the object - m_drawer->drawObject(m_shader, m_gridLineObj); + m_drawer->drawObject(lineShader, m_gridLineObj); } - linePos += lineStep; } - // Wall lines: side wall - linePos = -1.0; - GLfloat xPos = -backgroundMargin; + // Side wall + linePos = -1.0f; + lastSegment = m_axisCacheY.subSegmentCount() * m_axisCacheY.segmentCount(); + GLfloat lineXTrans = m_scaleXWithBackground; - if (m_xFlipped) - xPos = backgroundMargin; + if (!m_xFlipped) + lineXTrans = -lineXTrans; - for (int segment = 0; segment <= m_axisCacheY.segmentCount(); segment++) { + for (int segment = 0; segment <= lastSegment; segment++) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; QMatrix4x4 depthMVPMatrix; QMatrix4x4 itModelMatrix; - modelMatrix.translate(xPos * m_scaleX, linePos, 0.0f + zComp); + modelMatrix.translate(lineXTrans, linePos, zComp); - modelMatrix.scale(QVector3D(gridLineWidth, gridLineWidth, m_scaleZ * backgroundMargin)); - itModelMatrix.scale(QVector3D(gridLineWidth, gridLineWidth, m_scaleZ * backgroundMargin)); + modelMatrix.scale(gridLineScaleZ); + itModelMatrix.scale(gridLineScaleZ); - MVPMatrix = projectionMatrix * viewMatrix * modelMatrix; - depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix; + MVPMatrix = projectionViewMatrix * modelMatrix; + depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; // Set the rest of the shader bindings lineShader->setUniformValue(lineShader->model(), modelMatrix); @@ -763,10 +896,10 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader); lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); lineShader->setUniformValue(lineShader->lightS(), - m_cachedTheme.m_lightStrength / 10.0f); + adjustedLightStrength); // Draw the object - m_drawer->drawObject(m_shader, m_gridLineObj, 0, m_depthTexture); + m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture); } else #endif { @@ -775,12 +908,14 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) m_cachedTheme.m_lightStrength); // Draw the object - m_drawer->drawObject(m_shader, m_gridLineObj); + m_drawer->drawObject(lineShader, m_gridLineObj); } - linePos += lineStep; } } + + // Release line shader + lineShader->release(); } // Draw axis labels @@ -793,151 +928,167 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) } // Z Labels - if (m_axisCacheZ.segmentCount() > 0 && m_surfaceObj) { - GLfloat posStep = coordSpace / (m_axisCacheZ.segmentCount()); - GLfloat labelPos = 1.0; - - for (int segment = 0; segment <= m_axisCacheZ.segmentCount(); segment++) { - GLfloat labelXTrans = backgroundMargin * m_scaleX + labelMargin; - GLfloat labelYTrans = -backgroundBottom; - GLfloat rotLabelX = -90.0f; - GLfloat rotLabelY = 0.0f; - GLfloat rotLabelZ = 0.0f; - Qt::AlignmentFlag alignment = Qt::AlignRight; - - if (m_xFlipped) { - labelXTrans = -labelXTrans; - alignment = Qt::AlignLeft; - } - if (m_yFlipped) { - rotLabelZ += 180.0f; - rotLabelY += 180.0f; - labelYTrans = -labelYTrans; + QVector3D positionZComp(0.0f, 0.0f, zComp); + if (m_axisCacheZ.segmentCount() > 0) { + GLfloat posStep = 2.0f * aspectRatio * m_axisCacheZ.segmentStep() / m_scaleFactor; + GLfloat labelPos = m_scaleZ + zComp; + int lastSegment = m_axisCacheZ.segmentCount(); + int labelNbr = 0; + GLfloat labelXTrans = m_scaleXWithBackground + labelMargin; + GLfloat labelYTrans = -backgroundMargin; + GLfloat rotLabelX = -90.0f; + GLfloat rotLabelY = 0.0f; + GLfloat rotLabelZ = 0.0f; + Qt::AlignmentFlag alignment = Qt::AlignRight; + if (m_zFlipped) + rotLabelY = 180.0f; + if (m_xFlipped) { + labelXTrans = -labelXTrans; + alignment = Qt::AlignLeft; + } + if (m_yFlipped) { + rotLabelZ += 180.0f; + rotLabelY += 180.0f; + labelYTrans = -labelYTrans; + } + QVector3D labelTrans = QVector3D(labelXTrans, + labelYTrans, + labelPos); + QVector3D rotation(rotLabelX, rotLabelY, rotLabelZ); + + for (int segment = 0; segment <= lastSegment; segment++) { + if (m_axisCacheZ.labelItems().size() > labelNbr) { + labelTrans.setZ(labelPos); + + // Draw the label here + m_dummyRenderItem.setTranslation(labelTrans); + const LabelItem &axisLabelItem = *m_axisCacheZ.labelItems().at(labelNbr); + + m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, + positionZComp, rotation, 0, m_cachedSelectionMode, + m_labelShader, m_labelObj, m_cachedScene->activeCamera(), true, true, + Drawer::LabelMid, alignment); } - QVector3D labelTrans = QVector3D(labelXTrans, labelYTrans, labelPos * m_scaleZ + zComp); - - // Draw the label here - m_dummyRenderItem.setTranslation(labelTrans); - const LabelItem &axisLabelItem = *m_axisCacheZ.labelItems().at(segment); - - m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, - QVector3D(0.0f, 0.0f, zComp), - QVector3D(rotLabelX, rotLabelY, rotLabelZ), - 0, m_cachedSelectionMode, - m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid, - alignment); - + labelNbr++; labelPos -= posStep; } } - // X Labels - if (m_axisCacheX.segmentCount() > 0 && m_surfaceObj) { - GLfloat posStep = coordSpace / (m_axisCacheX.segmentCount()); - GLfloat labelPos = -1.0; - - for (int segment = 0; segment <= m_axisCacheX.segmentCount(); segment++) { - GLfloat labelYTrans = -backgroundBottom; - GLfloat labelZTrans = backgroundMargin * m_scaleZ + labelMargin; - GLfloat rotLabelX = -90.0f; - GLfloat rotLabelY = 90.0f; - GLfloat rotLabelZ = 0.0f; - Qt::AlignmentFlag alignment = Qt::AlignLeft; - - if (m_xFlipped) - rotLabelY = -90.0f; - if (m_zFlipped) { - labelZTrans = -labelZTrans; - alignment = Qt::AlignRight; - } - if (m_yFlipped) { - rotLabelZ += 180.0f; - rotLabelY += 180.0f; - labelYTrans = -labelYTrans; + if (m_axisCacheX.segmentCount() > 0) { + GLfloat posStep = 2.0f * aspectRatio * m_axisCacheX.segmentStep() / m_scaleFactor; + GLfloat labelPos = -m_scaleX; + int lastSegment = m_axisCacheX.segmentCount(); + + int labelNbr = 0; + GLfloat labelZTrans = m_scaleZWithBackground + labelMargin; + GLfloat labelYTrans = -backgroundMargin; + GLfloat rotLabelX = -90.0f; + GLfloat rotLabelY = 90.0f; + GLfloat rotLabelZ = 0.0f; + Qt::AlignmentFlag alignment = Qt::AlignLeft; + if (m_xFlipped) + rotLabelY = -90.0f; + if (m_zFlipped) { + labelZTrans = -labelZTrans; + alignment = Qt::AlignRight; + } + if (m_yFlipped) { + rotLabelZ += 180.0f; + rotLabelY += 180.0f; + labelYTrans = -labelYTrans; + } + QVector3D labelTrans = QVector3D(labelPos, + labelYTrans, + labelZTrans + zComp); + QVector3D rotation(rotLabelX, rotLabelY, rotLabelZ); + + for (int segment = 0; segment <= lastSegment; segment++) { + if (m_axisCacheX.labelItems().size() > labelNbr) { + // Draw the label here + labelTrans.setX(labelPos); + m_dummyRenderItem.setTranslation(labelTrans); + const LabelItem &axisLabelItem = *m_axisCacheX.labelItems().at(labelNbr); + + m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, + positionZComp, rotation, 0, m_cachedSelectionMode, + m_labelShader, m_labelObj, m_cachedScene->activeCamera(), true, true, + Drawer::LabelMid, alignment); } - QVector3D labelTrans = QVector3D(labelPos * m_scaleX, - labelYTrans, - labelZTrans + zComp); - - // Draw the label here - m_dummyRenderItem.setTranslation(labelTrans); - const LabelItem &axisLabelItem = *m_axisCacheX.labelItems().at(segment); - - m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, - QVector3D(0.0f, 0.0f, zComp), - QVector3D(rotLabelX, rotLabelY, rotLabelZ), - 0, m_cachedSelectionMode, - m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid, - alignment); - + labelNbr++; labelPos += posStep; } } - // Y Labels - if (m_axisCacheY.segmentCount() > 0 && m_surfaceObj) { - GLfloat posStep = coordSpace / (m_axisCacheY.segmentCount()); - GLfloat labelPos = -1.0; + if (m_axisCacheY.segmentCount() > 0) { + GLfloat posStep = 2.0f * m_axisCacheY.segmentStep() / m_heightNormalizer; + GLfloat labelPos = -1.0f; + int labelNbr = 0; + GLfloat labelXTrans = m_scaleXWithBackground; + GLfloat labelZTrans = m_scaleZWithBackground; + + GLfloat labelMarginXTrans = labelMargin; + GLfloat labelMarginZTrans = labelMargin; + GLfloat rotLabelX = 0.0f; + GLfloat rotLabelY = -90.0f; + GLfloat rotLabelZ = 0.0f; + Qt::AlignmentFlag alignment = Qt::AlignLeft; + if (!m_xFlipped) { + labelXTrans = -labelXTrans; + labelMarginXTrans = -labelMargin; + rotLabelY = 90.0f; + } + if (m_zFlipped) { + labelZTrans = -labelZTrans; + labelMarginZTrans = -labelMargin; + alignment = Qt::AlignRight; + } + + // Back wall + QVector3D rotation(rotLabelX, rotLabelY, rotLabelZ); for (int segment = 0; segment <= m_axisCacheY.segmentCount(); segment++) { - GLfloat labelXTrans = backgroundMargin * m_scaleX; - GLfloat labelZTrans = backgroundMargin * m_scaleZ; - GLfloat labelMarginXTrans = labelMargin; - GLfloat labelMarginZTrans = labelMargin; - GLfloat rotLabelX = 0.0f; - GLfloat rotLabelY = -90.0f; - GLfloat rotLabelZ = 0.0f; - Qt::AlignmentFlag alignment = Qt::AlignLeft; - - if (!m_xFlipped) { - labelXTrans = -labelXTrans; - labelMarginXTrans = -labelMargin; - rotLabelY = 90.0f; - } - if (m_zFlipped) { - labelZTrans = -labelZTrans; - labelMarginZTrans = -labelMargin; - alignment = Qt::AlignRight; + if (m_axisCacheY.labelItems().size() > labelNbr) { + const LabelItem &axisLabelItem = *m_axisCacheY.labelItems().at(labelNbr); + + QVector3D labelTrans = QVector3D(labelXTrans, labelPos, + labelZTrans + labelMarginZTrans + zComp); + if (m_xFlipped) + rotation.setY(-90.0f); + else + rotation.setY(90.0f); + if (m_zFlipped) + alignment = Qt::AlignRight; + else + alignment = Qt::AlignLeft; + + // Draw the label here + m_dummyRenderItem.setTranslation(labelTrans); + m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, + positionZComp, rotation, 0, m_cachedSelectionMode, + m_labelShader, m_labelObj, m_cachedScene->activeCamera(), true, true, + Drawer::LabelMid, alignment); + + // Side wall + if (m_xFlipped) + alignment = Qt::AlignLeft; + else + alignment = Qt::AlignRight; + if (m_zFlipped) + rotation.setY(180.0f); + else + rotation.setY(0.0f); + + labelTrans = QVector3D(-labelXTrans - labelMarginXTrans, labelPos, + -labelZTrans + zComp); + + // Draw the label here + m_dummyRenderItem.setTranslation(labelTrans); + m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, + positionZComp, rotation, 0, m_cachedSelectionMode, + m_labelShader, m_labelObj, m_cachedScene->activeCamera(), true, true, + Drawer::LabelMid, alignment); } - - QVector3D labelTrans = QVector3D(labelXTrans, - labelPos, - labelZTrans + labelMarginZTrans + zComp); - - // Draw the label here - m_dummyRenderItem.setTranslation(labelTrans); - const LabelItem &axisLabelItem = *m_axisCacheY.labelItems().at(segment); - - m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, - QVector3D(0.0f, 0.0f, zComp), - QVector3D(rotLabelX, rotLabelY, rotLabelZ), - 0, m_cachedSelectionMode, - m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid, - alignment); - - // Side wall - if (m_xFlipped) - alignment = Qt::AlignLeft; - else - alignment = Qt::AlignRight; - if (m_zFlipped) - rotLabelY = 180.0f; - else - rotLabelY = 0.0f; - - labelTrans = QVector3D(-labelXTrans - labelMarginXTrans, - labelPos, - -labelZTrans + zComp); - - // Draw the label here - m_dummyRenderItem.setTranslation(labelTrans); - m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, - QVector3D(0.0f, 0.0f, zComp), - QVector3D(rotLabelX, rotLabelY, rotLabelZ), - 0, m_cachedSelectionMode, - m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid, - alignment); - + labelNbr++; labelPos += posStep; } } @@ -1080,9 +1231,21 @@ void Surface3DRenderer::updateTextures() void Surface3DRenderer::calculateSceneScalingFactors() { // Calculate scene scaling and translation factors - m_scaleFactor = qMax(m_sampleSpace.width(), m_sampleSpace.height()); - m_scaleX = (coordSpace * m_sampleSpace.width()) / m_scaleFactor; - m_scaleZ = (coordSpace * m_sampleSpace.height()) / m_scaleFactor; + m_heightNormalizer = GLfloat(m_axisCacheY.max() - m_axisCacheY.min()); + m_areaSize.setHeight(m_axisCacheZ.max() - m_axisCacheZ.min()); + m_areaSize.setWidth(m_axisCacheX.max() - m_axisCacheX.min()); + m_scaleFactor = qMax(m_areaSize.width(), m_areaSize.height()); +#ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z + m_scaleX = aspectRatio * m_areaSize.width() / m_scaleFactor; + m_scaleZ = aspectRatio * m_areaSize.height() / m_scaleFactor; + m_scaleXWithBackground = m_scaleX * backgroundMargin; + m_scaleZWithBackground = m_scaleZ * backgroundMargin; +#else // ..and this if we want uniform scaling based on largest dimension + m_scaleX = aspectRatio / m_scaleFactor; + m_scaleZ = aspectRatio / m_scaleFactor; + m_scaleXWithBackground = aspectRatio * backgroundMargin; + m_scaleZWithBackground = aspectRatio * backgroundMargin; +#endif } bool Surface3DRenderer::updateSmoothStatus(bool enable) diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h index 771ecce4..a513e98e 100644 --- a/src/datavisualization/engine/surface3drenderer_p.h +++ b/src/datavisualization/engine/surface3drenderer_p.h @@ -86,6 +86,8 @@ private: GLfloat m_scaleFactor; GLfloat m_scaleX; GLfloat m_scaleZ; + GLfloat m_scaleXWithBackground; + GLfloat m_scaleZWithBackground; ObjectHelper *m_backgroundObj; ObjectHelper *m_gridLineObj; ObjectHelper *m_labelObj; @@ -111,6 +113,7 @@ private: QSurfaceDataArray m_dataArray; QRect m_sampleSpace; GLint m_shadowQualityMultiplier; + QSizeF m_areaSize; bool m_hasHeightAdjustmentChanged; |