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

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