/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Data Visualization module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL$
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "abstract3drenderer_p.h"
#include "texturehelper_p.h"
#include "q3dcamera_p.h"
#include "q3dtheme_p.h"
#include "qvalue3daxisformatter_p.h"
#include "shaderhelper_p.h"
#include "qcustom3ditem_p.h"
#include "qcustom3dlabel_p.h"
#include "qcustom3dvolume_p.h"
#include "scatter3drenderer_p.h"

#include <QtCore/qmath.h>
#include <QtGui/QOffscreenSurface>
#include <QtCore/QThread>

QT_BEGIN_NAMESPACE_DATAVISUALIZATION

// Defined in shaderhelper.cpp
extern void discardDebugMsgs(QtMsgType type, const QMessageLogContext &context, const QString &msg);

const qreal doublePi(M_PI * 2.0);
const int polarGridRoundness(64);
const qreal polarGridAngle(doublePi / qreal(polarGridRoundness));
const float polarGridAngleDegrees(float(360.0 / qreal(polarGridRoundness)));
const qreal polarGridHalfAngle(polarGridAngle / 2.0);

Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller)
    : QObject(0),
      m_hasNegativeValues(false),
      m_cachedTheme(new Q3DTheme()),
      m_drawer(new Drawer(m_cachedTheme)),
      m_cachedShadowQuality(QAbstract3DGraph::ShadowQualityMedium),
      m_autoScaleAdjustment(1.0f),
      m_cachedSelectionMode(QAbstract3DGraph::SelectionNone),
      m_cachedOptimizationHint(QAbstract3DGraph::OptimizationDefault),
      m_textureHelper(0),
      m_depthTexture(0),
      m_cachedScene(new Q3DScene()),
      m_selectionDirty(true),
      m_selectionState(SelectNone),
      m_devicePixelRatio(1.0f),
      m_selectionLabelDirty(true),
      m_clickResolved(false),
      m_graphPositionQueryPending(false),
      m_graphPositionQueryResolved(false),
      m_clickedSeries(0),
      m_clickedType(QAbstract3DGraph::ElementNone),
      m_selectedLabelIndex(-1),
      m_selectedCustomItemIndex(-1),
      m_selectionLabelItem(0),
      m_visibleSeriesCount(0),
      m_customItemShader(0),
      m_volumeTextureShader(0),
      m_volumeTextureLowDefShader(0),
      m_volumeTextureSliceShader(0),
      m_volumeSliceFrameShader(0),
      m_labelShader(0),
      m_cursorPositionShader(0),
      m_cursorPositionFrameBuffer(0),
      m_cursorPositionTexture(0),
      m_useOrthoProjection(false),
      m_xFlipped(false),
      m_yFlipped(false),
      m_zFlipped(false),
      m_yFlippedForGrid(false),
      m_backgroundObj(0),
      m_gridLineObj(0),
      m_labelObj(0),
      m_positionMapperObj(0),
      m_graphAspectRatio(2.0f),
      m_graphHorizontalAspectRatio(0.0f),
      m_polarGraph(false),
      m_radialLabelOffset(1.0f),
      m_polarRadius(2.0f),
      m_xRightAngleRotation(QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, 90.0f)),
      m_yRightAngleRotation(QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 90.0f)),
      m_zRightAngleRotation(QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, 90.0f)),
      m_xRightAngleRotationNeg(QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, -90.0f)),
      m_yRightAngleRotationNeg(QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, -90.0f)),
      m_zRightAngleRotationNeg(QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, -90.0f)),
      m_xFlipRotation(QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, -180.0f)),
      m_zFlipRotation(QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, -180.0f)),
      m_requestedMargin(-1.0f),
      m_vBackgroundMargin(0.1f),
      m_hBackgroundMargin(0.1f),
      m_scaleXWithBackground(0.0f),
      m_scaleYWithBackground(0.0f),
      m_scaleZWithBackground(0.0f),
      m_oldCameraTarget(QVector3D(2000.0f, 2000.0f, 2000.0f)), // Just random invalid target
      m_reflectionEnabled(false),
      m_reflectivity(0.5),
#if !defined(QT_OPENGL_ES_2)
      m_funcs_2_1(0),
#endif
      m_context(0),
      m_isOpenGLES(true)

{
    initializeOpenGLFunctions();
    m_isOpenGLES = Utils::isOpenGLES();
#if !defined(QT_OPENGL_ES_2)
    if (!m_isOpenGLES) {
        // Discard warnings about deprecated functions
        QtMessageHandler handler = qInstallMessageHandler(discardDebugMsgs);

        m_funcs_2_1 = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_2_1>();
        if (m_funcs_2_1)
            m_funcs_2_1->initializeOpenGLFunctions();

        // Restore original message handler
        qInstallMessageHandler(handler);

        if (!m_funcs_2_1)
            qFatal("OpenGL version is too low, at least 2.1 is required");
    }
#endif
    QObject::connect(m_drawer, &Drawer::drawerChanged, this, &Abstract3DRenderer::updateTextures);
    QObject::connect(this, &Abstract3DRenderer::needRender, controller,
                     &Abstract3DController::needRender, Qt::QueuedConnection);
    QObject::connect(this, &Abstract3DRenderer::requestShadowQuality, controller,
                     &Abstract3DController::handleRequestShadowQuality, Qt::QueuedConnection);
}

Abstract3DRenderer::~Abstract3DRenderer()
{
    contextCleanup();
    delete m_drawer;
    delete m_cachedScene;
    delete m_cachedTheme;
    delete m_selectionLabelItem;
    delete m_customItemShader;
    delete m_volumeTextureShader;
    delete m_volumeTextureLowDefShader;
    delete m_volumeSliceFrameShader;
    delete m_volumeTextureSliceShader;
    delete m_labelShader;
    delete m_cursorPositionShader;

    foreach (SeriesRenderCache *cache, m_renderCacheList) {
        cache->cleanup(m_textureHelper);
        delete cache;
    }
    m_renderCacheList.clear();

    foreach (CustomRenderItem *item, m_customRenderCache) {
        GLuint texture = item->texture();
        m_textureHelper->deleteTexture(&texture);
        delete item;
    }
    m_customRenderCache.clear();

    ObjectHelper::releaseObjectHelper(this, m_backgroundObj);
    ObjectHelper::releaseObjectHelper(this, m_gridLineObj);
    ObjectHelper::releaseObjectHelper(this, m_labelObj);
    ObjectHelper::releaseObjectHelper(this, m_positionMapperObj);

    if (m_textureHelper) {
        m_textureHelper->deleteTexture(&m_depthTexture);
        m_textureHelper->deleteTexture(&m_cursorPositionTexture);
        delete m_textureHelper;
    }

    m_axisCacheX.clearLabels();
    m_axisCacheY.clearLabels();
    m_axisCacheZ.clearLabels();
}

void Abstract3DRenderer::contextCleanup()
{
    if (QOpenGLContext::currentContext())
        m_textureHelper->glDeleteFramebuffers(1, &m_cursorPositionFrameBuffer);
}

void Abstract3DRenderer::initializeOpenGL()
{
    m_context = QOpenGLContext::currentContext();

    // Set OpenGL features
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);

#if !defined(QT_OPENGL_ES_2)
    if (!m_isOpenGLES) {
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
        glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
        glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
    }
#endif

    m_textureHelper = new TextureHelper();
    m_drawer->initializeOpenGL();

    axisCacheForOrientation(QAbstract3DAxis::AxisOrientationX).setDrawer(m_drawer);
    axisCacheForOrientation(QAbstract3DAxis::AxisOrientationY).setDrawer(m_drawer);
    axisCacheForOrientation(QAbstract3DAxis::AxisOrientationZ).setDrawer(m_drawer);

    initLabelShaders(QStringLiteral(":/shaders/vertexLabel"),
                     QStringLiteral(":/shaders/fragmentLabel"));

    initCursorPositionShaders(QStringLiteral(":/shaders/vertexPosition"),
                              QStringLiteral(":/shaders/fragmentPositionMap"));

    loadLabelMesh();
    loadPositionMapperMesh();

    QObject::connect(m_context.data(), &QOpenGLContext::aboutToBeDestroyed,
                     this, &Abstract3DRenderer::contextCleanup);
}

void Abstract3DRenderer::render(const GLuint defaultFboHandle)
{
    if (defaultFboHandle) {
        glDepthMask(true);
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LESS);
        glEnable(GL_CULL_FACE);
        glCullFace(GL_BACK);
        glDisable(GL_BLEND); // For QtQuick2 blending is enabled by default, but we don't want it to be
    }

    // Clear the graph background to the theme color
    glViewport(m_viewport.x(),
               m_viewport.y(),
               m_viewport.width(),
               m_viewport.height());
    glScissor(m_viewport.x(),
              m_viewport.y(),
              m_viewport.width(),
              m_viewport.height());
    glEnable(GL_SCISSOR_TEST);
    QVector4D clearColor = Utils::vectorFromColor(m_cachedTheme->windowColor());
    glClearColor(clearColor.x(), clearColor.y(), clearColor.z(), 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    glDisable(GL_SCISSOR_TEST);
}

void Abstract3DRenderer::updateSelectionState(SelectionState state)
{
    m_selectionState = state;
}

void Abstract3DRenderer::initGradientShaders(const QString &vertexShader,
                                             const QString &fragmentShader)
{
    // Do nothing by default
    Q_UNUSED(vertexShader)
    Q_UNUSED(fragmentShader)
}

void Abstract3DRenderer::initStaticSelectedItemShaders(const QString &vertexShader,
                                                       const QString &fragmentShader,
                                                       const QString &gradientVertexShader,
                                                       const QString &gradientFragmentShader)
{
    // Do nothing by default
    Q_UNUSED(vertexShader)
    Q_UNUSED(fragmentShader)
    Q_UNUSED(gradientVertexShader)
    Q_UNUSED(gradientFragmentShader)
}

void Abstract3DRenderer::initCustomItemShaders(const QString &vertexShader,
                                               const QString &fragmentShader)
{
    delete m_customItemShader;
    m_customItemShader = new ShaderHelper(this, vertexShader, fragmentShader);
    m_customItemShader->initialize();
}

void Abstract3DRenderer::initVolumeTextureShaders(const QString &vertexShader,
                                                  const QString &fragmentShader,
                                                  const QString &fragmentLowDefShader,
                                                  const QString &sliceShader,
                                                  const QString &sliceFrameVertexShader,
                                                  const QString &sliceFrameShader)
{

    delete m_volumeTextureShader;
    m_volumeTextureShader = new ShaderHelper(this, vertexShader, fragmentShader);
    m_volumeTextureShader->initialize();

    delete m_volumeTextureLowDefShader;
    m_volumeTextureLowDefShader = new ShaderHelper(this, vertexShader, fragmentLowDefShader);
    m_volumeTextureLowDefShader->initialize();

    delete m_volumeTextureSliceShader;
    m_volumeTextureSliceShader = new ShaderHelper(this, vertexShader, sliceShader);
    m_volumeTextureSliceShader->initialize();

    delete m_volumeSliceFrameShader;
    m_volumeSliceFrameShader = new ShaderHelper(this, sliceFrameVertexShader, sliceFrameShader);
    m_volumeSliceFrameShader->initialize();
}

void Abstract3DRenderer::initLabelShaders(const QString &vertexShader, const QString &fragmentShader)
{
    delete m_labelShader;
    m_labelShader = new ShaderHelper(this, vertexShader, fragmentShader);
    m_labelShader->initialize();
}

void Abstract3DRenderer::initCursorPositionShaders(const QString &vertexShader,
                                                   const QString &fragmentShader)
{
    // Init the shader
    delete m_cursorPositionShader;
    m_cursorPositionShader = new ShaderHelper(this, vertexShader, fragmentShader);
    m_cursorPositionShader->initialize();
}

void Abstract3DRenderer::initCursorPositionBuffer()
{
    m_textureHelper->deleteTexture(&m_cursorPositionTexture);
    m_textureHelper->glDeleteFramebuffers(1, &m_cursorPositionFrameBuffer);
    m_cursorPositionFrameBuffer = 0;

    if (m_primarySubViewport.size().isEmpty())
        return;

    m_cursorPositionTexture =
            m_textureHelper->createCursorPositionTexture(m_primarySubViewport.size(),
                                                         m_cursorPositionFrameBuffer);
}

void Abstract3DRenderer::updateTheme(Q3DTheme *theme)
{
    // Synchronize the controller theme with renderer
    bool updateDrawer = theme->d_ptr->sync(*m_cachedTheme->d_ptr);

    if (updateDrawer)
        m_drawer->setTheme(m_cachedTheme);
}

void Abstract3DRenderer::updateScene(Q3DScene *scene)
{
    m_viewport = scene->d_ptr->glViewport();
    m_secondarySubViewport = scene->d_ptr->glSecondarySubViewport();

    if (m_primarySubViewport != scene->d_ptr->glPrimarySubViewport()) {
        // Resize of primary subviewport means resizing shadow and selection buffers
        m_primarySubViewport = scene->d_ptr->glPrimarySubViewport();
        handleResize();
    }

    if (m_devicePixelRatio != scene->devicePixelRatio()) {
        m_devicePixelRatio = scene->devicePixelRatio();
        handleResize();
    }

    QPoint logicalPixelPosition = scene->selectionQueryPosition();
    m_inputPosition = QPoint(logicalPixelPosition.x() * m_devicePixelRatio,
                             logicalPixelPosition.y() * m_devicePixelRatio);

    QPoint logicalGraphPosition = scene->graphPositionQuery();
    m_graphPositionQuery = QPoint(logicalGraphPosition.x() * m_devicePixelRatio,
                                  logicalGraphPosition.y() * m_devicePixelRatio);

    // Synchronize the renderer scene to controller scene
    scene->d_ptr->sync(*m_cachedScene->d_ptr);

    updateCameraViewport();

    if (Q3DScene::invalidSelectionPoint() == logicalPixelPosition) {
        updateSelectionState(SelectNone);
    } else {
        if (scene->isSlicingActive()) {
            if (scene->isPointInPrimarySubView(logicalPixelPosition))
                updateSelectionState(SelectOnOverview);
            else if (scene->isPointInSecondarySubView(logicalPixelPosition))
                updateSelectionState(SelectOnSlice);
            else
                updateSelectionState(SelectNone);
        } else {
            updateSelectionState(SelectOnScene);
        }
    }

    if (Q3DScene::invalidSelectionPoint() != logicalGraphPosition)
        m_graphPositionQueryPending = true;

    // Queue up another render when we have a query that needs resolving.
    // This is needed because QtQuick scene graph can sometimes do a sync without following it up
    // with a render.
    if (m_graphPositionQueryPending || m_selectionState != SelectNone)
        emit needRender();
}

void Abstract3DRenderer::updateTextures()
{
    m_axisCacheX.updateTextures();
    m_axisCacheY.updateTextures();
    m_axisCacheZ.updateTextures();
}

void Abstract3DRenderer::reInitShaders()
{
    if (!m_isOpenGLES) {
        if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
            if (m_cachedOptimizationHint.testFlag(QAbstract3DGraph::OptimizationStatic)
                    && qobject_cast<Scatter3DRenderer *>(this)) {
                initGradientShaders(QStringLiteral(":/shaders/vertexShadow"),
                                    QStringLiteral(":/shaders/fragmentShadow"));
                initStaticSelectedItemShaders(QStringLiteral(":/shaders/vertexShadow"),
                                              QStringLiteral(":/shaders/fragmentShadowNoTex"),
                                              QStringLiteral(":/shaders/vertexShadow"),
                                              QStringLiteral(":/shaders/fragmentShadowNoTexColorOnY"));
                initShaders(QStringLiteral(":/shaders/vertexShadowNoMatrices"),
                            QStringLiteral(":/shaders/fragmentShadowNoTex"));
            } else {
                initGradientShaders(QStringLiteral(":/shaders/vertexShadow"),
                                    QStringLiteral(":/shaders/fragmentShadowNoTexColorOnY"));
                initShaders(QStringLiteral(":/shaders/vertexShadow"),
                            QStringLiteral(":/shaders/fragmentShadowNoTex"));
            }
            initBackgroundShaders(QStringLiteral(":/shaders/vertexShadow"),
                                  QStringLiteral(":/shaders/fragmentShadowNoTex"));
            initCustomItemShaders(QStringLiteral(":/shaders/vertexShadow"),
                                  QStringLiteral(":/shaders/fragmentShadow"));
        } else {
            if (m_cachedOptimizationHint.testFlag(QAbstract3DGraph::OptimizationStatic)
                    && qobject_cast<Scatter3DRenderer *>(this)) {
                initGradientShaders(QStringLiteral(":/shaders/vertexTexture"),
                                    QStringLiteral(":/shaders/fragmentTexture"));
                initStaticSelectedItemShaders(QStringLiteral(":/shaders/vertex"),
                                              QStringLiteral(":/shaders/fragment"),
                                              QStringLiteral(":/shaders/vertex"),
                                              QStringLiteral(":/shaders/fragmentColorOnY"));
                initShaders(QStringLiteral(":/shaders/vertexNoMatrices"),
                            QStringLiteral(":/shaders/fragment"));
            } else {
                initGradientShaders(QStringLiteral(":/shaders/vertex"),
                                    QStringLiteral(":/shaders/fragmentColorOnY"));
                initShaders(QStringLiteral(":/shaders/vertex"),
                            QStringLiteral(":/shaders/fragment"));
            }
            initBackgroundShaders(QStringLiteral(":/shaders/vertex"),
                                  QStringLiteral(":/shaders/fragment"));
            initCustomItemShaders(QStringLiteral(":/shaders/vertexTexture"),
                                  QStringLiteral(":/shaders/fragmentTexture"));
        }
        initVolumeTextureShaders(QStringLiteral(":/shaders/vertexTexture3D"),
                                 QStringLiteral(":/shaders/fragmentTexture3D"),
                                 QStringLiteral(":/shaders/fragmentTexture3DLowDef"),
                                 QStringLiteral(":/shaders/fragmentTexture3DSlice"),
                                 QStringLiteral(":/shaders/vertexPosition"),
                                 QStringLiteral(":/shaders/fragment3DSliceFrames"));
    } else  {
        if (m_cachedOptimizationHint.testFlag(QAbstract3DGraph::OptimizationStatic)
                && qobject_cast<Scatter3DRenderer *>(this)) {
            initGradientShaders(QStringLiteral(":/shaders/vertexTexture"),
                                QStringLiteral(":/shaders/fragmentTextureES2"));
            initStaticSelectedItemShaders(QStringLiteral(":/shaders/vertex"),
                                          QStringLiteral(":/shaders/fragmentES2"),
                                          QStringLiteral(":/shaders/vertex"),
                                          QStringLiteral(":/shaders/fragmentColorOnYES2"));
            initShaders(QStringLiteral(":/shaders/vertexNoMatrices"),
                        QStringLiteral(":/shaders/fragmentES2"));
        } else {
            initGradientShaders(QStringLiteral(":/shaders/vertex"),
                                QStringLiteral(":/shaders/fragmentColorOnYES2"));
            initShaders(QStringLiteral(":/shaders/vertex"),
                        QStringLiteral(":/shaders/fragmentES2"));
        }
        initBackgroundShaders(QStringLiteral(":/shaders/vertex"),
                              QStringLiteral(":/shaders/fragmentES2"));
        initCustomItemShaders(QStringLiteral(":/shaders/vertexTexture"),
                              QStringLiteral(":/shaders/fragmentTextureES2"));
    }
}

void Abstract3DRenderer::handleShadowQualityChange()
{
    reInitShaders();

    if (m_cachedScene->activeLight()->isAutoPosition()
            || m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
        m_cachedScene->d_ptr->setLightPositionRelativeToCamera(defaultLightPos);
        emit needRender();
    }
    if (m_isOpenGLES && m_cachedShadowQuality != QAbstract3DGraph::ShadowQualityNone) {
        emit requestShadowQuality(QAbstract3DGraph::ShadowQualityNone);
        qWarning("Shadows are not yet supported for OpenGL ES2");
        m_cachedShadowQuality = QAbstract3DGraph::ShadowQualityNone;
    }
}

void Abstract3DRenderer::updateSelectionMode(QAbstract3DGraph::SelectionFlags mode)
{
    m_cachedSelectionMode = mode;
    m_selectionDirty = true;
}

void Abstract3DRenderer::updateAspectRatio(float ratio)
{
    m_graphAspectRatio = ratio;
    foreach (SeriesRenderCache *cache, m_renderCacheList)
        cache->setDataDirty(true);
}

void Abstract3DRenderer::updateHorizontalAspectRatio(float ratio)
{
    m_graphHorizontalAspectRatio = ratio;
    foreach (SeriesRenderCache *cache, m_renderCacheList)
        cache->setDataDirty(true);
}

void Abstract3DRenderer::updatePolar(bool enable)
{
    m_polarGraph = enable;
    foreach (SeriesRenderCache *cache, m_renderCacheList)
        cache->setDataDirty(true);
}

void Abstract3DRenderer::updateRadialLabelOffset(float offset)
{
    m_radialLabelOffset = offset;
}

void Abstract3DRenderer::updateMargin(float margin)
{
    m_requestedMargin = margin;
}

void Abstract3DRenderer::updateOptimizationHint(QAbstract3DGraph::OptimizationHints hint)
{
    m_cachedOptimizationHint = hint;
    foreach (SeriesRenderCache *cache, m_renderCacheList)
        cache->setDataDirty(true);
}

void Abstract3DRenderer::handleResize()
{
    if (m_primarySubViewport.width() == 0 || m_primarySubViewport.height() == 0)
        return;

    // Recalculate zoom
    calculateZoomLevel();

    // Re-init selection buffer
    initSelectionBuffer();

    // Re-init depth buffer
    updateDepthBuffer();

    initCursorPositionBuffer();
}

void Abstract3DRenderer::calculateZoomLevel()
{
    // Calculate zoom level based on aspect ratio
    GLfloat div;
    GLfloat zoomAdjustment;
    div = qMin(m_primarySubViewport.width(), m_primarySubViewport.height());
    zoomAdjustment = defaultRatio
            * ((m_primarySubViewport.width() / div)
               / (m_primarySubViewport.height() / div));
    m_autoScaleAdjustment = qMin(zoomAdjustment, 1.0f); // clamp to 1.0f
}

void Abstract3DRenderer::updateAxisType(QAbstract3DAxis::AxisOrientation orientation,
                                        QAbstract3DAxis::AxisType type)
{
    axisCacheForOrientation(orientation).setType(type);
}

void Abstract3DRenderer::updateAxisTitle(QAbstract3DAxis::AxisOrientation orientation,
                                         const QString &title)
{
    axisCacheForOrientation(orientation).setTitle(title);
}

void Abstract3DRenderer::updateAxisLabels(QAbstract3DAxis::AxisOrientation orientation,
                                          const QStringList &labels)
{
    axisCacheForOrientation(orientation).setLabels(labels);
}

void Abstract3DRenderer::updateAxisRange(QAbstract3DAxis::AxisOrientation orientation,
                                         float min, float max)
{
    AxisRenderCache &cache = axisCacheForOrientation(orientation);
    cache.setMin(min);
    cache.setMax(max);

    foreach (SeriesRenderCache *cache, m_renderCacheList)
        cache->setDataDirty(true);
}

void Abstract3DRenderer::updateAxisSegmentCount(QAbstract3DAxis::AxisOrientation orientation,
                                                int count)
{
    AxisRenderCache &cache = axisCacheForOrientation(orientation);
    cache.setSegmentCount(count);
}

void Abstract3DRenderer::updateAxisSubSegmentCount(QAbstract3DAxis::AxisOrientation orientation,
                                                   int count)
{
    AxisRenderCache &cache = axisCacheForOrientation(orientation);
    cache.setSubSegmentCount(count);
}

void Abstract3DRenderer::updateAxisLabelFormat(QAbstract3DAxis::AxisOrientation orientation,
                                               const QString &format)
{
    axisCacheForOrientation(orientation).setLabelFormat(format);
}

void Abstract3DRenderer::updateAxisReversed(QAbstract3DAxis::AxisOrientation orientation,
                                            bool enable)
{
    axisCacheForOrientation(orientation).setReversed(enable);
    foreach (SeriesRenderCache *cache, m_renderCacheList)
        cache->setDataDirty(true);
}

void Abstract3DRenderer::updateAxisFormatter(QAbstract3DAxis::AxisOrientation orientation,
                                             QValue3DAxisFormatter *formatter)
{
    AxisRenderCache &cache = axisCacheForOrientation(orientation);
    if (cache.ctrlFormatter() != formatter) {
        delete cache.formatter();
        cache.setFormatter(formatter->createNewInstance());
        cache.setCtrlFormatter(formatter);
    }
    formatter->d_ptr->populateCopy(*(cache.formatter()));
    cache.markPositionsDirty();

    foreach (SeriesRenderCache *cache, m_renderCacheList)
        cache->setDataDirty(true);
}

void Abstract3DRenderer::updateAxisLabelAutoRotation(QAbstract3DAxis::AxisOrientation orientation,
                                                     float angle)
{
    AxisRenderCache &cache = axisCacheForOrientation(orientation);
    if (cache.labelAutoRotation() != angle)
        cache.setLabelAutoRotation(angle);
}

void Abstract3DRenderer::updateAxisTitleVisibility(QAbstract3DAxis::AxisOrientation orientation,
                                                   bool visible)
{
    AxisRenderCache &cache = axisCacheForOrientation(orientation);
    if (cache.isTitleVisible() != visible)
        cache.setTitleVisible(visible);
}

void Abstract3DRenderer::updateAxisTitleFixed(QAbstract3DAxis::AxisOrientation orientation,
                                              bool fixed)
{
    AxisRenderCache &cache = axisCacheForOrientation(orientation);
    if (cache.isTitleFixed() != fixed)
        cache.setTitleFixed(fixed);
}

void Abstract3DRenderer::modifiedSeriesList(const QVector<QAbstract3DSeries *> &seriesList)
{
    foreach (QAbstract3DSeries *series, seriesList) {
        SeriesRenderCache *cache = m_renderCacheList.value(series, 0);
        if (cache)
            cache->setDataDirty(true);
    }
}

void Abstract3DRenderer::fixMeshFileName(QString &fileName, QAbstract3DSeries::Mesh mesh)
{
    // Default implementation does nothing.
    Q_UNUSED(fileName)
    Q_UNUSED(mesh)
}

void Abstract3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesList)
{
    foreach (SeriesRenderCache *cache, m_renderCacheList)
        cache->setValid(false);

    m_visibleSeriesCount = 0;
    int seriesCount = seriesList.size();
    for (int i = 0; i < seriesCount; i++) {
        QAbstract3DSeries *series = seriesList.at(i);
        SeriesRenderCache *cache = m_renderCacheList.value(series);
        bool newSeries = false;
        if (!cache) {
            cache = createNewCache(series);
            m_renderCacheList[series] = cache;
            newSeries = true;
        }
        cache->setValid(true);
        cache->populate(newSeries);
        if (cache->isVisible())
            m_visibleSeriesCount++;
    }

    // Remove non-valid objects from the cache list
    foreach (SeriesRenderCache *cache, m_renderCacheList) {
        if (!cache->isValid())
            cleanCache(cache);
    }
}

void Abstract3DRenderer::updateCustomData(const QList<QCustom3DItem *> &customItems)
{
    if (customItems.isEmpty() && m_customRenderCache.isEmpty())
        return;

    foreach (CustomRenderItem *item, m_customRenderCache)
        item->setValid(false);

    int itemCount = customItems.size();
    // Check custom item list for items that are not yet in render item cache
    for (int i = 0; i < itemCount; i++) {
        QCustom3DItem *item = customItems.at(i);
        CustomRenderItem *renderItem = m_customRenderCache.value(item);
        if (!renderItem)
            renderItem = addCustomItem(item);
        renderItem->setValid(true);
        renderItem->setIndex(i); // always update index, as it must match the custom item index
    }

    // Check render item cache and remove items that are not in customItems list anymore
    foreach (CustomRenderItem *renderItem, m_customRenderCache) {
        if (!renderItem->isValid()) {
            m_customRenderCache.remove(renderItem->itemPointer());
            GLuint texture = renderItem->texture();
            m_textureHelper->deleteTexture(&texture);
            delete renderItem;
        }
    }

    m_customItemDrawOrder.clear();
    m_customItemDrawOrder = QList<QCustom3DItem *>(customItems);
}

void Abstract3DRenderer::updateCustomItems()
{
    // Check all items
    foreach (CustomRenderItem *item, m_customRenderCache)
        updateCustomItem(item);
}

SeriesRenderCache *Abstract3DRenderer::createNewCache(QAbstract3DSeries *series)
{
    return new SeriesRenderCache(series, this);
}

void Abstract3DRenderer::cleanCache(SeriesRenderCache *cache)
{
    m_renderCacheList.remove(cache->series());
    cache->cleanup(m_textureHelper);
    delete cache;
}

AxisRenderCache &Abstract3DRenderer::axisCacheForOrientation(
        QAbstract3DAxis::AxisOrientation orientation)
{
    switch (orientation) {
    case QAbstract3DAxis::AxisOrientationX:
        return m_axisCacheX;
    case QAbstract3DAxis::AxisOrientationY:
        return m_axisCacheY;
    case QAbstract3DAxis::AxisOrientationZ:
        return m_axisCacheZ;
    default:
        qFatal("Abstract3DRenderer::axisCacheForOrientation");
        return m_axisCacheX;
    }
}

void Abstract3DRenderer::lowerShadowQuality()
{
    QAbstract3DGraph::ShadowQuality newQuality = QAbstract3DGraph::ShadowQualityNone;

    switch (m_cachedShadowQuality) {
    case QAbstract3DGraph::ShadowQualityHigh:
        qWarning("Creating high quality shadows failed. Changing to medium quality.");
        newQuality = QAbstract3DGraph::ShadowQualityMedium;
        break;
    case QAbstract3DGraph::ShadowQualityMedium:
        qWarning("Creating medium quality shadows failed. Changing to low quality.");
        newQuality = QAbstract3DGraph::ShadowQualityLow;
        break;
    case QAbstract3DGraph::ShadowQualityLow:
        qWarning("Creating low quality shadows failed. Switching shadows off.");
        newQuality = QAbstract3DGraph::ShadowQualityNone;
        break;
    case QAbstract3DGraph::ShadowQualitySoftHigh:
        qWarning("Creating soft high quality shadows failed. Changing to soft medium quality.");
        newQuality = QAbstract3DGraph::ShadowQualitySoftMedium;
        break;
    case QAbstract3DGraph::ShadowQualitySoftMedium:
        qWarning("Creating soft medium quality shadows failed. Changing to soft low quality.");
        newQuality = QAbstract3DGraph::ShadowQualitySoftLow;
        break;
    case QAbstract3DGraph::ShadowQualitySoftLow:
        qWarning("Creating soft low quality shadows failed. Switching shadows off.");
        newQuality = QAbstract3DGraph::ShadowQualityNone;
        break;
    default:
        // You'll never get here
        break;
    }

    emit requestShadowQuality(newQuality);
    updateShadowQuality(newQuality);
}

void Abstract3DRenderer::drawAxisTitleY(const QVector3D &sideLabelRotation,
                                        const QVector3D &backLabelRotation,
                                        const QVector3D &sideLabelTrans,
                                        const QVector3D &backLabelTrans,
                                        const QQuaternion &totalSideRotation,
                                        const QQuaternion &totalBackRotation,
                                        AbstractRenderItem &dummyItem,
                                        const Q3DCamera *activeCamera,
                                        float labelsMaxWidth,
                                        const QMatrix4x4 &viewMatrix,
                                        const QMatrix4x4 &projectionMatrix,
                                        ShaderHelper *shader)
{
    float scaleFactor = m_drawer->scaledFontSize() / m_axisCacheY.titleItem().size().height();
    float titleOffset = 2.0f * (labelMargin + (labelsMaxWidth * scaleFactor));
    float yRotation;
    QVector3D titleTrans;
    QQuaternion totalRotation;
    if (m_xFlipped == m_zFlipped) {
        yRotation = backLabelRotation.y();
        titleTrans = backLabelTrans;
        totalRotation = totalBackRotation;
    } else {
        yRotation = sideLabelRotation.y();
        titleTrans = sideLabelTrans;
        totalRotation = totalSideRotation;
    }

    QQuaternion offsetRotator = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, yRotation);
    QVector3D titleOffsetVector =
            offsetRotator.rotatedVector(QVector3D(-titleOffset, 0.0f, 0.0f));

    QQuaternion titleRotation;
    if (m_axisCacheY.isTitleFixed()) {
        titleRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, yRotation)
                * m_zRightAngleRotation;
    } else {
        titleRotation = totalRotation * m_zRightAngleRotation;
    }
    dummyItem.setTranslation(titleTrans + titleOffsetVector);

    m_drawer->drawLabel(dummyItem, m_axisCacheY.titleItem(), viewMatrix,
                        projectionMatrix, zeroVector, titleRotation, 0,
                        m_cachedSelectionMode, shader, m_labelObj, activeCamera,
                        true, true, Drawer::LabelMid, Qt::AlignBottom);
}

void Abstract3DRenderer::drawAxisTitleX(const QVector3D &labelRotation,
                                        const QVector3D &labelTrans,
                                        const QQuaternion &totalRotation,
                                        AbstractRenderItem &dummyItem,
                                        const Q3DCamera *activeCamera,
                                        float labelsMaxWidth,
                                        const QMatrix4x4 &viewMatrix,
                                        const QMatrix4x4 &projectionMatrix,
                                        ShaderHelper *shader,
                                        bool radial)
{
    float scaleFactor = m_drawer->scaledFontSize() / m_axisCacheX.titleItem().size().height();
    float titleOffset;
    if (radial)
        titleOffset = -2.0f * (labelMargin + m_drawer->scaledFontSize());
    else
        titleOffset = 2.0f * (labelMargin + (labelsMaxWidth * scaleFactor));
    float zRotation = 0.0f;
    float yRotation = 0.0f;
    float xRotation = -90.0f + labelRotation.z();
    float offsetRotation = labelRotation.z();
    float extraRotation = -90.0f;
    Qt::AlignmentFlag alignment = Qt::AlignTop;
    if (m_yFlippedForGrid) {
        alignment = Qt::AlignBottom;
        zRotation = 180.0f;
        if (m_zFlipped) {
            titleOffset = -titleOffset;
            if (m_xFlipped) {
                offsetRotation = -offsetRotation;
                extraRotation = -extraRotation;
            } else {
                xRotation = -90.0f - labelRotation.z();
            }
        } else {
            yRotation = 180.0f;
            if (m_xFlipped) {
                offsetRotation = -offsetRotation;
                xRotation = -90.0f - labelRotation.z();
            } else {
                extraRotation = -extraRotation;
            }
        }
    } else {
        if (m_zFlipped) {
            titleOffset = -titleOffset;
            if (m_xFlipped) {
                yRotation = 180.0f;
                offsetRotation = -offsetRotation;
            } else {
                yRotation = 180.0f;
                xRotation = -90.0f - labelRotation.z();
                extraRotation = -extraRotation;
            }
        } else {
            if (m_xFlipped) {
                offsetRotation = -offsetRotation;
                xRotation = -90.0f - labelRotation.z();
                extraRotation = -extraRotation;
            }
        }
    }

    if (radial) {
        if (m_zFlipped) {
            titleOffset = -titleOffset;
        } else {
            if (m_yFlippedForGrid)
                alignment = Qt::AlignTop;
            else
                alignment = Qt::AlignBottom;
        }
    }

    if (offsetRotation == 180.0f || offsetRotation == -180.0f)
        offsetRotation = 0.0f;
    QQuaternion offsetRotator = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, offsetRotation);
    QVector3D titleOffsetVector =
            offsetRotator.rotatedVector(QVector3D(0.0f, 0.0f, titleOffset));

    QQuaternion titleRotation;
    if (m_axisCacheX.isTitleFixed()) {
        titleRotation = QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, zRotation)
                * QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, yRotation)
                * QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, xRotation);
    } else {
        titleRotation = totalRotation
                * QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, extraRotation);
    }
    dummyItem.setTranslation(labelTrans + titleOffsetVector);

    m_drawer->drawLabel(dummyItem, m_axisCacheX.titleItem(), viewMatrix,
                        projectionMatrix, zeroVector, titleRotation, 0,
                        m_cachedSelectionMode, shader, m_labelObj, activeCamera,
                        true, true, Drawer::LabelMid, alignment);
}

void Abstract3DRenderer::drawAxisTitleZ(const QVector3D &labelRotation,
                                        const QVector3D &labelTrans,
                                        const QQuaternion &totalRotation,
                                        AbstractRenderItem &dummyItem,
                                        const Q3DCamera *activeCamera,
                                        float labelsMaxWidth,
                                        const QMatrix4x4 &viewMatrix,
                                        const QMatrix4x4 &projectionMatrix,
                                        ShaderHelper *shader)
{
    float scaleFactor = m_drawer->scaledFontSize() / m_axisCacheZ.titleItem().size().height();
    float titleOffset = 2.0f * (labelMargin + (labelsMaxWidth * scaleFactor));
    float zRotation = labelRotation.z();
    float yRotation = -90.0f;
    float xRotation = -90.0f;
    float extraRotation = 90.0f;
    Qt::AlignmentFlag alignment = Qt::AlignTop;
    if (m_yFlippedForGrid) {
        alignment = Qt::AlignBottom;
        xRotation = -xRotation;
        if (m_zFlipped) {
            if (m_xFlipped) {
                titleOffset = -titleOffset;
                zRotation = -zRotation;
                extraRotation = -extraRotation;
            } else {
                zRotation = -zRotation;
                yRotation = -yRotation;
            }
        } else {
            if (m_xFlipped) {
                titleOffset = -titleOffset;
            } else {
                extraRotation = -extraRotation;
                yRotation = -yRotation;
            }
        }
    } else {
        if (m_zFlipped) {
            zRotation = -zRotation;
            if (m_xFlipped) {
                titleOffset = -titleOffset;
            } else {
                extraRotation = -extraRotation;
                yRotation = -yRotation;
            }
        } else {
            if (m_xFlipped) {
                titleOffset = -titleOffset;
                extraRotation = -extraRotation;
            } else {
                yRotation = -yRotation;
            }
        }
    }

    float offsetRotation = zRotation;
    if (offsetRotation == 180.0f || offsetRotation == -180.0f)
        offsetRotation = 0.0f;
    QQuaternion offsetRotator = QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, offsetRotation);
    QVector3D titleOffsetVector =
            offsetRotator.rotatedVector(QVector3D(titleOffset, 0.0f, 0.0f));

    QQuaternion titleRotation;
    if (m_axisCacheZ.isTitleFixed()) {
        titleRotation = QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, zRotation)
                * QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, yRotation)
                * QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, xRotation);
    } else {
        titleRotation = totalRotation
                * QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, extraRotation);
    }
    dummyItem.setTranslation(labelTrans + titleOffsetVector);

    m_drawer->drawLabel(dummyItem, m_axisCacheZ.titleItem(), viewMatrix,
                        projectionMatrix, zeroVector, titleRotation, 0,
                        m_cachedSelectionMode, shader, m_labelObj, activeCamera,
                        true, true, Drawer::LabelMid, alignment);
}

void Abstract3DRenderer::loadGridLineMesh()
{
    ObjectHelper::resetObjectHelper(this, m_gridLineObj,
                                    QStringLiteral(":/defaultMeshes/plane"));
}

void Abstract3DRenderer::loadLabelMesh()
{
    ObjectHelper::resetObjectHelper(this, m_labelObj,
                                    QStringLiteral(":/defaultMeshes/plane"));
}

void Abstract3DRenderer::loadPositionMapperMesh()
{
    ObjectHelper::resetObjectHelper(this, m_positionMapperObj,
                                    QStringLiteral(":/defaultMeshes/barFull"));
}

void Abstract3DRenderer::generateBaseColorTexture(const QColor &color, GLuint *texture)
{
    m_textureHelper->deleteTexture(texture);
    *texture = m_textureHelper->createUniformTexture(color);
}

void Abstract3DRenderer::fixGradientAndGenerateTexture(QLinearGradient *gradient,
                                                       GLuint *gradientTexture)
{
    // Readjust start/stop to match gradient texture size
    gradient->setStart(qreal(gradientTextureWidth), qreal(gradientTextureHeight));
    gradient->setFinalStop(0.0, 0.0);

    m_textureHelper->deleteTexture(gradientTexture);

    *gradientTexture = m_textureHelper->createGradientTexture(*gradient);
}

LabelItem &Abstract3DRenderer::selectionLabelItem()
{
    if (!m_selectionLabelItem)
        m_selectionLabelItem = new LabelItem;
    return *m_selectionLabelItem;
}

void Abstract3DRenderer::setSelectionLabel(const QString &label)
{
    if (m_selectionLabelItem)
        m_selectionLabelItem->clear();
    m_selectionLabel = label;
}

QString &Abstract3DRenderer::selectionLabel()
{
    return m_selectionLabel;
}

QVector4D Abstract3DRenderer::indexToSelectionColor(GLint index)
{
    GLubyte idxRed = index & 0xff;
    GLubyte idxGreen = (index & 0xff00) >> 8;
    GLubyte idxBlue = (index & 0xff0000) >> 16;

    return QVector4D(idxRed, idxGreen, idxBlue, 0);
}

CustomRenderItem *Abstract3DRenderer::addCustomItem(QCustom3DItem *item)
{
    CustomRenderItem *newItem = new CustomRenderItem();
    newItem->setRenderer(this);
    newItem->setItemPointer(item); // Store pointer for render item updates
    newItem->setMesh(item->meshFile());
    newItem->setOrigPosition(item->position());
    newItem->setOrigScaling(item->scaling());
    newItem->setScalingAbsolute(item->isScalingAbsolute());
    newItem->setPositionAbsolute(item->isPositionAbsolute());
    QImage textureImage = item->d_ptr->textureImage();
    bool facingCamera = false;
    GLuint texture = 0;
    if (item->d_ptr->m_isLabelItem) {
        QCustom3DLabel *labelItem = static_cast<QCustom3DLabel *>(item);
        newItem->setLabelItem(true);
        float pointSize = labelItem->font().pointSizeF();
        // Check do we have custom visuals or need to use theme
        if (!labelItem->dptr()->m_customVisuals) {
            // Recreate texture using theme
            labelItem->dptr()->createTextureImage(m_cachedTheme->labelBackgroundColor(),
                                                  m_cachedTheme->labelTextColor(),
                                                  m_cachedTheme->isLabelBackgroundEnabled(),
                                                  m_cachedTheme->isLabelBorderEnabled());
            pointSize = m_cachedTheme->font().pointSizeF();
            textureImage = item->d_ptr->textureImage();
        }
        // Calculate scaling based on text (texture size), font size and asked scaling
        float scaledFontSize = (0.05f + pointSize / 500.0f) / float(textureImage.height());
        QVector3D scaling = newItem->origScaling();
        scaling.setX(scaling.x() * textureImage.width() * scaledFontSize);
        scaling.setY(scaling.y() * textureImage.height() * scaledFontSize);
        newItem->setOrigScaling(scaling);
        // Check if facing camera
        facingCamera = labelItem->isFacingCamera();
    } else if (item->d_ptr->m_isVolumeItem && !m_isOpenGLES) {
        QCustom3DVolume *volumeItem = static_cast<QCustom3DVolume *>(item);
        newItem->setTextureWidth(volumeItem->textureWidth());
        newItem->setTextureHeight(volumeItem->textureHeight());
        newItem->setTextureDepth(volumeItem->textureDepth());
        if (volumeItem->textureFormat() == QImage::Format_Indexed8)
            newItem->setColorTable(volumeItem->colorTable());
        newItem->setTextureFormat(volumeItem->textureFormat());
        newItem->setVolume(true);
        newItem->setBlendNeeded(true);
        texture = m_textureHelper->create3DTexture(volumeItem->textureData(),
                                                   volumeItem->textureWidth(),
                                                   volumeItem->textureHeight(),
                                                   volumeItem->textureDepth(),
                                                   volumeItem->textureFormat());
        newItem->setSliceIndexX(volumeItem->sliceIndexX());
        newItem->setSliceIndexY(volumeItem->sliceIndexY());
        newItem->setSliceIndexZ(volumeItem->sliceIndexZ());
        newItem->setAlphaMultiplier(volumeItem->alphaMultiplier());
        newItem->setPreserveOpacity(volumeItem->preserveOpacity());
        newItem->setUseHighDefShader(volumeItem->useHighDefShader());

        newItem->setDrawSlices(volumeItem->drawSlices());
        newItem->setDrawSliceFrames(volumeItem->drawSliceFrames());
        newItem->setSliceFrameColor(volumeItem->sliceFrameColor());
        newItem->setSliceFrameWidths(volumeItem->sliceFrameWidths());
        newItem->setSliceFrameGaps(volumeItem->sliceFrameGaps());
        newItem->setSliceFrameThicknesses(volumeItem->sliceFrameThicknesses());
    }
    recalculateCustomItemScalingAndPos(newItem);
    newItem->setRotation(item->rotation());

    // In OpenGL ES we simply draw volumes as regular custom item placeholders.
    if (!item->d_ptr->m_isVolumeItem || m_isOpenGLES)
    {
        newItem->setBlendNeeded(textureImage.hasAlphaChannel());
        texture = m_textureHelper->create2DTexture(textureImage, true, true, true);
    }
    newItem->setTexture(texture);
    item->d_ptr->clearTextureImage();
    newItem->setVisible(item->isVisible());
    newItem->setShadowCasting(item->isShadowCasting());
    newItem->setFacingCamera(facingCamera);
    m_customRenderCache.insert(item, newItem);
    return newItem;
}

void Abstract3DRenderer::recalculateCustomItemScalingAndPos(CustomRenderItem *item)
{
    if (!m_polarGraph && !item->isLabel() && !item->isScalingAbsolute()
            && !item->isPositionAbsolute()) {
        QVector3D scale = item->origScaling() / 2.0f;
        QVector3D pos = item->origPosition();
        QVector3D minBounds(pos.x() - scale.x(),
                            pos.y() - scale.y(),
                            pos.z() + scale.z());
        QVector3D maxBounds(pos.x() + scale.x(),
                            pos.y() + scale.y(),
                            pos.z() - scale.z());
        QVector3D minCorner = convertPositionToTranslation(minBounds, false);
        QVector3D maxCorner = convertPositionToTranslation(maxBounds, false);
        scale = QVector3D(qAbs(maxCorner.x() - minCorner.x()),
                          qAbs(maxCorner.y() - minCorner.y()),
                          qAbs(maxCorner.z() - minCorner.z())) / 2.0f;
        if (item->isVolume()) {
            // Only volume items need to scale and reposition according to bounds
            QVector3D minBoundsNormal = minCorner;
            QVector3D maxBoundsNormal = maxCorner;
            // getVisibleItemBounds returns bounds normalized for fragment shader [-1,1]
            // Y and Z are also flipped.
            getVisibleItemBounds(minBoundsNormal, maxBoundsNormal);
            item->setMinBounds(minBoundsNormal);
            item->setMaxBounds(maxBoundsNormal);
            // For scaling calculations, we want [0,1] normalized values
            minBoundsNormal = item->minBoundsNormal();
            maxBoundsNormal = item->maxBoundsNormal();

            // Rescale and reposition the item so that it doesn't go over the edges
            QVector3D adjScaling =
                    QVector3D(scale.x() * (maxBoundsNormal.x() - minBoundsNormal.x()),
                              scale.y() * (maxBoundsNormal.y() - minBoundsNormal.y()),
                              scale.z() * (maxBoundsNormal.z() - minBoundsNormal.z()));

            item->setScaling(adjScaling);

            QVector3D adjPos = item->origPosition();
            QVector3D dataExtents = QVector3D(maxBounds.x() - minBounds.x(),
                                              maxBounds.y() - minBounds.y(),
                                              maxBounds.z() - minBounds.z()) / 2.0f;
            adjPos.setX(adjPos.x() + (dataExtents.x() * minBoundsNormal.x())
                        - (dataExtents.x() * (1.0f - maxBoundsNormal.x())));
            adjPos.setY(adjPos.y() + (dataExtents.y() * minBoundsNormal.y())
                        - (dataExtents.y() * (1.0f - maxBoundsNormal.y())));
            adjPos.setZ(adjPos.z() + (dataExtents.z() * minBoundsNormal.z())
                        - (dataExtents.z() * (1.0f - maxBoundsNormal.z())));
            item->setPosition(adjPos);
        } else {
            // Only scale for non-volume items, and do not readjust position
            item->setScaling(scale);
            item->setPosition(item->origPosition());
        }
    } else {
        item->setScaling(item->origScaling());
        item->setPosition(item->origPosition());
        if (item->isVolume()) {
            // Y and Z need to be flipped as shader flips those axes
            item->setMinBounds(QVector3D(-1.0f, 1.0f, 1.0f));
            item->setMaxBounds(QVector3D(1.0f, -1.0f, -1.0f));
        }
    }
    QVector3D translation = convertPositionToTranslation(item->position(),
                                                         item->isPositionAbsolute());
    item->setTranslation(translation);
}

void Abstract3DRenderer::updateCustomItem(CustomRenderItem *renderItem)
{
    QCustom3DItem *item = renderItem->itemPointer();
    if (item->d_ptr->m_dirtyBits.meshDirty) {
        renderItem->setMesh(item->meshFile());
        item->d_ptr->m_dirtyBits.meshDirty = false;
    }
    if (item->d_ptr->m_dirtyBits.positionDirty) {
        renderItem->setOrigPosition(item->position());
        renderItem->setPositionAbsolute(item->isPositionAbsolute());
        if (!item->d_ptr->m_dirtyBits.scalingDirty)
            recalculateCustomItemScalingAndPos(renderItem);
        item->d_ptr->m_dirtyBits.positionDirty = false;
    }
    if (item->d_ptr->m_dirtyBits.scalingDirty) {
        QVector3D scaling = item->scaling();
        renderItem->setOrigScaling(scaling);
        renderItem->setScalingAbsolute(item->isScalingAbsolute());
        // In case we have label item, we need to recreate texture for scaling adjustment
        if (item->d_ptr->m_isLabelItem) {
            QCustom3DLabel *labelItem = static_cast<QCustom3DLabel *>(item);
            float pointSize = labelItem->font().pointSizeF();
            // Check do we have custom visuals or need to use theme
            if (labelItem->dptr()->m_customVisuals) {
                // Recreate texture
                labelItem->dptr()->createTextureImage();
            } else {
                // Recreate texture using theme
                labelItem->dptr()->createTextureImage(m_cachedTheme->labelBackgroundColor(),
                                                      m_cachedTheme->labelTextColor(),
                                                      m_cachedTheme->isLabelBackgroundEnabled(),
                                                      m_cachedTheme->isLabelBorderEnabled());
                pointSize = m_cachedTheme->font().pointSizeF();
            }
            QImage textureImage = item->d_ptr->textureImage();
            // Calculate scaling based on text (texture size), font size and asked scaling
            float scaledFontSize = (0.05f + pointSize / 500.0f) / float(textureImage.height());
            scaling.setX(scaling.x() * textureImage.width() * scaledFontSize);
            scaling.setY(scaling.y() * textureImage.height() * scaledFontSize);
            item->d_ptr->clearTextureImage();
            renderItem->setOrigScaling(scaling);
        }
        recalculateCustomItemScalingAndPos(renderItem);
        item->d_ptr->m_dirtyBits.scalingDirty = false;
    }
    if (item->d_ptr->m_dirtyBits.rotationDirty) {
        renderItem->setRotation(item->rotation());
        item->d_ptr->m_dirtyBits.rotationDirty = false;
    }
    if (item->d_ptr->m_dirtyBits.textureDirty) {
        QImage textureImage = item->d_ptr->textureImage();
        if (item->d_ptr->m_isLabelItem) {
            QCustom3DLabel *labelItem = static_cast<QCustom3DLabel *>(item);
            // Check do we have custom visuals or need to use theme
            if (!labelItem->dptr()->m_customVisuals) {
                // Recreate texture using theme
                labelItem->dptr()->createTextureImage(m_cachedTheme->labelBackgroundColor(),
                                                      m_cachedTheme->labelTextColor(),
                                                      m_cachedTheme->isLabelBackgroundEnabled(),
                                                      m_cachedTheme->isLabelBorderEnabled());
                textureImage = item->d_ptr->textureImage();
            }
        } else if (!item->d_ptr->m_isVolumeItem || m_isOpenGLES) {
            renderItem->setBlendNeeded(textureImage.hasAlphaChannel());
            GLuint oldTexture = renderItem->texture();
            m_textureHelper->deleteTexture(&oldTexture);
            GLuint texture = m_textureHelper->create2DTexture(textureImage, true, true, true);
            renderItem->setTexture(texture);
        }
        item->d_ptr->clearTextureImage();
        item->d_ptr->m_dirtyBits.textureDirty = false;
    }
    if (item->d_ptr->m_dirtyBits.visibleDirty) {
        renderItem->setVisible(item->isVisible());
        item->d_ptr->m_dirtyBits.visibleDirty = false;
    }
    if (item->d_ptr->m_dirtyBits.shadowCastingDirty) {
        renderItem->setShadowCasting(item->isShadowCasting());
        item->d_ptr->m_dirtyBits.shadowCastingDirty = false;
    }
    if (item->d_ptr->m_isLabelItem) {
        QCustom3DLabel *labelItem = static_cast<QCustom3DLabel *>(item);
        if (labelItem->dptr()->m_facingCameraDirty) {
            renderItem->setFacingCamera(labelItem->isFacingCamera());
            labelItem->dptr()->m_facingCameraDirty = false;
        }
    } else if (item->d_ptr->m_isVolumeItem && !m_isOpenGLES) {
        QCustom3DVolume *volumeItem = static_cast<QCustom3DVolume *>(item);
        if (volumeItem->dptr()->m_dirtyBitsVolume.colorTableDirty) {
            renderItem->setColorTable(volumeItem->colorTable());
            volumeItem->dptr()->m_dirtyBitsVolume.colorTableDirty = false;
        }
        if (volumeItem->dptr()->m_dirtyBitsVolume.textureDimensionsDirty
                || volumeItem->dptr()->m_dirtyBitsVolume.textureDataDirty
                || volumeItem->dptr()->m_dirtyBitsVolume.textureFormatDirty) {
            GLuint oldTexture = renderItem->texture();
            m_textureHelper->deleteTexture(&oldTexture);
            GLuint texture = m_textureHelper->create3DTexture(volumeItem->textureData(),
                                                              volumeItem->textureWidth(),
                                                              volumeItem->textureHeight(),
                                                              volumeItem->textureDepth(),
                                                              volumeItem->textureFormat());
            renderItem->setTexture(texture);
            renderItem->setTextureWidth(volumeItem->textureWidth());
            renderItem->setTextureHeight(volumeItem->textureHeight());
            renderItem->setTextureDepth(volumeItem->textureDepth());
            renderItem->setTextureFormat(volumeItem->textureFormat());
            volumeItem->dptr()->m_dirtyBitsVolume.textureDimensionsDirty = false;
            volumeItem->dptr()->m_dirtyBitsVolume.textureDataDirty = false;
            volumeItem->dptr()->m_dirtyBitsVolume.textureFormatDirty = false;
        }
        if (volumeItem->dptr()->m_dirtyBitsVolume.slicesDirty) {
            renderItem->setDrawSlices(volumeItem->drawSlices());
            renderItem->setDrawSliceFrames(volumeItem->drawSliceFrames());
            renderItem->setSliceFrameColor(volumeItem->sliceFrameColor());
            renderItem->setSliceFrameWidths(volumeItem->sliceFrameWidths());
            renderItem->setSliceFrameGaps(volumeItem->sliceFrameGaps());
            renderItem->setSliceFrameThicknesses(volumeItem->sliceFrameThicknesses());
            renderItem->setSliceIndexX(volumeItem->sliceIndexX());
            renderItem->setSliceIndexY(volumeItem->sliceIndexY());
            renderItem->setSliceIndexZ(volumeItem->sliceIndexZ());
            volumeItem->dptr()->m_dirtyBitsVolume.slicesDirty = false;
        }
        if (volumeItem->dptr()->m_dirtyBitsVolume.alphaDirty) {
            renderItem->setAlphaMultiplier(volumeItem->alphaMultiplier());
            renderItem->setPreserveOpacity(volumeItem->preserveOpacity());
            volumeItem->dptr()->m_dirtyBitsVolume.alphaDirty = false;
        }
        if (volumeItem->dptr()->m_dirtyBitsVolume.shaderDirty) {
            renderItem->setUseHighDefShader(volumeItem->useHighDefShader());
            volumeItem->dptr()->m_dirtyBitsVolume.shaderDirty = false;
        }
    }
}

void Abstract3DRenderer::updateCustomItemPositions()
{
    foreach (CustomRenderItem *renderItem, m_customRenderCache)
        recalculateCustomItemScalingAndPos(renderItem);
}

void Abstract3DRenderer::drawCustomItems(RenderingState state,
                                         ShaderHelper *regularShader,
                                         const QMatrix4x4 &viewMatrix,
                                         const QMatrix4x4 &projectionViewMatrix,
                                         const QMatrix4x4 &depthProjectionViewMatrix,
                                         GLuint depthTexture,
                                         GLfloat shadowQuality,
                                         GLfloat reflection)
{
    if (m_customRenderCache.isEmpty())
        return;

    ShaderHelper *shader = regularShader;
    shader->bind();

    if (RenderingNormal == state) {
        shader->setUniformValue(shader->lightP(), m_cachedScene->activeLight()->position());
        shader->setUniformValue(shader->ambientS(), m_cachedTheme->ambientLightStrength());
        shader->setUniformValue(shader->lightColor(),
                                Utils::vectorFromColor(m_cachedTheme->lightColor()));
        shader->setUniformValue(shader->view(), viewMatrix);
    }

    // Draw custom items - first regular and then volumes
    bool volumeDetected = false;
    int loopCount = 0;
    while (loopCount < 2) {
        for (QCustom3DItem *customItem : qAsConst(m_customItemDrawOrder)) {
            CustomRenderItem *item = m_customRenderCache.value(customItem);
            // Check that the render item is visible, and skip drawing if not
            // Also check if reflected item is on the "wrong" side, and skip drawing if it is
            if (!item->isVisible() || ((m_reflectionEnabled && reflection < 0.0f)
                    && (m_yFlipped == (item->translation().y() >= 0.0)))) {
                continue;
            }
            if (loopCount == 0) {
                if (item->isVolume()) {
                    volumeDetected = true;
                    continue;
                }
            } else {
                if (!item->isVolume())
                    continue;
            }

            // If the render item is in data coordinates and not within axis ranges, skip it
            if (!item->isPositionAbsolute()
                    && (item->position().x() < m_axisCacheX.min()
                        || item->position().x() > m_axisCacheX.max()
                        || item->position().z() < m_axisCacheZ.min()
                        || item->position().z() > m_axisCacheZ.max()
                        || item->position().y() < m_axisCacheY.min()
                        || item->position().y() > m_axisCacheY.max())) {
                continue;
            }

            QMatrix4x4 modelMatrix;
            QMatrix4x4 itModelMatrix;
            QMatrix4x4 MVPMatrix;

            QQuaternion rotation = item->rotation();
            // Check if the (label) item should be facing camera, and adjust rotation accordingly
            if (item->isFacingCamera()) {
                float camRotationX = m_cachedScene->activeCamera()->xRotation();
                float camRotationY = m_cachedScene->activeCamera()->yRotation();
                rotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, -camRotationX)
                        * QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, -camRotationY);
            }

            if (m_reflectionEnabled) {
                if (reflection < 0.0f) {
                    if (item->itemPointer()->d_ptr->m_isLabelItem)
                        continue;
                    else
                        glCullFace(GL_FRONT);
                } else {
                    glCullFace(GL_BACK);
                }
                QVector3D trans = item->translation();
                trans.setY(reflection * trans.y());
                modelMatrix.translate(trans);
                if (reflection < 0.0f) {
                    QQuaternion mirror = QQuaternion(rotation.scalar(),
                                                     -rotation.x(), rotation.y(), -rotation.z());
                    modelMatrix.rotate(mirror);
                    itModelMatrix.rotate(mirror);
                } else {
                    modelMatrix.rotate(rotation);
                    itModelMatrix.rotate(rotation);
                }
                QVector3D scale = item->scaling();
                scale.setY(reflection * scale.y());
                modelMatrix.scale(scale);
            } else {
                modelMatrix.translate(item->translation());
                modelMatrix.rotate(rotation);
                modelMatrix.scale(item->scaling());
                itModelMatrix.rotate(rotation);
            }
            if (!item->isFacingCamera())
                itModelMatrix.scale(item->scaling());
            MVPMatrix = projectionViewMatrix * modelMatrix;

            if (RenderingNormal == state) {
                // Normal render
                ShaderHelper *prevShader = shader;
                if (item->isVolume() && !m_isOpenGLES) {
                    if (item->drawSlices() &&
                            (item->sliceIndexX() >= 0
                             || item->sliceIndexY() >= 0
                             || item->sliceIndexZ() >= 0)) {
                        shader = m_volumeTextureSliceShader;
                    } else if (item->useHighDefShader()) {
                        shader = m_volumeTextureShader;
                    } else {
                        shader = m_volumeTextureLowDefShader;
                    }
                } else if (item->isLabel()) {
                    shader = m_labelShader;
                } else {
                    shader = regularShader;
                }
                if (shader != prevShader)
                    shader->bind();
                shader->setUniformValue(shader->model(), modelMatrix);
                shader->setUniformValue(shader->MVP(), MVPMatrix);
                shader->setUniformValue(shader->nModel(), itModelMatrix.inverted().transposed());

                if (item->isBlendNeeded()) {
                    glEnable(GL_BLEND);
                    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                    if (!item->isVolume() && !m_isOpenGLES)
                        glDisable(GL_CULL_FACE);
                } else {
                    glDisable(GL_BLEND);
                    glEnable(GL_CULL_FACE);
                }

                if (!m_isOpenGLES && m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone
                        && !item->isVolume()) {
                    // Set shadow shader bindings
                    shader->setUniformValue(shader->shadowQ(), shadowQuality);
                    shader->setUniformValue(shader->depth(), depthProjectionViewMatrix * modelMatrix);
                    shader->setUniformValue(shader->lightS(), m_cachedTheme->lightStrength() / 10.0f);
                    m_drawer->drawObject(shader, item->mesh(), item->texture(), depthTexture);
                } else {
                    // Set shadowless shader bindings
                    if (item->isVolume() && !m_isOpenGLES) {
                        QVector3D cameraPos = m_cachedScene->activeCamera()->position();
                        cameraPos = MVPMatrix.inverted().map(cameraPos);
                        // Adjust camera position according to min/max bounds
                        cameraPos = -(cameraPos
                                      + ((oneVector - cameraPos) * item->minBoundsNormal())
                                      - ((oneVector + cameraPos) * (oneVector - item->maxBoundsNormal())));
                        shader->setUniformValue(shader->cameraPositionRelativeToModel(), cameraPos);
                        GLint color8Bit = (item->textureFormat() == QImage::Format_Indexed8) ? 1 : 0;
                        if (color8Bit) {
                            shader->setUniformValueArray(shader->colorIndex(),
                                                         item->colorTable().constData(), 256);
                        }
                        shader->setUniformValue(shader->color8Bit(), color8Bit);
                        shader->setUniformValue(shader->alphaMultiplier(), item->alphaMultiplier());
                        shader->setUniformValue(shader->preserveOpacity(),
                                                item->preserveOpacity() ? 1 : 0);

                        shader->setUniformValue(shader->minBounds(), item->minBounds());
                        shader->setUniformValue(shader->maxBounds(), item->maxBounds());

                        if (shader == m_volumeTextureSliceShader) {
                            shader->setUniformValue(shader->volumeSliceIndices(),
                                                    item->sliceFractions());
                        } else {
                            // Precalculate texture dimensions so we can optimize
                            // ray stepping to hit every texture layer.
                            QVector3D textureDimensions(1.0f / float(item->textureWidth()),
                                                        1.0f / float(item->textureHeight()),
                                                        1.0f / float(item->textureDepth()));

                            // Worst case scenario sample count
                            int sampleCount;
                            if (shader == m_volumeTextureLowDefShader) {
                                sampleCount = qMax(item->textureWidth(),
                                                   qMax(item->textureDepth(), item->textureHeight()));
                                // Further improve speed with big textures by simply dropping every
                                // other sample:
                                if (sampleCount > 256)
                                    sampleCount /= 2;
                            } else {
                                sampleCount = item->textureWidth() + item->textureHeight()
                                        + item->textureDepth();
                            }
                            shader->setUniformValue(shader->textureDimensions(), textureDimensions);
                            shader->setUniformValue(shader->sampleCount(), sampleCount);
                        }
                        if (item->drawSliceFrames()) {
                            // Set up the slice frame shader
                            glDisable(GL_CULL_FACE);
                            m_volumeSliceFrameShader->bind();
                            m_volumeSliceFrameShader->setUniformValue(
                                        m_volumeSliceFrameShader->color(), item->sliceFrameColor());

                            // Draw individual slice frames.
                            if (item->sliceIndexX() >= 0)
                                drawVolumeSliceFrame(item, Qt::XAxis, projectionViewMatrix);
                            if (item->sliceIndexY() >= 0)
                                drawVolumeSliceFrame(item, Qt::YAxis, projectionViewMatrix);
                            if (item->sliceIndexZ() >= 0)
                                drawVolumeSliceFrame(item, Qt::ZAxis, projectionViewMatrix);

                            glEnable(GL_CULL_FACE);
                            shader->bind();
                        }
                        m_drawer->drawObject(shader, item->mesh(), 0, 0, item->texture());
                    } else {
                        shader->setUniformValue(shader->lightS(), m_cachedTheme->lightStrength());
                        m_drawer->drawObject(shader, item->mesh(), item->texture());
                    }
                }
            } else if (RenderingSelection == state) {
                // Selection render
                shader->setUniformValue(shader->MVP(), MVPMatrix);
                QVector4D itemColor = indexToSelectionColor(item->index());
                itemColor.setW(customItemAlpha);
                itemColor /= 255.0f;
                shader->setUniformValue(shader->color(), itemColor);
                m_drawer->drawObject(shader, item->mesh());
            } else if (item->isShadowCasting()) {
                // Depth render
                shader->setUniformValue(shader->MVP(), depthProjectionViewMatrix * modelMatrix);
                m_drawer->drawObject(shader, item->mesh());
            }
        }
        loopCount++;
        if (!volumeDetected)
            loopCount++; // Skip second run if no volumes detected
    }

    if (RenderingNormal == state) {
        glDisable(GL_BLEND);
        glEnable(GL_CULL_FACE);
    }
}

void Abstract3DRenderer::drawVolumeSliceFrame(const CustomRenderItem *item, Qt::Axis axis,
                                              const QMatrix4x4 &projectionViewMatrix)
{
    QVector2D frameWidth;
    QVector3D frameScaling;
    QVector3D translation = item->translation();
    QQuaternion rotation = item->rotation();
    float fracTrans;
    bool needRotate = !rotation.isIdentity();
    QMatrix4x4 rotationMatrix;
    if (needRotate)
        rotationMatrix.rotate(rotation);

    if (axis == Qt::XAxis) {
        fracTrans = item->sliceFractions().x();
        float range = item->maxBoundsNormal().x() - item->minBoundsNormal().x();
        float minMult = item->minBoundsNormal().x() / range;
        float maxMult = (1.0f - item->maxBoundsNormal().x()) / range;
        fracTrans = fracTrans - ((1.0f - fracTrans) * minMult) + ((1.0f + fracTrans) * maxMult);
        if (needRotate)
            translation += rotationMatrix.map(QVector3D(fracTrans * item->scaling().x(), 0.0f, 0.0f));
        else
            translation.setX(translation.x() + fracTrans * item->scaling().x());
        frameScaling = QVector3D(item->scaling().z()
                                + (item->scaling().z() * item->sliceFrameGaps().z())
                                + (item->scaling().z() * item->sliceFrameWidths().z()),
                                item->scaling().y()
                                + (item->scaling().y() * item->sliceFrameGaps().y())
                                + (item->scaling().y() * item->sliceFrameWidths().y()),
                                item->scaling().x() * item->sliceFrameThicknesses().x());
        frameWidth = QVector2D(item->scaling().z() * item->sliceFrameWidths().z(),
                               item->scaling().y() * item->sliceFrameWidths().y());
        rotation *= m_yRightAngleRotation;
    } else if (axis == Qt::YAxis) {
        fracTrans = item->sliceFractions().y();
        float range = item->maxBoundsNormal().y() - item->minBoundsNormal().y();
        // Y axis is logically flipped, so we need to swam min and max bounds
        float minMult = (1.0f - item->maxBoundsNormal().y()) / range;
        float maxMult = item->minBoundsNormal().y() / range;
        fracTrans = fracTrans - ((1.0f - fracTrans) * minMult) + ((1.0f + fracTrans) * maxMult);
        if (needRotate)
            translation -= rotationMatrix.map(QVector3D(0.0f, fracTrans * item->scaling().y(), 0.0f));
        else
            translation.setY(translation.y() - fracTrans * item->scaling().y());
        frameScaling = QVector3D(item->scaling().x()
                                + (item->scaling().x() * item->sliceFrameGaps().x())
                                + (item->scaling().x() * item->sliceFrameWidths().x()),
                                item->scaling().z()
                                + (item->scaling().z() * item->sliceFrameGaps().z())
                                + (item->scaling().z() * item->sliceFrameWidths().z()),
                                item->scaling().y() * item->sliceFrameThicknesses().y());
        frameWidth = QVector2D(item->scaling().x() * item->sliceFrameWidths().x(),
                               item->scaling().z() * item->sliceFrameWidths().z());
        rotation *= m_xRightAngleRotation;
    } else { // Z axis
        fracTrans = item->sliceFractions().z();
        float range = item->maxBoundsNormal().z() - item->minBoundsNormal().z();
        // Z axis is logically flipped, so we need to swam min and max bounds
        float minMult = (1.0f - item->maxBoundsNormal().z()) / range;
        float maxMult = item->minBoundsNormal().z() / range;
        fracTrans = fracTrans - ((1.0f - fracTrans) * minMult) + ((1.0f + fracTrans) * maxMult);
        if (needRotate)
            translation -= rotationMatrix.map(QVector3D(0.0f, 0.0f, fracTrans * item->scaling().z()));
        else
            translation.setZ(translation.z() - fracTrans * item->scaling().z());
        frameScaling = QVector3D(item->scaling().x()
                                + (item->scaling().x() * item->sliceFrameGaps().x())
                                + (item->scaling().x() * item->sliceFrameWidths().x()),
                                item->scaling().y()
                                + (item->scaling().y() * item->sliceFrameGaps().y())
                                + (item->scaling().y() * item->sliceFrameWidths().y()),
                                item->scaling().z() * item->sliceFrameThicknesses().z());
        frameWidth = QVector2D(item->scaling().x() * item->sliceFrameWidths().x(),
                               item->scaling().y() * item->sliceFrameWidths().y());
    }

    // If the slice is outside the shown area, don't show the frame
    if (fracTrans < -1.0 || fracTrans > 1.0)
        return;

    // Shader needs the width of clear space in the middle.
    frameWidth.setX(1.0f - (frameWidth.x() / frameScaling.x()));
    frameWidth.setY(1.0f - (frameWidth.y() / frameScaling.y()));

    QMatrix4x4 modelMatrix;
    QMatrix4x4 mvpMatrix;

    modelMatrix.translate(translation);
    modelMatrix.rotate(rotation);
    modelMatrix.scale(frameScaling);
    mvpMatrix = projectionViewMatrix * modelMatrix;
    m_volumeSliceFrameShader->setUniformValue(m_volumeSliceFrameShader->MVP(), mvpMatrix);
    m_volumeSliceFrameShader->setUniformValue(m_volumeSliceFrameShader->sliceFrameWidth(),
                                              frameWidth);

    m_drawer->drawObject(m_volumeSliceFrameShader, item->mesh());

}

void Abstract3DRenderer::queriedGraphPosition(const QMatrix4x4 &projectionViewMatrix,
                                              const QVector3D &scaling,
                                              GLuint defaultFboHandle)
{
    m_cursorPositionShader->bind();

    // Set up mapper framebuffer
    glBindFramebuffer(GL_FRAMEBUFFER, m_cursorPositionFrameBuffer);
    glViewport(0, 0,
               m_primarySubViewport.width(),
               m_primarySubViewport.height());
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glDisable(GL_DITHER); // Dither may affect colors if enabled
    glEnable(GL_CULL_FACE);
    glCullFace(GL_FRONT);

    // Draw a cube scaled to the graph dimensions
    QMatrix4x4 modelMatrix;
    QMatrix4x4 MVPMatrix;

    modelMatrix.scale(scaling);

    MVPMatrix = projectionViewMatrix * modelMatrix;
    m_cursorPositionShader->setUniformValue(m_cursorPositionShader->MVP(), MVPMatrix);
    m_drawer->drawObject(m_cursorPositionShader, m_positionMapperObj);

    QVector4D dataColor = Utils::getSelection(m_graphPositionQuery,
                                              m_primarySubViewport.height());
    if (dataColor.w() > 0.0f) {
        // If position is outside the graph, set the position well outside the graph boundaries
        dataColor = QVector4D(-10000.0f, -10000.0f, -10000.0f, 0.0f);
    } else {
        // Normalize to range [0.0, 1.0]
        dataColor /= 255.0f;
    }

    // Restore state
    glEnable(GL_DITHER);
    glCullFace(GL_BACK);

    // Note: Zeroing the frame buffer before resetting it is a workaround for flickering that occurs
    // during zoom in some environments.
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle);
    glViewport(m_primarySubViewport.x(),
               m_primarySubViewport.y(),
               m_primarySubViewport.width(),
               m_primarySubViewport.height());

    QVector3D normalizedValues = dataColor.toVector3D() * 2.0f;
    normalizedValues -= oneVector;
    m_queriedGraphPosition = QVector3D(normalizedValues.x(),
                                       normalizedValues.y(),
                                       normalizedValues.z());
    m_graphPositionQueryResolved = true;
    m_graphPositionQueryPending = false;
}

void Abstract3DRenderer::calculatePolarXZ(const QVector3D &dataPos, float &x, float &z) const
{
    // x is angular, z is radial
    qreal angle = m_axisCacheX.formatter()->positionAt(dataPos.x()) * doublePi;
    qreal radius = m_axisCacheZ.formatter()->positionAt(dataPos.z());

    // Convert angle & radius to X and Z coords
    x = float(radius * qSin(angle)) * m_polarRadius;
    z = -float(radius * qCos(angle)) * m_polarRadius;
}

void Abstract3DRenderer::drawRadialGrid(ShaderHelper *shader, float yFloorLinePos,
                                        const QMatrix4x4 &projectionViewMatrix,
                                        const QMatrix4x4 &depthMatrix)
{
    static QVector<QQuaternion> lineRotations;
    if (!lineRotations.size()) {
        lineRotations.resize(polarGridRoundness);
        for (int j = 0; j < polarGridRoundness; j++) {
            lineRotations[j] = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f,
                                                             polarGridAngleDegrees * float(j));
        }
    }
    int gridLineCount = m_axisCacheZ.gridLineCount();
    const QVector<float> &gridPositions = m_axisCacheZ.formatter()->gridPositions();
    const QVector<float> &subGridPositions = m_axisCacheZ.formatter()->subGridPositions();
    int mainSize = gridPositions.size();
    QVector3D translateVector(0.0f, yFloorLinePos, 0.0f);
    QQuaternion finalRotation = m_xRightAngleRotationNeg;
    if (m_yFlippedForGrid)
        finalRotation *= m_xFlipRotation;

    for (int i = 0; i < gridLineCount; i++) {
        float gridPosition = (i >= mainSize)
                ? subGridPositions.at(i - mainSize) : gridPositions.at(i);
        float radiusFraction = m_polarRadius * gridPosition;
        QVector3D gridLineScaler(radiusFraction * float(qSin(polarGridHalfAngle)),
                                 gridLineWidth, gridLineWidth);
        translateVector.setZ(gridPosition * m_polarRadius);
        for (int j = 0; j < polarGridRoundness; j++) {
            QMatrix4x4 modelMatrix;
            QMatrix4x4 itModelMatrix;
            modelMatrix.rotate(lineRotations.at(j));
            itModelMatrix.rotate(lineRotations.at(j));
            modelMatrix.translate(translateVector);
            modelMatrix.scale(gridLineScaler);
            itModelMatrix.scale(gridLineScaler);
            modelMatrix.rotate(finalRotation);
            itModelMatrix.rotate(finalRotation);
            QMatrix4x4 MVPMatrix = projectionViewMatrix * modelMatrix;

            shader->setUniformValue(shader->model(), modelMatrix);
            shader->setUniformValue(shader->nModel(), itModelMatrix.inverted().transposed());
            shader->setUniformValue(shader->MVP(), MVPMatrix);
            if (!m_isOpenGLES) {
                if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
                    // Set shadow shader bindings
                    QMatrix4x4 depthMVPMatrix = depthMatrix * modelMatrix;
                    shader->setUniformValue(shader->depth(), depthMVPMatrix);
                    // Draw the object
                    m_drawer->drawObject(shader, m_gridLineObj, 0, m_depthTexture);
                } else {
                    // Draw the object
                    m_drawer->drawObject(shader, m_gridLineObj);
                }
            } else {
                m_drawer->drawLine(shader);
            }
        }
    }
}

void Abstract3DRenderer::drawAngularGrid(ShaderHelper *shader, float yFloorLinePos,
                                         const QMatrix4x4 &projectionViewMatrix,
                                         const QMatrix4x4 &depthMatrix)
{
    float halfRatio((m_polarRadius + (labelMargin / 2.0f)) / 2.0f);
    QVector3D gridLineScaler(gridLineWidth, gridLineWidth, halfRatio);
    int gridLineCount = m_axisCacheX.gridLineCount();
    const QVector<float> &gridPositions = m_axisCacheX.formatter()->gridPositions();
    const QVector<float> &subGridPositions = m_axisCacheX.formatter()->subGridPositions();
    int mainSize = gridPositions.size();
    QVector3D translateVector(0.0f, yFloorLinePos, -halfRatio);
    QQuaternion finalRotation;
    if (m_isOpenGLES)
        finalRotation = m_yRightAngleRotationNeg;
    else
        finalRotation = m_xRightAngleRotationNeg;
    if (m_yFlippedForGrid)
        finalRotation *= m_xFlipRotation;
    for (int i = 0; i < gridLineCount; i++) {
        QMatrix4x4 modelMatrix;
        QMatrix4x4 itModelMatrix;
        float gridPosition = (i >= mainSize)
                ? subGridPositions.at(i - mainSize) : gridPositions.at(i);
        QQuaternion lineRotation = QQuaternion::fromAxisAndAngle(upVector, gridPosition * 360.0f);
        modelMatrix.rotate(lineRotation);
        itModelMatrix.rotate(lineRotation);
        modelMatrix.translate(translateVector);
        modelMatrix.scale(gridLineScaler);
        itModelMatrix.scale(gridLineScaler);
        modelMatrix.rotate(finalRotation);
        itModelMatrix.rotate(finalRotation);
        QMatrix4x4 MVPMatrix = projectionViewMatrix * modelMatrix;

        shader->setUniformValue(shader->model(), modelMatrix);
        shader->setUniformValue(shader->nModel(), itModelMatrix.inverted().transposed());
        shader->setUniformValue(shader->MVP(), MVPMatrix);
        if (m_isOpenGLES) {
            m_drawer->drawLine(shader);
        } else {
            if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
                // Set shadow shader bindings
                QMatrix4x4 depthMVPMatrix = depthMatrix * modelMatrix;
                shader->setUniformValue(shader->depth(), depthMVPMatrix);
                // Draw the object
                m_drawer->drawObject(shader, m_gridLineObj, 0, m_depthTexture);
            } else {
                // Draw the object
                m_drawer->drawObject(shader, m_gridLineObj);
            }
        }
    }
}

float Abstract3DRenderer::calculatePolarBackgroundMargin()
{
    // Check each extents of each angular label
    // Calculate angular position
    QVector<float> &labelPositions = m_axisCacheX.formatter()->labelPositions();
    float actualLabelHeight = m_drawer->scaledFontSize() * 2.0f; // All labels are same height
    float maxNeededMargin = 0.0f;

    // Axis title needs to be accounted for
    if (m_axisCacheX.isTitleVisible())
        maxNeededMargin = 2.0f * actualLabelHeight + 3.0f * labelMargin;

    for (int label = 0; label < labelPositions.size(); label++) {
        QSize labelSize = m_axisCacheX.labelItems().at(label)->size();
        float actualLabelWidth = actualLabelHeight / labelSize.height() * labelSize.width();
        float labelPosition = labelPositions.at(label);
        qreal angle = labelPosition * M_PI * 2.0;
        float x = qAbs((m_polarRadius + labelMargin) * float(qSin(angle)))
                + actualLabelWidth - m_polarRadius + labelMargin;
        float z = qAbs(-(m_polarRadius + labelMargin) * float(qCos(angle)))
                + actualLabelHeight - m_polarRadius + labelMargin;
        float neededMargin = qMax(x, z);
        maxNeededMargin = qMax(maxNeededMargin, neededMargin);
    }

    return maxNeededMargin;
}

void Abstract3DRenderer::updateCameraViewport()
{
    QVector3D adjustedTarget = m_cachedScene->activeCamera()->target();
    fixCameraTarget(adjustedTarget);
    if (m_oldCameraTarget != adjustedTarget) {
        QVector3D cameraBase = cameraDistanceVector + adjustedTarget;

        m_cachedScene->activeCamera()->d_ptr->setBaseOrientation(cameraBase,
                                                                 adjustedTarget,
                                                                 upVector);
        m_oldCameraTarget = adjustedTarget;
    }
    m_cachedScene->activeCamera()->d_ptr->updateViewMatrix(m_autoScaleAdjustment);
    // Set light position (i.e rotate light with activeCamera, a bit above it).
    // Check if we want to use automatic light positioning even without shadows
    if (m_cachedScene->activeLight()->isAutoPosition()
            || m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
        m_cachedScene->d_ptr->setLightPositionRelativeToCamera(defaultLightPos);
    }
}

QT_END_NAMESPACE_DATAVISUALIZATION
