1// Copyright (C) 2017 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#include "qtexturematerial.h"
5#include "qtexturematerial_p.h"
6#include <Qt3DRender/qfilterkey.h>
7#include <Qt3DRender/qmaterial.h>
8#include <Qt3DRender/qeffect.h>
9#include <Qt3DRender/qtexture.h>
10#include <Qt3DRender/qtechnique.h>
11#include <Qt3DRender/qshaderprogram.h>
12#include <Qt3DRender/qparameter.h>
13#include <Qt3DRender/qrenderpass.h>
14#include <Qt3DRender/qgraphicsapifilter.h>
15#include <Qt3DRender/qblendequation.h>
16#include <Qt3DRender/qblendequationarguments.h>
17#include <Qt3DRender/qnodepthmask.h>
18#include <QUrl>
19
20QT_BEGIN_NAMESPACE
21
22using namespace Qt3DRender;
23
24namespace Qt3DExtras {
25
26QTextureMaterialPrivate::QTextureMaterialPrivate()
27 : QMaterialPrivate()
28 , m_textureEffect(new QEffect)
29 , m_textureParameter(new QParameter(QStringLiteral("diffuseTexture"), new QTexture2D))
30 , m_textureTransformParameter(new QParameter(QStringLiteral("texCoordTransform"), QVariant::fromValue(value: QMatrix3x3())))
31 , m_textureGL3Technique(new QTechnique)
32 , m_textureGL2Technique(new QTechnique)
33 , m_textureES2Technique(new QTechnique)
34 , m_textureRHITechnique(new QTechnique)
35 , m_textureGL3RenderPass(new QRenderPass)
36 , m_textureGL2RenderPass(new QRenderPass)
37 , m_textureES2RenderPass(new QRenderPass)
38 , m_textureRHIRenderPass(new QRenderPass)
39 , m_textureGL3Shader(new QShaderProgram)
40 , m_textureGL2ES2Shader(new QShaderProgram)
41 , m_textureRHIShader(new QShaderProgram)
42 , m_noDepthMask(new QNoDepthMask())
43 , m_blendState(new QBlendEquationArguments())
44 , m_blendEquation(new QBlendEquation())
45 , m_filterKey(new QFilterKey)
46{
47}
48
49void QTextureMaterialPrivate::init()
50{
51 connect(sender: m_textureParameter, signal: &Qt3DRender::QParameter::valueChanged,
52 receiverPrivate: this, slot: &QTextureMaterialPrivate::handleTextureChanged);
53 connect(sender: m_textureTransformParameter, signal: &Qt3DRender::QParameter::valueChanged,
54 receiverPrivate: this, slot: &QTextureMaterialPrivate::handleTextureTransformChanged);
55
56 m_textureGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(sourceUrl: QUrl(QStringLiteral("qrc:/shaders/gl3/unlittexture.vert"))));
57 m_textureGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(sourceUrl: QUrl(QStringLiteral("qrc:/shaders/gl3/unlittexture.frag"))));
58 m_textureGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(sourceUrl: QUrl(QStringLiteral("qrc:/shaders/es2/unlittexture.vert"))));
59 m_textureGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(sourceUrl: QUrl(QStringLiteral("qrc:/shaders/es2/unlittexture.frag"))));
60 m_textureRHIShader->setVertexShaderCode(QShaderProgram::loadSource(sourceUrl: QUrl(QStringLiteral("qrc:/shaders/rhi/unlittexture.vert"))));
61 m_textureRHIShader->setFragmentShaderCode(QShaderProgram::loadSource(sourceUrl: QUrl(QStringLiteral("qrc:/shaders/rhi/unlittexture.frag"))));
62
63 m_textureGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
64 m_textureGL3Technique->graphicsApiFilter()->setMajorVersion(3);
65 m_textureGL3Technique->graphicsApiFilter()->setMinorVersion(1);
66 m_textureGL3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile);
67
68 m_textureGL2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
69 m_textureGL2Technique->graphicsApiFilter()->setMajorVersion(2);
70 m_textureGL2Technique->graphicsApiFilter()->setMinorVersion(0);
71 m_textureGL2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
72
73 m_textureES2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGLES);
74 m_textureES2Technique->graphicsApiFilter()->setMajorVersion(2);
75 m_textureES2Technique->graphicsApiFilter()->setMinorVersion(0);
76 m_textureES2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
77
78 m_textureRHITechnique->graphicsApiFilter()->setApi(QGraphicsApiFilter::RHI);
79 m_textureRHITechnique->graphicsApiFilter()->setMajorVersion(1);
80 m_textureRHITechnique->graphicsApiFilter()->setMinorVersion(0);
81
82 m_noDepthMask->setEnabled(false);
83 m_blendState->setEnabled(false);
84 m_blendState->setSourceRgb(QBlendEquationArguments::SourceAlpha);
85 m_blendState->setDestinationRgb(QBlendEquationArguments::OneMinusSourceAlpha);
86 m_blendEquation->setEnabled(false);
87 m_blendEquation->setBlendFunction(QBlendEquation::Add);
88
89 Q_Q(QTextureMaterial);
90 m_filterKey->setParent(q);
91 m_filterKey->setName(QStringLiteral("renderingStyle"));
92 m_filterKey->setValue(QStringLiteral("forward"));
93
94 m_textureGL3Technique->addFilterKey(filterKey: m_filterKey);
95 m_textureGL2Technique->addFilterKey(filterKey: m_filterKey);
96 m_textureES2Technique->addFilterKey(filterKey: m_filterKey);
97 m_textureRHITechnique->addFilterKey(filterKey: m_filterKey);
98
99 m_textureGL3RenderPass->setShaderProgram(m_textureGL3Shader);
100 m_textureGL2RenderPass->setShaderProgram(m_textureGL2ES2Shader);
101 m_textureES2RenderPass->setShaderProgram(m_textureGL2ES2Shader);
102 m_textureRHIRenderPass->setShaderProgram(m_textureRHIShader);
103
104 m_textureGL3RenderPass->addRenderState(state: m_noDepthMask);
105 m_textureGL3RenderPass->addRenderState(state: m_blendState);
106 m_textureGL3RenderPass->addRenderState(state: m_blendEquation);
107
108 m_textureGL2RenderPass->addRenderState(state: m_noDepthMask);
109 m_textureGL2RenderPass->addRenderState(state: m_blendState);
110 m_textureGL2RenderPass->addRenderState(state: m_blendEquation);
111
112 m_textureES2RenderPass->addRenderState(state: m_noDepthMask);
113 m_textureES2RenderPass->addRenderState(state: m_blendState);
114 m_textureES2RenderPass->addRenderState(state: m_blendEquation);
115
116 m_textureRHIRenderPass->addRenderState(state: m_noDepthMask);
117 m_textureRHIRenderPass->addRenderState(state: m_blendState);
118 m_textureRHIRenderPass->addRenderState(state: m_blendEquation);
119
120 m_textureGL3Technique->addRenderPass(pass: m_textureGL3RenderPass);
121 m_textureGL2Technique->addRenderPass(pass: m_textureGL2RenderPass);
122 m_textureES2Technique->addRenderPass(pass: m_textureES2RenderPass);
123 m_textureRHITechnique->addRenderPass(pass: m_textureRHIRenderPass);
124
125 m_textureEffect->addTechnique(t: m_textureGL3Technique);
126 m_textureEffect->addTechnique(t: m_textureGL2Technique);
127 m_textureEffect->addTechnique(t: m_textureES2Technique);
128 m_textureEffect->addTechnique(t: m_textureRHITechnique);
129
130 m_textureEffect->addParameter(parameter: m_textureParameter);
131 m_textureEffect->addParameter(parameter: m_textureTransformParameter);
132
133 q->setEffect(m_textureEffect);
134}
135
136void QTextureMaterialPrivate::handleTextureChanged(const QVariant &var)
137{
138 Q_Q(QTextureMaterial);
139 emit q->textureChanged(texture: var.value<QAbstractTexture *>());
140}
141
142void QTextureMaterialPrivate::handleTextureTransformChanged(const QVariant &var)
143{
144 Q_Q(QTextureMaterial);
145 const QMatrix3x3 matrix = var.value<QMatrix3x3>();
146 emit q->textureTransformChanged(textureTransform: matrix);
147 emit q->textureOffsetChanged(textureOffset: QVector2D(matrix(0, 2), matrix(1, 2)));
148}
149
150/*!
151 \class Qt3DExtras::QTextureMaterial
152 \ingroup qt3d-extras-materials
153 \brief The QTextureMaterial provides a default implementation of a simple unlit
154 texture material.
155 \inmodule Qt3DExtras
156 \since 5.9
157 \inherits Qt3DRender::QMaterial
158
159 This material uses an effect with a single render pass approach. Techniques are provided
160 for OpenGL 2, OpenGL 3 or above as well as OpenGL ES 2.
161*/
162
163/*!
164 Constructs a new QTextureMaterial instance with parent object \a parent.
165 */
166QTextureMaterial::QTextureMaterial(QNode *parent)
167 : QMaterial(*new QTextureMaterialPrivate, parent)
168{
169 Q_D(QTextureMaterial);
170 d->init();
171}
172
173/*!
174 Destroys the QTextureMaterial instance.
175*/
176QTextureMaterial::~QTextureMaterial()
177{
178}
179
180/*!
181 \property QTextureMaterial::texture
182
183 Holds the current texture used by the material.
184*/
185QAbstractTexture *QTextureMaterial::texture() const
186{
187 Q_D(const QTextureMaterial);
188 return d->m_textureParameter->value().value<QAbstractTexture *>();
189}
190
191/*!
192 \property QTextureMaterial::textureOffset
193
194 This is a utility property. It sets the translation component of the general
195 texture transform matrix
196
197*/
198QVector2D QTextureMaterial::textureOffset() const
199{
200 Q_D(const QTextureMaterial);
201 const QMatrix3x3 matrix = d->m_textureTransformParameter->value().value<QMatrix3x3>();
202 return QVector2D(matrix(0, 2), matrix(1, 2));
203}
204
205
206/*!
207 \property QTextureMaterial::textureTransform
208
209 Holds the current texture transform. It is applied to texture
210 coordinates at render time. Defaults to identity matrix.
211
212*/
213QMatrix3x3 QTextureMaterial::textureTransform() const
214{
215 Q_D(const QTextureMaterial);
216 return d->m_textureTransformParameter->value().value<QMatrix3x3>();
217}
218
219void QTextureMaterial::setTexture(QAbstractTexture *texture)
220{
221 Q_D(QTextureMaterial);
222 d->m_textureParameter->setValue(QVariant::fromValue(value: texture));
223}
224
225void QTextureMaterial::setTextureOffset(QVector2D textureOffset)
226{
227 Q_D(QTextureMaterial);
228 QMatrix3x3 matrix = d->m_textureTransformParameter->value().value<QMatrix3x3>();
229 matrix(0, 2) = textureOffset.x();
230 matrix(1, 2) = textureOffset.y();
231 d->m_textureTransformParameter->setValue(QVariant::fromValue(value: matrix));
232}
233
234void QTextureMaterial::setTextureTransform(const QMatrix3x3 &matrix)
235{
236 Q_D(QTextureMaterial);
237 d->m_textureTransformParameter->setValue(QVariant::fromValue(value: matrix));
238}
239
240/*!
241 \property QTextureMaterial::alphaBlending
242
243 Indicates if the alpha information coming from the diffuse property will
244 be taken into account during rendering. Defaults to false.
245*/
246/*!
247 \qmlproperty bool TextureMaterial::alphaBlending
248
249 Indicates if the alpha information coming from the diffuse property will
250 be taken into account during rendering. Defaults to false.
251*/
252bool QTextureMaterial::isAlphaBlendingEnabled() const
253{
254 Q_D(const QTextureMaterial);
255 return d->m_noDepthMask->isEnabled();
256}
257
258void QTextureMaterial::setAlphaBlendingEnabled(bool enabled)
259{
260 Q_D(QTextureMaterial);
261 d->m_noDepthMask->setEnabled(enabled);
262 d->m_blendState->setEnabled(enabled);
263 d->m_blendEquation->setEnabled(enabled);
264}
265
266} // namespace Qt3DExtras
267
268QT_END_NAMESPACE
269
270#include "moc_qtexturematerial.cpp"
271

source code of qt3d/src/extras/defaults/qtexturematerial.cpp