Kirigami2

shadowedrectanglematerial.cpp
1 /*
2  * SPDX-FileCopyrightText: 2020 Arjen Hiemstra <[email protected]>
3  *
4  * SPDX-License-Identifier: LGPL-2.0-or-later
5  */
6 
7 #include "shadowedrectanglematerial.h"
8 
9 #include <QOpenGLContext>
10 
11 QSGMaterialType ShadowedRectangleMaterial::staticType;
12 
13 ShadowedRectangleMaterial::ShadowedRectangleMaterial()
14 {
16 }
17 
18 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
20 #else
21 QSGMaterialShader *ShadowedRectangleMaterial::createShader(QSGRendererInterface::RenderMode) const
22 #endif
23 {
24  return new ShadowedRectangleShader{shaderType};
25 }
26 
27 QSGMaterialType *ShadowedRectangleMaterial::type() const
28 {
29  return &staticType;
30 }
31 
32 int ShadowedRectangleMaterial::compare(const QSGMaterial *other) const
33 {
34  auto material = static_cast<const ShadowedRectangleMaterial *>(other);
35  /* clang-format off */
36  if (material->color == color
37  && material->shadowColor == shadowColor
38  && material->offset == offset
39  && material->aspect == aspect
40  && qFuzzyCompare(material->size, size)
41  && qFuzzyCompare(material->radius, radius)) { /* clang-format on */
42  return 0;
43  }
44 
45  return QSGMaterial::compare(other);
46 }
47 
48 ShadowedRectangleShader::ShadowedRectangleShader(ShadowedRectangleMaterial::ShaderType shaderType)
49 {
50  setShader(shaderType, QStringLiteral("shadowedrectangle"));
51 }
52 
53 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
54 const char *const *ShadowedRectangleShader::attributeNames() const
55 {
56  static char const *const names[] = {"in_vertex", "in_uv", nullptr};
57  return names;
58 }
59 
61 {
63  m_matrixLocation = program()->uniformLocation("matrix");
64  m_aspectLocation = program()->uniformLocation("aspect");
65  m_opacityLocation = program()->uniformLocation("opacity");
66  m_sizeLocation = program()->uniformLocation("size");
67  m_radiusLocation = program()->uniformLocation("radius");
68  m_colorLocation = program()->uniformLocation("color");
69  m_shadowColorLocation = program()->uniformLocation("shadowColor");
70  m_offsetLocation = program()->uniformLocation("offset");
71 }
72 
74 {
75  auto p = program();
76 
77  if (state.isMatrixDirty()) {
78  p->setUniformValue(m_matrixLocation, state.combinedMatrix());
79  }
80 
81  if (state.isOpacityDirty()) {
82  p->setUniformValue(m_opacityLocation, state.opacity());
83  }
84 
85  if (!oldMaterial || newMaterial->compare(oldMaterial) != 0 || state.isCachedMaterialDataDirty()) {
86  auto material = static_cast<ShadowedRectangleMaterial *>(newMaterial);
87  p->setUniformValue(m_aspectLocation, material->aspect);
88  p->setUniformValue(m_sizeLocation, material->size);
89  p->setUniformValue(m_radiusLocation, material->radius);
90  p->setUniformValue(m_colorLocation, material->color);
91  p->setUniformValue(m_shadowColorLocation, material->shadowColor);
92  p->setUniformValue(m_offsetLocation, material->offset);
93  }
94 }
95 #else
96 bool ShadowedRectangleShader::updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
97 {
98  bool changed = false;
99  QByteArray *buf = state.uniformData();
100  Q_ASSERT(buf->size() >= 160);
101 
102  if (state.isMatrixDirty()) {
103  const QMatrix4x4 m = state.combinedMatrix();
104  memcpy(buf->data(), m.constData(), 64);
105  changed = true;
106  }
107 
108  if (state.isOpacityDirty()) {
109  const float opacity = state.opacity();
110  memcpy(buf->data() + 72, &opacity, 4);
111  changed = true;
112  }
113 
114  if (!oldMaterial || newMaterial->compare(oldMaterial) != 0) {
115  const auto material = static_cast<ShadowedRectangleMaterial *>(newMaterial);
116  memcpy(buf->data() + 64, &material->aspect, 8);
117  memcpy(buf->data() + 76, &material->size, 4);
118  memcpy(buf->data() + 80, &material->radius, 16);
119  float c[4];
120  material->color.getRgbF(&c[0], &c[1], &c[2], &c[3]);
121  memcpy(buf->data() + 96, c, 16);
122  material->shadowColor.getRgbF(&c[0], &c[1], &c[2], &c[3]);
123  memcpy(buf->data() + 112, c, 16);
124  memcpy(buf->data() + 128, &material->offset, 8);
125  changed = true;
126  }
127 
128  return changed;
129 }
130 #endif
131 
132 void ShadowedRectangleShader::setShader(ShadowedRectangleMaterial::ShaderType shaderType, const QString &shader)
133 {
134  const auto shaderRoot = QStringLiteral(":/org/kde/kirigami/shaders/");
135 
136 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
137  auto header = QOpenGLContext::currentContext()->isOpenGLES() ? QStringLiteral("header_es.glsl") : QStringLiteral("header_desktop.glsl");
138 
139  setShaderSourceFiles(QOpenGLShader::Vertex, {shaderRoot + header, shaderRoot + QStringLiteral("shadowedrectangle.vert")});
140 
141  QString shaderFile = shader + QStringLiteral(".frag");
142  auto sdfFile = QStringLiteral("sdf.glsl");
143  if (shaderType == ShadowedRectangleMaterial::ShaderType::LowPower) {
144  shaderFile = shader + QStringLiteral("_lowpower.frag");
145  sdfFile = QStringLiteral("sdf_lowpower.glsl");
146  }
147 
148  setShaderSourceFiles(QOpenGLShader::Fragment, {shaderRoot + header, shaderRoot + sdfFile, shaderRoot + shaderFile});
149 #else
150  setShaderFileName(QSGMaterialShader::VertexStage, shaderRoot + QStringLiteral("shadowedrectangle.vert.qsb"));
151 
152  auto shaderFile = shader;
153  if (shaderType == ShadowedRectangleMaterial::ShaderType::LowPower) {
154  shaderFile += QStringLiteral("_lowpower");
155  }
156  setShaderFileName(QSGMaterialShader::FragmentStage, shaderRoot + shaderFile + QStringLiteral(".frag.qsb"));
157 #endif
158 }
bool isOpacityDirty() const const
QMatrix4x4 combinedMatrix() const const
void setFlag(QSGMaterial::Flags flags, bool on)
const float * constData() const const
bool isMatrixDirty() const const
virtual void initialize()
QOpenGLContext * currentContext()
virtual const char *const * attributeNames() const const=0
virtual int compare(const QSGMaterial *other) const const
bool isOpenGLES() const const
float opacity() const const
virtual QSGMaterialShader * createShader() const const=0
virtual void updateState(const QSGMaterialShader::RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
bool isCachedMaterialDataDirty() const const
A material rendering a rectangle with a shadow.
int size() const const
char * data()
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sun Jan 29 2023 04:11:03 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.