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 | |
20 | QT_BEGIN_NAMESPACE |
21 | |
22 | using namespace Qt3DRender; |
23 | |
24 | namespace Qt3DExtras { |
25 | |
26 | 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 | |
49 | void QTextureMaterialPrivate::() |
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 | |
136 | void QTextureMaterialPrivate::handleTextureChanged(const QVariant &var) |
137 | { |
138 | Q_Q(QTextureMaterial); |
139 | emit q->textureChanged(texture: var.value<QAbstractTexture *>()); |
140 | } |
141 | |
142 | void 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 | */ |
166 | 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 | */ |
176 | QTextureMaterial::() |
177 | { |
178 | } |
179 | |
180 | /*! |
181 | \property QTextureMaterial::texture |
182 | |
183 | Holds the current texture used by the material. |
184 | */ |
185 | QAbstractTexture *QTextureMaterial::() 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 | */ |
198 | QVector2D QTextureMaterial::() 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 | */ |
213 | QMatrix3x3 QTextureMaterial::() const |
214 | { |
215 | Q_D(const QTextureMaterial); |
216 | return d->m_textureTransformParameter->value().value<QMatrix3x3>(); |
217 | } |
218 | |
219 | void QTextureMaterial::(QAbstractTexture *texture) |
220 | { |
221 | Q_D(QTextureMaterial); |
222 | d->m_textureParameter->setValue(QVariant::fromValue(value: texture)); |
223 | } |
224 | |
225 | void QTextureMaterial::(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 | |
234 | void QTextureMaterial::(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 | */ |
252 | bool QTextureMaterial::() const |
253 | { |
254 | Q_D(const QTextureMaterial); |
255 | return d->m_noDepthMask->isEnabled(); |
256 | } |
257 | |
258 | void QTextureMaterial::(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 | |
268 | QT_END_NAMESPACE |
269 | |
270 | #include "moc_qtexturematerial.cpp" |
271 | |