summaryrefslogtreecommitdiffstats
path: root/src/datavis3d/engine/q3dbars.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/datavis3d/engine/q3dbars.cpp')
-rw-r--r--src/datavis3d/engine/q3dbars.cpp625
1 files changed, 625 insertions, 0 deletions
diff --git a/src/datavis3d/engine/q3dbars.cpp b/src/datavis3d/engine/q3dbars.cpp
new file mode 100644
index 00000000..36ca1b0a
--- /dev/null
+++ b/src/datavis3d/engine/q3dbars.cpp
@@ -0,0 +1,625 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "q3dbars.h"
+#include "q3dbars_p.h"
+#include "meshloader_p.h"
+#include "vertexindexer_p.h"
+#include "camerahelper_p.h"
+
+#include <QMatrix4x4>
+#include <QOpenGLShaderProgram>
+#include <QScreen>
+#include <QMouseEvent>
+
+//#include <qmath.h>
+
+#include <QDebug>
+
+QTCOMMERCIALDATAVIS3D_BEGIN_NAMESPACE
+
+const float maxSceneSize = 40.0;
+
+Q3DBars::Q3DBars()
+ : d_ptr(new Q3DBarsPrivate(this))
+{
+}
+
+Q3DBars::~Q3DBars()
+{
+ glDeleteBuffers(1, &d_ptr->m_vertexbuffer);
+ glDeleteBuffers(1, &d_ptr->m_uvbuffer);
+ glDeleteBuffers(1, &d_ptr->m_normalbuffer);
+ glDeleteBuffers(1, &d_ptr->m_elementbuffer);
+ glDeleteBuffers(1, &d_ptr->m_vertexbufferBackground);
+ glDeleteBuffers(1, &d_ptr->m_uvbufferBackground);
+ glDeleteBuffers(1, &d_ptr->m_normalbufferBackground);
+ glDeleteBuffers(1, &d_ptr->m_elementbufferBackground);
+}
+
+void Q3DBars::initialize()
+{
+ // Initialize shaders
+ d_ptr->initShaders(QStringLiteral(":/shaders/vertex"), QStringLiteral(":/shaders/fragment"));
+
+ // Load default mesh
+ d_ptr->loadBarMesh();
+
+ // Load background mesh
+ d_ptr->loadBackgroundMesh();
+
+ // Set clear color
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+
+ // Set OpenGL features
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LESS);
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+ //glFrontFace(GL_CCW);
+
+ // Set initial camera position
+ // X must be 0 for rotation to work - we can use "setCameraRotation" for setting it later
+ CameraHelper::setDefaultCameraOrientation(QVector3D(0.0f, 0.0f, 6.0f)
+ , QVector3D(0.0f, 0.0f, 0.0f)
+ , QVector3D(0.0f, 1.0f, 0.0f));
+
+ CameraHelper::setCameraRotation(QPointF(-45.0f, 15.0f));
+
+ // Set view port
+ glViewport(0, 0, width(), height());
+}
+
+void Q3DBars::render()
+{
+ int startBar = 0;
+ int stopBar = 0;
+ int stepBar = 0;
+
+ int startRow = 0;
+ int stopRow = 0;
+ int stepRow = 0;
+
+ float barPos = 0;
+ float rowPos = 0;
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ d_ptr->m_program->bind();
+
+ QMatrix4x4 projectionMatrix;
+ projectionMatrix.perspective(45.0f, (float)width() / (float)height(), 0.1f, 100.0f);
+
+ QMatrix4x4 viewMatrix = CameraHelper::calculateViewMatrix(d_ptr->m_mousePos, d_ptr->m_zoomLevel
+ , width(), height());
+
+ // Calculate drawing order
+ //qDebug() << "viewMatrix" << viewMatrix.row(0).z(); // jos negatiivinen, käännä bar -piirtojärjestys
+ //qDebug() << "viewMatrix" << viewMatrix.row(0).x(); // jos negatiivinen, käännä row -piirtojärjestys
+ // TODO: Needs more tuning unless we get depth test working correctly
+ if (viewMatrix.row(0).x() < 0) {
+ startRow = 0;
+ stopRow = d_ptr->m_sampleCount.y();
+ stepRow = 1;
+ }
+ else {
+ startRow = d_ptr->m_sampleCount.y() - 1;
+ stopRow = -1;
+ stepRow = -1;
+ }
+ if (viewMatrix.row(0).z() > 0) {
+ startBar = 0;
+ stopBar = d_ptr->m_sampleCount.x();
+ stepBar = 1;
+ }
+ else {
+ startBar = d_ptr->m_sampleCount.x() - 1;
+ stopBar = -1;
+ stepBar = -1;
+ }
+
+ //qDebug() << "projectionMatrix" << projectionMatrix;
+ QVector3D lightPos = QVector3D(0.0f, 1.5f
+ , (d_ptr->m_sampleCount.y() / 5.0f));
+
+ // Draw background
+ if (d_ptr->m_background) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ modelMatrix.scale(QVector3D(d_ptr->m_rowWidth * d_ptr->m_sceneScale
+ , 1.0f
+ , d_ptr->m_columnDepth * d_ptr->m_sceneScale));
+ modelMatrix.rotate(-90.0f, 0.0f, 1.0f, 0.0f);
+
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+
+ //qDebug() << "modelMatrix" << modelMatrix;
+ //qDebug() << "MVPMatrix" << MVPMatrix;
+
+ QVector3D barColor = QVector3D(0.5, 0.5, 0.5);
+
+ d_ptr->m_program->setUniformValue(d_ptr->m_lightPositionUniform, lightPos);
+ d_ptr->m_program->setUniformValue(d_ptr->m_viewMatrixUniform, viewMatrix);
+ d_ptr->m_program->setUniformValue(d_ptr->m_modelMatrixUniform, modelMatrix);
+ d_ptr->m_program->setUniformValue(d_ptr->m_invTransModelMatrixUniform
+ , modelMatrix.inverted().transposed());
+ d_ptr->m_program->setUniformValue(d_ptr->m_mvpMatrixUniform, MVPMatrix);
+ d_ptr->m_program->setUniformValue(d_ptr->m_colorUniform, barColor);
+ d_ptr->m_program->setUniformValue(d_ptr->m_lightStrengthUniform, 4.0f);
+
+ // 1st attribute buffer : vertices
+ glEnableVertexAttribArray(0);
+ glBindBuffer(GL_ARRAY_BUFFER, d_ptr->m_vertexbufferBackground);
+ glVertexAttribPointer(d_ptr->m_positionAttr, 3, GL_FLOAT, GL_TRUE, 0, (void*)0);
+
+ // 2nd attribute buffer : normals
+ glEnableVertexAttribArray(1);
+ glBindBuffer(GL_ARRAY_BUFFER, d_ptr->m_normalbufferBackground);
+ glVertexAttribPointer(d_ptr->m_normalAttr, 3, GL_FLOAT, GL_TRUE, 0, (void*)0);
+
+ // 3rd attribute buffer : UVs
+ //glEnableVertexAttribArray(2);
+ //glBindBuffer(GL_ARRAY_BUFFER, d_ptr->m_uvbufferBackground);
+ //glVertexAttribPointer(d_ptr->m_uvAttr, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
+
+ // Index buffer
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, d_ptr->m_elementbufferBackground);
+
+ // Draw the triangles
+ glDrawElements(GL_TRIANGLES, d_ptr->m_indexCountBackground, GL_UNSIGNED_SHORT, (void*)0);
+
+ glDisableVertexAttribArray(0);
+ glDisableVertexAttribArray(1);
+ //glDisableVertexAttribArray(2);
+ }
+
+ // Draw bars
+ for (int row = startRow; row != stopRow; row += stepRow) {
+ for (int bar = startBar; bar != stopBar; bar += stepBar) {
+ float barHeight = d_ptr->m_dataSet.at(row).at(bar);
+ //qDebug() << "barHeight" << barHeight;
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ barPos = (bar + 1) * (d_ptr->m_barSpacing.x());
+ //qDebug() << "x" << d_ptr->m_rowWidth << "-" << barPos << "=" << d_ptr->m_rowWidth - barPos;
+ rowPos = (row + 1) * (d_ptr->m_barSpacing.y());
+ //qDebug() << "z" << rowPos << "-" << d_ptr->m_columnDepth << "=" << rowPos - d_ptr->m_columnDepth;
+ modelMatrix.translate((d_ptr->m_rowWidth - barPos) / d_ptr->m_scaleFactorX
+ , barHeight - 1.0f
+ , (d_ptr->m_columnDepth - rowPos) / d_ptr->m_scaleFactorZ);
+ modelMatrix.scale(QVector3D(d_ptr->m_scaleX, barHeight, d_ptr->m_scaleZ));
+
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+
+ //qDebug() << "modelMatrix" << modelMatrix;
+ //qDebug() << "MVPMatrix" << MVPMatrix;
+
+ QVector3D barColor = QVector3D(float(row) / float(d_ptr->m_sampleCount.y())
+ , 0
+ , barHeight);
+ //QVector3D barColor = QVector3D(0.1, 0.1, 0.5);
+
+ d_ptr->m_program->setUniformValue(d_ptr->m_lightPositionUniform, lightPos);
+ d_ptr->m_program->setUniformValue(d_ptr->m_viewMatrixUniform, viewMatrix);
+ d_ptr->m_program->setUniformValue(d_ptr->m_modelMatrixUniform, modelMatrix);
+ d_ptr->m_program->setUniformValue(d_ptr->m_invTransModelMatrixUniform
+ , modelMatrix.inverted().transposed());
+ d_ptr->m_program->setUniformValue(d_ptr->m_mvpMatrixUniform, MVPMatrix);
+ d_ptr->m_program->setUniformValue(d_ptr->m_colorUniform, barColor);
+ d_ptr->m_program->setUniformValue(d_ptr->m_lightStrengthUniform, 4.0f);
+ //qDebug() << "height:" << barHeight;
+
+ // 1st attribute buffer : vertices
+ glEnableVertexAttribArray(0);
+ glBindBuffer(GL_ARRAY_BUFFER, d_ptr->m_vertexbuffer);
+ glVertexAttribPointer(d_ptr->m_positionAttr, 3, GL_FLOAT, GL_TRUE, 0, (void*)0);
+
+ // 2nd attribute buffer : normals
+ glEnableVertexAttribArray(1);
+ glBindBuffer(GL_ARRAY_BUFFER, d_ptr->m_normalbuffer);
+ glVertexAttribPointer(d_ptr->m_normalAttr, 3, GL_FLOAT, GL_TRUE, 0, (void*)0);
+
+ // 3rd attribute buffer : UVs
+ //glEnableVertexAttribArray(2);
+ //glBindBuffer(GL_ARRAY_BUFFER, d_ptr->m_uvbuffer);
+ //glVertexAttribPointer(d_ptr->m_uvAttr, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
+
+ // Index buffer
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, d_ptr->m_elementbuffer);
+
+ // Draw the triangles
+ glDrawElements(GL_TRIANGLES, d_ptr->m_indexCount, GL_UNSIGNED_SHORT, (void*)0);
+
+ glDisableVertexAttribArray(0);
+ glDisableVertexAttribArray(1);
+ //glDisableVertexAttribArray(2);
+ }
+ }
+
+ d_ptr->m_program->release();
+}
+
+void Q3DBars::mousePressEvent(QMouseEvent *event)
+{
+ // TODO: for testing shaders
+ static bool shaderOne = true;
+ //qDebug() << "mouse button pressed" << event->button();
+ if (Qt::LeftButton == event->button()) {
+ d_ptr->m_mousePressed = true;
+ // update mouse positions to prevent jumping when releasing or repressing a button
+ d_ptr->m_mousePos = event->pos();
+ }
+ else if (Qt::RightButton == event->button()) {
+ // reset rotations
+ d_ptr->m_mousePos = QPoint(0, 0);
+ }
+ else if (Qt::MiddleButton == event->button()) {
+ // TODO: testing shaders
+ if (shaderOne) {
+ shaderOne = false;
+ d_ptr->initShaders(QStringLiteral(":/shaders/vertex")
+ , QStringLiteral(":/shaders/fragmentAmbient"));
+ }
+ else {
+ shaderOne = true;
+ d_ptr->initShaders(QStringLiteral(":/shaders/vertex")
+ , QStringLiteral(":/shaders/fragment"));
+ }
+ }
+ CameraHelper::updateMousePos(d_ptr->m_mousePos);
+}
+
+void Q3DBars::mouseReleaseEvent(QMouseEvent *event)
+{
+ //qDebug() << "mouse button released" << event->button();
+ d_ptr->m_mousePressed = false;
+ // update mouse positions to prevent jumping when releasing or repressing a button
+ d_ptr->m_mousePos = event->pos();
+ CameraHelper::updateMousePos(event->pos());
+}
+
+void Q3DBars::mouseMoveEvent(QMouseEvent *event)
+{
+ if (d_ptr->m_mousePressed) {
+ //qDebug() << "mouse moved while pressed" << event->pos();
+ d_ptr->m_mousePos = event->pos();
+ }
+}
+
+void Q3DBars::wheelEvent(QWheelEvent *event)
+{
+ if (d_ptr->m_zoomLevel > 100) {
+ d_ptr->m_zoomLevel += event->angleDelta().y() / 12;
+ }
+ else if (d_ptr->m_zoomLevel > 50) {
+ d_ptr->m_zoomLevel += event->angleDelta().y() / 60;
+ }
+ else {
+ d_ptr->m_zoomLevel += event->angleDelta().y() / 120;
+ }
+ if (d_ptr->m_zoomLevel > 500) {
+ d_ptr->m_zoomLevel = 500;
+ }
+ else if (d_ptr->m_zoomLevel < 10) {
+ d_ptr->m_zoomLevel = 10;
+ }
+
+}
+
+void Q3DBars::resizeEvent(QResizeEvent *event)
+{
+ Q_UNUSED(event);
+
+ // Set view port
+ glViewport(0, 0, width(), height());
+
+ // If orientation changes, we need to scale again
+ // TODO: Handle it
+}
+
+void Q3DBars::addDataSet(QVector<float> data)
+{
+ // Check that the input data fits into sample space, and resize if it doesn't
+ if (data.size() > d_ptr->m_sampleCount.x()) {
+ data.resize(d_ptr->m_sampleCount.x());
+ qWarning("Data set too large for sample space");
+ }
+ // The vector contains data (=height) for each bar, a row at a time
+ // With each new row, the previous data set (=row) must be moved back
+ // ie. we need as many vectors as we have rows in the sample space
+ d_ptr->m_dataSet.prepend(data);
+ // if the added data pushed us over sample space, remove the oldest data set
+ if (d_ptr->m_dataSet.size() > d_ptr->m_sampleCount.y())
+ d_ptr->m_dataSet.resize(d_ptr->m_sampleCount.y());
+}
+
+void Q3DBars::setBarSpecs(QPointF thickness, QPointF spacing, bool relative)
+{
+ d_ptr->m_barThickness = thickness;
+ if (relative) {
+ d_ptr->m_barSpacing.setX((thickness.x() * 2) * (spacing.x() + 1.0f));
+ d_ptr->m_barSpacing.setY((thickness.y() * 2) * (spacing.y() + 1.0f));
+ }
+ else {
+ d_ptr->m_barSpacing = thickness * 2 + spacing * 2;
+ }
+ // Calculate here and at setting sample space
+ d_ptr->calculateSceneScalingFactors();
+}
+
+void Q3DBars::setBarType(BarStyle style, bool smooth)
+{
+ if (style == Bars) {
+ if (smooth) {
+ d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/barSmooth");
+ }
+ else {
+ d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/bar");
+ }
+ }
+ else if (style == Pyramids) {
+ if (smooth) {
+ d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/pyramidSmooth");
+ }
+ else {
+ d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/pyramid");
+ }
+ }
+ else if (style == Cones) {
+ if (smooth) {
+ d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/coneSmooth");
+ }
+ else {
+ d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/cone");
+ }
+ }
+ else if (style == Cylinders) {
+ if (smooth) {
+ d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/cylinderSmooth");
+ }
+ else {
+ d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/cylinder");
+ }
+ }
+ else if (style == Apes) {
+ if (smooth) {
+ d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/apeSmooth");
+ }
+ else {
+ d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/ape");
+ }
+ }
+ // Reload mesh data
+ d_ptr->loadBarMesh();
+}
+
+void Q3DBars::setMeshFileName(const QString &objFileName)
+{
+ d_ptr->m_objFile = objFileName;
+}
+
+void Q3DBars::setupSampleSpace(QPoint sampleCount)
+{
+ d_ptr->m_sampleCount = sampleCount;
+ // Initialize data set
+ QVector<float> row;
+ for (int columns = 0; columns < sampleCount.x(); columns ++) {
+ row.append(0.0f);
+ }
+ for (int rows = 0; rows < sampleCount.y(); rows++) {
+ d_ptr->m_dataSet.append(row);
+ }
+ // Calculate here and at setting bar specs
+ d_ptr->calculateSceneScalingFactors();
+}
+
+Q3DBarsPrivate::Q3DBarsPrivate(Q3DBars *q)
+ : q_ptr(q)
+ , m_program(0)
+ , m_sampleCount(QPoint(0, 0))
+ , m_objFile(QStringLiteral(":/defaultMeshes/bar"))
+ , m_vertexCount(0)
+ , m_indexCount(0)
+ , m_indexCountBackground(0)
+ , m_mousePressed(false)
+ , m_mousePos(QPoint(0, 0))
+ , m_zoomLevel(100)
+ , m_barThickness(QPointF(0.75f, 0.75f))
+ , m_barSpacing(m_barThickness * 3.0f)
+ , m_meshDataLoaded(false)
+ , m_background(false)
+ , m_dataSet(0)
+ , m_rowWidth(0)
+ , m_columnDepth(0)
+ , m_maxDimension(0)
+ , m_scaleX(0)
+ , m_scaleZ(0)
+ , m_scaleFactorX(0)
+ , m_scaleFactorZ(0)
+ , m_sceneScale(0)
+{
+}
+
+Q3DBarsPrivate::~Q3DBarsPrivate()
+{
+}
+
+void Q3DBarsPrivate::loadBarMesh()
+{
+ if (m_meshDataLoaded) {
+ // Delete old data
+ glDeleteBuffers(1, &m_vertexbuffer);
+ glDeleteBuffers(1, &m_uvbuffer);
+ glDeleteBuffers(1, &m_normalbuffer);
+ glDeleteBuffers(1, &m_elementbuffer);
+ }
+ QVector<QVector3D> vertices;
+ QVector<QVector2D> uvs;
+ QVector<QVector3D> normals;
+ bool loadOk = MeshLoader::loadOBJ(m_objFile, vertices, uvs, normals);
+ if (!loadOk)
+ qFatal("loading failed");
+
+ m_vertexCount = vertices.size();
+ qDebug() << "vertex count" << m_vertexCount;
+
+ // 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);
+
+ m_indexCount = indices.size();
+ //qDebug() << "index count" << m_indexCount;
+
+ glGenBuffers(1, &m_vertexbuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, m_vertexbuffer);
+ glBufferData(GL_ARRAY_BUFFER, indexed_vertices.size() * sizeof(QVector3D)
+ , &indexed_vertices.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)
+ , 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);
+
+ 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);
+
+ m_meshDataLoaded = true;
+}
+
+void Q3DBarsPrivate::loadBackgroundMesh()
+{
+ QVector<QVector3D> vertices;
+ QVector<QVector2D> uvs;
+ QVector<QVector3D> normals;
+ bool loadOk = MeshLoader::loadOBJ(QStringLiteral(":/defaultMeshes/background")
+ , vertices, uvs, normals);
+ if (!loadOk)
+ 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);
+
+ m_indexCountBackground = indices.size();
+
+ glGenBuffers(1, &m_vertexbufferBackground);
+ glBindBuffer(GL_ARRAY_BUFFER, m_vertexbufferBackground);
+ glBufferData(GL_ARRAY_BUFFER, indexed_vertices.size() * sizeof(QVector3D)
+ , &indexed_vertices.at(0)
+ , GL_STATIC_DRAW);
+
+ glGenBuffers(1, &m_normalbufferBackground);
+ glBindBuffer(GL_ARRAY_BUFFER, m_normalbufferBackground);
+ glBufferData(GL_ARRAY_BUFFER, indexed_normals.size() * sizeof(QVector3D)
+ , &indexed_normals.at(0)
+ , GL_STATIC_DRAW);
+
+ //glGenBuffers(1, &m_uvbufferBackground);
+ //glBindBuffer(GL_ARRAY_BUFFER, m_uvbufferBackground);
+ //glBufferData(GL_ARRAY_BUFFER, indexed_uvs.size() * sizeof(QVector2D), &indexed_uvs.at(0)
+ // , GL_STATIC_DRAW);
+
+ glGenBuffers(1, &m_elementbufferBackground);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementbufferBackground);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned short), &indices.at(0)
+ , GL_STATIC_DRAW);
+
+ m_background = true;
+}
+
+void Q3DBarsPrivate::initShaders(QString vertexShader, QString fragmentShader)
+{
+ if (m_program)
+ delete m_program;
+ m_program = new QOpenGLShaderProgram(q_ptr);
+ if (!m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, vertexShader))
+ qFatal("Compiling Vertex shader failed");
+ if (!m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, fragmentShader))
+ qFatal("Compiling Fragment shader failed");
+ m_program->link();
+ m_mvpMatrixUniform = m_program->uniformLocation("MVP");
+ m_viewMatrixUniform = m_program->uniformLocation("V");
+ m_modelMatrixUniform = m_program->uniformLocation("M");
+ m_invTransModelMatrixUniform = m_program->uniformLocation("itM");
+ m_positionAttr = m_program->attributeLocation("vertexPosition_mdl");
+ m_uvAttr = m_program->attributeLocation("vertexUV");
+ m_normalAttr = m_program->attributeLocation("vertexNormal_mdl");
+ m_lightPositionUniform = m_program->uniformLocation("lightPosition_wrld");
+ m_colorUniform = m_program->uniformLocation("color_mdl");
+ m_lightStrengthUniform = m_program->uniformLocation("lightStrength");
+}
+
+void Q3DBarsPrivate::calculateSceneScalingFactors()
+{
+ // Calculate scene scaling and translation factors
+ m_rowWidth = ((m_sampleCount.x() + 1) * m_barSpacing.x()) / 2.0f;
+ m_columnDepth = ((m_sampleCount.y() + 1) * m_barSpacing.y()) / 2.0f;
+ m_maxDimension = (m_rowWidth > m_columnDepth) ? m_rowWidth : m_columnDepth;
+ m_scaleX = m_barThickness.x() / m_sampleCount.x() * (maxSceneSize / m_maxDimension);
+ m_scaleZ = m_barThickness.y() / m_sampleCount.x() * (maxSceneSize / m_maxDimension);
+ m_sceneScale = (m_scaleX < m_scaleZ) ? m_scaleX : m_scaleZ;
+ float minThickness = (m_barThickness.x() < m_barThickness.y()) ? m_barThickness.x() : m_barThickness.y();
+ m_sceneScale = m_sceneScale / minThickness;
+ m_scaleFactorX = m_sampleCount.x() * (m_maxDimension / maxSceneSize);
+ m_scaleFactorZ = m_sampleCount.x() * (m_maxDimension / maxSceneSize);
+ qDebug() << "m_scaleX" << m_scaleX << "m_scaleFactorX" << m_scaleFactorX;
+ qDebug() << "m_scaleZ" << m_scaleZ << "m_scaleFactorZ" << m_scaleFactorZ;
+ qDebug() << "m_rowWidth:" << m_rowWidth << "m_columnDepth:" << m_columnDepth << "m_maxDimension:" << m_maxDimension;
+ qDebug() << m_rowWidth * m_sceneScale << m_columnDepth * m_sceneScale;
+}
+
+QTCOMMERCIALDATAVIS3D_END_NAMESPACE