diff options
author | Mika Salmela <mika.salmela@digia.com> | 2013-07-15 16:25:54 +0300 |
---|---|---|
committer | Mika Salmela <mika.salmela@digia.com> | 2013-07-15 16:26:52 +0300 |
commit | 2d4688233fbd551bae8f327215247985cd843958 (patch) | |
tree | 58444eb52c0077dbd2454b2eaf9224dc18ec47aa /src/datavis3d/utils/surfaceobject.cpp | |
parent | 6bc7fabac51ddac7b95ffd85a1eef748f9d2e592 (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.cpp | 352 |
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 << ")"; + |