diff options
Diffstat (limited to 'src/datavisualization/utils')
-rw-r--r-- | src/datavisualization/utils/abstractobjecthelper_p.h | 1 | ||||
-rw-r--r-- | src/datavisualization/utils/camerahelper_p.h | 2 | ||||
-rw-r--r-- | src/datavisualization/utils/objecthelper.cpp | 107 | ||||
-rw-r--r-- | src/datavisualization/utils/objecthelper_p.h | 24 | ||||
-rw-r--r-- | src/datavisualization/utils/scatterobjectbufferhelper.cpp | 226 | ||||
-rw-r--r-- | src/datavisualization/utils/scatterobjectbufferhelper_p.h | 50 | ||||
-rw-r--r-- | src/datavisualization/utils/scatterpointbufferhelper.cpp | 113 | ||||
-rw-r--r-- | src/datavisualization/utils/scatterpointbufferhelper_p.h | 61 | ||||
-rw-r--r-- | src/datavisualization/utils/shaderhelper_p.h | 1 | ||||
-rw-r--r-- | src/datavisualization/utils/surfaceobject.cpp | 211 | ||||
-rw-r--r-- | src/datavisualization/utils/surfaceobject_p.h | 32 | ||||
-rw-r--r-- | src/datavisualization/utils/texturehelper.cpp | 18 | ||||
-rw-r--r-- | src/datavisualization/utils/texturehelper_p.h | 3 | ||||
-rw-r--r-- | src/datavisualization/utils/utils.cpp | 46 | ||||
-rw-r--r-- | src/datavisualization/utils/utils.pri | 8 | ||||
-rw-r--r-- | src/datavisualization/utils/utils_p.h | 18 |
16 files changed, 750 insertions, 171 deletions
diff --git a/src/datavisualization/utils/abstractobjecthelper_p.h b/src/datavisualization/utils/abstractobjecthelper_p.h index 3220b37d..c1618909 100644 --- a/src/datavisualization/utils/abstractobjecthelper_p.h +++ b/src/datavisualization/utils/abstractobjecthelper_p.h @@ -30,7 +30,6 @@ #define ABSTRACTOBJECTHELPER_H #include "datavisualizationglobal_p.h" -#include <QtGui/QOpenGLFunctions> QT_BEGIN_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/utils/camerahelper_p.h b/src/datavisualization/utils/camerahelper_p.h index f410ceb5..89dd48f4 100644 --- a/src/datavisualization/utils/camerahelper_p.h +++ b/src/datavisualization/utils/camerahelper_p.h @@ -33,9 +33,7 @@ #include "q3dcamera.h" class QMatrix4x4; -class QVector3D; class QPoint; -class QPointF; QT_BEGIN_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/utils/objecthelper.cpp b/src/datavisualization/utils/objecthelper.cpp index 97695193..a66e0f7e 100644 --- a/src/datavisualization/utils/objecthelper.cpp +++ b/src/datavisualization/utils/objecthelper.cpp @@ -19,7 +19,6 @@ #include "meshloader_p.h" #include "vertexindexer_p.h" #include "objecthelper_p.h" -#include "abstractobjecthelper_p.h" QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -27,15 +26,87 @@ ObjectHelper::ObjectHelper(const QString &objectFile) : m_objectFile(objectFile) { m_indicesType = GL_UNSIGNED_SHORT; + load(); } +struct ObjectHelperRef { + int refCount; + ObjectHelper *obj; +}; + +// The "Abstract3DRenderer *" key identifies the renderer +static QHash<const Abstract3DRenderer *, QHash<QString, ObjectHelperRef *> *> cacheTable; + ObjectHelper::~ObjectHelper() { } -void ObjectHelper::setObjectFile(const QString &objectFile) +void ObjectHelper::resetObjectHelper(const Abstract3DRenderer *cacheId, ObjectHelper *&obj, + const QString &meshFile) +{ + Q_ASSERT(cacheId); + + if (obj) { + const QString &oldFile = obj->objectFile(); + if (meshFile == oldFile) + return; // same file, do nothing + releaseObjectHelper(cacheId, obj); + } + obj = getObjectHelper(cacheId, meshFile); +} + +void ObjectHelper::releaseObjectHelper(const Abstract3DRenderer *cacheId, ObjectHelper *&obj) +{ + Q_ASSERT(cacheId); + + if (obj) { + QHash<QString, ObjectHelperRef *> *objectTable = cacheTable.value(cacheId, 0); + if (objectTable) { + // Delete object if last reference is released + ObjectHelperRef *objRef = objectTable->value(obj->m_objectFile, 0); + if (objRef) { + objRef->refCount--; + if (objRef->refCount <= 0) { + objectTable->remove(obj->m_objectFile); + delete objRef->obj; + delete objRef; + } + } + if (objectTable->isEmpty()) { + // Remove the entire cache if last object was removed + cacheTable.remove(cacheId); + delete objectTable; + } + } else { + // Just delete the object if unknown cache + delete obj; + } + obj = 0; + } +} + +ObjectHelper *ObjectHelper::getObjectHelper(const Abstract3DRenderer *cacheId, + const QString &objectFile) { - m_objectFile = objectFile; + if (objectFile.isEmpty()) + return 0; + + QHash<QString, ObjectHelperRef *> *objectTable = cacheTable.value(cacheId, 0); + if (!objectTable) { + objectTable = new QHash<QString, ObjectHelperRef *>; + cacheTable.insert(cacheId, objectTable); + } + + // Check if object helper for this mesh already exists + ObjectHelperRef *objRef = objectTable->value(objectFile, 0); + if (!objRef) { + objRef = new ObjectHelperRef; + objRef->refCount = 0; + objRef->obj = new ObjectHelper(objectFile); + objectTable->insert(objectFile, objRef); + } + objRef->refCount++; + return objRef->obj; } void ObjectHelper::load() @@ -47,6 +118,10 @@ void ObjectHelper::load() glDeleteBuffers(1, &m_uvbuffer); glDeleteBuffers(1, &m_normalbuffer); glDeleteBuffers(1, &m_elementbuffer); + m_indices.clear(); + m_indexedVertices.clear(); + m_indexedUVs.clear(); + m_indexedNormals.clear(); } QVector<QVector3D> vertices; QVector<QVector2D> uvs; @@ -56,36 +131,32 @@ void ObjectHelper::load() qFatal("loading failed"); // Index vertices - QVector<unsigned short> indices; - QVector<QVector3D> indexed_vertices; - QVector<QVector2D> indexed_uvs; - QVector<QVector3D> indexed_normals; - VertexIndexer::indexVBO(vertices, uvs, normals, indices, indexed_vertices, indexed_uvs, - indexed_normals); + VertexIndexer::indexVBO(vertices, uvs, normals, m_indices, m_indexedVertices, m_indexedUVs, + m_indexedNormals); - m_indexCount = indices.size(); + m_indexCount = m_indices.size(); glGenBuffers(1, &m_vertexbuffer); glBindBuffer(GL_ARRAY_BUFFER, m_vertexbuffer); - glBufferData(GL_ARRAY_BUFFER, indexed_vertices.size() * sizeof(QVector3D), - &indexed_vertices.at(0), + glBufferData(GL_ARRAY_BUFFER, m_indexedVertices.size() * sizeof(QVector3D), + &m_indexedVertices.at(0), GL_STATIC_DRAW); glGenBuffers(1, &m_normalbuffer); glBindBuffer(GL_ARRAY_BUFFER, m_normalbuffer); - glBufferData(GL_ARRAY_BUFFER, indexed_normals.size() * sizeof(QVector3D), - &indexed_normals.at(0), + glBufferData(GL_ARRAY_BUFFER, m_indexedNormals.size() * sizeof(QVector3D), + &m_indexedNormals.at(0), GL_STATIC_DRAW); glGenBuffers(1, &m_uvbuffer); glBindBuffer(GL_ARRAY_BUFFER, m_uvbuffer); - glBufferData(GL_ARRAY_BUFFER, indexed_uvs.size() * sizeof(QVector2D), - &indexed_uvs.at(0), GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, m_indexedUVs.size() * sizeof(QVector2D), + &m_indexedUVs.at(0), GL_STATIC_DRAW); glGenBuffers(1, &m_elementbuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementbuffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned short), - &indices.at(0), GL_STATIC_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indices.size() * sizeof(unsigned short), + &m_indices.at(0), GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); diff --git a/src/datavisualization/utils/objecthelper_p.h b/src/datavisualization/utils/objecthelper_p.h index 0260dd05..c84f53bd 100644 --- a/src/datavisualization/utils/objecthelper_p.h +++ b/src/datavisualization/utils/objecthelper_p.h @@ -31,22 +31,38 @@ #include "datavisualizationglobal_p.h" #include "abstractobjecthelper_p.h" -#include <QtGui/QOpenGLFunctions> QT_BEGIN_NAMESPACE_DATAVISUALIZATION +class Abstract3DRenderer; + class ObjectHelper : public AbstractObjectHelper { +private: + ObjectHelper(const QString &objectFile); public: - ObjectHelper(const QString &objectFile = QString()); ~ObjectHelper(); - void setObjectFile(const QString &objectFile); + static void resetObjectHelper(const Abstract3DRenderer *cacheId, ObjectHelper *&obj, + const QString &meshFile); + static void releaseObjectHelper(const Abstract3DRenderer *cacheId, ObjectHelper *&obj); + inline const QString &objectFile() { return m_objectFile; } - void load(); + inline const QVector<unsigned short> &indices() const { return m_indices; } + inline const QVector<QVector3D> &indexedvertices() const { return m_indexedVertices; } + inline const QVector<QVector2D> &indexedUVs() const { return m_indexedUVs; } + inline const QVector<QVector3D> &indexedNormals() const { return m_indexedNormals; } private: + static ObjectHelper *getObjectHelper(const Abstract3DRenderer *cacheId, + const QString &objectFile); + void load(); + QString m_objectFile; + QVector<unsigned short> m_indices; + QVector<QVector3D> m_indexedVertices; + QVector<QVector2D> m_indexedUVs; + QVector<QVector3D> m_indexedNormals; }; QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/utils/scatterobjectbufferhelper.cpp b/src/datavisualization/utils/scatterobjectbufferhelper.cpp new file mode 100644 index 00000000..123588f1 --- /dev/null +++ b/src/datavisualization/utils/scatterobjectbufferhelper.cpp @@ -0,0 +1,226 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "scatterobjectbufferhelper_p.h" +#include "objecthelper_p.h" +#include <QtGui/QVector2D> +#include <QtGui/QMatrix4x4> + +QT_BEGIN_NAMESPACE_DATAVISUALIZATION + +const GLfloat itemScaler = 3.0f; + +ScatterObjectBufferHelper::ScatterObjectBufferHelper() +{ + m_indicesType = GL_UNSIGNED_INT; +} + +ScatterObjectBufferHelper::~ScatterObjectBufferHelper() +{ +} + +void ScatterObjectBufferHelper::fullLoad(ScatterSeriesRenderCache *cache, qreal dotScale) +{ + initializeOpenGLFunctions(); + + ObjectHelper *dotObj = cache->object(); + ScatterRenderItemArray &renderArray = cache->renderArray(); + const uint renderArraySize = renderArray.size(); + uint itemCount = renderArraySize; + QQuaternion seriesRotation(cache->meshRotation()); + + if (m_meshDataLoaded) { + // Delete old data + glDeleteBuffers(1, &m_vertexbuffer); + glDeleteBuffers(1, &m_uvbuffer); + glDeleteBuffers(1, &m_normalbuffer); + glDeleteBuffers(1, &m_elementbuffer); + } + + // Index vertices + const QVector<unsigned short> indices = dotObj->indices(); + const QVector<QVector3D> indexed_vertices = dotObj->indexedvertices(); + const QVector<QVector2D> indexed_uvs = dotObj->indexedUVs(); + const QVector<QVector3D> indexed_normals = dotObj->indexedNormals(); + int indicesCount = indices.count(); + int verticeCount = indexed_vertices.count(); + int uvsCount = indexed_uvs.count(); + int normalsCount = indexed_normals.count(); + + float itemSize = cache->itemSize() / itemScaler; + if (itemSize == 0.0f) + itemSize = dotScale; + QVector3D modelScaler(itemSize, itemSize, itemSize); + QMatrix4x4 modelMatrix; + if (!seriesRotation.isIdentity()) { + QMatrix4x4 matrix; + matrix.rotate(seriesRotation); + modelMatrix = matrix.transposed(); + } + modelMatrix.scale(modelScaler); + + QVector<QVector3D> scaled_vertices; + scaled_vertices.resize(verticeCount); + for (int i = 0; i < verticeCount; i++) + scaled_vertices[i] = indexed_vertices[i] * modelMatrix; + + QVector<GLuint> buffered_indices; + QVector<QVector3D> buffered_vertices; + QVector<QVector2D> buffered_uvs; + QVector<QVector3D> buffered_normals; + + buffered_indices.resize(indicesCount * renderArraySize); + buffered_vertices.resize(verticeCount * renderArraySize); + buffered_uvs.resize(uvsCount * renderArraySize); + buffered_normals.resize(normalsCount * renderArraySize); + uint pos = 0; + for (uint i = 0; i < renderArraySize; i++) { + ScatterRenderItem &item = renderArray[i]; + if (!item.isVisible()) { + itemCount--; + continue; + } + + int offset = pos * verticeCount; + if (item.rotation().isIdentity()) { + for (int j = 0; j < verticeCount; j++) + buffered_vertices[j + offset] = scaled_vertices[j] + item.translation(); + } else { + QMatrix4x4 matrix; + matrix.rotate(seriesRotation * item.rotation()); + modelMatrix = matrix.transposed(); + modelMatrix.scale(modelScaler); + + for (int j = 0; j < verticeCount; j++) + buffered_vertices[j + offset] = indexed_vertices[j] * modelMatrix + + item.translation(); + } + + offset = pos * normalsCount; + for (int j = 0; j < normalsCount; j++) + buffered_normals[j + offset] = indexed_normals[j]; + + offset = pos * uvsCount; + for (int j = 0; j < uvsCount; j++) + buffered_uvs[j + offset] = indexed_uvs[j]; + + int offsetVertice = i * verticeCount; + offset = pos * indicesCount; + for (int j = 0; j < indicesCount; j++) { + buffered_indices[j + offset] = GLuint(indices[j] + offsetVertice); + } + + pos++; + } + + m_indexCount = indicesCount * itemCount; + + glGenBuffers(1, &m_vertexbuffer); + glBindBuffer(GL_ARRAY_BUFFER, m_vertexbuffer); + glBufferData(GL_ARRAY_BUFFER, verticeCount * itemCount * sizeof(QVector3D), + &buffered_vertices.at(0), + GL_STATIC_DRAW); + + glGenBuffers(1, &m_normalbuffer); + glBindBuffer(GL_ARRAY_BUFFER, m_normalbuffer); + glBufferData(GL_ARRAY_BUFFER, normalsCount * itemCount * sizeof(QVector3D), + &buffered_normals.at(0), + GL_STATIC_DRAW); + + glGenBuffers(1, &m_uvbuffer); + glBindBuffer(GL_ARRAY_BUFFER, m_uvbuffer); + glBufferData(GL_ARRAY_BUFFER, uvsCount * itemCount * sizeof(QVector2D), + &buffered_uvs.at(0), GL_STATIC_DRAW); + + glGenBuffers(1, &m_elementbuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementbuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesCount * itemCount * sizeof(GLint), + &buffered_indices.at(0), GL_STATIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + m_meshDataLoaded = true; +} + +void ScatterObjectBufferHelper::update(ScatterSeriesRenderCache *cache, qreal dotScale) +{ + initializeOpenGLFunctions(); + + ObjectHelper *dotObj = cache->object(); + ScatterRenderItemArray &renderArray = cache->renderArray(); + const int renderArraySize = renderArray.size(); + QQuaternion seriesRotation(cache->meshRotation()); + + // Index vertices + const QVector<QVector3D> indexed_vertices = dotObj->indexedvertices(); + int verticeCount = indexed_vertices.count(); + + float itemSize = cache->itemSize() / itemScaler; + if (itemSize == 0.0f) + itemSize = dotScale; + QVector3D modelScaler(itemSize, itemSize, itemSize); + QMatrix4x4 modelMatrix; + if (!seriesRotation.isIdentity()) { + QMatrix4x4 matrix; + matrix.rotate(seriesRotation); + modelMatrix = matrix.transposed(); + } + modelMatrix.scale(modelScaler); + + QVector<QVector3D> scaled_vertices; + scaled_vertices.resize(verticeCount); + for (int i = 0; i < verticeCount; i++) + scaled_vertices[i] = indexed_vertices[i] * modelMatrix; + + QVector<QVector3D> buffered_vertices; + + buffered_vertices.resize(verticeCount * renderArraySize); + for (int i = 0; i < renderArraySize; i++) { + ScatterRenderItem &item = renderArray[i]; + if (!item.isVisible()) + continue; + + const int offset = i * verticeCount; + if (item.rotation().isIdentity()) { + for (int j = 0; j < verticeCount; j++) + buffered_vertices[j + offset] = scaled_vertices[j] + item.translation(); + } else { + QMatrix4x4 matrix; + matrix.rotate(seriesRotation * item.rotation()); + modelMatrix = matrix.transposed(); + modelMatrix.scale(modelScaler); + + for (int j = 0; j < verticeCount; j++) + buffered_vertices[j + offset] = indexed_vertices[j] * modelMatrix + + item.translation(); + } + } + + glBindBuffer(GL_ARRAY_BUFFER, m_vertexbuffer); + glBufferData(GL_ARRAY_BUFFER, buffered_vertices.size() * sizeof(QVector3D), + &buffered_vertices.at(0), + GL_DYNAMIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + m_meshDataLoaded = true; +} + +QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/utils/scatterobjectbufferhelper_p.h b/src/datavisualization/utils/scatterobjectbufferhelper_p.h new file mode 100644 index 00000000..952c3d7d --- /dev/null +++ b/src/datavisualization/utils/scatterobjectbufferhelper_p.h @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVisualization 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 SCATTEROBJECTBUFFERHELPER_P_H +#define SCATTEROBJECTBUFFERHELPER_P_H + +#include "datavisualizationglobal_p.h" +#include "abstractobjecthelper_p.h" +#include "scatterseriesrendercache_p.h" + +QT_BEGIN_NAMESPACE_DATAVISUALIZATION + +class ScatterObjectBufferHelper : public AbstractObjectHelper +{ +public: + ScatterObjectBufferHelper(); + ~ScatterObjectBufferHelper(); + + void fullLoad(ScatterSeriesRenderCache *cache, qreal dotScale); + void update(ScatterSeriesRenderCache *cache, qreal dotScale); +}; + +QT_END_NAMESPACE_DATAVISUALIZATION + +#endif diff --git a/src/datavisualization/utils/scatterpointbufferhelper.cpp b/src/datavisualization/utils/scatterpointbufferhelper.cpp new file mode 100644 index 00000000..0f290aeb --- /dev/null +++ b/src/datavisualization/utils/scatterpointbufferhelper.cpp @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "scatterpointbufferhelper_p.h" + +QT_BEGIN_NAMESPACE_DATAVISUALIZATION + +const GLfloat itemScaler = 3.0f; +const QVector3D hiddenPos(-1000.0f, -1000.0f, -1000.0f); + +ScatterPointBufferHelper::ScatterPointBufferHelper() + : m_pointbuffer(0), + m_oldRemoveIndex(0), + m_oldRemove(false) +{ + m_indicesType = GL_UNSIGNED_INT; +} + +ScatterPointBufferHelper::~ScatterPointBufferHelper() +{ + if (QOpenGLContext::currentContext()) + glDeleteBuffers(1, &m_pointbuffer); +} + +GLuint ScatterPointBufferHelper::pointBuf() +{ + if (!m_meshDataLoaded) + qFatal("No loaded object"); + return m_pointbuffer; +} + +void ScatterPointBufferHelper::pushPoint(uint pointIndex) +{ + glBindBuffer(GL_ARRAY_BUFFER, m_pointbuffer); + + if (m_oldRemove && m_oldRemoveIndex < pointIndex) { + glBufferSubData(GL_ARRAY_BUFFER, m_oldRemoveIndex * sizeof(QVector3D), + sizeof(QVector3D), &m_bufferedPoints.at(m_oldRemoveIndex)); + } + + glBufferSubData(GL_ARRAY_BUFFER, pointIndex * sizeof(QVector3D), + sizeof(QVector3D), + &hiddenPos); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + + m_oldRemoveIndex = pointIndex; + m_oldRemove = true; +} + +void ScatterPointBufferHelper::popPoint() +{ + if (m_oldRemove) { + glBindBuffer(GL_ARRAY_BUFFER, m_pointbuffer); + glBufferSubData(GL_ARRAY_BUFFER, m_oldRemoveIndex * sizeof(QVector3D), + sizeof(QVector3D), &m_bufferedPoints.at(m_oldRemoveIndex)); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + + m_oldRemoveIndex = 0; + m_oldRemove = false; +} + +void ScatterPointBufferHelper::load(ScatterSeriesRenderCache *cache) +{ + initializeOpenGLFunctions(); + + ScatterRenderItemArray &renderArray = cache->renderArray(); + const int renderArraySize = renderArray.size(); + + if (m_meshDataLoaded) { + // Delete old data + glDeleteBuffers(1, &m_pointbuffer); + m_bufferedPoints.clear(); + } + + m_bufferedPoints.resize(renderArraySize); + for (int i = 0; i < renderArraySize; i++) { + ScatterRenderItem &item = renderArray[i]; + if (!item.isVisible()) + m_bufferedPoints[i] = hiddenPos; + else + m_bufferedPoints[i] = item.translation(); + } + + m_indexCount = renderArraySize; + + glGenBuffers(1, &m_pointbuffer); + glBindBuffer(GL_ARRAY_BUFFER, m_pointbuffer); + glBufferData(GL_ARRAY_BUFFER, m_bufferedPoints.size() * sizeof(QVector3D), + &m_bufferedPoints.at(0), + GL_DYNAMIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + m_meshDataLoaded = true; +} + +QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/utils/scatterpointbufferhelper_p.h b/src/datavisualization/utils/scatterpointbufferhelper_p.h new file mode 100644 index 00000000..b3adcfa8 --- /dev/null +++ b/src/datavisualization/utils/scatterpointbufferhelper_p.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVisualization 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 SCATTERPOINTBUFFERHELPER_P_H +#define SCATTERPOINTBUFFERHELPER_P_H + +#include "datavisualizationglobal_p.h" +#include "abstractobjecthelper_p.h" +#include "scatterseriesrendercache_p.h" + +QT_BEGIN_NAMESPACE_DATAVISUALIZATION + +class ScatterPointBufferHelper : public AbstractObjectHelper +{ +public: + ScatterPointBufferHelper(); + ~ScatterPointBufferHelper(); + + GLuint pointBuf(); + + void pushPoint(uint pointIndex); + void popPoint(); + void load(ScatterSeriesRenderCache *cache); + +public: + GLuint m_pointbuffer; + +private: + QVector<QVector3D> m_bufferedPoints; + uint m_oldRemoveIndex; + bool m_oldRemove; +}; + +QT_END_NAMESPACE_DATAVISUALIZATION + +#endif diff --git a/src/datavisualization/utils/shaderhelper_p.h b/src/datavisualization/utils/shaderhelper_p.h index ced27572..fdef0dff 100644 --- a/src/datavisualization/utils/shaderhelper_p.h +++ b/src/datavisualization/utils/shaderhelper_p.h @@ -30,7 +30,6 @@ #define SHADERHELPER_P_H #include "datavisualizationglobal_p.h" -#include <QtGui/QOpenGLFunctions> class QOpenGLShaderProgram; diff --git a/src/datavisualization/utils/surfaceobject.cpp b/src/datavisualization/utils/surfaceobject.cpp index 9bcdfee2..d999ba90 100644 --- a/src/datavisualization/utils/surfaceobject.cpp +++ b/src/datavisualization/utils/surfaceobject.cpp @@ -17,17 +17,21 @@ ****************************************************************************/ #include "surfaceobject_p.h" -#include "abstractobjecthelper_p.h" +#include "surface3drenderer_p.h" #include <QtGui/QVector2D> QT_BEGIN_NAMESPACE_DATAVISUALIZATION -SurfaceObject::SurfaceObject() +SurfaceObject::SurfaceObject(Surface3DRenderer *renderer) : m_surfaceType(Undefined), m_columns(0), m_rows(0), - m_gridIndexCount(0) + m_gridIndexCount(0), + m_axisCacheX(renderer->m_axisCacheX), + m_axisCacheY(renderer->m_axisCacheY), + m_axisCacheZ(renderer->m_axisCacheZ) + { m_indicesType = GL_UNSIGNED_INT; initializeOpenGLFunctions(); @@ -45,16 +49,11 @@ SurfaceObject::~SurfaceObject() } void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QRect &space, - GLfloat yRange, GLfloat yMin, bool changeGeometry) + bool changeGeometry, bool flipXZ) { m_columns = space.width(); m_rows = space.height(); int totalSize = m_rows * m_columns; - GLfloat xMin = dataArray.at(0)->at(0).x(); - GLfloat zMin = dataArray.at(0)->at(0).z(); - GLfloat xNormalizer = (dataArray.at(0)->last().x() - xMin) / 2.0f; - GLfloat yNormalizer = yRange / 2.0f; - GLfloat zNormalizer = (dataArray.last()->at(0).z() - zMin) / -2.0f; GLfloat uvX = 1.0f / GLfloat(m_columns - 1); GLfloat uvY = 1.0f / GLfloat(m_rows - 1); @@ -68,21 +67,31 @@ void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QR if (changeGeometry) uvs.resize(totalSize); int totalIndex = 0; + + AxisRenderCache &xCache = flipXZ ? m_axisCacheZ : m_axisCacheX; + AxisRenderCache &zCache = flipXZ ? m_axisCacheX : m_axisCacheZ; + for (int i = 0; i < m_rows; i++) { const QSurfaceDataRow &p = *dataArray.at(i); for (int j = 0; j < m_columns; j++) { const QSurfaceDataItem &data = p.at(j); - float normalizedX = ((data.x() - xMin) / xNormalizer); - float normalizedY = ((data.y() - yMin) / yNormalizer); - float normalizedZ = ((data.z() - zMin) / zNormalizer); - m_vertices[totalIndex] = QVector3D(normalizedX - 1.0f, normalizedY - 1.0f, - normalizedZ + 1.0f); + float normalizedX = xCache.positionAt(data.x()); + float normalizedY = m_axisCacheY.positionAt(data.y()); + float normalizedZ = zCache.positionAt(data.z()); + m_vertices[totalIndex] = QVector3D(normalizedX, normalizedY, normalizedZ); if (changeGeometry) uvs[totalIndex] = QVector2D(GLfloat(j) * uvX, GLfloat(i) * uvY); totalIndex++; } } + if (flipXZ) { + for (int i = 0; i < m_vertices.size(); i++) { + m_vertices[i].setX(-m_vertices.at(i).x()); + m_vertices[i].setZ(-m_vertices.at(i).z()); + } + } + // Create normals int rowLimit = m_rows - 1; int colLimit = m_columns - 1; @@ -92,25 +101,30 @@ void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QR m_normals.resize(totalSize); totalIndex = 0; + const bool flipNormal = checkFlipNormal(dataArray); for (int row = 0; row < rowColLimit; row += m_columns) { for (int j = 0; j < colLimit; j++) { m_normals[totalIndex++] = normal(m_vertices.at(row + j), m_vertices.at(row + j + 1), - m_vertices.at(row + m_columns + j)); + m_vertices.at(row + m_columns + j), + flipNormal); } int p = row + colLimit; m_normals[totalIndex++] = normal(m_vertices.at(p), m_vertices.at(p + m_columns), - m_vertices.at(p - 1)); + m_vertices.at(p - 1), + flipNormal); } for (int j = rowColLimit; j < totalLimit; j++) { m_normals[totalIndex++] = normal(m_vertices.at(j), m_vertices.at(j - m_columns), - m_vertices.at(j + 1)); + m_vertices.at(j + 1), + flipNormal); } m_normals[totalIndex++] = normal(m_vertices.at(totalLimit), m_vertices.at(totalLimit - 1), - m_vertices.at(totalLimit - m_columns)); + m_vertices.at(totalLimit - m_columns), + flipNormal); // Create indices table if (changeGeometry) @@ -123,24 +137,18 @@ void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QR createBuffers(m_vertices, uvs, m_normals, 0, changeGeometry); } -void SurfaceObject::updateSmoothRow(const QSurfaceDataArray &dataArray, int rowIndex, - GLfloat yRange, GLfloat yMin) +void SurfaceObject::updateSmoothRow(const QSurfaceDataArray &dataArray, int rowIndex) { - GLfloat xMin = dataArray.at(0)->at(0).x(); - GLfloat zMin = dataArray.at(0)->at(0).z(); - GLfloat xNormalizer = (dataArray.at(0)->last().x() - xMin) / 2.0f; - GLfloat yNormalizer = yRange / 2.0f; - GLfloat zNormalizer = (dataArray.last()->at(0).z() - zMin) / -2.0f; - // Update vertices int p = rowIndex * m_columns; const QSurfaceDataRow &dataRow = *dataArray.at(rowIndex); + for (int j = 0; j < m_columns; j++) { const QSurfaceDataItem &data = dataRow.at(j); - float normalizedX = ((data.x() - xMin) / xNormalizer); - float normalizedY = ((data.y() - yMin) / yNormalizer); - float normalizedZ = ((data.z() - zMin) / zNormalizer); - m_vertices[p++] = QVector3D(normalizedX - 1.0f, normalizedY - 1.0f, normalizedZ + 1.0f); + float normalizedX = m_axisCacheX.positionAt(data.x()); + float normalizedY = m_axisCacheY.positionAt(data.y()); + float normalizedZ = m_axisCacheZ.positionAt(data.z()); + m_vertices[p++] = QVector3D(normalizedX, normalizedY, normalizedZ); } // Create normals @@ -153,18 +161,21 @@ void SurfaceObject::updateSmoothRow(const QSurfaceDataArray &dataArray, int rowI if (rowIndex == m_rows - 1) rowLimit = rowIndex * m_columns; // The rowIndex is top most row, special handling + const bool flipNormal = checkFlipNormal(dataArray); for (int row = totalIndex; row < rowLimit; row += m_columns) { for (int j = 0; j < colLimit; j++) { // One right and one up m_normals[totalIndex++] = normal(m_vertices.at(row + j), m_vertices.at(row + j + 1), - m_vertices.at(row + m_columns + j)); + m_vertices.at(row + m_columns + j), + flipNormal); } int p = row + colLimit; // One up and one left m_normals[totalIndex++] = normal(m_vertices.at(p), m_vertices.at(p + m_columns), - m_vertices.at(p - 1)); + m_vertices.at(p - 1), + flipNormal); } if (rowIndex == m_rows - 1) { // Top most line, nothing above, must have different handling. @@ -173,32 +184,26 @@ void SurfaceObject::updateSmoothRow(const QSurfaceDataArray &dataArray, int rowI for (int j = rowIndex * m_columns; j < rowLimit; j++) { m_normals[totalIndex++] = normal(m_vertices.at(j), m_vertices.at(j - m_columns), - m_vertices.at(j + 1)); + m_vertices.at(j + 1), + flipNormal); } // Top left corner. Take from one left and one down m_normals[totalIndex++] = normal(m_vertices.at(rowLimit), m_vertices.at(rowLimit - 1), - m_vertices.at(rowLimit - m_columns)); + m_vertices.at(rowLimit - m_columns), + flipNormal); } } -void SurfaceObject::updateSmoothItem(const QSurfaceDataArray &dataArray, int row, - int column, GLfloat yRange, GLfloat yMin) +void SurfaceObject::updateSmoothItem(const QSurfaceDataArray &dataArray, int row, int column) { - GLfloat xMin = dataArray.at(0)->at(0).x(); - GLfloat zMin = dataArray.at(0)->at(0).z(); - GLfloat xNormalizer = (dataArray.at(0)->last().x() - xMin) / 2.0f; - GLfloat yNormalizer = yRange / 2.0f; - GLfloat zNormalizer = (dataArray.last()->at(0).z() - zMin) / -2.0f; - // Update a vertice const QSurfaceDataItem &data = dataArray.at(row)->at(column); - float normalizedX = ((data.x() - xMin) / xNormalizer); - float normalizedY = ((data.y() - yMin) / yNormalizer); - float normalizedZ = ((data.z() - zMin) / zNormalizer); - m_vertices[row * m_columns + column] = QVector3D(normalizedX - 1.0f, normalizedY - 1.0f, - normalizedZ + 1.0f); + float normalizedX = m_axisCacheX.positionAt(data.x()); + float normalizedY = m_axisCacheY.positionAt(data.y()); + float normalizedZ = m_axisCacheZ.positionAt(data.z()); + m_vertices[row * m_columns + column] = QVector3D(normalizedX, normalizedY, normalizedZ); // Create normals int startRow = row; @@ -210,6 +215,7 @@ void SurfaceObject::updateSmoothItem(const QSurfaceDataArray &dataArray, int row int rightCol = m_columns - 1; int topRow = m_rows - 1; + const bool flipNormal = checkFlipNormal(dataArray); for (int i = startRow; i <= row; i++) { for (int j = startCol; j <= column; j++) { int p = i * m_columns + j; @@ -218,12 +224,14 @@ void SurfaceObject::updateSmoothItem(const QSurfaceDataArray &dataArray, int row // One right and one up m_normals[p] = normal(m_vertices.at(p), m_vertices.at(p + 1), - m_vertices.at(p + m_columns)); + m_vertices.at(p + m_columns), + flipNormal); } else { // Last item, nothing on the right. One up and one left m_normals[p] = normal(m_vertices.at(p), m_vertices.at(p + m_columns), - m_vertices.at(p - 1)); + m_vertices.at(p - 1), + flipNormal); } } else { // Top most line, nothing above, must have different handling. @@ -231,12 +239,14 @@ void SurfaceObject::updateSmoothItem(const QSurfaceDataArray &dataArray, int row // Take from one down and one right. Read till second-to-last m_normals[p] = normal(m_vertices.at(p), m_vertices.at(p - m_columns), - m_vertices.at(p + 1)); + m_vertices.at(p + 1), + flipNormal); } else { // Top left corner. Take from one left and one down m_normals[p] = normal(m_vertices.at(p), m_vertices.at(p - 1), - m_vertices.at(p - m_columns)); + m_vertices.at(p - m_columns), + flipNormal); } } } @@ -321,16 +331,11 @@ void SurfaceObject::createSmoothGridlineIndices(int x, int y, int endX, int endY } void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &space, - GLfloat yRange, GLfloat yMin, bool changeGeometry) + bool changeGeometry, bool flipXZ) { m_columns = space.width(); m_rows = space.height(); int totalSize = m_rows * m_columns * 2; - GLfloat xMin = dataArray.at(0)->at(0).x(); - GLfloat zMin = dataArray.at(0)->at(0).z(); - GLfloat xNormalizer = (dataArray.at(0)->last().x() - xMin) / 2.0f; - GLfloat yNormalizer = yRange / 2.0f; - GLfloat zNormalizer = (dataArray.last()->at(0).z() - zMin) / -2.0f; GLfloat uvX = 1.0f / GLfloat(m_columns - 1); GLfloat uvY = 1.0f / GLfloat(m_rows - 1); @@ -350,15 +355,17 @@ void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &s int doubleColumns = m_columns * 2 - 2; int rowColLimit = rowLimit * doubleColumns; + AxisRenderCache &xCache = flipXZ ? m_axisCacheZ : m_axisCacheX; + AxisRenderCache &zCache = flipXZ ? m_axisCacheX : m_axisCacheZ; + for (int i = 0; i < m_rows; i++) { const QSurfaceDataRow &row = *dataArray.at(i); for (int j = 0; j < m_columns; j++) { const QSurfaceDataItem &data = row.at(j); - float normalizedX = ((data.x() - xMin) / xNormalizer); - float normalizedY = ((data.y() - yMin) / yNormalizer); - float normalizedZ = ((data.z() - zMin) / zNormalizer); - m_vertices[totalIndex] = QVector3D(normalizedX - 1.0f, normalizedY - 1.0f, - normalizedZ + 1.0f); + float normalizedX = xCache.positionAt(data.x()); + float normalizedY = m_axisCacheY.positionAt(data.y()); + float normalizedZ = zCache.positionAt(data.z()); + m_vertices[totalIndex] = QVector3D(normalizedX, normalizedY, normalizedZ); if (changeGeometry) uvs[totalIndex] = QVector2D(GLfloat(j) * uvX, GLfloat(i) * uvY); @@ -373,6 +380,13 @@ void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &s } } + if (flipXZ) { + for (int i = 0; i < m_vertices.size(); i++) { + m_vertices[i].setX(-m_vertices.at(i).x()); + m_vertices[i].setZ(-m_vertices.at(i).z()); + } + } + // Create normals & indices table GLint *indices = 0; int p = 0; @@ -384,6 +398,7 @@ void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &s } totalIndex = 0; + const bool flipNormal = checkFlipNormal(dataArray); for (int row = 0, upperRow = doubleColumns; row < rowColLimit; row += doubleColumns, upperRow += doubleColumns) { @@ -391,12 +406,14 @@ void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &s // Normal for the left triangle m_normals[totalIndex++] = normal(m_vertices.at(row + j), m_vertices.at(row + j + 1), - m_vertices.at(upperRow + j)); + m_vertices.at(upperRow + j), + flipNormal); // Normal for the right triangle m_normals[totalIndex++] = normal(m_vertices.at(row + j + 1), m_vertices.at(upperRow + j + 1), - m_vertices.at(upperRow + j)); + m_vertices.at(upperRow + j), + flipNormal); if (changeGeometry) { // Left triangle @@ -421,26 +438,20 @@ void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &s delete[] indices; } -void SurfaceObject::updateCoarseRow(const QSurfaceDataArray &dataArray, int rowIndex, - GLfloat yRange, GLfloat yMin) +void SurfaceObject::updateCoarseRow(const QSurfaceDataArray &dataArray, int rowIndex) { - GLfloat xMin = dataArray.at(0)->at(0).x(); - GLfloat zMin = dataArray.at(0)->at(0).z(); - GLfloat xNormalizer = (dataArray.at(0)->last().x() - xMin) / 2.0f; - GLfloat yNormalizer = yRange / 2.0f; - GLfloat zNormalizer = (dataArray.last()->at(0).z() - zMin) / -2.0f; - int colLimit = m_columns - 1; int doubleColumns = m_columns * 2 - 2; int p = rowIndex * doubleColumns; const QSurfaceDataRow &dataRow = *dataArray.at(rowIndex); + for (int j = 0; j < m_columns; j++) { const QSurfaceDataItem &data = dataRow.at(j); - float normalizedX = ((data.x() - xMin) / xNormalizer); - float normalizedY = ((data.y() - yMin) / yNormalizer); - float normalizedZ = ((data.z() - zMin) / zNormalizer); - m_vertices[p++] = QVector3D(normalizedX - 1.0f, normalizedY - 1.0f, normalizedZ + 1.0f); + float normalizedX = m_axisCacheX.positionAt(data.x()); + float normalizedY = m_axisCacheY.positionAt(data.y()); + float normalizedZ = m_axisCacheZ.positionAt(data.z()); + m_vertices[p++] = QVector3D(normalizedX, normalizedY, normalizedZ); if (j > 0 && j < colLimit) { m_vertices[p] = m_vertices[p - 1]; @@ -455,6 +466,7 @@ void SurfaceObject::updateCoarseRow(const QSurfaceDataArray &dataArray, int rowI int rowLimit = (rowIndex + 1) * doubleColumns; if (rowIndex == m_rows - 1) rowLimit = rowIndex * doubleColumns; //Topmost row, no normals + const bool flipNormal = checkFlipNormal(dataArray); for (int row = p, upperRow = p + doubleColumns; row < rowLimit; row += doubleColumns, upperRow += doubleColumns) { @@ -462,35 +474,30 @@ void SurfaceObject::updateCoarseRow(const QSurfaceDataArray &dataArray, int rowI // Normal for the left triangle m_normals[p++] = normal(m_vertices.at(row + j), m_vertices.at(row + j + 1), - m_vertices.at(upperRow + j)); + m_vertices.at(upperRow + j), + flipNormal); // Normal for the right triangle m_normals[p++] = normal(m_vertices.at(row + j + 1), m_vertices.at(upperRow + j + 1), - m_vertices.at(upperRow + j)); + m_vertices.at(upperRow + j), + flipNormal); } } } -void SurfaceObject::updateCoarseItem(const QSurfaceDataArray &dataArray, int row, - int column, GLfloat yRange, GLfloat yMin) +void SurfaceObject::updateCoarseItem(const QSurfaceDataArray &dataArray, int row, int column) { - GLfloat xMin = dataArray.at(0)->at(0).x(); - GLfloat zMin = dataArray.at(0)->at(0).z(); - GLfloat xNormalizer = (dataArray.at(0)->last().x() - xMin) / 2.0f; - GLfloat yNormalizer = yRange / 2.0f; - GLfloat zNormalizer = (dataArray.last()->at(0).z() - zMin) / -2.0f; - int colLimit = m_columns - 1; int doubleColumns = m_columns * 2 - 2; // Update a vertice int p = row * doubleColumns + column * 2 - (column > 0); const QSurfaceDataItem &data = dataArray.at(row)->at(column); - float normalizedX = ((data.x() - xMin) / xNormalizer); - float normalizedY = ((data.y() - yMin) / yNormalizer); - float normalizedZ = ((data.z() - zMin) / zNormalizer); - m_vertices[p] = QVector3D(normalizedX - 1.0f, normalizedY - 1.0f, normalizedZ + 1.0f); + float normalizedX = m_axisCacheX.positionAt(data.x()); + float normalizedY = m_axisCacheY.positionAt(data.y()); + float normalizedZ = m_axisCacheZ.positionAt(data.z()); + m_vertices[p] = QVector3D(normalizedX, normalizedY, normalizedZ); p++; if (column > 0 && column < colLimit) @@ -508,19 +515,22 @@ void SurfaceObject::updateCoarseItem(const QSurfaceDataArray &dataArray, int row if (column == m_columns - 1) column--; + const bool flipNormal = checkFlipNormal(dataArray); for (int i = startRow; i <= row; i++) { for (int j = startCol; j <= column; j++) { p = i * doubleColumns + j * 2; // Normal for the left triangle m_normals[p] = normal(m_vertices.at(p), m_vertices.at(p + 1), - m_vertices.at(p + doubleColumns)); + m_vertices.at(p + doubleColumns), + flipNormal); p++; // Normal for the right triangle m_normals[p] = normal(m_vertices.at(p), m_vertices.at(p + doubleColumns), - m_vertices.at(p + doubleColumns - 1)); + m_vertices.at(p + doubleColumns - 1), + flipNormal); } } } @@ -656,6 +666,13 @@ void SurfaceObject::createBuffers(const QVector<QVector3D> &vertices, const QVec m_meshDataLoaded = true; } +bool SurfaceObject::checkFlipNormal(const QSurfaceDataArray &array) +{ + const bool ascendingX = array.at(0)->at(0).x() < array.at(0)->at(array.at(0)->size() - 1).x(); + const bool ascendingZ = array.at(0)->at(0).z() < array.at(array.size() - 1)->at(0).z(); + return ascendingX != ascendingZ; +} + GLuint SurfaceObject::gridElementBuf() { if (!m_meshDataLoaded) @@ -686,13 +703,19 @@ void SurfaceObject::clear() m_gridIndexCount = 0; m_indexCount = 0; m_surfaceType = Undefined; + m_vertices.clear(); + m_normals.clear(); } -QVector3D SurfaceObject::normal(const QVector3D &a, const QVector3D &b, const QVector3D &c) +QVector3D SurfaceObject::normal(const QVector3D &a, const QVector3D &b, const QVector3D &c, + bool flipNormal) { QVector3D v1 = b - a; QVector3D v2 = c - a; - return QVector3D::crossProduct(v1, v2); + QVector3D normal = QVector3D::crossProduct(v1, v2); + if (flipNormal) + normal *= -1; + return normal; } QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/utils/surfaceobject_p.h b/src/datavisualization/utils/surfaceobject_p.h index 69cb7e5d..9c18dcb2 100644 --- a/src/datavisualization/utils/surfaceobject_p.h +++ b/src/datavisualization/utils/surfaceobject_p.h @@ -37,6 +37,9 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION +class Surface3DRenderer; +class AxisRenderCache; + class SurfaceObject : public AbstractObjectHelper { public: @@ -47,21 +50,17 @@ public: }; public: - SurfaceObject(); + SurfaceObject(Surface3DRenderer *renderer); ~SurfaceObject(); - void setUpData(const QSurfaceDataArray &dataArray, const QRect &space, GLfloat yRange, - GLfloat yMin, bool changeGeometry); - void setUpSmoothData(const QSurfaceDataArray &dataArray, const QRect &space, GLfloat yRange, - GLfloat yMin, bool changeGeometry); - void updateCoarseRow(const QSurfaceDataArray &dataArray, int rowIndex, - GLfloat yRange, GLfloat yMin); - void updateSmoothRow(const QSurfaceDataArray &dataArray, int startRow, - GLfloat yRange, GLfloat yMin); - void updateSmoothItem(const QSurfaceDataArray &dataArray, int row, - int column, GLfloat yRange, GLfloat yMin); - void updateCoarseItem(const QSurfaceDataArray &dataArray, int row, - int column, GLfloat yRange, GLfloat yMin); + void setUpData(const QSurfaceDataArray &dataArray, const QRect &space, + bool changeGeometry, bool flipXZ = false); + void setUpSmoothData(const QSurfaceDataArray &dataArray, const QRect &space, + bool changeGeometry, bool flipXZ = false); + void updateCoarseRow(const QSurfaceDataArray &dataArray, int rowIndex); + void updateSmoothRow(const QSurfaceDataArray &dataArray, int startRow); + void updateSmoothItem(const QSurfaceDataArray &dataArray, int row, int column); + void updateCoarseItem(const QSurfaceDataArray &dataArray, int row, int column); void createSmoothIndices(int x, int y, int endX, int endY); void createCoarseIndices(int x, int y, int columns, int rows); void createSmoothGridlineIndices(int x, int y, int endX, int endY); @@ -73,10 +72,11 @@ public: void clear(); private: - QVector3D normal(const QVector3D &a, const QVector3D &b, const QVector3D &c); + QVector3D normal(const QVector3D &a, const QVector3D &b, const QVector3D &c, bool flipNormal); void createBuffers(const QVector<QVector3D> &vertices, const QVector<QVector2D> &uvs, const QVector<QVector3D> &normals, const GLint *indices, bool changeGeometry); + bool checkFlipNormal(const QSurfaceDataArray &array); private: SurfaceType m_surfaceType; @@ -86,6 +86,10 @@ private: GLuint m_gridIndexCount; QVector<QVector3D> m_vertices; QVector<QVector3D> m_normals; + // Caches are not owned + AxisRenderCache &m_axisCacheX; + AxisRenderCache &m_axisCacheY; + AxisRenderCache &m_axisCacheZ; }; QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/utils/texturehelper.cpp b/src/datavisualization/utils/texturehelper.cpp index 52c673dc..185d99e4 100644 --- a/src/datavisualization/utils/texturehelper.cpp +++ b/src/datavisualization/utils/texturehelper.cpp @@ -108,13 +108,8 @@ GLuint TextureHelper::createSelectionTexture(const QSize &size, GLuint &frameBuf glBindTexture(GL_TEXTURE_2D, textureid); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -#if !defined(QT_OPENGL_ES_2) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); -#else - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size.width(), size.height(), 0, GL_RGB, - GL_UNSIGNED_BYTE, NULL); -#endif glBindTexture(GL_TEXTURE_2D, 0); // Create render buffer @@ -198,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); @@ -228,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]; @@ -244,9 +241,12 @@ void TextureHelper::fillDepthTexture(GLuint texture,const QSize &size, GLuint te } #endif -void TextureHelper::deleteTexture(const GLuint *texture) +void TextureHelper::deleteTexture(GLuint *texture) { - glDeleteTextures(1, texture); + if (texture && *texture) { + glDeleteTextures(1, texture); + *texture = 0; + } } QImage TextureHelper::convertToGLFormat(const QImage &srcImage) diff --git a/src/datavisualization/utils/texturehelper_p.h b/src/datavisualization/utils/texturehelper_p.h index ebfaa042..aec137a4 100644 --- a/src/datavisualization/utils/texturehelper_p.h +++ b/src/datavisualization/utils/texturehelper_p.h @@ -30,7 +30,6 @@ #define TEXTUREHELPER_P_H #include "datavisualizationglobal_p.h" -#include <QtGui/QOpenGLFunctions> #include <QtGui/QRgb> #include <QtGui/QLinearGradient> @@ -56,7 +55,7 @@ class TextureHelper : protected QOpenGLFunctions GLuint createDepthTextureFrameBuffer(const QSize &size, GLuint &frameBuffer, GLuint textureSize); void fillDepthTexture(GLuint texture, const QSize &size, GLuint textureSize, GLfloat value); #endif - void deleteTexture(const GLuint *texture); + void deleteTexture(GLuint *texture); private: QImage convertToGLFormat(const QImage &srcImage); diff --git a/src/datavisualization/utils/utils.cpp b/src/datavisualization/utils/utils.cpp index e0b1370e..5852bf11 100644 --- a/src/datavisualization/utils/utils.cpp +++ b/src/datavisualization/utils/utils.cpp @@ -18,12 +18,7 @@ #include "utils_p.h" -#include <QtGui/QColor> #include <QtGui/QPainter> -#include <QtCore/QPoint> -#include <QtGui/QImage> -#include <QtCore/QRegExp> -#include <QtCore/qmath.h> QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -38,14 +33,21 @@ GLuint Utils::getNearestPowerOfTwo(GLuint value, GLuint &padding) return powOfTwoValue; } -QVector3D Utils::vectorFromColor(const QColor &color) +QVector4D Utils::vectorFromColor(const QColor &color) { - return QVector3D(color.redF(), color.greenF(), color.blueF()); + return QVector4D(color.redF(), color.greenF(), color.blueF(), color.alphaF()); } QColor Utils::colorFromVector(const QVector3D &colorVector) { - return QColor(colorVector.x() * 255.0f, colorVector.y() * 255.0f, colorVector.z() * 255.0f); + return QColor(colorVector.x() * 255.0f, colorVector.y() * 255.0f, + colorVector.z() * 255.0f, 255.0f); +} + +QColor Utils::colorFromVector(const QVector4D &colorVector) +{ + return QColor(colorVector.x() * 255.0f, colorVector.y() * 255.0f, + colorVector.z() * 255.0f, colorVector.w() * 255.0f); } QImage Utils::printTextToImage(const QFont &font, const QString &text, const QColor &bgrColor, @@ -126,18 +128,27 @@ QImage Utils::printTextToImage(const QFont &font, const QString &text, const QCo return image; } -QVector3D Utils::getSelection(QPoint mousepos, int height) +QVector4D Utils::getSelection(QPoint mousepos, int height) { // This is the only one that works with OpenGL ES 2.0, so we're forced to use it // Item count will be limited to 256*256*256 - GLubyte pixel[4] = {255, 255, 255, 0}; + GLubyte pixel[4] = {255, 255, 255, 255}; glReadPixels(mousepos.x(), height - mousepos.y(), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void *)pixel); - QVector3D selectedColor(pixel[0], pixel[1], pixel[2]); - + QVector4D selectedColor(pixel[0], pixel[1], pixel[2], pixel[3]); return selectedColor; } +QImage Utils::getGradientImage(const QLinearGradient &gradient) +{ + QImage image(QSize(1, 101), QImage::Format_RGB32); + QPainter pmp(&image); + pmp.setBrush(QBrush(gradient)); + pmp.setPen(Qt::NoPen); + pmp.drawRect(0, 0, 1, 101); + return image; +} + Utils::ParamType Utils::mapFormatCharToParamType(const QChar &formatChar) { ParamType retVal = ParamTypeUnknown; @@ -177,7 +188,7 @@ Utils::ParamType Utils::findFormatParamType(const QString &format) return ParamTypeUnknown; } -QString Utils::formatLabel(const QByteArray &format, ParamType paramType, float value) +QString Utils::formatLabel(const QByteArray &format, ParamType paramType, qreal value) { switch (paramType) { case ParamTypeInt: @@ -218,4 +229,13 @@ float Utils::wrapValue(float value, float min, float max) return value; } +QQuaternion Utils::calculateRotation(const QVector3D &xyzRotations) +{ + QQuaternion rotQuatX = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, xyzRotations.x()); + QQuaternion rotQuatY = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, xyzRotations.y()); + QQuaternion rotQuatZ = QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, xyzRotations.z()); + QQuaternion totalRotation = rotQuatY * rotQuatZ * rotQuatX; + return totalRotation; +} + QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/utils/utils.pri b/src/datavisualization/utils/utils.pri index 8ce8794e..30bfb156 100644 --- a/src/datavisualization/utils/utils.pri +++ b/src/datavisualization/utils/utils.pri @@ -7,7 +7,9 @@ HEADERS += $$PWD/meshloader_p.h \ $$PWD/utils_p.h \ $$PWD/abstractobjecthelper_p.h \ $$PWD/surfaceobject_p.h \ - $$PWD/qutils.h + $$PWD/qutils.h \ + $$PWD/scatterobjectbufferhelper_p.h \ + $$PWD/scatterpointbufferhelper_p.h SOURCES += $$PWD/meshloader.cpp \ $$PWD/vertexindexer.cpp \ @@ -17,4 +19,6 @@ SOURCES += $$PWD/meshloader.cpp \ $$PWD/texturehelper.cpp \ $$PWD/utils.cpp \ $$PWD/abstractobjecthelper.cpp \ - $$PWD/surfaceobject.cpp + $$PWD/surfaceobject.cpp \ + $$PWD/scatterobjectbufferhelper.cpp \ + $$PWD/scatterpointbufferhelper.cpp diff --git a/src/datavisualization/utils/utils_p.h b/src/datavisualization/utils/utils_p.h index 7288419b..d7187c16 100644 --- a/src/datavisualization/utils/utils_p.h +++ b/src/datavisualization/utils/utils_p.h @@ -31,12 +31,7 @@ #include "datavisualizationglobal_p.h" -class QVector3D; -class QColor; -class QPainter; -class QString; -class QPoint; -class QImage; +class QLinearGradient; QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -51,10 +46,9 @@ public: }; static GLuint getNearestPowerOfTwo(GLuint value, GLuint &padding); - static QVector3D vectorFromColor(const QColor &color); + static QVector4D vectorFromColor(const QColor &color); static QColor colorFromVector(const QVector3D &colorVector); - static void printText(QPainter *painter, const QString &text, const QSize &position, - bool absoluteCoords = true, float rotation = 0.0f, float scale = 1.0f); + static QColor colorFromVector(const QVector4D &colorVector); static QImage printTextToImage(const QFont &font, const QString &text, const QColor &bgrColor, @@ -62,13 +56,15 @@ public: bool labelBackground, bool borders = false, int maxLabelWidth = 0); - static QVector3D getSelection(QPoint mousepos, int height); + static QVector4D getSelection(QPoint mousepos, int height); + static QImage getGradientImage(const QLinearGradient &gradient); static ParamType findFormatParamType(const QString &format); - static QString formatLabel(const QByteArray &format, ParamType paramType, float value); + static QString formatLabel(const QByteArray &format, ParamType paramType, qreal value); static QString defaultLabelFormat(); static float wrapValue(float value, float min, float max); + static QQuaternion calculateRotation(const QVector3D &xyzRotations); private: static ParamType mapFormatCharToParamType(const QChar &formatChar); |