summaryrefslogtreecommitdiffstats
path: root/src/datavis3d/utils/surfaceobject.cpp
diff options
context:
space:
mode:
authorMika Salmela <mika.salmela@digia.com>2013-07-15 16:25:54 +0300
committerMika Salmela <mika.salmela@digia.com>2013-07-15 16:26:52 +0300
commit2d4688233fbd551bae8f327215247985cd843958 (patch)
tree58444eb52c0077dbd2454b2eaf9224dc18ec47aa /src/datavis3d/utils/surfaceobject.cpp
parent6bc7fabac51ddac7b95ffd85a1eef748f9d2e592 (diff)
Finally first visible surface.
Change-Id: Ib168cbb8cd636539aee62098b98e6e24a112dab6 Reviewed-by: Mika Salmela <mika.salmela@digia.com>
Diffstat (limited to 'src/datavis3d/utils/surfaceobject.cpp')
-rw-r--r--src/datavis3d/utils/surfaceobject.cpp352
1 files changed, 352 insertions, 0 deletions
diff --git a/src/datavis3d/utils/surfaceobject.cpp b/src/datavis3d/utils/surfaceobject.cpp
new file mode 100644
index 00000000..7a34349e
--- /dev/null
+++ b/src/datavis3d/utils/surfaceobject.cpp
@@ -0,0 +1,352 @@
+/****************************************************************************
+**
+** 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 "surfaceobject_p.h"
+#include "abstractobjecthelper_p.h"
+
+#include <QVector3D>
+#include <QVector2D>
+
+#include <QDebug>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+SurfaceObject::SurfaceObject()
+{
+}
+
+SurfaceObject::~SurfaceObject()
+{
+}
+
+void SurfaceObject::setUpSmoothData(QList<qreal> series, int columns, int rows, GLfloat yRange)
+{
+ GLfloat width = (GLfloat(columns) - 1.0f) / 2.0f;
+ GLfloat depth = (GLfloat(rows) - 1.0f) / -2.0f;
+ GLfloat height = yRange / 2.0f;
+
+ // Create vertice table
+ QVector<QVector3D> vertices;
+ QVector<QVector2D> uvs;
+ for (int i = 0, row = 0; i < rows; i++, row += columns) {
+ for (int j = 0; j < columns; j++) {
+ vertices.append(QVector3D(float(j) / width - 1.0f,
+ series.at(row + j) / height - 1.0f,
+ float(i) / depth + 1.0f));
+ uvs.append(QVector2D(1.0f / float(j), 1.0f / float(i)));
+ }
+ }
+
+ qDebug() << "vertices.count() = " << vertices.count();
+
+ // Create normals
+ QVector<QVector3D> normals;
+ for (int i = 0, row = 0; i < rows - 1; i++, row += columns) {
+ for (int j = 0; j < columns - 1; j++) {
+ normals.append(normal(vertices.at(row + j),
+ vertices.at(row + j + 1),
+ vertices.at(row + columns + j)));
+ }
+ int p = row + columns - 1;
+ normals.append(normal(vertices.at(p),
+ vertices.at(p + columns),
+ vertices.at(p - 1)));
+ }
+ for (int j = (rows - 1) * columns ; j < rows * columns - 1; j++) {
+ normals.append(normal(vertices.at(j),
+ vertices.at(j - columns),
+ vertices.at(j + 1)));
+ }
+ int p = rows * columns - 1;
+ normals.append(normal(vertices.at(p),
+ vertices.at(p - 1),
+ vertices.at(p - columns - 1)));
+
+ // Create indice table
+ m_indexCount = 6 * (columns - 1) * (rows - 1);
+ GLushort *indices = new GLushort[m_indexCount];
+ p = 0;
+ for (int i = 0, row = 0; i < rows - 1; i++, row += columns) {
+ for (int j = 0; j < columns - 1; j++) {
+ // Left triangle
+ indices[p++] = row + j + 1;
+ indices[p++] = row + columns + j;
+ indices[p++] = row + j;
+
+ // Right triangle
+ indices[p++] = row + columns + j + 1;
+ indices[p++] = row + columns + j;
+ indices[p++] = row + j + 1;
+ }
+ }
+
+ // Create line element indices
+ m_gridIndexCount = 2 * columns * (rows - 1) + 2 * rows * (columns - 1);
+ GLushort *gridIndices = new GLushort[m_gridIndexCount];
+ p = 0;
+ for (int i = 0, row = 0; i < rows; i++, row += columns) {
+ for (int j = 0; j < columns - 1; j++) {
+ gridIndices[p++] = row + j;
+ gridIndices[p++] = row + j + 1;
+ }
+ }
+ for (int i = 0, row = 0; i < rows - 1; i++, row += columns) {
+ for (int j = 0; j < columns; j++) {
+ gridIndices[p++] = row + j;
+ gridIndices[p++] = row + j + columns;
+ }
+ }
+// for (int i = columns - 1; i < (rows - 1) * columns; i += columns) {
+// gridIndices[p++] = i;
+// gridIndices[p++] = i + doubleColumns;
+// }
+
+ createBuffers(vertices, uvs, normals, indices, gridIndices);
+
+ delete indices;
+ delete gridIndices;
+}
+
+
+void SurfaceObject::setUpData(QList<qreal> series, int columns, int rows, GLfloat yRange)
+{
+ GLfloat width = (GLfloat(columns) - 1.0f) / 2.0f;
+ GLfloat depth = (GLfloat(rows) - 1.0f) / -2.0f;
+ GLfloat height = yRange / 2.0f;
+
+ // Create vertice table
+ QVector<QVector3D> vertices;
+ QVector<QVector2D> uvs;
+ for (int i = 0, row = 0; i < rows; i++, row += columns) {
+ for (int j = 0; j < columns; j++) {
+ vertices.append(QVector3D(float(j) / width - 1.0f,
+ series.at(row + j) / height - 1.0f,
+ float(i) / depth + 1.0f));
+ uvs.append(QVector2D(1.0f / float(j), 1.0f / float(i)));
+ if (j > 0 && j < columns - 1) {
+ vertices.append(vertices.last());
+ uvs.append(QVector2D(1.0f / float(j), 1.0f / float(i)));
+ }
+ }
+ }
+
+ // Create normals
+ QVector<QVector3D> normals;
+ int doubleColumns = columns * 2 - 2;
+ for (int i = 0, row = 0; i < rows - 1; i++, row += doubleColumns) {
+ for (int j = 0; j < columns * 2 - 2; j += 2) {
+ normals.append(normal(vertices.at(row + j),
+ vertices.at(row + j + 1),
+ vertices.at(row + doubleColumns + j)));
+ normals.append(normal(vertices.at(row + j + 1),
+ vertices.at(row + doubleColumns + j + 1),
+ vertices.at(row + doubleColumns + j)));
+ }
+ }
+ for (int j = (rows - 2) * doubleColumns ; j < (rows - 1) * doubleColumns; j++)
+ normals.append(normals.at(j));
+
+ // Create indice table
+ m_indexCount = 6 * (columns - 1) * (rows - 1);
+ GLushort *indices = new GLushort[6 * (columns - 1) * (rows - 1)];
+ int indWidth = columns - 1;
+ for (int i = 0, row = 0; i < rows - 1; i++, row += doubleColumns) {
+ for (int j = 0, jj = 0; j < columns - 1; j++, jj += 2) {
+ int p = (i * indWidth + j) * 2 * 3;
+ // Left triangle
+ indices[p + 0] = row + jj + 1;
+ indices[p + 1] = (i + 1) * doubleColumns + jj;
+ indices[p + 2] = row + jj;
+
+ // Right triangle
+ indices[p + 3] = (i + 1) * doubleColumns + (jj + 1);
+ indices[p + 4] = (i + 1) * doubleColumns + jj;
+ indices[p + 5] = row + jj + 1;
+ }
+ }
+
+ // Create line element indices
+ m_gridIndexCount = 2 * columns * (rows - 1) + 2 * rows * (columns - 1);
+ GLushort *gridIndices = new GLushort[m_gridIndexCount];
+ int p = 0;
+ for (int i = 0, row = 0; i < rows; i++, row += doubleColumns) {
+ for (int j = 0, jj = 0; j < columns - 1; j++, jj += 2) {
+ gridIndices[p++] = row + jj;
+ gridIndices[p++] = row + jj + 1;
+ }
+ }
+ for (int i = 0, row = 0; i < rows - 1; i++, row += doubleColumns) {
+ for (int j = 0, jj = 0; j < columns - 1; j++, jj += 2) {
+ gridIndices[p++] = row + jj;
+ gridIndices[p++] = row + jj + doubleColumns;
+ }
+ }
+ for (int i = doubleColumns - 1; i < (rows - 1) * doubleColumns; i += doubleColumns) {
+ gridIndices[p++] = i;
+ gridIndices[p++] = i + doubleColumns;
+ }
+
+ createBuffers(vertices, uvs, normals, indices, gridIndices);
+
+ delete indices;
+ delete gridIndices;
+}
+
+
+void SurfaceObject::createBuffers(const QVector<QVector3D> &vertices, const QVector<QVector2D> &uvs,
+ const QVector<QVector3D> &normals, const GLushort *indices,
+ const GLushort *gridIndices)
+{
+ initializeOpenGLFunctions();
+ if (m_meshDataLoaded) {
+ // Delete old data
+ glDeleteBuffers(1, &m_vertexbuffer);
+ glDeleteBuffers(1, &m_uvbuffer);
+ glDeleteBuffers(1, &m_normalbuffer);
+ glDeleteBuffers(1, &m_elementbuffer);
+ }
+
+ // Move to buffers
+ glGenBuffers(1, &m_vertexbuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, m_vertexbuffer);
+ glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(QVector3D),
+ &vertices.at(0), GL_STATIC_DRAW);
+
+ glGenBuffers(1, &m_normalbuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, m_normalbuffer);
+ glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(QVector3D),
+ &normals.at(0), GL_STATIC_DRAW);
+
+ glGenBuffers(1, &m_uvbuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, m_uvbuffer);
+ glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(QVector2D),
+ &uvs.at(0), GL_STATIC_DRAW);
+
+ glGenBuffers(1, &m_elementbuffer);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementbuffer);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indexCount * sizeof(GLushort),
+ indices, GL_STATIC_DRAW);
+
+ glGenBuffers(1, &m_gridElementbuffer);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_gridElementbuffer);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_gridIndexCount * sizeof(GLushort),
+ gridIndices, GL_STATIC_DRAW);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+ // We're done. Set the flag ON
+ m_meshDataLoaded = true;
+}
+
+GLuint SurfaceObject::gridElementBuf()
+{
+ if (!m_meshDataLoaded)
+ qFatal("No loaded object");
+ return m_gridElementbuffer;
+}
+
+GLuint SurfaceObject::gridIndexCount()
+{
+ return m_gridIndexCount;
+}
+
+QVector3D SurfaceObject::normal(const QVector3D &a, const QVector3D &b, const QVector3D &c)
+{
+ QVector3D v1 = b - a;
+ QVector3D v2 = c - a;
+ return QVector3D::crossProduct(v1, v2);
+}
+
+QT_DATAVIS3D_END_NAMESPACE
+
+
+
+// For rainy days
+
+// QVector3D vertices[] = {
+// QVector3D(-0.5f, 0.0f, 0.1f),
+// QVector3D(0.5f, 0.0f, 0.1f),
+// QVector3D(0.0f, 1.0f, -0.5f)
+// };
+
+// QVector3D normals[] = {
+// QVector3D(0.5, 0.0, 1.0),
+// QVector3D(0.5, 0.0, 1.0),
+// QVector3D(0.5, 0.0, 1.0)
+// };
+
+// vertices.append(QVector3D(-1.0f, 0.0f, 0.1f));
+// vertices.append(QVector3D(0.0f, 0.0f, 0.1f));
+// vertices.append(QVector3D(0.0f, 0.5f, -0.5f));
+
+// normals.append(QVector3D(0.5, 0.0, 1.0));
+// normals.append(QVector3D(0.5, 0.0, 1.0));
+// normals.append(QVector3D(0.5, 0.0, 1.0));
+
+//GLushort indices[] = {0, 1, 2, 1, 3, 2};
+//GLushort indices[] = {1, 3, 2};
+
+//qDebug() << indices[p + 0] << ", " << indices[p + 1] << ", " << indices[p + 2];
+//qDebug() << indices[p + 3] << ", " << indices[p + 4] << ", " << indices[p + 5];
+
+//qDebug() << "(" << float(j) / width << ", 0.0, " << float(i) / depth * -1.0f << ")";
+
+//normals.append(QVector3D(1,0,0));
+//normals.append(QVector3D(0,1,0));
+//normals.append(QVector3D(0,0,1));
+//normals.append(QVector3D(1,0,1));
+
+//normals.append(QVector3D(1,0,0));
+//normals.append(QVector3D(0,1,0));
+//normals.append(QVector3D(0,0,1));
+//normals.append(QVector3D(1,0,1));
+
+//normals.append(QVector3D(1,0,0));
+//normals.append(QVector3D(0,1,0));
+//normals.append(QVector3D(0,0,1));
+//normals.append(QVector3D(1,0,1));
+
+
+//qDebug() << "Left normal from (" << row + j << ", " << row + j + 1 << ", " << row + doubleColumns + j << ")";
+
+//qDebug() << "right normal from (" << row + j +1 << ", " << row + doubleColumns + j + 1 << ", " << row + doubleColumns + j << ")";
+