- Qt 6.7
- Qt Graphs
- Volumetric Rendering
- Qt Graphs | Commercial or GPLv3

# Volumetric Rendering

     // Copyright (C) 2023 The Qt Company Ltd.
     // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause

     #ifndef VOLUMETRICMODIFIER_H
     #define VOLUMETRICMODIFIER_H

     #include <QtCore/qtimer.h>
     #include <QtGraphs/q3dscatter.h>
     #include <QtGraphs/qcustom3dvolume.h>
     #include <QtGui/qrgb.h>
     #include <QtWidgets/qlabel.h>
     #include <QtWidgets/qradiobutton.h>
     #include <QtWidgets/qslider.h>

     class VolumetricModifier : public QObject
     {
         Q_OBJECT
     public:
         explicit VolumetricModifier(Q3DScatter *scatter);
         ~VolumetricModifier();

         void setFpsLabel(QLabel *fpsLabel);
         void setMediumDetailRB(QRadioButton *button);
         void setHighDetailRB(QRadioButton *button);
         void setSliceLabels(QLabel *xLabel, QLabel *yLabel, QLabel *zLabel);
         void setAlphaMultiplierLabel(QLabel *label);

     public Q_SLOTS:
         void sliceX(int enabled);
         void sliceY(int enabled);
         void sliceZ(int enabled);
         void adjustSliceX(int value);
         void adjustSliceY(int value);
         void adjustSliceZ(int value);
         void handleFpsChange(qreal fps);
         void handleTimeout();
         void toggleLowDetail(bool enabled);
         void toggleMediumDetail(bool enabled);
         void toggleHighDetail(bool enabled);
         void setFpsMeasurement(bool enabled);
         void setSliceSliders(QSlider *sliderX, QSlider *sliderY, QSlider *sliderZ);
         void changeColorTable(int enabled);
         void setPreserveOpacity(bool enabled);
         void setTransparentGround(bool enabled);
         void setUseHighDefShader(bool enabled);
         void setUsePerspectiveCamera(bool enabled);
         void adjustAlphaMultiplier(int value);
         void toggleAreaAll(bool enabled);
         void toggleAreaMine(bool enabled);
         void toggleAreaMountain(bool enabled);
         void setDrawSliceFrames(int enabled);

     private:
         void initHeightMap(QString fileName, QList<uchar> &layerData);
         void initMineShaftArray();
         int createVolume(int textureSize, int startIndex, int count, QList<uchar> *textureData);
         int excavateMineShaft(int textureSize, int startIndex, int count, QList<uchar> *textureData);
         void excavateMineBlock(int textureSize, int dataIndex, int size, QList<uchar> *textureData);
         void handleSlicingChanges();

         Q3DScatter *m_graph = nullptr;
         QCustom3DVolume *m_volumeItem = nullptr;
         int m_sliceIndexX = 0;
         int m_sliceIndexY = 0;
         int m_sliceIndexZ = 0;
         bool m_slicingX = false;
         bool m_slicingY = false;
         bool m_slicingZ = false;
         QLabel *m_fpsLabel = nullptr;
         QRadioButton *m_mediumDetailRB = nullptr;
         QRadioButton *m_highDetailRB = nullptr;
         QList<uchar> *m_lowDetailData = nullptr;
         QList<uchar> *m_mediumDetailData = nullptr;
         QList<uchar> *m_highDetailData = nullptr;
         int m_mediumDetailIndex = 0;
         int m_highDetailIndex = 0;
         int m_mediumDetailShaftIndex = 0;
         int m_highDetailShaftIndex = 0;
         QSlider *m_sliceSliderX = nullptr;
         QSlider *m_sliceSliderY = nullptr;
         QSlider *m_sliceSliderZ = nullptr;
         QList<QRgb> m_colorTable1 = {};
         QList<QRgb> m_colorTable2 = {};
         bool m_usingPrimaryTable = true;
         QLabel *m_sliceLabelX = nullptr;
         QLabel *m_sliceLabelY = nullptr;
         QLabel *m_sliceLabelZ = nullptr;
         QLabel *m_alphaMultiplierLabel = nullptr;
         QList<uchar> m_magmaLayer = {};
         QList<uchar> m_waterLayer = {};
         QList<uchar> m_groundLayer = {};
         QList<QPair<QVector3D, QVector3D>> m_mineShaftArray = {};
         QTimer m_timer;
     };

     #endif