1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qsgtexturematerial_p.h"
44 #include <QtGui/qopenglshaderprogram.h>
45 #include <QtGui/qopenglfunctions.h>
49 inline static bool isPowerOfTwo(int x)
55 const char qt_scenegraph_texture_material_vertex_code[] =
56 "uniform highp mat4 qt_Matrix; \n"
57 "attribute highp vec4 qt_VertexPosition; \n"
58 "attribute highp vec2 qt_VertexTexCoord; \n"
59 "varying highp vec2 qt_TexCoord; \n"
61 " qt_TexCoord = qt_VertexTexCoord; \n"
62 " gl_Position = qt_Matrix * qt_VertexPosition; \n"
65 const char qt_scenegraph_texture_material_fragment[] =
66 "varying highp vec2 qt_TexCoord; \n"
67 "uniform sampler2D qt_Texture; \n"
69 " gl_FragColor = texture2D(qt_Texture, qt_TexCoord);\n"
73 const char *QSGOpaqueTextureMaterialShader::vertexShader() const
75 return qt_scenegraph_texture_material_vertex_code;
78 const char *QSGOpaqueTextureMaterialShader::fragmentShader() const
80 return qt_scenegraph_texture_material_fragment;
83 QSGMaterialType QSGOpaqueTextureMaterialShader::type;
85 char const *const *QSGOpaqueTextureMaterialShader::attributeNames() const
87 static char const *const attr[] = { "qt_VertexPosition", "qt_VertexTexCoord", 0 };
91 void QSGOpaqueTextureMaterialShader::initialize()
93 m_matrix_id = program()->uniformLocation("qt_Matrix");
96 void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
98 Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type());
99 QSGOpaqueTextureMaterial *tx = static_cast<QSGOpaqueTextureMaterial *>(newEffect);
100 QSGOpaqueTextureMaterial *oldTx = static_cast<QSGOpaqueTextureMaterial *>(oldEffect);
102 QSGTexture *t = tx->texture();
104 t->setFiltering(tx->filtering());
105 #ifdef QT_OPENGL_ES_2
106 bool npotSupported = QOpenGLFunctions(const_cast<QOpenGLContext *>(state.context())).hasOpenGLFeature(QOpenGLFunctions::NPOTTextures);
107 QSize size = t->textureSize();
108 bool isNpot = !isPowerOfTwo(size.width()) || !isPowerOfTwo(size.height());
109 if (!npotSupported && isNpot) {
110 t->setHorizontalWrapMode(QSGTexture::ClampToEdge);
111 t->setVerticalWrapMode(QSGTexture::ClampToEdge);
115 t->setHorizontalWrapMode(tx->horizontalWrapMode());
116 t->setVerticalWrapMode(tx->verticalWrapMode());
118 t->setMipmapFiltering(tx->mipmapFiltering());
120 if (oldTx == 0 || oldTx->texture()->textureId() != t->textureId())
123 t->updateBindOptions();
125 if (state.isMatrixDirty())
126 program()->setUniformValue(m_matrix_id, state.combinedMatrix());
131 \class QSGOpaqueTextureMaterial
132 \brief The QSGOpaqueTextureMaterial class provides a convenient way of
133 rendering textured geometry in the scene graph.
135 The opaque textured material will fill every pixel in a geometry with
136 the supplied texture. The material does not respect the opacity of the
137 QSGMaterialShader::RenderState, so opacity nodes in the parent chain
138 of nodes using this material, have no effect.
140 The geometry to be rendered with an opaque texture material requires
141 vertices in attribute location 0 and texture coordinates in attribute
142 location 1. The texture coordinate is a 2-dimensional floating-point
143 tuple. The QSGGeometry::defaultAttributes_TexturedPoint2D returns an
144 attribute set compatible with this material.
146 The texture to be rendered is can be set using setTexture(). How the
147 texure should be rendered can be specified using setMipmapFiltering(),
148 setFiltering(), setHorizontalWrapMode() and setVerticalWrapMode().
149 The rendering state is set on the texture instance just before it
152 The opaque textured material respects the current matrix and the alpha
153 channel of the texture. It will disregard the accumulated opacity in
156 A texture material must have a texture set before it is used as
157 a material in the scene graph.
163 Creates a new QSGOpaqueTextureMaterial.
165 The default mipmap filtering and filtering mode is set to
166 QSGTexture::Nearest. The default wrap modes is set to
167 QSGTexture::ClampToEdge.
170 QSGOpaqueTextureMaterial::QSGOpaqueTextureMaterial()
172 , m_filtering(QSGTexture::Nearest)
173 , m_mipmap_filtering(QSGTexture::Nearest)
174 , m_horizontal_wrap(QSGTexture::ClampToEdge)
175 , m_vertical_wrap(QSGTexture::ClampToEdge)
183 QSGMaterialType *QSGOpaqueTextureMaterial::type() const
185 return &QSGOpaqueTextureMaterialShader::type;
191 QSGMaterialShader *QSGOpaqueTextureMaterial::createShader() const
193 return new QSGOpaqueTextureMaterialShader;
199 \fn QSGTexture *QSGOpaqueTextureMaterial::texture() const
201 Returns this texture material's texture.
207 Sets the texture of this material to \a texture.
209 The material does not take ownership over the texture.
212 void QSGOpaqueTextureMaterial::setTexture(QSGTexture *texture)
215 setFlag(Blending, m_texture ? m_texture->hasAlphaChannel() : false);
221 \fn void QSGOpaqueTextureMaterial::setMipmapFiltering(QSGTexture::Filtering filtering)
223 Sets the mipmap mode to \a filtering.
225 The mipmap filtering mode is set on the texture instance just before the
226 texture is bound for rendering.
228 If the texture does not have mipmapping support, enabling mipmapping has no
235 \fn QSGTexture::Filtering QSGOpaqueTextureMaterial::mipmapFiltering() const
237 Returns this material's mipmap filtering mode.
239 The default mipmap mode is QSGTexture::Nearest.
245 \fn void QSGOpaqueTextureMaterial::setFiltering(QSGTexture::Filtering filtering)
247 Sets the filtering to \a filtering.
249 The filtering mode is set on the texture instance just before the texture
250 is bound for rendering.
256 \fn QSGTexture::Filtering filtering() const
258 Returns this material's filtering mode.
260 The default filtering is QSGTexture::Nearest.
266 \fn void setHorizontalWrapMode(QSGTexture::WrapMode mode)
268 Sets the horizontal wrap mode to \a mode.
270 The horizontal wrap mode is set on the texture instance just before the texture
271 is bound for rendering.
277 \fn QSGTexture::WrapMode horizontalWrapMode() const
279 Returns this material's horizontal wrap mode.
281 The default horizontal wrap mode is QSGTexutre::ClampToEdge
287 \fn void setVerticalWrapMode(QSGTexture::WrapMode mode)
289 Sets the vertical wrap mode to \a mode.
291 The vertical wrap mode is set on the texture instance just before the texture
292 is bound for rendering.
298 \fn QSGTexture::WrapMode verticalWrapMode() const
300 Returns this material's vertical wrap mode.
302 The default vertical wrap mode is QSGTexutre::ClampToEdge
311 int QSGOpaqueTextureMaterial::compare(const QSGMaterial *o) const
313 Q_ASSERT(o && type() == o->type());
314 const QSGOpaqueTextureMaterial *other = static_cast<const QSGOpaqueTextureMaterial *>(o);
315 if (int diff = m_texture->textureId() - other->texture()->textureId())
317 return int(m_filtering) - int(other->m_filtering);
323 \class QSGTextureMaterial
324 \brief The QSGTextureMaterial class provides a convenient way of
325 rendering textured geometry in the scene graph.
327 The textured material will fill every pixel in a geometry with
328 the supplied texture.
330 The geometry to be rendered with a texture material requires
331 vertices in attribute location 0 and texture coordinates in attribute
332 location 1. The texture coordinate is a 2-dimensional floating-point
333 tuple. The QSGGeometry::defaultAttributes_TexturedPoint2D returns an
334 attribute set compatible with this material.
336 The texture to be rendered is set using setTexture(). How the
337 texure should be rendered can be specified using setMipmapFiltering(),
338 setFiltering(), setHorizontalWrapMode() and setVerticalWrapMode().
339 The rendering state is set on the texture instance just before it
342 The textured material respects the current matrix and the alpha
343 channel of the texture. It will also respect the accumulated opacity
346 A texture material must have a texture set before it is used as
347 a material in the scene graph.
350 static const char qt_scenegraph_texture_material_opacity_fragment[] =
351 "varying highp vec2 qt_TexCoord; \n"
352 "uniform sampler2D qt_Texture; \n"
353 "uniform lowp float opacity; \n"
355 " gl_FragColor = texture2D(qt_Texture, qt_TexCoord) * opacity; \n"
358 class QSGTextureMaterialShader : public QSGOpaqueTextureMaterialShader
361 virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
362 virtual void initialize();
364 static QSGMaterialType type;
367 virtual const char *fragmentShader() const { return qt_scenegraph_texture_material_opacity_fragment; }
371 QSGMaterialType QSGTextureMaterialShader::type;
379 QSGMaterialType *QSGTextureMaterial::type() const
381 return &QSGTextureMaterialShader::type;
390 QSGMaterialShader *QSGTextureMaterial::createShader() const
392 return new QSGTextureMaterialShader;
395 void QSGTextureMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
397 Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type());
398 if (state.isOpacityDirty())
399 program()->setUniformValue(m_opacity_id, state.opacity());
401 QSGOpaqueTextureMaterialShader::updateState(state, newEffect, oldEffect);
404 void QSGTextureMaterialShader::initialize()
406 QSGOpaqueTextureMaterialShader::initialize();
407 m_opacity_id = program()->uniformLocation("opacity");