1/****************************************************************************
2**
3** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt3D module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QT3DRENDER_RENDER_UNIFORM_P_H
41#define QT3DRENDER_RENDER_UNIFORM_P_H
42
43//
44// W A R N I N G
45// -------------
46//
47// This file is not part of the Qt API. It exists for the convenience
48// of other Qt classes. This header file may change from version to
49// version without notice, or even be removed.
50//
51// We mean it.
52//
53
54#include <qt3drender_global.h>
55#include <Qt3DCore/qnodeid.h>
56#include <Qt3DCore/private/matrix4x4_p.h>
57#include <Qt3DCore/private/vector3d_p.h>
58#include <Qt3DCore/private/vector4d_p.h>
59#include <Qt3DRender/private/qt3drender_global_p.h>
60#include <QMatrix4x4>
61#include <QVector2D>
62#include <QVector3D>
63#include <QColor>
64
65#include <QDebug>
66#include <string.h>
67
68QT_BEGIN_NAMESPACE
69
70namespace Qt3DRender {
71namespace Render {
72
73enum UniformType {
74 Float = 0,
75 Vec2,
76 Vec3,
77 Vec4,
78 Double,
79 DVec2,
80 DVec3,
81 DVec4,
82 Int,
83 IVec2,
84 IVec3,
85 IVec4,
86 UInt,
87 UIVec2,
88 UIVec3,
89 UIVec4,
90 Bool,
91 BVec2,
92 BVec3,
93 BVec4,
94 Mat2,
95 Mat3,
96 Mat4,
97 Mat2x3,
98 Mat3x2,
99 Mat2x4,
100 Mat4x2,
101 Mat3x4,
102 Mat4x3,
103 Sampler,
104 Image,
105 Unknown
106};
107
108class Q_3DRENDERSHARED_PRIVATE_EXPORT UniformValue
109{
110public:
111 enum ValueType {
112 ScalarValue,
113 NodeId,
114 TextureValue,
115 BufferValue,
116 ShaderImageValue
117 };
118
119 // UniformValue implicitely converts doubles to floats to ensure
120 // correct rendering behavior for the cases where Qt3D parameters created from
121 // a double or QVariant(double) are used to fill uniform values that in reality
122 // should be floats. This occur especially with QML where qreal might be double
123 // and not float. Otherwise, at when filling the uniforms, calling constData<float>
124 // on something that contains a double will result in wrong values
125
126 UniformValue()
127 : m_data(4)
128 {
129 memset(m_data.data(), 0, m_data.size() * sizeof(float));
130 }
131
132 UniformValue(int i) : UniformValue() { data<int>()[0] = i; }
133 UniformValue(uint i) : UniformValue() { data<uint>()[0] = i; }
134 UniformValue(float f) : UniformValue() { data<float>()[0] = f; }
135 UniformValue(double d) : UniformValue() { data<float>()[0] = d; } // Double to float conversion
136 UniformValue(bool b) : UniformValue() { data<bool>()[0] = b; }
137 UniformValue(const QVector2D &vec2) : UniformValue() { memcpy(m_data.data(), &vec2, sizeof(QVector2D)); }
138 UniformValue(const Vector3D &vec3) : UniformValue() { memcpy(m_data.data(), &vec3, sizeof(Vector3D)); }
139 UniformValue(const Vector4D &vec4) : m_data(sizeof(Vector4D) / sizeof(float)) { memcpy(m_data.data(), &vec4, sizeof(Vector4D)); }
140
141 UniformValue(const QMatrix3x3 &mat33)
142 : m_data(9)
143 {
144 // Use constData because we want column-major layout
145 memcpy(m_data.data(), mat33.constData(), 9 * sizeof(float));
146 }
147
148 // We don t want the QMatrix4x4 builder to use sizeof since QMatrix4x4 contains a type flag
149#if defined(__SSE2__) || defined(__AVX2__)
150 UniformValue(const Matrix4x4 &mat44)
151 : m_data(sizeof(Matrix4x4) / sizeof(float))
152 {
153 // Use constData because we want column-major layout
154 memcpy(m_data.data(), &mat44, sizeof(Matrix4x4));
155 }
156#else
157 UniformValue(const QMatrix4x4 &mat44)
158 : m_data(16)
159 {
160 // Use constData because we want column-major layout
161 memcpy(m_data.data(), mat44.constData(), 16 * sizeof(float));
162 }
163#endif
164
165 UniformValue(const QVector<QMatrix4x4> &v)
166 : m_data(16 * v.size())
167 {
168 int offset = 0;
169 const int byteSize = 16 * sizeof(float);
170 float *data = m_data.data();
171 for (const auto &m : v) {
172 memcpy(data + offset, m.constData(), byteSize);
173 offset += 16;
174 }
175 }
176
177 // Reserve data to be filled in later
178 UniformValue(int byteSize, ValueType valueType)
179 : m_data(byteSize / sizeof(float))
180 , m_valueType(valueType)
181 {
182 }
183
184 // For nodes which will later be replaced by a Texture or Buffer
185 UniformValue(Qt3DCore::QNodeId id)
186 : m_data(sizeof(Qt3DCore::QNodeId) / sizeof(float))
187 {
188 m_valueType = NodeId;
189 memcpy(m_data.data(), &id, sizeof(Qt3DCore::QNodeId));
190 }
191
192 ValueType valueType() const { return m_valueType; }
193 UniformType storedType() const { return m_storedType; }
194
195 template<typename T>
196 void setData(const QVector<T> &v)
197 {
198 m_data.resize(v.size() * sizeof(T) / sizeof(float));
199 m_valueType = ScalarValue;
200 float *data = m_data.data();
201 memcpy(data, v.constData(), v.size() * sizeof(T));
202 }
203
204 static UniformValue fromVariant(const QVariant &variant);
205
206 int byteSize() const { return m_data.size() * sizeof(float); }
207
208 template<typename T>
209 const T *constData() const
210 {
211 return reinterpret_cast<const T *>(m_data.constData());
212 }
213
214 template<typename T>
215 T *data()
216 {
217 return reinterpret_cast<T *>(m_data.data());
218 }
219
220 bool operator==(const UniformValue &other) const
221 {
222 return other.m_data == m_data;
223 }
224
225 bool operator!=(const UniformValue &other) const
226 {
227 return !(*this == other);
228 }
229private:
230 // Allocate 16 floats on stack
231 // For larger elements, heap allocation will be used
232 QVarLengthArray<float, 16> m_data;
233
234 ValueType m_valueType = ScalarValue;
235
236 // TODO: Replace this hack see QTBUG-57510
237 UniformType m_storedType = Unknown;
238};
239
240template<>
241Q_3DRENDERSHARED_PRIVATE_EXPORT void UniformValue::setData<QMatrix4x4>(const QVector<QMatrix4x4> &v);
242
243} // namespace Render
244} // namespace Qt3DRender
245
246QT_END_NAMESPACE
247
248Q_DECLARE_METATYPE(Qt3DRender::Render::UniformType) // LCOV_EXCL_LINE
249
250#endif // QT3DRENDER_RENDER_UNIFORM_P_H
251

source code of qt3d/src/render/backend/uniform_p.h