File indexing completed on 2024-05-05 16:16:43

0001 /*
0002  * This file is part of KQuickCharts
0003  * SPDX-FileCopyrightText: 2019 Arjen Hiemstra <ahiemstra@heimr.nl>
0004  *
0005  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006  */
0007 
0008 #include "LineChartMaterial.h"
0009 
0010 LineChartMaterial::LineChartMaterial()
0011 {
0012     setFlag(QSGMaterial::Blending);
0013 }
0014 
0015 LineChartMaterial::~LineChartMaterial()
0016 {
0017 }
0018 
0019 QSGMaterialType *LineChartMaterial::type() const
0020 {
0021     static QSGMaterialType type;
0022     return &type;
0023 }
0024 
0025 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0026 QSGMaterialShader *LineChartMaterial::createShader() const
0027 #else
0028 QSGMaterialShader *LineChartMaterial::createShader(QSGRendererInterface::RenderMode) const
0029 #endif
0030 {
0031     return new LineChartShader();
0032 }
0033 
0034 int LineChartMaterial::compare(const QSGMaterial *other) const
0035 {
0036     auto material = static_cast<const LineChartMaterial *>(other);
0037 
0038     /* clang-format off */
0039     if (qFuzzyCompare(material->aspect, aspect)
0040         && qFuzzyCompare(material->lineWidth, lineWidth)
0041         && qFuzzyCompare(material->smoothing, smoothing)) { /* clang-format on */
0042         return 0;
0043     }
0044 
0045     return QSGMaterial::compare(other);
0046 }
0047 
0048 LineChartShader::LineChartShader()
0049 {
0050     setShaders(QStringLiteral("linechart.vert"), QStringLiteral("linechart.frag"));
0051 }
0052 
0053 LineChartShader::~LineChartShader()
0054 {
0055 }
0056 
0057 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0058 const char *const *LineChartShader::attributeNames() const
0059 {
0060     /* clang-format off */
0061     static char const *const names[] = {
0062         "in_vertex",
0063         "in_uv",
0064         "in_lineColor",
0065         "in_fillColor",
0066         "in_bounds",
0067         "in_count",
0068         "in_points_0",
0069         "in_points_1",
0070         "in_points_2",
0071         "in_points_3",
0072         "in_points_4",
0073         "in_points_5",
0074         "in_points_6",
0075         "in_points_7",
0076         "in_points_8",
0077         nullptr
0078     }; /* clang-format on */
0079     return names;
0080 }
0081 
0082 void LineChartShader::initialize()
0083 {
0084     QSGMaterialShader::initialize();
0085     m_matrixLocation = program()->uniformLocation("matrix");
0086     m_opacityLocation = program()->uniformLocation("opacity");
0087     m_lineWidthLocation = program()->uniformLocation("lineWidth");
0088     m_aspectLocation = program()->uniformLocation("aspect");
0089     m_smoothingLocation = program()->uniformLocation("smoothing");
0090 }
0091 
0092 void LineChartShader::updateState(const QSGMaterialShader::RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
0093 {
0094     if (state.isMatrixDirty()) {
0095         program()->setUniformValue(m_matrixLocation, state.combinedMatrix());
0096     }
0097     if (state.isOpacityDirty()) {
0098         program()->setUniformValue(m_opacityLocation, state.opacity());
0099     }
0100 
0101     if (!oldMaterial || newMaterial->compare(oldMaterial) != 0) {
0102         LineChartMaterial *material = static_cast<LineChartMaterial *>(newMaterial);
0103         program()->setUniformValue(m_lineWidthLocation, material->lineWidth);
0104         program()->setUniformValue(m_aspectLocation, material->aspect);
0105         program()->setUniformValue(m_smoothingLocation, material->smoothing);
0106     }
0107 }
0108 #else
0109 bool LineChartShader::updateUniformData(QSGMaterialShader::RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
0110 {
0111     bool changed = false;
0112     QByteArray *buf = state.uniformData();
0113     Q_ASSERT(buf->size() >= 80);
0114 
0115     if (state.isMatrixDirty()) {
0116         const QMatrix4x4 m = state.combinedMatrix();
0117         memcpy(buf->data(), m.constData(), 64);
0118         changed = true;
0119     }
0120 
0121     if (state.isOpacityDirty()) {
0122         const float opacity = state.opacity();
0123         memcpy(buf->data() + 72, &opacity, 4);
0124         changed = true;
0125     }
0126 
0127     if (!oldMaterial || newMaterial->compare(oldMaterial) != 0) {
0128         const auto material = static_cast<LineChartMaterial *>(newMaterial);
0129         memcpy(buf->data() + 64, &material->lineWidth, 4);
0130         memcpy(buf->data() + 68, &material->aspect, 4);
0131         memcpy(buf->data() + 76, &material->smoothing, 4);
0132         changed = true;
0133     }
0134 
0135     return changed;
0136 }
0137 #endif