diff options
author | Tomi Korpipää <tomi.korpipaa@digia.com> | 2013-04-17 10:02:35 +0300 |
---|---|---|
committer | Tomi Korpipää <tomi.korpipaa@digia.com> | 2013-04-17 13:16:32 +0300 |
commit | 009d385085992d34a8a30ecb5500303a3b50af41 (patch) | |
tree | db29e00a593cf49b8a6b7248fdb6392de7d04207 /src/datavis3d | |
parent | 30bb9a571d9bccba1fb45f07277a014b91ac043c (diff) |
Added bar label drawing in zoom selection view
Change-Id: Iae58ef8395d7ad41df72e8698a2deca723e9b29c
Change-Id: Iae58ef8395d7ad41df72e8698a2deca723e9b29c
Reviewed-by: Mika Salmela <mika.salmela@digia.com>
Diffstat (limited to 'src/datavis3d')
-rw-r--r-- | src/datavis3d/engine/drawer.cpp | 21 | ||||
-rw-r--r-- | src/datavis3d/engine/drawer_p.h | 10 | ||||
-rw-r--r-- | src/datavis3d/engine/engine.pri | 6 | ||||
-rw-r--r-- | src/datavis3d/engine/labelitem.cpp | 76 | ||||
-rw-r--r-- | src/datavis3d/engine/labelitem_p.h | 79 | ||||
-rw-r--r-- | src/datavis3d/engine/q3dbars.cpp | 185 | ||||
-rw-r--r-- | src/datavis3d/engine/q3dbars.h | 21 | ||||
-rw-r--r-- | src/datavis3d/engine/q3dbars_p.h | 30 | ||||
-rw-r--r-- | src/datavis3d/engine/qdataset.cpp | 102 | ||||
-rw-r--r-- | src/datavis3d/engine/qdataset_p.h | 23 |
10 files changed, 433 insertions, 120 deletions
diff --git a/src/datavis3d/engine/drawer.cpp b/src/datavis3d/engine/drawer.cpp index c33dd625..4f5789ac 100644 --- a/src/datavis3d/engine/drawer.cpp +++ b/src/datavis3d/engine/drawer.cpp @@ -51,9 +51,9 @@ QTCOMMERCIALDATAVIS3D_BEGIN_NAMESPACE Drawer::Drawer(const Theme &theme, const QFont &font, Q3DBars::LabelTransparency transparency) : m_theme(theme), - m_font(font), - m_transparency(transparency), - m_textureHelper(new TextureHelper()) + m_font(font), + m_transparency(transparency), + m_textureHelper(new TextureHelper()) { initializeOpenGLFunctions(); } @@ -66,16 +66,19 @@ Drawer::~Drawer() void Drawer::setTheme(const Theme &theme) { m_theme = theme; + emit drawerChanged(); } void Drawer::setFont(const QFont &font) { m_font = font; + emit drawerChanged(); } void Drawer::setTransparency(Q3DBars::LabelTransparency transparency) { m_transparency = transparency; + emit drawerChanged(); } void Drawer::drawObject(ShaderHelper *shader, ObjectHelper *object, bool textured, @@ -133,7 +136,6 @@ void Drawer::generateLabelTexture(QDataItem *item) // (basically we could create textures for all bars when data is added, but we // may not need them -> better to do it here dynamically) glDeleteTextures(1, &labelTexture); - item->d_ptr->setTextureId(0); } // Create labels @@ -150,8 +152,13 @@ void Drawer::generateLabelTexture(QDataItem *item) item->d_ptr->setTextureId(m_textureHelper->create2DTexture(label, true, true)); } -GLuint Drawer::generateLabelTexture(const QString &text, QSize &labelSize) +void Drawer::generateLabelItem(LabelItem &item, const QString &text) { + // Delete previous texture, if there is one + GLuint labelTexture = item.textureId(); + if (labelTexture) + glDeleteTextures(1, &labelTexture); + // Create labels // Print label into a QImage using QPainter QImage label = Utils::printTextToImage(m_font, @@ -161,9 +168,9 @@ GLuint Drawer::generateLabelTexture(const QString &text, QSize &labelSize) m_transparency); // Set label size - labelSize = label.size(); + item.setSize(label.size()); // Insert text texture into label - return m_textureHelper->create2DTexture(label, true, true); + item.setTextureId(m_textureHelper->create2DTexture(label, true, true)); } QTCOMMERCIALDATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/engine/drawer_p.h b/src/datavis3d/engine/drawer_p.h index 60cf06c5..3464503d 100644 --- a/src/datavis3d/engine/drawer_p.h +++ b/src/datavis3d/engine/drawer_p.h @@ -55,6 +55,7 @@ #include "QtDataVis3D/qdatavis3dglobal.h" #include "q3dbars.h" #include "theme_p.h" +#include "labelitem_p.h" #include <QFont> QTCOMMERCIALDATAVIS3D_BEGIN_NAMESPACE @@ -64,8 +65,10 @@ class ShaderHelper; class ObjectHelper; class TextureHelper; -class Drawer : protected QOpenGLFunctions +class Drawer : public QObject, protected QOpenGLFunctions { + Q_OBJECT + public: explicit Drawer(const Theme &theme, const QFont &font, Q3DBars::LabelTransparency transparency); ~Drawer(); @@ -77,7 +80,10 @@ public: void drawObject(ShaderHelper *shader, ObjectHelper *object, bool textured = false, GLuint textureId = 0); void generateLabelTexture(QDataItem *item); - GLuint generateLabelTexture(const QString &text, QSize &labelSize); + void generateLabelItem(LabelItem &item, const QString &text); + +Q_SIGNALS: + void drawerChanged(); private: Theme m_theme; diff --git a/src/datavis3d/engine/engine.pri b/src/datavis3d/engine/engine.pri index e9d3fbb9..ab330803 100644 --- a/src/datavis3d/engine/engine.pri +++ b/src/datavis3d/engine/engine.pri @@ -4,7 +4,8 @@ SOURCES += $$PWD/q3dwindow.cpp \ $$PWD/qdatarow.cpp \ $$PWD/qdataset.cpp \ $$PWD/theme.cpp \ - $$PWD/drawer.cpp + $$PWD/drawer.cpp \ + $$PWD/labelitem.cpp HEADERS += $$PWD/q3dwindow_p.h \ $$PWD/q3dwindow.h \ @@ -17,6 +18,7 @@ HEADERS += $$PWD/q3dwindow_p.h \ $$PWD/qdataset.h \ $$PWD/qdataset_p.h \ $$PWD/theme_p.h \ - $$PWD/drawer_p.h + $$PWD/drawer_p.h \ + $$PWD/labelitem_p.h RESOURCES += engine/engine.qrc diff --git a/src/datavis3d/engine/labelitem.cpp b/src/datavis3d/engine/labelitem.cpp new file mode 100644 index 00000000..6ce0663c --- /dev/null +++ b/src/datavis3d/engine/labelitem.cpp @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtDataVis3D module. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "labelitem_p.h" + +QTCOMMERCIALDATAVIS3D_BEGIN_NAMESPACE + +LabelItem::LabelItem() + : m_size(QSize(0, 0)), + m_textureId(0) +{ +} + +LabelItem::~LabelItem() +{ +} + +void LabelItem::setSize(const QSize &size) +{ + m_size = size; +} + +QSize LabelItem::size() +{ + return m_size; +} + +void LabelItem::setTextureId(GLuint textureId) +{ + m_textureId = textureId; +} + +GLuint LabelItem::textureId() +{ + return m_textureId; +} + +QTCOMMERCIALDATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/engine/labelitem_p.h b/src/datavis3d/engine/labelitem_p.h new file mode 100644 index 00000000..49693631 --- /dev/null +++ b/src/datavis3d/engine/labelitem_p.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtDataVis3D module. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef LABELITEM_P_H +#define LABELITEM_P_H + +#include "qdatavis3dglobal.h" +#include <QOpenGLFunctions> +#include <QSize> + +QTCOMMERCIALDATAVIS3D_BEGIN_NAMESPACE + +class LabelItem +{ +public: + explicit LabelItem(); + ~LabelItem(); + + void setSize(const QSize &size); + QSize size(); + void setTextureId(GLuint textureId); + GLuint textureId(); + +private: + QSize m_size; + GLuint m_textureId; +}; + +QTCOMMERCIALDATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/engine/q3dbars.cpp b/src/datavis3d/engine/q3dbars.cpp index 218351f0..6f29268e 100644 --- a/src/datavis3d/engine/q3dbars.cpp +++ b/src/datavis3d/engine/q3dbars.cpp @@ -62,7 +62,7 @@ #include <QDebug> -#define DISPLAY_RENDER_SPEED +//#define DISPLAY_RENDER_SPEED #ifdef DISPLAY_RENDER_SPEED #include <QTime> @@ -73,7 +73,7 @@ QTCOMMERCIALDATAVIS3D_BEGIN_NAMESPACE #define USE_HAX0R_SELECTION // keep this defined until the "real" method works //#define USE_PAINTER_TEXT // Use QPainter labels or opengl labels -const float zComp = 10.0f; // Compensation for z position; move all objects to positive z, as shader can't handle negative values correctly +const GLfloat zComp = 10.0f; // Compensation for z position; move all objects to positive z, as shader can't handle negative values correctly const QVector3D defaultLightPos = QVector3D(0.0f, 3.0f, zComp); Q3DBars::Q3DBars() @@ -95,8 +95,8 @@ void Q3DBars::initialize() d_ptr->initShaders(QStringLiteral(":/shaders/vertex"), QStringLiteral(":/shaders/fragment")); } - // d_ptr->initBackgroundShaders(QStringLiteral(":/shaders/vertexTexture"), - // QStringLiteral(":/shaders/fragmentTexture")); + //d_ptr->initBackgroundShaders(QStringLiteral(":/shaders/vertexTexture"), + // QStringLiteral(":/shaders/fragmentTexture")); d_ptr->initBackgroundShaders(QStringLiteral(":/shaders/vertex"), QStringLiteral(":/shaders/fragment")); #ifndef USE_PAINTER_TEXT @@ -151,7 +151,7 @@ void Q3DBars::render() // For speed computation static bool firstRender = true; static QTime lastTime; - static int nbFrames = 0; + static GLint nbFrames = 0; if (firstRender) { lastTime.start(); firstRender = false; @@ -212,7 +212,7 @@ void Q3DBars::render(QPainter *painter) Utils::printText(painter, data->d_ptr->valueStr(), data->d_ptr->labelSize()); // use size for screen position; this way we don't need 2 member variables in qdataitem } else if (d_ptr->m_zoomActivated) { glDisable(GL_DEPTH_TEST); - float scale = 1.0f; + GLfloat scale = 1.0f; //painter->setWindow(d_ptr->m_zoomViewPort); // Using these causes unwanted transformations //painter->setViewport(d_ptr->m_zoomViewPort); // Using these causes unwanted transformations //painter->setViewTransformEnabled(false); // Using these causes unwanted transformations @@ -222,7 +222,7 @@ void Q3DBars::render(QPainter *painter) // we need to convert 3D coordinates to screen coordinates for printing // posX = (2 * X - W) / H -> coordX = (posX * H + W) / 2 // posY = 1 - (2 * Y) / H -> coordY = ((1 - posY) * H) / 2 - float coordX; + GLfloat coordX; if (ZoomColumn == d_ptr->m_selectionMode) { coordX = (-(item->d_ptr->translation().z() - zComp) // flip front to left * d_ptr->m_zoomViewPort.height() / 2.0f @@ -233,8 +233,8 @@ void Q3DBars::render(QPainter *painter) + d_ptr->m_zoomViewPort.width()) / 2.0f; } if (d_ptr->m_zoomViewPort.height() > d_ptr->m_zoomViewPort.width()) { - scale = (float)d_ptr->m_zoomViewPort.width() - / (float)d_ptr->m_zoomViewPort.height(); + scale = (GLfloat)d_ptr->m_zoomViewPort.width() + / (GLfloat)d_ptr->m_zoomViewPort.height(); } //float coordY = ((1.0f - item->d_ptr->translation().y()) // * d_ptr->m_zoomViewPort.height()) / 2.0f; @@ -265,10 +265,10 @@ void Q3DBars::drawZoomScene() if (!d_ptr->m_zoomActivated) return; - float barPosX = 0; - int startBar = 0; - int stopBar = d_ptr->m_zoomSelection->d_ptr->row().size(); - int stepBar = 1; + GLfloat barPosX = 0; + GLint startBar = 0; + GLint stopBar = d_ptr->m_zoomSelection->d_ptr->row().size(); + GLint stepBar = 1; QVector3D lightPos; // Specify viewport @@ -277,8 +277,8 @@ void Q3DBars::drawZoomScene() // Set up projection matrix QMatrix4x4 projectionMatrix; - projectionMatrix.perspective(45.0f, (float)d_ptr->m_zoomViewPort.width() - / (float)d_ptr->m_zoomViewPort.height(), 0.1f, 100.0f); + projectionMatrix.perspective(45.0f, (GLfloat)d_ptr->m_zoomViewPort.width() + / (GLfloat)d_ptr->m_zoomViewPort.height(), 0.1f, 100.0f); #ifdef ROTATE_ZOOM_SELECTION // Calculate view matrix @@ -306,7 +306,7 @@ void Q3DBars::drawZoomScene() viewMatrix.lookAt(QVector3D(0.0f, 0.0f, d_ptr->m_scaleFactorX + zComp), QVector3D(0.0f, 0.0f, zComp), QVector3D(0.0f, 1.0f, 0.0f)); - float zoomwidth; + GLfloat zoomwidth; if (ZoomRow == d_ptr->m_selectionMode) { zoomwidth = d_ptr->m_zoomSelection->d_ptr->getItem(0)->d_ptr->translation().x() - d_ptr->m_zoomSelection->d_ptr->getItem(d_ptr->m_zoomSelection->d_ptr->row().size() @@ -322,8 +322,8 @@ void Q3DBars::drawZoomScene() viewMatrix.scale(0.5f / zoomwidth); #endif if (d_ptr->m_zoomViewPort.height() > d_ptr->m_zoomViewPort.width()) { - viewMatrix.scale((float)d_ptr->m_zoomViewPort.width() - / (float)d_ptr->m_zoomViewPort.height()); + viewMatrix.scale((GLfloat)d_ptr->m_zoomViewPort.width() + / (GLfloat)d_ptr->m_zoomViewPort.height()); // TODO: Center shrunk view } @@ -344,7 +344,7 @@ void Q3DBars::drawZoomScene() QDataItem *item = d_ptr->m_zoomSelection->d_ptr->getItem(bar); if (!item) continue; - float barHeight = item->d_ptr->value() / d_ptr->m_heightNormalizer; + GLfloat barHeight = item->d_ptr->value() / d_ptr->m_heightNormalizer; QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; if (ZoomRow == d_ptr->m_selectionMode) @@ -363,7 +363,7 @@ void Q3DBars::drawZoomScene() QVector3D barColor = baseColor + heightColor; - float lightStrength = d_ptr->m_theme->m_lightStrength; + GLfloat lightStrength = d_ptr->m_theme->m_lightStrength; #if 0 // TODO: Implement selection in zoom if (d_ptr->m_selectionMode > None) { Q3DBarsPrivate::SelectionType selectionType = d_ptr->isSelected(row, bar, selection); @@ -450,22 +450,40 @@ void Q3DBars::drawZoomScene() glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } + // Draw labels for axes + // TODO: label of selected row/column above the bars + // TODO: label of selected column/row below the bar labels + + // Draw labels for bars for (int col = 0; col < d_ptr->m_zoomSelection->d_ptr->row().size(); col++) { QDataItem *item = d_ptr->m_zoomSelection->d_ptr->getItem(col); // Draw values - drawLabel(*item, item->d_ptr->textureId(), viewMatrix, projectionMatrix, false, 0.0f, + drawLabel(*item, item->d_ptr->textureId(), item->d_ptr->labelSize(), viewMatrix, + projectionMatrix, false, 0.0f, LabelOver); - // Draw labels // TODO: Generate label textures + // Draw labels + LabelItem labelItem; if (ZoomRow == d_ptr->m_selectionMode) { - drawLabel(*item, item->d_ptr->textureId(), viewMatrix, projectionMatrix, false, -45.0f, - LabelBelow); - // drawLabel(*item, d_ptr->m_dataSet->d_ptr->rowLabels().at(col), viewMatrix, - // projectionMatrix, false, -45.0f, LabelBelow); + // TODO: Testi, piirrä axislabel kokeeksi +// LabelItem x, z, y; +// d_ptr->m_dataSet->d_ptr->axisLabelItems(&x, &z, &y); +// drawLabel(*item, x.textureId(), x.size(), +// viewMatrix, projectionMatrix, false, -45.0f, LabelBelow); + if (d_ptr->m_dataSet->d_ptr->columnLabelItems().size() > col) + labelItem = d_ptr->m_dataSet->d_ptr->columnLabelItems().at(col); } else { - drawLabel(*item, item->d_ptr->textureId(), viewMatrix, projectionMatrix, false, -45.0f, - LabelBelow); - // drawLabel(*item, d_ptr->m_dataSet->d_ptr->columnLabels().at(col), viewMatrix, - // projectionMatrix, false, -45.0f, LabelBelow); + // TODO: Testi, piirrä axislabel kokeeksi +// LabelItem x, z, y; +// d_ptr->m_dataSet->d_ptr->axisLabelItems(&x, &z, &y); +// drawLabel(*item, z.textureId(), z.size(), +// viewMatrix, projectionMatrix, false, -45.0f, LabelBelow); + if (d_ptr->m_dataSet->d_ptr->rowLabelItems().size() > col) + labelItem = d_ptr->m_dataSet->d_ptr->rowLabelItems().at(col); + } + // Check if there is a label before drawing + if (labelItem.textureId() > 0) { + drawLabel(*item, labelItem.textureId(), labelItem.size(), + viewMatrix, projectionMatrix, false, -45.0f, LabelBelow); } } @@ -481,18 +499,18 @@ void Q3DBars::drawZoomScene() void Q3DBars::drawScene() { - int startBar = 0; - int stopBar = 0; - int stepBar = 0; + GLint startBar = 0; + GLint stopBar = 0; + GLint stepBar = 0; - int startRow = 0; - int stopRow = 0; - int stepRow = 0; + GLint startRow = 0; + GLint stopRow = 0; + GLint stepRow = 0; - float backgroundRotation = 0; + GLfloat backgroundRotation = 0; - float barPos = 0; - float rowPos = 0; + GLfloat barPos = 0; + GLfloat rowPos = 0; static QVector3D selection = QVector3D(0, 0, 0); @@ -502,8 +520,8 @@ void Q3DBars::drawScene() // Set up projection matrix QMatrix4x4 projectionMatrix; - projectionMatrix.perspective(45.0f, (float)d_ptr->m_sceneViewPort.width() - / (float)d_ptr->m_sceneViewPort.height(), 0.1f, 100.0f); + projectionMatrix.perspective(45.0f, (GLfloat)d_ptr->m_sceneViewPort.width() + / (GLfloat)d_ptr->m_sceneViewPort.height(), 0.1f, 100.0f); // Calculate view matrix QMatrix4x4 viewMatrix = CameraHelper::calculateViewMatrix(d_ptr->m_mousePos, @@ -511,8 +529,8 @@ void Q3DBars::drawScene() d_ptr->m_sceneViewPort.width(), d_ptr->m_sceneViewPort.height()); if (d_ptr->m_sceneViewPort.height() > d_ptr->m_sceneViewPort.width()) { - viewMatrix.scale((float)d_ptr->m_sceneViewPort.width() - / (float)d_ptr->m_sceneViewPort.height()); + viewMatrix.scale((GLfloat)d_ptr->m_sceneViewPort.width() + / (GLfloat)d_ptr->m_sceneViewPort.height()); // TODO: Center shrunk view } @@ -566,7 +584,7 @@ void Q3DBars::drawScene() QDataItem *item = d_ptr->m_dataSet->d_ptr->getRow(row)->d_ptr->getItem(bar); if (!item) continue; - float barHeight = item->d_ptr->value() / d_ptr->m_heightNormalizer; + GLfloat barHeight = item->d_ptr->value() / d_ptr->m_heightNormalizer; QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; barPos = (bar + 1) * (d_ptr->m_barSpacing.x()); @@ -580,10 +598,10 @@ void Q3DBars::drawScene() MVPMatrix = projectionMatrix * viewMatrix * modelMatrix; // add +2 to avoid black - QVector3D barColor = QVector3D((float)(row + 2) - / (float)(d_ptr->m_sampleCount.y() + 2), - (float)(bar + 2) - / (float)(d_ptr->m_sampleCount.x() + 2), + QVector3D barColor = QVector3D((GLfloat)(row + 2) + / (GLfloat)(d_ptr->m_sampleCount.y() + 2), + (GLfloat)(bar + 2) + / (GLfloat)(d_ptr->m_sampleCount.x() + 2), 0.0f); d_ptr->m_selectionShader->setUniformValue(d_ptr->m_selectionShader->MVP(), @@ -721,7 +739,7 @@ void Q3DBars::drawScene() QDataItem *item = d_ptr->m_dataSet->d_ptr->getRow(row)->d_ptr->getItem(bar); if (!item) continue; - float barHeight = item->d_ptr->value() / d_ptr->m_heightNormalizer; + GLfloat barHeight = item->d_ptr->value() / d_ptr->m_heightNormalizer; if (barHeight == 0) continue; QMatrix4x4 modelMatrix; @@ -740,11 +758,11 @@ void Q3DBars::drawScene() QVector3D heightColor = Utils::vectorFromColor(d_ptr->m_theme->m_heightColor) * barHeight; QVector3D depthColor = Utils::vectorFromColor(d_ptr->m_theme->m_depthColor) - * (float(row) / float(d_ptr->m_sampleCount.y())); + * (float(row) / GLfloat(d_ptr->m_sampleCount.y())); QVector3D barColor = baseColor + heightColor + depthColor; - float lightStrength = d_ptr->m_theme->m_lightStrength; + GLfloat lightStrength = d_ptr->m_theme->m_lightStrength; if (d_ptr->m_selectionMode > None) { Q3DBarsPrivate::SelectionType selectionType = d_ptr->isSelected(row, bar, selection); @@ -857,7 +875,8 @@ void Q3DBars::drawScene() prevItem = d_ptr->m_selectedBar; } - drawLabel(*d_ptr->m_selectedBar, d_ptr->m_selectedBar->d_ptr->textureId(), viewMatrix, + drawLabel(*d_ptr->m_selectedBar, d_ptr->m_selectedBar->d_ptr->textureId(), + d_ptr->m_selectedBar->d_ptr->labelSize(), viewMatrix, projectionMatrix, true); glDisable(GL_TEXTURE_2D); @@ -874,9 +893,9 @@ void Q3DBars::drawScene() d_ptr->m_barShader->release(); } -void Q3DBars::drawLabel(const QDataItem &item, GLuint textureId, const QMatrix4x4 &viewmatrix, - const QMatrix4x4 &projectionmatrix, bool useDepth, qreal rotation, - Q3DBars::LabelPosition position) +void Q3DBars::drawLabel(const QDataItem &item, GLuint textureId, QSize textureSize, + const QMatrix4x4 &viewmatrix, const QMatrix4x4 &projectionmatrix, + bool useDepth, qreal rotation, Q3DBars::LabelPosition position) { // Draw label QMatrix4x4 modelMatrix; @@ -886,6 +905,8 @@ void Q3DBars::drawLabel(const QDataItem &item, GLuint textureId, const QMatrix4x case Q3DBars::LabelBelow: { yPosition = -1.5f; + if (!useDepth) + yPosition -= 0.25f; break; } case Q3DBars::LabelLow: @@ -933,11 +954,11 @@ void Q3DBars::drawLabel(const QDataItem &item, GLuint textureId, const QMatrix4x } // Calculate scale factor to get uniform font size - float scaledFontSize = 0.05f + d_ptr->m_fontSize / 500.0f; - float scaleFactor = scaledFontSize / (float)item.d_ptr->labelSize().height(); + GLfloat scaledFontSize = 0.05f + d_ptr->m_fontSize / 500.0f; + GLfloat scaleFactor = scaledFontSize / (GLfloat)textureSize.height(); // Scale label based on text size - modelMatrix.scale(QVector3D((float)item.d_ptr->labelSize().width() * scaleFactor + modelMatrix.scale(QVector3D((GLfloat)textureSize.width() * scaleFactor , scaledFontSize , 0.0f)); @@ -953,7 +974,7 @@ void Q3DBars::drawLabel(const QDataItem &item, GLuint textureId, const QMatrix4x void Q3DBars::mousePressEvent(QMouseEvent *event) { // TODO: for testing shaders - //static int shaderNo = 1; + //static GLint shaderNo = 1; //qDebug() << "mouse button pressed" << event->button(); if (Qt::LeftButton == event->button()) { if (d_ptr->m_zoomActivated) { @@ -1025,7 +1046,7 @@ void Q3DBars::mouseMoveEvent(QMouseEvent *event) //qDebug() << "mouse position in scene" << mouse3D; // TODO: Testi laske focal point - float focalPoint = tan(45.0f / 2.0f); + GLfloat focalPoint = tan(45.0f / 2.0f); // TODO: Testi - laske viewmatriisin kerroin QVector3D worldRay = QVector3D(0.0f, 0.0f, 0.0f) @@ -1112,7 +1133,6 @@ void Q3DBars::setupSampleSpace(QPoint sampleCount, const QString &labelRow, { d_ptr->m_sampleCount = sampleCount; d_ptr->m_dataSet->setLabels(labelRow, labelColumn, labelHeight); - // TODO: Generate axis textures and replace qstrings with texture ids in qdataset // TODO: Invent "idiotproof" max scene size formula.. // This seems to work ok if spacing is not negative d_ptr->m_maxSceneSize = 2 * qSqrt(sampleCount.x() * sampleCount.y()); @@ -1129,7 +1149,7 @@ void Q3DBars::setCameraPreset(CameraPreset preset) CameraHelper::setCameraPreset(preset); } -void Q3DBars::setCameraPosition(float horizontal, float vertical, int distance) +void Q3DBars::setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance) { d_ptr->m_horizontalRotation = qBound(-180.0f, horizontal, 180.0f); d_ptr->m_verticalRotation = qBound(0.0f, vertical, 90.0f); @@ -1248,8 +1268,16 @@ void Q3DBars::addDataRow(QDataRow *dataRow) void Q3DBars::addDataSet(const QVector< QVector<float> > &data, const QVector<QString> &labelsRow, const QVector<QString> &labelsColumn) { + // Copy axis labels + QString xAxis; + QString zAxis; + QString yAxis; + d_ptr->m_dataSet->d_ptr->axisLabels(&xAxis, &zAxis, &yAxis); + // Delete old data set delete d_ptr->m_dataSet; d_ptr->m_dataSet = new QDataSet(); + // Give drawer to data set + d_ptr->m_dataSet->d_ptr->setDrawer(d_ptr->m_drawer); // Convert to QDataRow and add to QDataSet QDataRow *row; for (int rowNr = 0; rowNr < data.size(); rowNr++) { @@ -1264,9 +1292,7 @@ void Q3DBars::addDataSet(const QVector< QVector<float> > &data, const QVector<QS row++; } d_ptr->m_heightNormalizer = d_ptr->m_dataSet->d_ptr->highestValue(); - // Empty QStrings won't override already set axis labels - d_ptr->m_dataSet->setLabels(QString(), QString(), QString(), labelsRow, labelsColumn); - // TODO: generate label textures and replace qstring vectors with texture id (GLuint) vectors + d_ptr->m_dataSet->setLabels(xAxis, zAxis, yAxis, labelsRow, labelsColumn); d_ptr->m_dataSet->d_ptr->verifySize(d_ptr->m_sampleCount.y()); } @@ -1274,8 +1300,16 @@ void Q3DBars::addDataSet(const QVector< QVector<QDataItem*> > &data, const QVector<QString> &labelsRow, const QVector<QString> &labelsColumn) { + // Copy axis labels + QString xAxis; + QString zAxis; + QString yAxis; + d_ptr->m_dataSet->d_ptr->axisLabels(&xAxis, &zAxis, &yAxis); + // Delete old data set delete d_ptr->m_dataSet; d_ptr->m_dataSet = new QDataSet(); + // Give drawer to data set + d_ptr->m_dataSet->d_ptr->setDrawer(d_ptr->m_drawer); // Convert to QDataRow and add to QDataSet QDataRow *row; for (int rowNr = 0; rowNr < data.size(); rowNr++) { @@ -1290,9 +1324,7 @@ void Q3DBars::addDataSet(const QVector< QVector<QDataItem*> > &data, row++; } d_ptr->m_heightNormalizer = d_ptr->m_dataSet->d_ptr->highestValue(); - // Empty QStrings won't override already set axis labels - d_ptr->m_dataSet->setLabels(QString(), QString(), QString(), labelsRow, labelsColumn); - // TODO: generate label textures and replace qstring vectors with texture id (GLuint) vectors + d_ptr->m_dataSet->setLabels(xAxis, zAxis, yAxis, labelsRow, labelsColumn); d_ptr->m_dataSet->d_ptr->verifySize(d_ptr->m_sampleCount.y()); } @@ -1305,7 +1337,8 @@ void Q3DBars::addDataSet(QDataSet* dataSet) d_ptr->m_dataSet = dataSet; // Find highest value d_ptr->m_heightNormalizer = d_ptr->m_dataSet->d_ptr->highestValue(); - // TODO: generate label textures and replace qstring vectors with texture id (GLuint) vectors + // Give drawer to data set + d_ptr->m_dataSet->d_ptr->setDrawer(d_ptr->m_drawer); } Q3DBarsPrivate::Q3DBarsPrivate(Q3DBars *q) @@ -1355,6 +1388,7 @@ Q3DBarsPrivate::Q3DBarsPrivate(Q3DBars *q) m_font(QFont(QStringLiteral("Arial"))), m_drawer(new Drawer(*m_theme, m_font, m_labelTransparency)) { + m_dataSet->d_ptr->setDrawer(m_drawer); } Q3DBarsPrivate::~Q3DBarsPrivate() @@ -1484,7 +1518,7 @@ void Q3DBarsPrivate::calculateSceneScalingFactors() m_scaleX = m_barThickness.x() / m_sampleCount.x() * (m_maxSceneSize / m_maxDimension); m_scaleZ = m_barThickness.y() / m_sampleCount.x() * (m_maxSceneSize / m_maxDimension); m_sceneScale = qMin(m_scaleX, m_scaleZ); - float minThickness = qMin(m_barThickness.x(), m_barThickness.y()); + GLfloat minThickness = qMin(m_barThickness.x(), m_barThickness.y()); m_sceneScale = m_sceneScale / minThickness; m_scaleFactorX = m_sampleCount.x() * (m_maxDimension / m_maxSceneSize); m_scaleFactorZ = m_sampleCount.x() * (m_maxDimension / m_maxSceneSize); @@ -1494,15 +1528,16 @@ void Q3DBarsPrivate::calculateSceneScalingFactors() //qDebug() << m_rowWidth * m_sceneScale << m_columnDepth * m_sceneScale; } -Q3DBarsPrivate::SelectionType Q3DBarsPrivate::isSelected(int row, int bar, const QVector3D &selection) +Q3DBarsPrivate::SelectionType Q3DBarsPrivate::isSelected(GLint row, GLint bar, + const QVector3D &selection) { SelectionType isSelectedType = None; if (selection == Utils::vectorFromColor(m_theme->m_windowColor)) return isSelectedType; // skip window - QVector3D current = QVector3D((GLubyte)(((float)(row + 2) / (float)(m_sampleCount.y() + 2)) - * 255.0), - (GLubyte)(((float)(bar + 2) / (float)(m_sampleCount.x() + 2)) - * 255.0), + QVector3D current = QVector3D((GLubyte)(((GLfloat)(row + 2) / (GLfloat)(m_sampleCount.y() + 2)) + * 255.0 + 0.49f), // +0.49 to fix rounding (there are conversions from unsigned short to GLfloat and back) + (GLubyte)(((GLfloat)(bar + 2) / (GLfloat)(m_sampleCount.x() + 2)) + * 255.0 + 0.49f), // +0.49 to fix rounding (there are conversions from unsigned short to GLfloat and back) 0); if (current == selection) isSelectedType = Bar; diff --git a/src/datavis3d/engine/q3dbars.h b/src/datavis3d/engine/q3dbars.h index 0251a306..314e6a03 100644 --- a/src/datavis3d/engine/q3dbars.h +++ b/src/datavis3d/engine/q3dbars.h @@ -132,11 +132,9 @@ public: // Add a row of data. Each new row is added to the front of the sample space, moving previous // rows back (if sample space is more than one row deep) - // TODO: Replace QVector<..> with a data row class (QDataRow)? Move labels to class. - void addDataRow(const QVector<float> &dataRow, + void addDataRow(const QVector<GLfloat> &dataRow, const QString &labelRow = QString(), const QVector<QString> &labelsColumn = QVector<QString>()); - // TODO: Replace QVector<..> with a data row class (QDataRow)? Move labels to class. // ownership of dataItems is transferred void addDataRow(const QVector<QDataItem*> &dataRow, const QString &labelRow = QString(), @@ -145,12 +143,10 @@ public: void addDataRow(QDataRow *dataRow); // Add complete data set at a time, as a vector of data rows - // TODO: Replace QVector<QVector<..>> with a data set class (QDataSet)? Move labels to class. - void addDataSet(const QVector< QVector<float> > &data, + void addDataSet(const QVector< QVector<GLfloat> > &data, const QVector<QString> &labelsRow = QVector<QString>(), const QVector<QString> &labelsColumn = QVector<QString>()); - // TODO: Replace QVector<QVector<..>> with a data set class (QDataSet)? Move labels to class. // ownership of dataItems is transferred void addDataSet(const QVector< QVector<QDataItem*> > &data, const QVector<QString> &labelsRow = QVector<QString>(), @@ -181,7 +177,7 @@ public: // Set camera rotation if you don't want to use the presets (in horizontal (-180...180) and // vertical (0...90) angles and distance in percentage (10...500)) - void setCameraPosition(float horizontal, float vertical, int distance = 100); + void setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance = 100); // Set theme (bar colors, shaders, window color, background colors, light intensity and text colors are affected) void setTheme(ColorTheme theme); @@ -196,8 +192,8 @@ public: // Set window title void setWindowTitle(const QString &title); - // Font size adjustment (should it be in enum (smallest, smaller, small, normal, large, larger, largest), or just float? - void setFontSize(float fontsize); + // Font size adjustment (should it be in enum (smallest, smaller, small, normal, large, larger, largest), or just GLfloat? + void setFontSize(GLfloat fontsize); // Set font void setFont(const QFont &font); @@ -215,9 +211,10 @@ protected: private: void drawZoomScene(); void drawScene(); - void drawLabel(const QDataItem &item, GLuint textureId, const QMatrix4x4 &viewmatrix, - const QMatrix4x4 &projectionmatrix, bool useDepth = false, - qreal rotation = 0.0f, Q3DBars::LabelPosition position = Q3DBars::LabelOver); + void drawLabel(const QDataItem &item, GLuint textureId, QSize textureSize, + const QMatrix4x4 &viewmatrix, const QMatrix4x4 &projectionmatrix, + bool useDepth = false, qreal rotation = 0.0f, + Q3DBars::LabelPosition position = Q3DBars::LabelOver); QScopedPointer<Q3DBarsPrivate> d_ptr; Q_DISABLE_COPY(Q3DBars) }; diff --git a/src/datavis3d/engine/q3dbars_p.h b/src/datavis3d/engine/q3dbars_p.h index 675c553f..cb13aea1 100644 --- a/src/datavis3d/engine/q3dbars_p.h +++ b/src/datavis3d/engine/q3dbars_p.h @@ -103,7 +103,7 @@ public: void initLabelShaders(const QString &vertexShader, const QString &fragmentShader); void initSelectionBuffer(); void calculateSceneScalingFactors(); - SelectionType isSelected(int row, int bar, const QVector3D &selection); + SelectionType isSelected(GLint row, GLint bar, const QVector3D &selection); GLuint m_framebufferSelection; @@ -121,21 +121,21 @@ public: QString m_objFile; MousePressType m_mousePressed; QPoint m_mousePos; - int m_zoomLevel; - float m_horizontalRotation; - float m_verticalRotation; + GLint m_zoomLevel; + GLfloat m_horizontalRotation; + GLfloat m_verticalRotation; QPointF m_barThickness; QPointF m_barSpacing; - float m_heightNormalizer; - float m_rowWidth; - float m_columnDepth; - float m_maxDimension; - float m_scaleX; - float m_scaleZ; - float m_scaleFactorX; - float m_scaleFactorZ; - float m_sceneScale; - float m_maxSceneSize; + GLfloat m_heightNormalizer; + GLfloat m_rowWidth; + GLfloat m_columnDepth; + GLfloat m_maxDimension; + GLfloat m_scaleX; + GLfloat m_scaleZ; + GLfloat m_scaleFactorX; + GLfloat m_scaleFactorZ; + GLfloat m_sceneScale; + GLfloat m_maxSceneSize; Theme *m_theme; bool m_isInitialized; Q3DBars::SelectionMode m_selectionMode; @@ -150,7 +150,7 @@ public: bool m_zoomActivated; TextureHelper *m_textureHelper; Q3DBars::LabelTransparency m_labelTransparency; - float m_fontSize; + GLfloat m_fontSize; QFont m_font; Drawer *m_drawer; }; diff --git a/src/datavis3d/engine/qdataset.cpp b/src/datavis3d/engine/qdataset.cpp index 08e129ff..f32507b6 100644 --- a/src/datavis3d/engine/qdataset.cpp +++ b/src/datavis3d/engine/qdataset.cpp @@ -47,6 +47,8 @@ #include <QPoint> #include <QString> +//#include <QDebug> + QTCOMMERCIALDATAVIS3D_BEGIN_NAMESPACE QDataSet::QDataSet() @@ -68,14 +70,39 @@ void QDataSet::setLabels(const QString &xAxis, { QString empty; // skip empty labels, keep the previous ones - if (xAxis != empty) + if (xAxis != empty && d_ptr->m_xAxis != xAxis) { d_ptr->m_xAxis = xAxis; - if (zAxis != empty) + // Generate axis label texture + if (d_ptr->m_drawer) + d_ptr->m_drawer->generateLabelItem(d_ptr->m_xAxisItem, xAxis); + } + if (zAxis != empty && d_ptr->m_zAxis != zAxis) { d_ptr->m_zAxis = zAxis; - if (yAxis != empty) + // Generate axis label texture + if (d_ptr->m_drawer) + d_ptr->m_drawer->generateLabelItem(d_ptr->m_zAxisItem, xAxis); + } + if (yAxis != empty && d_ptr->m_yAxis != yAxis) { d_ptr->m_yAxis = yAxis; + // Generate axis label texture + if (d_ptr->m_drawer) + d_ptr->m_drawer->generateLabelItem(d_ptr->m_yAxisItem, xAxis); + } d_ptr->m_labelsRow = labelsRow; d_ptr->m_labelsColumn = labelsColumn; + // Generate row and column label textures + if (d_ptr->m_drawer) { + for (int itemCount = 0; itemCount < labelsColumn.size(); itemCount++) { + d_ptr->m_labelItemsColumn.append(LabelItem()); + d_ptr->m_drawer->generateLabelItem(d_ptr->m_labelItemsColumn[itemCount], + labelsColumn.at(itemCount)); + } + for (int itemCount = 0; itemCount < labelsRow.size(); itemCount++) { + d_ptr->m_labelItemsRow.append(LabelItem()); + d_ptr->m_drawer->generateLabelItem(d_ptr->m_labelItemsRow[itemCount], + labelsRow.at(itemCount)); + } + } } void QDataSet::addRow(QDataRow *row) @@ -90,7 +117,13 @@ QDataSetPrivate::QDataSetPrivate(QDataSet *q) m_zAxis(QString()), m_yAxis(QString()), m_labelsRow(QVector<QString>()), - m_labelsColumn(QVector<QString>()) + m_labelsColumn(QVector<QString>()), + m_xAxisItem(LabelItem()), + m_zAxisItem(LabelItem()), + m_yAxisItem(LabelItem()), + m_labelItemsRow(QVector<LabelItem>()), + m_labelItemsColumn(QVector<LabelItem>()), + m_drawer(0) { } @@ -99,6 +132,36 @@ QDataSetPrivate::~QDataSetPrivate() for (int itemCount = 0; itemCount < m_set.size(); itemCount++) delete m_set.at(itemCount); m_set.clear(); + // Delete axis textures + GLuint textureid = m_xAxisItem.textureId(); + if (textureid) + glDeleteTextures(1, &textureid); + textureid = m_zAxisItem.textureId(); + if (textureid) + glDeleteTextures(1, &textureid); + textureid = m_yAxisItem.textureId(); + if (textureid) + glDeleteTextures(1, &textureid); + // Delete row and column textures + for (int itemCount = 0; itemCount < m_labelItemsColumn.size(); itemCount++) { + LabelItem item = m_labelItemsColumn.at(itemCount); + textureid = item.textureId(); + if (textureid) + glDeleteTextures(1, &textureid); + } + for (int itemCount = 0; itemCount < m_labelItemsRow.size(); itemCount++) { + LabelItem item = m_labelItemsRow.at(itemCount); + textureid = item.textureId(); + if (textureid) + glDeleteTextures(1, &textureid); + } +} + +void QDataSetPrivate::setDrawer(Drawer *drawer) +{ + m_drawer = drawer; + connect(m_drawer, SIGNAL(drawerChanged()), this, SLOT(updateTextures())); + updateTextures(); } QVector<QDataRow*> QDataSetPrivate::set() @@ -124,6 +187,16 @@ QVector<QString> QDataSetPrivate::columnLabels() return m_labelsColumn; } +QVector<LabelItem> QDataSetPrivate::rowLabelItems() +{ + return m_labelItemsRow; +} + +QVector<LabelItem> QDataSetPrivate::columnLabelItems() +{ + return m_labelItemsColumn; +} + void QDataSetPrivate::axisLabels(QString *xAxis, QString *zAxis, QString *yAxis) { *xAxis = m_xAxis; @@ -131,6 +204,14 @@ void QDataSetPrivate::axisLabels(QString *xAxis, QString *zAxis, QString *yAxis) *yAxis = m_yAxis; } +void QDataSetPrivate::axisLabelItems(LabelItem *xAxisItem, LabelItem *zAxisItem, + LabelItem *yAxisItem) +{ + *xAxisItem = m_xAxisItem; + *zAxisItem = m_zAxisItem; + *yAxisItem = m_yAxisItem; +} + void QDataSetPrivate::verifySize(int colSize, int rowSize) { // First verify columns @@ -164,4 +245,17 @@ float QDataSetPrivate::highestValue() return max; } +void QDataSetPrivate::updateTextures() +{ + m_drawer->generateLabelItem(m_xAxisItem, m_xAxis); + m_drawer->generateLabelItem(m_zAxisItem, m_zAxis); + m_drawer->generateLabelItem(m_yAxisItem, m_yAxis); + for (int itemCount = 0; itemCount < m_labelsColumn.size(); itemCount++) { + m_drawer->generateLabelItem(m_labelItemsColumn[itemCount], m_labelsColumn.at(itemCount)); + } + for (int itemCount = 0; itemCount < m_labelsRow.size(); itemCount++) { + m_drawer->generateLabelItem(m_labelItemsRow[itemCount], m_labelsRow.at(itemCount)); + } +} + QTCOMMERCIALDATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/engine/qdataset_p.h b/src/datavis3d/engine/qdataset_p.h index 873b292f..2e7a5bdb 100644 --- a/src/datavis3d/engine/qdataset_p.h +++ b/src/datavis3d/engine/qdataset_p.h @@ -54,26 +54,37 @@ #include "qdatavis3dglobal.h" #include "qdataset.h" +#include "drawer_p.h" +#include "labelitem_p.h" #include <QVector> #include <QString> QTCOMMERCIALDATAVIS3D_BEGIN_NAMESPACE -class QDataSetPrivate +class QDataSetPrivate : public QObject { - public: + Q_OBJECT + +public: explicit QDataSetPrivate(QDataSet *q); ~QDataSetPrivate(); + void setDrawer(Drawer *drawer); QVector<QDataRow*> set(); QDataRow *getRow(int rowIndex); QVector<QString> rowLabels(); QVector<QString> columnLabels(); + QVector<LabelItem> rowLabelItems(); + QVector<LabelItem> columnLabelItems(); void axisLabels(QString *xAxis, QString *zAxis, QString *yAxis); + void axisLabelItems(LabelItem *xAxisItem, LabelItem *zAxisItem, LabelItem *yAxisItem); void verifySize(int colSize, int rowSize = 0); // If rowSize is 0, don't verify rows float highestValue(); - private: +public Q_SLOTS: + void updateTextures(); + +private: QDataSet *q_ptr; QVector<QDataRow*> m_set; QString m_xAxis; @@ -81,6 +92,12 @@ class QDataSetPrivate QString m_yAxis; QVector<QString> m_labelsRow; QVector<QString> m_labelsColumn; + LabelItem m_xAxisItem; + LabelItem m_zAxisItem; + LabelItem m_yAxisItem; + QVector<LabelItem> m_labelItemsRow; + QVector<LabelItem> m_labelItemsColumn; + Drawer *m_drawer; friend class QDataSet; }; |