diff options
Diffstat (limited to 'src/datavis3d/engine/q3dbars.cpp')
-rw-r--r-- | src/datavis3d/engine/q3dbars.cpp | 625 |
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 |