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_TEXTURE_H
41#define QT3DRENDER_RENDER_TEXTURE_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/private/backendnode_p.h>
55#include <Qt3DRender/private/handle_types_p.h>
56#include <Qt3DRender/private/qabstracttexture_p.h>
57#include <Qt3DRender/qtexture.h>
58#include <Qt3DRender/qtexturedata.h>
59#include <Qt3DRender/qtexturegenerator.h>
60#include <QOpenGLContext>
61#include <QMutex>
62
63QT_BEGIN_NAMESPACE
64
65class QOpenGLTexture;
66
67namespace Qt3DRender {
68
69class QAbstractTexture;
70
71namespace Render {
72
73class TextureManager;
74class TextureImageManager;
75
76/**
77 * General, constant properties of a texture
78 */
79struct TextureProperties
80{
81 int width = 1;
82 int height = 1;
83 int depth = 1;
84 int layers = 1;
85 int mipLevels = 1;
86 int samples = 1;
87 QAbstractTexture::Target target = QAbstractTexture::TargetAutomatic;
88 QAbstractTexture::TextureFormat format = QAbstractTexture::NoFormat;
89 bool generateMipMaps = false;
90 QAbstractTexture::Status status = QAbstractTexture::None;
91
92 bool operator==(const TextureProperties &o) const {
93 return (width == o.width) && (height == o.height) && (depth == o.depth)
94 && (layers == o.layers) && (mipLevels == o.mipLevels) && (target == o.target)
95 && (format == o.format) && (generateMipMaps == o.generateMipMaps)
96 && (samples == o.samples) && (status == o.status);
97 }
98 inline bool operator!=(const TextureProperties &o) const { return !(*this == o); }
99};
100
101
102/**
103 * Texture parameters that are independent of texture data and that may
104 * change without the re-uploading the texture
105 */
106struct TextureParameters
107{
108 QAbstractTexture::Filter magnificationFilter = QAbstractTexture::Nearest;
109 QAbstractTexture::Filter minificationFilter = QAbstractTexture::Nearest;
110 QTextureWrapMode::WrapMode wrapModeX = QTextureWrapMode::ClampToEdge;
111 QTextureWrapMode::WrapMode wrapModeY = QTextureWrapMode::ClampToEdge;
112 QTextureWrapMode::WrapMode wrapModeZ = QTextureWrapMode::ClampToEdge;
113 float maximumAnisotropy = 1.0f;
114 QAbstractTexture::ComparisonFunction comparisonFunction = QAbstractTexture::CompareLessEqual;
115 QAbstractTexture::ComparisonMode comparisonMode = QAbstractTexture::CompareNone;
116
117 bool operator==(const TextureParameters &o) const {
118 return (magnificationFilter == o.magnificationFilter) && (minificationFilter == o.minificationFilter)
119 && (wrapModeX == o.wrapModeX) && (wrapModeY == o.wrapModeY) && (wrapModeZ == o.wrapModeZ)
120 && (maximumAnisotropy == o.maximumAnisotropy)
121 && (comparisonFunction == o.comparisonFunction) && (comparisonMode == o.comparisonMode);
122 }
123 inline bool operator!=(const TextureParameters &o) const { return !(*this == o); }
124};
125
126/**
127 * Backend object for QAbstractTexture. Just holds texture properties and parameters.
128 * Will query the TextureImplManager for an instance of TextureImpl that matches it's
129 * properties.
130 */
131class Q_AUTOTEST_EXPORT Texture : public BackendNode
132{
133public:
134 Texture();
135 ~Texture();
136
137 enum DirtyFlag {
138 NotDirty = 0,
139 DirtyProperties = (1 << 0),
140 DirtyParameters = (1 << 1),
141 DirtyImageGenerators = (1 << 2),
142 DirtyDataGenerator = (1 << 3),
143 DirtySharedTextureId = (1 << 4),
144 DirtyPendingDataUpdates = (1 << 5),
145 };
146 Q_DECLARE_FLAGS(DirtyFlags, DirtyFlag)
147
148 struct TextureUpdateInfo
149 {
150 TextureProperties properties;
151 QVariant handle;
152 QAbstractTexture::HandleType handleType;
153 };
154
155 void addDirtyFlag(DirtyFlags flags);
156 DirtyFlags dirtyFlags();
157 void unsetDirty();
158
159 void addTextureImage(Qt3DCore::QNodeId id);
160 void removeTextureImage(Qt3DCore::QNodeId id);
161 void cleanup();
162
163 void addTextureDataUpdate(const QTextureDataUpdate &update);
164 QVector<QTextureDataUpdate> takePendingTextureDataUpdates() { return std::move(m_pendingTextureDataUpdates); }
165
166 void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
167
168 inline const TextureProperties& properties() const { return m_properties; }
169 inline const TextureParameters& parameters() const { return m_parameters; }
170 inline const Qt3DCore::QNodeIdVector textureImageIds() const { return m_textureImageIds; }
171 inline const QTextureGeneratorPtr& dataGenerator() const { return m_dataFunctor; }
172 inline int sharedTextureId() const { return m_sharedTextureId; }
173
174 void setDataGenerator(const QTextureGeneratorPtr &generator);
175 void updatePropertiesAndNotify(const TextureUpdateInfo &updateInfo);
176 bool isValid(TextureImageManager *manager) const;
177private:
178 void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
179
180 DirtyFlags m_dirty;
181 TextureProperties m_properties;
182 TextureParameters m_parameters;
183 int m_sharedTextureId;
184
185 QTextureGeneratorPtr m_dataFunctor;
186 Qt3DCore::QNodeIdVector m_textureImageIds;
187
188 QMutex m_flagsMutex;
189 QVector<QTextureDataUpdate> m_pendingTextureDataUpdates;
190};
191
192class Q_AUTOTEST_EXPORT TextureFunctor : public Qt3DCore::QBackendNodeMapper
193{
194public:
195 explicit TextureFunctor(AbstractRenderer *renderer,
196 TextureManager *textureNodeManager);
197 Qt3DCore::QBackendNode *create(const Qt3DCore::QNodeCreatedChangeBasePtr &change) const final;
198 Qt3DCore::QBackendNode *get(Qt3DCore::QNodeId id) const final;
199 void destroy(Qt3DCore::QNodeId id) const final;
200
201private:
202 AbstractRenderer *m_renderer;
203 TextureManager *m_textureNodeManager;
204};
205
206#ifndef QT_NO_DEBUG_STREAM
207inline QDebug operator<<(QDebug dbg, const Texture &texture)
208{
209 QDebugStateSaver saver(dbg);
210 dbg << "QNodeId =" << texture.peerId() << "imageCount =" << texture.textureImageIds().size() << endl;
211 return dbg;
212}
213#endif
214
215} // namespace Render
216} // namespace Qt3DRender
217
218QT_END_NAMESPACE
219
220Q_DECLARE_METATYPE(Qt3DRender::Render::Texture*) // LCOV_EXCL_LINE
221Q_DECLARE_METATYPE(Qt3DRender::Render::TextureProperties) // LCOV_EXCL_LINE
222
223#endif // QT3DRENDER_RENDER_TEXTURE_H
224