Remove "All rights reserved" line from license headers.
[profile/ivi/qtdeclarative.git] / src / quick / items / qquickshadereffectmesh.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qquickshadereffectmesh_p.h"
43 #include <QtQuick/qsggeometry.h>
44 #include "qquickshadereffect_p.h"
45
46 QT_BEGIN_NAMESPACE
47
48 QQuickShaderEffectMesh::QQuickShaderEffectMesh(QObject *parent)
49     : QObject(parent)
50 {
51 }
52
53 /*!
54     \qmlclass GridMesh QQuickGridMesh
55     \inqmlmodule QtQuick 2
56     \ingroup qml-utility-elements
57     \brief GridMesh defines a mesh with vertices arranged in a grid.
58
59     GridMesh defines a rectangular mesh consisting of vertices arranged in an
60     evenly spaced grid. It is used to generate \l{QSGGeometry}{geometry}.
61     The grid resolution is specified with the \l resolution property.
62 */
63
64 QQuickGridMesh::QQuickGridMesh(QObject *parent)
65     : QQuickShaderEffectMesh(parent)
66     , m_resolution(1, 1)
67 {
68     connect(this, SIGNAL(resolutionChanged()), this, SIGNAL(geometryChanged()));
69 }
70
71 QSGGeometry *QQuickGridMesh::updateGeometry(QSGGeometry *geometry, const QVector<QByteArray> &attributes, const QRectF &dstRect)
72 {
73     int vmesh = m_resolution.height();
74     int hmesh = m_resolution.width();
75     int attrCount = attributes.count();
76
77     int positionIndex = attributes.indexOf(qtPositionAttributeName());
78     int texCoordIndex = attributes.indexOf(qtTexCoordAttributeName());
79
80     if (!geometry) {
81         switch (attrCount) {
82         case 0:
83             m_log = QLatin1String("Error: No attributes specified.");
84             return 0;
85         case 1:
86             if (positionIndex != 0) {
87                 m_log = QLatin1String("Error: Missing \'");
88                 m_log += QLatin1String(qtPositionAttributeName());
89                 m_log += QLatin1String("\' attribute.\n");
90                 return 0;
91             }
92             break;
93         case 2:
94             if (positionIndex == -1 || texCoordIndex == -1) {
95                 m_log.clear();
96                 if (positionIndex == -1) {
97                     m_log = QLatin1String("Error: Missing \'");
98                     m_log += QLatin1String(qtPositionAttributeName());
99                     m_log += QLatin1String("\' attribute.\n");
100                 }
101                 if (texCoordIndex == -1) {
102                     m_log += QLatin1String("Error: Missing \'");
103                     m_log += QLatin1String(qtTexCoordAttributeName());
104                     m_log += QLatin1String("\' attribute.\n");
105                 }
106                 return 0;
107             }
108             break;
109         default:
110             m_log = QLatin1String("Error: Too many attributes specified.");
111             return 0;
112         }
113
114         geometry = new QSGGeometry(attrCount == 1
115                                    ? QSGGeometry::defaultAttributes_Point2D()
116                                    : QSGGeometry::defaultAttributes_TexturedPoint2D(),
117                                    (vmesh + 1) * (hmesh + 1), vmesh * 2 * (hmesh + 2),
118                                    GL_UNSIGNED_SHORT);
119
120     } else {
121         geometry->allocate((vmesh + 1) * (hmesh + 1), vmesh * 2 * (hmesh + 2));
122     }
123
124     QSGGeometry::Point2D *vdata = static_cast<QSGGeometry::Point2D *>(geometry->vertexData());
125
126     QRectF srcRect(0, 0, 1, 1);
127     for (int iy = 0; iy <= vmesh; ++iy) {
128         float fy = iy / float(vmesh);
129         float y = float(dstRect.top()) + fy * float(dstRect.height());
130         float ty = float(srcRect.top()) + fy * float(srcRect.height());
131         for (int ix = 0; ix <= hmesh; ++ix) {
132             float fx = ix / float(hmesh);
133             for (int ia = 0; ia < attrCount; ++ia) {
134                 if (ia == positionIndex) {
135                     vdata->x = float(dstRect.left()) + fx * float(dstRect.width());
136                     vdata->y = y;
137                     ++vdata;
138                 } else {
139                     vdata->x = float(srcRect.left()) + fx * float(srcRect.width());
140                     vdata->y = ty;
141                     ++vdata;
142                 }
143             }
144         }
145     }
146
147     quint16 *indices = (quint16 *)geometry->indexDataAsUShort();
148     int i = 0;
149     for (int iy = 0; iy < vmesh; ++iy) {
150         *(indices++) = i + hmesh + 1;
151         for (int ix = 0; ix <= hmesh; ++ix, ++i) {
152             *(indices++) = i + hmesh + 1;
153             *(indices++) = i;
154         }
155         *(indices++) = i - 1;
156     }
157
158     return geometry;
159 }
160
161 /*!
162     \qmlproperty size QtQuick2::GridMesh::resolution
163
164     This property holds the grid resolution. The resolution's width and height
165     specify the number of cells or spacings between vertices horizontally and
166     vertically respectively. The minimum and default is 1x1, which corresponds
167     to four vertices in total, one in each corner.
168     For non-linear vertex transformations, you probably want to set the
169     resolution higher.
170
171     \row
172     \o \image declarative-gridmesh.png
173     \o \qml
174         import QtQuick 2.0
175
176         ShaderEffect {
177             width: 200
178             height: 200
179             mesh: GridMesh {
180                 resolution: Qt.size(20, 20)
181             }
182             property variant source: Image {
183                 source: "qt-logo.png"
184                 sourceSize { width: 200; height: 200 }
185                 smooth: true
186             }
187             vertexShader: "
188                 uniform highp mat4 qt_Matrix;
189                 attribute highp vec4 qt_Vertex;
190                 attribute highp vec2 qt_MultiTexCoord0;
191                 varying highp vec2 qt_TexCoord0;
192                 uniform highp float width;
193                 void main() {
194                     highp vec4 pos = qt_Vertex;
195                     highp float d = .5 * smoothstep(0., 1., qt_MultiTexCoord0.y);
196                     pos.x = width * mix(d, 1.0 - d, qt_MultiTexCoord0.x);
197                     gl_Position = qt_Matrix * pos;
198                     qt_TexCoord0 = qt_MultiTexCoord0;
199                 }"
200         }
201         \endqml
202     \endrow
203 */
204
205 void QQuickGridMesh::setResolution(const QSize &res)
206 {
207     if (res == m_resolution)
208         return;
209     if (res.width() < 1 || res.height() < 1) {
210         return;
211     }
212     m_resolution = res;
213     emit resolutionChanged();
214 }
215
216 QSize QQuickGridMesh::resolution() const
217 {
218     return m_resolution;
219 }
220
221 QT_END_NAMESPACE