Commit 02b5213289ed51b32a0e2376b947610e2e8e4646

QGLVertexArray is dead, long live QGLVertexBuffer.
  
217217 pageFlipMath.setShowPageReverse(false);
218218 pageFlipMath.compute(posn);
219219
220 QGLVertexArray vertices(QGL::Position, 2, QGL::TextureCoord0, 2,
221 QGL::CustomVertex0, 1);
222 vertices.setRawData(pageFlipMath.vertexArray(), 4 * 5 * 5);
220 QGLAttributeValue positions
221 (2, GL_FLOAT, pageFlipMath.stride(), pageFlipMath.vertexArray());
222 QGLAttributeValue texCoords
223 (2, GL_FLOAT, pageFlipMath.stride(), pageFlipMath.vertexArray() + 2);
224 QGLAttributeValue gradientCoords
225 (1, GL_FLOAT, pageFlipMath.stride(), pageFlipMath.vertexArray() + 4);
223226
224227#if defined(QT_OPENGL_ES_1)
225228 painter.setStandardEffect(QGL::FlatReplaceTexture2D);
232232 painter.setColor(colors[colorIndex]);
233233 painter.setTexture(0, &(textures[colorIndex]));
234234 painter.setTexture(1, &gradientTexture);
235 painter.setVertexArray(vertices);
235 painter.setVertexAttribute(QGL::Position, positions);
236 painter.setVertexAttribute(QGL::TextureCoord0, texCoords);
237 painter.setVertexAttribute(QGL::CustomVertex0, gradientCoords);
236238 setAlphaValue(1.0f);
237239 painter.update();
238240 pageFlipMath.drawPage(0);
265265 painter.setTexture(1, (QGLTexture2D *)0);
266266
267267 painter.setStandardEffect(QGL::FlatColor);
268 painter.setVertexArray(vertices);
268 painter.setVertexAttribute(QGL::Position, positions);
269 painter.setVertexAttribute(QGL::TextureCoord0, texCoords);
270 painter.setVertexAttribute(QGL::CustomVertex0, gradientCoords);
269271 painter.setColor(QColor(0, 0, 0, 255));
270272 painter.update();
271273 pageFlipMath.drawOutline(2);
  
8585 const GLfloat *vertexArray() const { return vertices[0][0]; }
8686
8787 // Get the vertex array stride in bytes.
88 int stride() const { return 5 * 5 * sizeof(GLfloat); }
88 int stride() const { return 5 * sizeof(GLfloat); }
8989
9090 // Draw a specific page.
9191 void drawPage(int page) const;
  
4141
4242#include "qglheightmap.h"
4343#include <QVector3D>
44#include "qglvertexarray.h"
4544#include "qgldisplaylist.h"
4645#include "qgloperation.h"
4746
  
4444#include "qglcube.h"
4545#include "qglteapot.h"
4646#include "qglsphere.h"
47#include "qglvertexarray.h"
4847#include <math.h>
4948#include <QVector3D>
5049#include "qglheightmap.h"
  
4141
4242#include "triplane.h"
4343
44#include "qglvertexarray.h"
44#include "qglvertexbuffer.h"
4545#include "qglindexarray.h"
4646#include "qglpainter.h"
4747#include "qline3d.h"
110110 // pointers to minimize copies) to do the next column
111111 QLine3D *l0 = &sideLine;
112112 QLine3D *l1 = &nxSideLine;
113 QGLVertexArray vertices(QGL::Position, 3);
113 QVector3DArray vertices;
114114 for (int col = 0; col < divisions; ++col)
115115 {
116116 // ternary ops here are avoiding fmuls & rounding errors at bounds
127127 vertices.append(l1->point(t));
128128 }
129129 qSwap(l0, l1);
130 g->setVertexArray(vertices);
130 QGLVertexBuffer *buffer = new QGLVertexBuffer();
131 buffer->addAttribute(QGL::Position, vertices);
132 g->setVertexBuffer(buffer);
131133 mStrips.append(g);
132134 }
133135
  
870870
871871 QCOMPARE(displayList.sections().count(), 0);
872872
873#if 0 // TODO: needs to check the vertex buffer instead
873874 QGeometryData *geom = node->geometry();
874875
875876 QGLVertexArray verts = geom->toVertexArray();
920920 QCOMPARE(verts2.vector3DAt(tri, desc.indexOf(QGL::Position)), e);
921921 QCOMPARE(verts2.vector3DAt(tri, desc.indexOf(QGL::Normal)), n10);
922922 QCOMPARE(verts2.vector2DAt(tri, desc.indexOf(QGL::TextureCoord0)), ta);
923#endif
923924}
924925
925926QTEST_APPLESS_MAIN(tst_QGLDisplayList)
  
5858{
5959 QGLGeometry geom;
6060 QCOMPARE(geom.drawingMode(), QGL::NoDrawingMode);
61 QVERIFY(geom.vertexArray().isEmpty());
6261 QVERIFY(geom.indexArray().isEmpty());
6362 QCOMPARE(geom.bufferThreshold(), 32);
6463 QVERIFY(geom.boundingBox().isNull());
6565
6666void tst_QGLGeometry::accessors()
6767{
68 QGLVertexArray array;
6968 QGLGeometry geom;
70 geom.setVertexArray(array);
71 QCOMPARE(geom.vertexArray(), array);
72 array << QVector3D(1.0, 2.0, 3.0);
73 QVERIFY(geom.vertexArray() != array);
74 geom.setVertexArray(array);
75 QCOMPARE(geom.vertexArray(), array);
7669 QGLIndexArray indexes;
7770 indexes.append(1, 2, 3, 4);
7871 geom.setIndexArray(indexes);
  
8282}
8383
8484// Draw a set of triangles from a vertex array.
85void QGLSimulator::drawTriangles(const QGLVertexArray& array)
85void QGLSimulator::drawTriangles(const QVector2DArray& array)
8686{
8787 QVector<QPointF> points;
8888
89 int field = array.fieldIndex(QGL::Position);
90 if (field == -1)
91 return;
92 int size = array.fields().fieldSize(field);
89 for (int index = 0; index < array.count(); ++index) {
90 QVector3D v = array[index];
91 points.append(project(v));
92 }
9393
94 for (int index = 0; index < array.vertexCount(); ++index) {
95 QVector3D v;
96 if (size == 3)
97 v = array.vector3DAt(index, field);
98 else
99 v = array.vector2DAt(index, field);
94 m_painter->drawPolygon(points);
95}
96
97void QGLSimulator::drawTriangles(const QVector3DArray& array)
98{
99 QVector<QPointF> points;
100
101 for (int index = 0; index < array.count(); ++index) {
102 QVector3D v = array[index];
100103 points.append(project(v));
101104 }
102105
  
4646#include <QtGui/qcolor.h>
4747#include <QtGui/qmatrix4x4.h>
4848#include <QtGui/qvector3d.h>
49#include "qglvertexarray.h"
49#include "qvectorarray.h"
5050
5151class QGLSimulator
5252{
7070
7171 void setColor(const QColor& color);
7272
73 void drawTriangles(const QGLVertexArray& array);
73 void drawTriangles(const QVector2DArray& array);
74 void drawTriangles(const QVector3DArray& array);
7475
7576private:
7677 QPainter *m_painter;
  
118118 painter.projectionMatrix().ortho(widget->rect());
119119 painter.modelViewMatrix().setToIdentity();
120120
121 QGLVertexArray vertices(QGL::Position, 2);
121 QVector2DArray vertices;
122122 vertices.append(10, 100);
123123 vertices.append(500, 100);
124124 vertices.append(500, 500);
125125
126126 painter.setStandardEffect(QGL::FlatColor);
127127 painter.setColor(Qt::green);
128 painter.setVertexArray(vertices);
128 painter.setVertexAttribute(QGL::Position, vertices);
129129 painter.draw(QGL::Triangles, 3);
130130}
131131
140140 proj.ortho(widget->rect());
141141 sim.setProjectionMatrix(proj);
142142
143 QGLVertexArray vertices(QGL::Position, 2);
143 QVector2DArray vertices;
144144 vertices.append(10, 100);
145145 vertices.append(500, 100);
146146 vertices.append(500, 500);
  
1load(qttest_p4.prf)
2TARGET=qglvertexarray
3TEMPLATE=app
4QT += testlib
5CONFIG += unittest warn_on
6
7SOURCES += tst_qglvertexarray.cpp
8
9LIBS += -L../../../../lib -L../../../../bin
10
11include(../../../../threed/threed_dep.pri)
  
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the Qt3D module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** No Commercial Usage
11** This file contains pre-release code and may not be distributed.
12** You may use this file in accordance with the terms and conditions
13** contained in the Technology Preview License Agreement accompanying
14** this package.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** If you have questions regarding the use of this file, please contact
29** Nokia at qt-info@nokia.com.
30**
31**
32**
33**
34**
35**
36**
37**
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <QtTest/QtTest>
43#include "qglvertexarray.h"
44
45class tst_QGLVertexArray : public QObject
46{
47 Q_OBJECT
48public:
49 tst_QGLVertexArray() {}
50 ~tst_QGLVertexArray() {}
51
52private slots:
53 void create();
54 void addField();
55 void copy();
56 void append1D();
57 void append2D();
58 void append3D();
59 void append4D();
60 void appendLots();
61 void setFloatAt();
62 void setVector2DAt();
63 void setVector3DAt();
64 void setVector4DAt();
65 void extractAndInterleave();
66 void operatorEquals();
67};
68
69void tst_QGLVertexArray::create()
70{
71 QGLVertexArray array;
72 QCOMPARE(array.stride(), 0);
73 QCOMPARE(array.vertexCount(), 0);
74 QCOMPARE(array.componentCount(), 0);
75 QCOMPARE(array.fieldCount(), 0);
76 QVERIFY(array.isEmpty());
77 QVERIFY(array.data() == 0);
78 QVERIFY(array.constData() == 0);
79
80 array.reserve(100);
81 QCOMPARE(array.stride(), 0);
82 QCOMPARE(array.vertexCount(), 0);
83 QCOMPARE(array.componentCount(), 0);
84 QCOMPARE(array.fieldCount(), 0);
85 QVERIFY(array.isEmpty());
86 QVERIFY(array.data() == 0);
87 QVERIFY(array.constData() == 0);
88
89 array.append(1.0f, 2.0f, 3.0f);
90 QCOMPARE(array.stride(), 0);
91 QCOMPARE(array.vertexCount(), 3);
92 QCOMPARE(array.componentCount(), 3);
93 QCOMPARE(array.fieldCount(), 0);
94 QVERIFY(!array.isEmpty());
95
96 array.addField(QGL::Normal, 3);
97 QCOMPARE(array.stride(), 3);
98 QCOMPARE(array.vertexCount(), 1);
99 QCOMPARE(array.componentCount(), 3);
100 QCOMPARE(array.fieldCount(), 1);
101 QVERIFY(!array.isEmpty());
102 QVERIFY(array.fields().fieldAttribute(0) == QGL::Normal);
103 QVERIFY(array.fields().fieldSize(0) == 3);
104 QVERIFY(array.fields().fieldOffset(0) == 0);
105 QVERIFY(array.attributeValue(1).isNull());
106 QVERIFY(!array.attributeValue(0).isNull());
107 QVERIFY(array.attributeValue(-1).isNull());
108 QVERIFY(array.vector3DAt(0, 0) == QVector3D(1.0f, 2.0f, 3.0f));
109 QVERIFY(array.attributeValue(QGL::Normal).tupleSize() == 3);
110 QVERIFY(array.attributeValue(QGL::Position).isNull());
111}
112
113void tst_QGLVertexArray::addField()
114{
115 QGLVertexArray array1(QGL::Normal, 3);
116 QCOMPARE(array1.stride(), 3);
117 QCOMPARE(array1.vertexCount(), 0);
118 QCOMPARE(array1.componentCount(), 0);
119 QCOMPARE(array1.fieldCount(), 1);
120 QVERIFY(array1.isEmpty());
121 QVERIFY(array1.fields().fieldAttribute(0) == QGL::Normal);
122 QVERIFY(array1.fields().fieldSize(0) == 3);
123 QVERIFY(array1.fields().fieldOffset(0) == 0);
124
125 QGLVertexArray array2(QGL::Normal, 3, QGL::TextureCoord0, 2);
126 QCOMPARE(array2.stride(), 5);
127 QCOMPARE(array2.vertexCount(), 0);
128 QCOMPARE(array2.componentCount(), 0);
129 QCOMPARE(array2.fieldCount(), 2);
130 QVERIFY(array2.isEmpty());
131 QVERIFY(array2.fields().fieldAttribute(0) == QGL::Normal);
132 QVERIFY(array2.fields().fieldSize(0) == 3);
133 QVERIFY(array2.fields().fieldOffset(0) == 0);
134 QVERIFY(array2.fields().fieldAttribute(1) == QGL::TextureCoord0);
135 QVERIFY(array2.fields().fieldSize(1) == 2);
136 QVERIFY(array2.fields().fieldOffset(1) == 3);
137
138 QGLVertexArray array3(QGL::Normal, 3, QGL::TextureCoord0, 2,
139 QGL::Position, 1);
140 QCOMPARE(array3.stride(), 6);
141 QCOMPARE(array3.vertexCount(), 0);
142 QCOMPARE(array3.componentCount(), 0);
143 QCOMPARE(array3.fieldCount(), 3);
144 QVERIFY(array3.isEmpty());
145 QVERIFY(array3.fields().fieldAttribute(0) == QGL::Normal);
146 QVERIFY(array3.fields().fieldSize(0) == 3);
147 QVERIFY(array3.fields().fieldOffset(0) == 0);
148 QVERIFY(array3.fields().fieldAttribute(1) == QGL::TextureCoord0);
149 QVERIFY(array3.fields().fieldSize(1) == 2);
150 QVERIFY(array3.fields().fieldOffset(1) == 3);
151 QVERIFY(array3.fields().fieldAttribute(2) == QGL::Position);
152 QVERIFY(array3.fields().fieldSize(2) == 1);
153 QVERIFY(array3.fields().fieldOffset(2) == 5);
154
155 QGLVertexArray array4(QGL::Normal, 3, QGL::TextureCoord0, 2,
156 QGL::Position, 1, QGL::Color, 4);
157 QCOMPARE(array4.stride(), 10);
158 QCOMPARE(array4.vertexCount(), 0);
159 QCOMPARE(array4.componentCount(), 0);
160 QCOMPARE(array4.fieldCount(), 4);
161 QVERIFY(array4.isEmpty());
162 QVERIFY(array4.fields().fieldAttribute(0) == QGL::Normal);
163 QVERIFY(array4.fields().fieldSize(0) == 3);
164 QVERIFY(array4.fields().fieldOffset(0) == 0);
165 QVERIFY(array4.fields().fieldAttribute(1) == QGL::TextureCoord0);
166 QVERIFY(array4.fields().fieldSize(1) == 2);
167 QVERIFY(array4.fields().fieldOffset(1) == 3);
168 QVERIFY(array4.fields().fieldAttribute(2) == QGL::Position);
169 QVERIFY(array4.fields().fieldSize(2) == 1);
170 QVERIFY(array4.fields().fieldOffset(2) == 5);
171 QVERIFY(array4.fields().fieldAttribute(3) == QGL::Color);
172 QVERIFY(array4.fields().fieldSize(3) == 4);
173 QVERIFY(array4.fields().fieldOffset(3) == 6);
174
175 array1.addField(QGL::TextureCoord0, 2);
176 QCOMPARE(array1.stride(), 5);
177 QCOMPARE(array1.vertexCount(), 0);
178 QCOMPARE(array1.componentCount(), 0);
179 QCOMPARE(array1.fieldCount(), 2);
180 QVERIFY(array1.isEmpty());
181 QVERIFY(array1.fields().fieldAttribute(0) == QGL::Normal);
182 QVERIFY(array1.fields().fieldSize(0) == 3);
183 QVERIFY(array1.fields().fieldOffset(0) == 0);
184 QVERIFY(array1.fields().fieldAttribute(1) == QGL::TextureCoord0);
185 QVERIFY(array1.fields().fieldSize(1) == 2);
186 QVERIFY(array1.fields().fieldOffset(1) == 3);
187
188 array1.addField(QGL::Position, 1);
189 QCOMPARE(array1.stride(), 6);
190 QCOMPARE(array1.vertexCount(), 0);
191 QCOMPARE(array1.componentCount(), 0);
192 QCOMPARE(array1.fieldCount(), 3);
193 QVERIFY(array1.isEmpty());
194 QVERIFY(array1.fields().fieldAttribute(0) == QGL::Normal);
195 QVERIFY(array1.fields().fieldSize(0) == 3);
196 QVERIFY(array1.fields().fieldOffset(0) == 0);
197 QVERIFY(array1.fields().fieldAttribute(1) == QGL::TextureCoord0);
198 QVERIFY(array1.fields().fieldSize(1) == 2);
199 QVERIFY(array1.fields().fieldOffset(1) == 3);
200 QVERIFY(array1.fields().fieldAttribute(2) == QGL::Position);
201 QVERIFY(array1.fields().fieldSize(2) == 1);
202 QVERIFY(array1.fields().fieldOffset(2) == 5);
203
204 array1.addField(QGL::Color, 4);
205 QCOMPARE(array1.stride(), 10);
206 QCOMPARE(array1.vertexCount(), 0);
207 QCOMPARE(array1.componentCount(), 0);
208 QCOMPARE(array1.fieldCount(), 4);
209 QVERIFY(array1.isEmpty());
210 QVERIFY(array1.fields().fieldAttribute(0) == QGL::Normal);
211 QVERIFY(array1.fields().fieldSize(0) == 3);
212 QVERIFY(array1.fields().fieldOffset(0) == 0);
213 QVERIFY(array1.fields().fieldAttribute(1) == QGL::TextureCoord0);
214 QVERIFY(array1.fields().fieldSize(1) == 2);
215 QVERIFY(array1.fields().fieldOffset(1) == 3);
216 QVERIFY(array1.fields().fieldAttribute(2) == QGL::Position);
217 QVERIFY(array1.fields().fieldSize(2) == 1);
218 QVERIFY(array1.fields().fieldOffset(2) == 5);
219 QVERIFY(array1.fields().fieldAttribute(3) == QGL::Color);
220 QVERIFY(array1.fields().fieldSize(3) == 4);
221 QVERIFY(array1.fields().fieldOffset(3) == 6);
222
223 QVERIFY(array1.attributeValue(QGL::CustomVertex2).isNull());
224}
225
226void tst_QGLVertexArray::copy()
227{
228 QGLVertexArray array(QGL::Position, 3);
229 array.append(1.0f, 2.0f, 3.0f);
230 QCOMPARE(array.stride(), 3);
231 QCOMPARE(array.vertexCount(), 1);
232
233 // Copy the array and check its contents.
234 QGLVertexArray array2;
235 array2 = array;
236 QCOMPARE(array2.stride(), 3);
237 QCOMPARE(array2.vertexCount(), 1);
238 QVERIFY(!array2.isEmpty());
239 QVERIFY(array2.data() != 0);
240 QVERIFY(array2.constData() != 0);
241 QVERIFY(array2.vector3DAt(0, 0) == QVector3D(1.0f, 2.0f, 3.0f));
242
243 // Modify the original and check that the copy is unchanged.
244 array.setAt(0, 0, QVector3D(4.0f, 5.0f, 6.0f));
245 QVERIFY(array.vector3DAt(0, 0) == QVector3D(4.0f, 5.0f, 6.0f));
246 QCOMPARE(array2.stride(), 3);
247 QCOMPARE(array2.vertexCount(), 1);
248 QVERIFY(!array2.isEmpty());
249 QVERIFY(array2.data() != 0);
250 QVERIFY(array2.constData() != 0);
251 QVERIFY(array2.vector3DAt(0, 0) == QVector3D(1.0f, 2.0f, 3.0f));
252
253 // Copy the original back in.
254 array2 = array;
255 QCOMPARE(array2.stride(), 3);
256 QCOMPARE(array2.vertexCount(), 1);
257 QVERIFY(!array2.isEmpty());
258 QVERIFY(array2.data() != 0);
259 QVERIFY(array2.constData() != 0);
260 QVERIFY(array2.vector3DAt(0, 0) == QVector3D(4.0f, 5.0f, 6.0f));
261
262 // Copy the array using the constructor form.
263 QGLVertexArray array3(array);
264 QCOMPARE(array3.stride(), 3);
265 QCOMPARE(array3.vertexCount(), 1);
266 QVERIFY(!array3.isEmpty());
267 QVERIFY(array3.data() != 0);
268 QVERIFY(array3.constData() != 0);
269 QVERIFY(array3.vector3DAt(0, 0) == QVector3D(4.0f, 5.0f, 6.0f));
270
271 // Modify the original and check that the copy is unchanged.
272 array.setAt(0, 0, QVector3D(1.0f, 2.0f, 3.0f));
273 QVERIFY(array.vector3DAt(0, 0) == QVector3D(1.0f, 2.0f, 3.0f));
274 QCOMPARE(array3.stride(), 3);
275 QCOMPARE(array3.vertexCount(), 1);
276 QVERIFY(!array3.isEmpty());
277 QVERIFY(array3.data() != 0);
278 QVERIFY(array3.constData() != 0);
279 QVERIFY(array3.vector3DAt(0, 0) == QVector3D(4.0f, 5.0f, 6.0f));
280}
281
282void tst_QGLVertexArray::append1D()
283{
284 QGLVertexArray array(QGL::Position, 1);
285 array.append(1.0f);
286 array.append(2.0f);
287 array.append(3.0f);
288 QCOMPARE(array.floatAt(-1, 0), (qreal)0.0f);
289 QCOMPARE(array.floatAt(0, 0), (qreal)1.0f);
290 QCOMPARE(array.floatAt(1, 0), (qreal)2.0f);
291 QCOMPARE(array.floatAt(2, 0), (qreal)3.0f);
292 QCOMPARE(array.floatAt(3, 0), (qreal)0.0f);
293 QCOMPARE(array.stride(), 1);
294 QCOMPARE(array.vertexCount(), 3);
295 QVERIFY(array.vector3DAt(0, 0) == QVector3D(1.0f, 2.0f, 3.0f));
296
297 QGLVertexArray array2(QGL::Position, 3);
298 array2.append(1.0f);
299 array2.append(2.0f);
300 array2.append(3.0f);
301 array2.append(4.0f, 5.0f, 6.0f);
302 QCOMPARE(array2.stride(), 3);
303 QCOMPARE(array2.vertexCount(), 2);
304 QCOMPARE(array2.floatAt(0, 0), (qreal)1.0f);
305 QCOMPARE(array2.floatAt(1, 0), (qreal)4.0f);
306 QVERIFY(array2.vector2DAt(0, 0) == QVector2D(1.0f, 2.0f));
307 QVERIFY(array2.vector2DAt(1, 0) == QVector2D(4.0f, 5.0f));
308 QVERIFY(array2.vector3DAt(0, 0) == QVector3D(1.0f, 2.0f, 3.0f));
309 QVERIFY(array2.vector3DAt(1, 0) == QVector3D(4.0f, 5.0f, 6.0f));
310 QVERIFY(array2.vector4DAt(0, 0) == QVector4D(1.0f, 2.0f, 3.0f, 4.0f));
311
312 array2.append(7.0f, 8.0f);
313 QCOMPARE(array2.stride(), 3);
314 QCOMPARE(array2.vertexCount(), 2);
315 array2.append(9.0f);
316 QCOMPARE(array2.stride(), 3);
317 QCOMPARE(array2.vertexCount(), 3);
318 QVERIFY(array2.vector3DAt(2, 0) == QVector3D(7.0f, 8.0f, 9.0f));
319 QVERIFY(array2.vector4DAt(1, 0) == QVector4D(4.0f, 5.0f, 6.0f, 7.0f));
320
321 QGLVertexArray array3(QGL::Position, 3, QGL::Normal, 3);
322 array3.append(1.0f);
323 array3.append(2.0f);
324 array3.append(3.0f);
325 array3.append(4.0f, 5.0f, 6.0f);
326 QCOMPARE(array3.stride(), 6);
327 QCOMPARE(array3.vertexCount(), 1);
328 QCOMPARE(array3.floatAt(0, 0), (qreal)1.0f);
329 QCOMPARE(array3.floatAt(0, 1), (qreal)4.0f);
330 QVERIFY(array3.vector2DAt(0, 0) == QVector2D(1.0f, 2.0f));
331 QVERIFY(array3.vector2DAt(0, 1) == QVector2D(4.0f, 5.0f));
332 QVERIFY(array3.vector3DAt(0, 0) == QVector3D(1.0f, 2.0f, 3.0f));
333 QVERIFY(array3.vector3DAt(0, 1) == QVector3D(4.0f, 5.0f, 6.0f));
334}
335
336void tst_QGLVertexArray::append2D()
337{
338 QGLVertexArray array(QGL::Position, 2);
339 array.append(1.0f, 2.0f);
340 array.append(3.0f, 4.0f);
341 QCOMPARE(array.floatAt(0, 0), (qreal)1.0f);
342 QCOMPARE(array.floatAt(1, 0), (qreal)3.0f);
343 QVERIFY(array.vector2DAt(-1, 0).isNull());
344 QVERIFY(array.vector2DAt(0, 0) == QVector2D(1.0f, 2.0f));
345 QVERIFY(array.vector2DAt(1, 0) == QVector2D(3.0f, 4.0f));
346 QVERIFY(array.vector2DAt(2, 0).isNull());
347 QCOMPARE(array.stride(), 2);
348 QCOMPARE(array.vertexCount(), 2);
349 QVERIFY(array.vector3DAt(0, 0) == QVector3D(1.0f, 2.0f, 3.0f));
350 QVERIFY(array.vector4DAt(0, 0) == QVector4D(1.0f, 2.0f, 3.0f, 4.0f));
351
352 QGLVertexArray array2(QGL::Position, 3);
353 array2.append(1.0f, 2.0f);
354 array2.append(3.0f, 4.0f);
355 array2.append(5.0f, 6.0f);
356 array2.append(7.0f, 8.0f, 9.0f);
357 QCOMPARE(array2.stride(), 3);
358 QCOMPARE(array2.vertexCount(), 3);
359 QCOMPARE(array2.floatAt(0, 0), (qreal)1.0f);
360 QCOMPARE(array2.floatAt(1, 0), (qreal)4.0f);
361 QCOMPARE(array2.floatAt(2, 0), (qreal)7.0f);
362 QVERIFY(array2.vector2DAt(0, 0) == QVector2D(1.0f, 2.0f));
363 QVERIFY(array2.vector2DAt(1, 0) == QVector2D(4.0f, 5.0f));
364 QVERIFY(array2.vector2DAt(2, 0) == QVector2D(7.0f, 8.0f));
365 QVERIFY(array2.vector3DAt(0, 0) == QVector3D(1.0f, 2.0f, 3.0f));
366 QVERIFY(array2.vector3DAt(1, 0) == QVector3D(4.0f, 5.0f, 6.0f));
367 QVERIFY(array2.vector3DAt(2, 0) == QVector3D(7.0f, 8.0f, 9.0f));
368 QVERIFY(array2.vector4DAt(0, 0) == QVector4D(1.0f, 2.0f, 3.0f, 4.0f));
369 QVERIFY(array2.vector4DAt(1, 0) == QVector4D(4.0f, 5.0f, 6.0f, 7.0f));
370 QVERIFY(array2.vector4DAt(2, 0).isNull());
371
372 array2.append(10.0f, 11.0f);
373 QCOMPARE(array2.stride(), 3);
374 QCOMPARE(array2.vertexCount(), 3);
375 array2.append(12.0f);
376 QVERIFY(array2.vector4DAt(2, 0) == QVector4D(7.0f, 8.0f, 9.0f, 10.0f));
377 QCOMPARE(array2.stride(), 3);
378 QCOMPARE(array2.vertexCount(), 4);
379 QVERIFY(array2.vector3DAt(3, 0) == QVector3D(10.0f, 11.0f, 12.0f));
380
381 QGLVertexArray array3(QGL::Position, 2, QGL::TextureCoord0, 2);
382 array3.append(1.0f, 2.0f);
383 array3.append(3.0f, 4.0f);
384 QCOMPARE(array3.stride(), 4);
385 QCOMPARE(array3.vertexCount(), 1);
386 QCOMPARE(array3.floatAt(0, 0), (qreal)1.0f);
387 QCOMPARE(array3.floatAt(0, 1), (qreal)3.0f);
388 QVERIFY(array3.vector2DAt(0, 0) == QVector2D(1.0f, 2.0f));
389 QVERIFY(array3.vector2DAt(0, 1) == QVector2D(3.0f, 4.0f));
390 QVERIFY(array3.vector3DAt(0, 0) == QVector3D(1.0f, 2.0f, 3.0f));
391 QVERIFY(array3.vector3DAt(0, 1).isNull());
392 QVERIFY(array3.vector4DAt(0, 0) == QVector4D(1.0f, 2.0f, 3.0f, 4.0f));
393 QVERIFY(array3.vector4DAt(0, 1).isNull());
394}
395
396void tst_QGLVertexArray::append3D()
397{
398 QGLVertexArray array(QGL::Position, 3);
399 array.append(1.0f, 2.0f, 3.0f);
400 array.append(4.0f, 5.0f, 6.0f);
401 QCOMPARE(array.floatAt(0, 0), (qreal)1.0f);
402 QCOMPARE(array.floatAt(1, 0), (qreal)4.0f);
403 QVERIFY(array.vector2DAt(0, 0) == QVector2D(1.0f, 2.0f));
404 QVERIFY(array.vector2DAt(1, 0) == QVector2D(4.0f, 5.0f));
405 QVERIFY(array.vector3DAt(-1, 0).isNull());
406 QVERIFY(array.vector3DAt(0, 0) == QVector3D(1.0f, 2.0f, 3.0f));
407 QVERIFY(array.vector3DAt(1, 0) == QVector3D(4.0f, 5.0f, 6.0f));
408 QVERIFY(array.vector3DAt(2, 0).isNull());
409 QCOMPARE(array.stride(), 3);
410 QCOMPARE(array.vertexCount(), 2);
411 QVERIFY(array.vector4DAt(0, 0) == QVector4D(1.0f, 2.0f, 3.0f, 4.0f));
412 QVERIFY(array.vector4DAt(1, 0).isNull());
413
414 QGLVertexArray array2(QGL::Position, 4);
415 array2.append(1.0f, 2.0f, 3.0f);
416 array2.append(4.0f, 5.0f, 6.0f);
417 array2.append(7.0f, 8.0f, 9.0f);
418 QCOMPARE(array2.stride(), 4);
419 QCOMPARE(array2.vertexCount(), 2);
420 QCOMPARE(array2.floatAt(0, 0), (qreal)1.0f);
421 QCOMPARE(array2.floatAt(1, 0), (qreal)5.0f);
422 QCOMPARE(array2.floatAt(2, 0), (qreal)9.0f);
423 QVERIFY(array2.vector2DAt(0, 0) == QVector2D(1.0f, 2.0f));
424 QVERIFY(array2.vector2DAt(1, 0) == QVector2D(5.0f, 6.0f));
425 QVERIFY(array2.vector3DAt(0, 0) == QVector3D(1.0f, 2.0f, 3.0f));
426 QVERIFY(array2.vector3DAt(1, 0) == QVector3D(5.0f, 6.0f, 7.0f));
427 QVERIFY(array2.vector3DAt(2, 0).isNull());
428 QVERIFY(array2.vector4DAt(0, 0) == QVector4D(1.0f, 2.0f, 3.0f, 4.0f));
429 QVERIFY(array2.vector4DAt(1, 0) == QVector4D(5.0f, 6.0f, 7.0f, 8.0f));
430 QVERIFY(array2.vector4DAt(2, 0).isNull());
431
432 array2.append(10.0f, 11.0f, 12.0f);
433 QCOMPARE(array2.stride(), 4);
434 QCOMPARE(array2.vertexCount(), 3);
435 QCOMPARE(array2.floatAt(2, 0), (qreal)9.0f);
436 QVERIFY(array2.vector2DAt(2, 0) == QVector2D(9.0f, 10.0f));
437 QVERIFY(array2.vector3DAt(2, 0) == QVector3D(9.0f, 10.0f, 11.0f));
438 QVERIFY(array2.vector4DAt(2, 0) == QVector4D(9.0f, 10.0f, 11.0f, 12.0f));
439
440 QGLVertexArray array3(QGL::Position, 2, QGL::TextureCoord0, 2);
441 array3.append(1.0f, 2.0f, 3.0f);
442 array3.append(4.0f, 5.0f, 6.0f);
443 array3.append(7.0f, 8.0f, 9.0f);
444 QCOMPARE(array3.stride(), 4);
445 QCOMPARE(array3.vertexCount(), 2);
446 QCOMPARE(array3.floatAt(0, 0), (qreal)1.0f);
447 QCOMPARE(array3.floatAt(0, 1), (qreal)3.0f);
448 QCOMPARE(array3.floatAt(1, 0), (qreal)5.0f);
449 QCOMPARE(array3.floatAt(1, 1), (qreal)7.0f);
450 QVERIFY(array3.vector2DAt(0, 0) == QVector2D(1.0f, 2.0f));
451 QVERIFY(array3.vector2DAt(0, 1) == QVector2D(3.0f, 4.0f));
452 QVERIFY(array3.vector2DAt(1, 0) == QVector2D(5.0f, 6.0f));
453 QVERIFY(array3.vector2DAt(1, 1) == QVector2D(7.0f, 8.0f));
454 QVERIFY(array3.vector3DAt(0, 0) == QVector3D(1.0f, 2.0f, 3.0f));
455 QVERIFY(array3.vector3DAt(0, 1) == QVector3D(3.0f, 4.0f, 5.0f));
456 QVERIFY(array3.vector3DAt(1, 0) == QVector3D(5.0f, 6.0f, 7.0f));
457 QVERIFY(array3.vector3DAt(1, 1) == QVector3D(7.0f, 8.0f, 9.0f));
458 QVERIFY(array3.vector4DAt(0, 0) == QVector4D(1.0f, 2.0f, 3.0f, 4.0f));
459 QVERIFY(array3.vector4DAt(0, 1) == QVector4D(3.0f, 4.0f, 5.0f, 6.0f));
460 QVERIFY(array3.vector4DAt(1, 0) == QVector4D(5.0f, 6.0f, 7.0f, 8.0f));
461 QVERIFY(array3.vector4DAt(1, 1).isNull());
462}
463
464void tst_QGLVertexArray::append4D()
465{
466 QGLVertexArray array(QGL::Position, 4);
467 array.append(1.0f, 2.0f, 3.0f, 4.0f);
468 array.append(5.0f, 6.0f, 7.0f, 8.0f);
469 QCOMPARE(array.floatAt(0, 0), (qreal)1.0f);
470 QCOMPARE(array.floatAt(1, 0), (qreal)5.0f);
471 QVERIFY(array.vector2DAt(0, 0) == QVector2D(1.0f, 2.0f));
472 QVERIFY(array.vector2DAt(1, 0) == QVector2D(5.0f, 6.0f));
473 QVERIFY(array.vector3DAt(0, 0) == QVector3D(1.0f, 2.0f, 3.0f));
474 QVERIFY(array.vector3DAt(1, 0) == QVector3D(5.0f, 6.0f, 7.0f));
475 QVERIFY(array.vector3DAt(2, 0).isNull());
476 QVERIFY(array.vector4DAt(0, 0) == QVector4D(1.0f, 2.0f, 3.0f, 4.0f));
477 QVERIFY(array.vector4DAt(1, 0) == QVector4D(5.0f, 6.0f, 7.0f, 8.0f));
478 QVERIFY(array.vector4DAt(2, 0).isNull());
479 QCOMPARE(array.stride(), 4);
480 QCOMPARE(array.vertexCount(), 2);
481
482 QGLVertexArray array2(QGL::Position, 3);
483 array2.append(1.0f, 2.0f, 3.0f, 4.0f);
484 array2.append(5.0f, 6.0f, 7.0f, 8.0f);
485 array2.append(9.0f, 10.0f, 11.0f, 12.0f);
486 QCOMPARE(array2.stride(), 3);
487 QCOMPARE(array2.vertexCount(), 4);
488 QCOMPARE(array2.floatAt(0, 0), (qreal)1.0f);
489 QCOMPARE(array2.floatAt(1, 0), (qreal)4.0f);
490 QCOMPARE(array2.floatAt(2, 0), (qreal)7.0f);
491 QCOMPARE(array2.floatAt(3, 0), (qreal)10.0f);
492 QVERIFY(array2.vector2DAt(0, 0) == QVector2D(1.0f, 2.0f));
493 QVERIFY(array2.vector2DAt(1, 0) == QVector2D(4.0f, 5.0f));
494 QVERIFY(array2.vector2DAt(2, 0) == QVector2D(7.0f, 8.0f));
495 QVERIFY(array2.vector2DAt(3, 0) == QVector2D(10.0f, 11.0f));
496 QVERIFY(array2.vector3DAt(0, 0) == QVector3D(1.0f, 2.0f, 3.0f));
497 QVERIFY(array2.vector3DAt(1, 0) == QVector3D(4.0f, 5.0f, 6.0f));
498 QVERIFY(array2.vector3DAt(2, 0) == QVector3D(7.0f, 8.0f, 9.0f));
499 QVERIFY(array2.vector3DAt(3, 0) == QVector3D(10.0f, 11.0f, 12.0f));
500 QVERIFY(array2.vector4DAt(0, 0) == QVector4D(1.0f, 2.0f, 3.0f, 4.0f));
501 QVERIFY(array2.vector4DAt(1, 0) == QVector4D(4.0f, 5.0f, 6.0f, 7.0f));
502 QVERIFY(array2.vector4DAt(2, 0) == QVector4D(7.0f, 8.0f, 9.0f, 10.0f));
503 QVERIFY(array2.vector4DAt(3, 0).isNull());
504
505 array2.append(13.0f, 14.0f, 15.0f);
506 QCOMPARE(array2.stride(), 3);
507 QCOMPARE(array2.vertexCount(), 5);
508 QCOMPARE(array2.floatAt(4, 0), (qreal)13.0f);
509 QVERIFY(array2.vector2DAt(4, 0) == QVector2D(13.0f, 14.0f));
510 QVERIFY(array2.vector3DAt(4, 0) == QVector3D(13.0f, 14.0f, 15.0f));
511 QVERIFY(array2.vector4DAt(4, 0).isNull());
512 array2.append(16.0f);
513 QVERIFY(array2.vector3DAt(5, 0).isNull());
514 QVERIFY(array2.vector4DAt(4, 0) == QVector4D(13.0f, 14.0f, 15.0f, 16.0f));
515
516 QGLVertexArray array3(QGL::Position, 2, QGL::TextureCoord0, 2);
517 array3.append(1.0f, 2.0f, 3.0f, 4.0f);
518 array3.append(5.0f, 6.0f, 7.0f, 8.0f);
519 QCOMPARE(array3.stride(), 4);
520 QCOMPARE(array3.vertexCount(), 2);
521 QCOMPARE(array3.floatAt(0, 0), (qreal)1.0f);
522 QCOMPARE(array3.floatAt(0, 1), (qreal)3.0f);
523 QCOMPARE(array3.floatAt(1, 0), (qreal)5.0f);
524 QCOMPARE(array3.floatAt(1, 1), (qreal)7.0f);
525 QVERIFY(array3.vector2DAt(0, 0) == QVector2D(1.0f, 2.0f));
526 QVERIFY(array3.vector2DAt(0, 1) == QVector2D(3.0f, 4.0f));
527 QVERIFY(array3.vector2DAt(1, 0) == QVector2D(5.0f, 6.0f));
528 QVERIFY(array3.vector2DAt(1, 1) == QVector2D(7.0f, 8.0f));
529 QVERIFY(array3.vector3DAt(0, 0) == QVector3D(1.0f, 2.0f, 3.0f));
530 QVERIFY(array3.vector3DAt(0, 1) == QVector3D(3.0f, 4.0f, 5.0f));
531 QVERIFY(array3.vector3DAt(1, 0) == QVector3D(5.0f, 6.0f, 7.0f));
532 QVERIFY(array3.vector3DAt(1, 1).isNull());
533 QVERIFY(array3.vector4DAt(0, 0) == QVector4D(1.0f, 2.0f, 3.0f, 4.0f));
534 QVERIFY(array3.vector4DAt(0, 1) == QVector4D(3.0f, 4.0f, 5.0f, 6.0f));
535 QVERIFY(array3.vector4DAt(1, 0) == QVector4D(5.0f, 6.0f, 7.0f, 8.0f));
536 QVERIFY(array3.vector4DAt(1, 1).isNull());
537}
538
539void tst_QGLVertexArray::appendLots()
540{
541 QGLVertexArray array(QGL::Color, 4);
542 int index;
543
544 for (index = 0; index < 2048; ++index)
545 array.append((qreal)index);
546
547 QCOMPARE(array.stride(), 4);
548 QCOMPARE(array.vertexCount(), 2048 / 4);
549
550 for (index = 0; index < 2048; index += 4) {
551 QVERIFY(array.vector4DAt(index / 4, 0) == QVector4D(index, index + 1, index + 2, index + 3));
552 }
553}
554
555void tst_QGLVertexArray::setFloatAt()
556{
557 QGLVertexArray array(QGL::Position, 1);
558 QCOMPARE(array.floatAt(0, 0), (qreal)0.0f);
559
560 array.append(1.0f);
561 QCOMPARE(array.floatAt(0, 0), (qreal)1.0f);
562 QCOMPARE(array.floatAt(-1, 0), (qreal)0.0f);
563 QCOMPARE(array.floatAt(1, 0), (qreal)0.0f);
564
565 array.setAt(0, 0, 6.0f);
566 QCOMPARE(array.floatAt(0, 0), (qreal)6.0f);
567
568 array.append(2.0f);
569 QCOMPARE(array.floatAt(0, 0), (qreal)6.0f);
570 QCOMPARE(array.floatAt(1, 0), (qreal)2.0f);
571
572 array.setAt(1, 0, 7.0f);
573 QCOMPARE(array.floatAt(0, 0), (qreal)6.0f);
574 QCOMPARE(array.floatAt(1, 0), (qreal)7.0f);
575
576 array.setAt(0, 0, 3.0f, 4.0f);
577 QCOMPARE(array.floatAt(0, 0), (qreal)3.0f);
578 QCOMPARE(array.floatAt(1, 0), (qreal)4.0f);
579 QVERIFY(array.vector2DAt(0, 0) == QVector2D(3.0f, 4.0f));
580 QVERIFY(array.vector2DAt(1, 0).isNull());
581
582 array.setAt(0, 0, QVector2D(1.0f, 2.0f));
583 QCOMPARE(array.floatAt(0, 0), (qreal)1.0f);
584 QCOMPARE(array.floatAt(1, 0), (qreal)2.0f);
585 QVERIFY(array.vector2DAt(0, 0) == QVector2D(1.0f, 2.0f));
586 QVERIFY(array.vector2DAt(1, 0).isNull());
587
588 // Out of range set should change nothing.
589 array.setAt(0, 0, QVector3D(4.0f, 5.0f, 6.0f));
590 QCOMPARE(array.floatAt(0, 0), (qreal)1.0f);
591 QCOMPARE(array.floatAt(1, 0), (qreal)2.0f);
592 QVERIFY(array.vector2DAt(0, 0) == QVector2D(1.0f, 2.0f));
593 QVERIFY(array.vector2DAt(1, 0).isNull());
594
595 QGLVertexArray array2(QGL::Position, 3, QGL::TextureCoord0, 2);
596 array2.append(1.0f, 2.0f, 3.0f);
597 array2.append(4.0f, 5.0f);
598 array2.setAt(0, 0, 6.0f);
599 array2.setAt(0, 1, 7.0f);
600 QVERIFY(array2.vector2DAt(0, 0) == QVector2D(6.0f, 2.0f));
601 QVERIFY(array2.vector2DAt(0, 1) == QVector2D(7.0f, 5.0f));
602}
603
604void tst_QGLVertexArray::setVector2DAt()
605{
606 QGLVertexArray array(QGL::Position, 2);
607 QVERIFY(array.vector2DAt(0, 0).isNull());
608
609 array.append(1.0f, 2.0f);
610 array.append(3.0f, 4.0f);
611 QVERIFY(array.vector2DAt(0, 0) == QVector2D(1.0f, 2.0f));
612 QVERIFY(array.vector2DAt(1, 0) == QVector2D(3.0f, 4.0f));
613
614 array.setAt(0, 0, 6.0f, 7.0f);
615 array.setAt(1, 0, QVector2D(8.0f, 9.0f));
616 QVERIFY(array.vector2DAt(0, 0) == QVector2D(6.0f, 7.0f));
617 QVERIFY(array.vector2DAt(1, 0) == QVector2D(8.0f, 9.0f));
618
619 // Out of range set should change nothing.
620 array.setAt(1, 0, QVector3D(4.0f, 5.0f, 6.0f));
621 QVERIFY(array.vector2DAt(0, 0) == QVector2D(6.0f, 7.0f));
622 QVERIFY(array.vector2DAt(1, 0) == QVector2D(8.0f, 9.0f));
623
624 QGLVertexArray array2(QGL::Position, 3, QGL::TextureCoord0, 2);
625 array2.append(1.0f, 2.0f, 3.0f);
626 array2.append(4.0f, 5.0f);
627 array2.setAt(0, 0, 6.0f, 7.0f);
628 array2.setAt(0, 1, QVector2D(8.0f, 9.0f));
629 QVERIFY(array2.vector2DAt(0, 0) == QVector2D(6.0f, 7.0f));
630 QVERIFY(array2.vector2DAt(0, 1) == QVector2D(8.0f, 9.0f));
631}
632
633void tst_QGLVertexArray::setVector3DAt()
634{
635 QGLVertexArray array(QGL::Position, 3);
636 QVERIFY(array.vector3DAt(0, 0).isNull());
637
638 array.append(1.0f, 2.0f, 3.0f);
639 array.append(4.0f, 5.0f, 6.0f);
640 QVERIFY(array.vector3DAt(0, 0) == QVector3D(1.0f, 2.0f, 3.0f));
641 QVERIFY(array.vector3DAt(1, 0) == QVector3D(4.0f, 5.0f, 6.0f));
642
643 array.setAt(0, 0, 7.0f, 8.0f, 9.0f);
644 array.setAt(1, 0, QVector3D(10.0f, 11.0f, 12.0f));
645 QVERIFY(array.vector3DAt(0, 0) == QVector3D(7.0f, 8.0f, 9.0f));
646 QVERIFY(array.vector3DAt(1, 0) == QVector3D(10.0f, 11.0f, 12.0f));
647
648 // Out of range set should change nothing.
649 array.setAt(1, 0, QVector4D(20.0f, 21.0f, 22.0f, 23.0f));
650 QVERIFY(array.vector3DAt(0, 0) == QVector3D(7.0f, 8.0f, 9.0f));
651 QVERIFY(array.vector3DAt(1, 0) == QVector3D(10.0f, 11.0f, 12.0f));
652
653 QGLVertexArray array2(QGL::Position, 3, QGL::Normal, 3);
654 array2.append(1.0f, 2.0f, 3.0f);
655 array2.append(4.0f, 5.0f, 6.0f);
656 array2.setAt(0, 0, 6.0f, 7.0f, 8.0f);
657 array2.setAt(0, 1, QVector3D(9.0f, 10.0f, 11.0f));
658 QVERIFY(array2.vector3DAt(0, 0) == QVector3D(6.0f, 7.0f, 8.0f));
659 QVERIFY(array2.vector3DAt(0, 1) == QVector3D(9.0f, 10.0f, 11.0f));
660}
661
662void tst_QGLVertexArray::setVector4DAt()
663{
664 QGLVertexArray array(QGL::Position, 4);
665 QVERIFY(array.vector4DAt(0, 0).isNull());
666
667 array.append(1.0f, 2.0f, 3.0f, 4.0f);
668 array.append(5.0f, 6.0f, 7.0f, 8.0f);
669 QVERIFY(array.vector4DAt(0, 0) == QVector4D(1.0f, 2.0f, 3.0f, 4.0f));
670 QVERIFY(array.vector4DAt(1, 0) == QVector4D(5.0f, 6.0f, 7.0f, 8.0f));
671
672 array.setAt(0, 0, 7.0f, 8.0f, 9.0f, 10.0f);
673 array.setAt(1, 0, QVector4D(11.0f, 12.0f, 13.0f, 14.0f));
674 QVERIFY(array.vector4DAt(0, 0) == QVector4D(7.0f, 8.0f, 9.0f, 10.0f));
675 QVERIFY(array.vector4DAt(1, 0) == QVector4D(11.0f, 12.0f, 13.0f, 14.0f));
676
677 QGLVertexArray array2(QGL::Position, 4, QGL::Color, 4);
678 array2.append(1.0f, 2.0f, 3.0f, 4.0f);
679 array2.append(5.0f, 6.0f, 7.0f, 8.0f);
680 array2.setAt(0, 0, 6.0f, 7.0f, 8.0f, 9.0f);
681 array2.setAt(0, 1, QVector4D(9.0f, 10.0f, 11.0f, 12.0f));
682 QVERIFY(array2.vector4DAt(0, 0) == QVector4D(6.0f, 7.0f, 8.0f, 9.0f));
683 QVERIFY(array2.vector4DAt(0, 1) == QVector4D(9.0f, 10.0f, 11.0f, 12.0f));
684}
685
686void tst_QGLVertexArray::extractAndInterleave()
687{
688 QGLVertexArray array(QGL::Position, 2, QGL::TextureCoord0, 2);
689 array.append(1.0f, 2.0f, 3.0f, 4.0f);
690 array.append(5.0f, 6.0f, 7.0f, 8.0f);
691
692 QGLVertexArray array2 = array.extractField(0);
693 QGLVertexArray array3 = array.extractField(QGL::TextureCoord0);
694
695 QCOMPARE(array2.stride(), 2);
696 QCOMPARE(array2.vertexCount(), 2);
697 QCOMPARE(array2.fieldCount(), 1);
698 QVERIFY(array2.fields().fieldAttribute(0) == QGL::Position);
699 QVERIFY(array2.fields().fieldSize(0) == 2);
700 QVERIFY(array2.fields().fieldOffset(0) == 0);
701 QVERIFY(array2.vector2DAt(0, 0) == QVector2D(1.0f, 2.0f));
702 QVERIFY(array2.vector2DAt(1, 0) == QVector2D(5.0f, 6.0f));
703
704 QCOMPARE(array3.stride(), 2);
705 QCOMPARE(array3.vertexCount(), 2);
706 QCOMPARE(array3.fieldCount(), 1);
707 QVERIFY(array3.fields().fieldAttribute(0) == QGL::TextureCoord0);
708 QVERIFY(array3.fields().fieldSize(0) == 2);
709 QVERIFY(array3.fields().fieldOffset(0) == 0);
710 QVERIFY(array3.vector2DAt(0, 0) == QVector2D(3.0f, 4.0f));
711 QVERIFY(array3.vector2DAt(1, 0) == QVector2D(7.0f, 8.0f));
712
713 array3.append(9.0f, 10.0f);
714
715 QGLVertexArray array4 = array2.interleaved(array3);
716 QCOMPARE(array4.stride(), 4);
717 QCOMPARE(array4.vertexCount(), 3);
718
719 QVERIFY(array4.vector2DAt(0, 0) == array.vector2DAt(0, 0));
720 QVERIFY(array4.vector2DAt(0, 1) == array.vector2DAt(0, 1));
721 QVERIFY(array4.vector2DAt(1, 0) == array.vector2DAt(1, 0));
722 QVERIFY(array4.vector2DAt(1, 1) == array.vector2DAt(1, 1));
723 QVERIFY(array4.vector2DAt(2, 0) == QVector2D(0.0f, 0.0f));
724 QVERIFY(array4.vector2DAt(2, 1) == QVector2D(9.0f, 10.0f));
725}
726
727void tst_QGLVertexArray::operatorEquals()
728{
729 QGLVertexArray array(QGL::Position, 2, QGL::TextureCoord0, 2);
730 array.append(1.0f, 2.0f, 3.0f, 4.0f);
731 array.append(5.0f, 6.0f, 7.0f, 8.0f);
732
733 QGLVertexArray array2(QGL::Position, 2, QGL::TextureCoord0, 2); // null array
734 QGLVertexArray array3(QGL::Position, 2, QGL::TextureCoord0, 2); // contains same items
735 array3.append(1.0f, 2.0f, 3.0f, 4.0f);
736 array3.append(5.0f, 6.0f, 7.0f, 8.0f);
737 QGLVertexArray array4(QGL::Position, 2, QGL::TextureCoord0, 2); // another null
738 QGLVertexArray array5(QGL::Position, 2, QGL::TextureCoord0, 2); // contains same number of items, but they differ
739 array5.append(1.0f, 2.0f, 3.0f, 4.0f);
740 array5.append(5.0f, 8.0f, 9.0f, 8.0f);
741 QGLVertexArray array6(QGL::Position, 2, QGL::TextureCoord0, 2); // contains different number of items
742 array6.append(1.0f, 2.0f, 3.0f, 4.0f);
743 array6.append(5.0f, 6.0f, 7.0f, 8.0f);
744 array6.append(1.0f, 2.0f, 3.0f, 4.0f);
745 array6.append(5.0f, 6.0f, 7.0f, 8.0f);
746
747 QCOMPARE(array, array); // calls operator == under the hood, should be self equal
748 QVERIFY(!(array == array2)); // not equal to a null
749 QCOMPARE(array, array3); // same items, should be equal
750 QVERIFY(!(array == array5)); // same item count, but contents differ: !=
751 QVERIFY(!(array == array6)); // different item count, should (quickly) return false
752
753 QCOMPARE(array2, array2); // should be self equal, even tho' null
754 QVERIFY(!(array2 == array3)); // null not equal, other way round
755 QCOMPARE(array2, array4); // two null arrays equal
756}
757
758QTEST_APPLESS_MAIN(tst_QGLVertexArray)
759
760#include "tst_qglvertexarray.moc"
  
1load(qttest_p4.prf)
2TARGET=qglvertexdescription
3TEMPLATE=app
4QT += testlib
5CONFIG += unittest warn_on
6
7SOURCES += tst_qglvertexdescription.cpp
8
9LIBS += -L../../../../lib -L../../../../bin
10
11include(../../../../threed/threed_dep.pri)
  
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the Qt3D module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** No Commercial Usage
11** This file contains pre-release code and may not be distributed.
12** You may use this file in accordance with the terms and conditions
13** contained in the Technology Preview License Agreement accompanying
14** this package.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** If you have questions regarding the use of this file, please contact
29** Nokia at qt-info@nokia.com.
30**
31**
32**
33**
34**
35**
36**
37**
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <QtTest/QtTest>
43#include "qglvertexdescription.h"
44
45class tst_QGLVertexDescription : public QObject
46{
47 Q_OBJECT
48public:
49 tst_QGLVertexDescription() {}
50 ~tst_QGLVertexDescription() {}
51
52private slots:
53 void create();
54 void addField();
55};
56
57void tst_QGLVertexDescription::create()
58{
59 QGLVertexDescription desc;
60 QCOMPARE(desc.stride(), 0);
61 QCOMPARE(desc.fieldCount(), 0);
62
63 desc.addField(QGL::Normal, 3);
64 QCOMPARE(desc.stride(), 3);
65 QCOMPARE(desc.fieldCount(), 1);
66 QVERIFY(desc.fieldAttribute(0) == QGL::Normal);
67 QCOMPARE(desc.fieldSize(0), 3);
68 QCOMPARE(desc.fieldOffset(0), 0);
69 QCOMPARE(desc.indexOf(QGL::Normal), 0);
70 QCOMPARE(desc.indexOf(QGL::Position), -1);
71
72 // Out of range field indexes.
73 QVERIFY(desc.fieldAttribute(1) == QGL::Position);
74 QCOMPARE(desc.fieldSize(1), 0);
75 QCOMPARE(desc.fieldOffset(1), 0);
76 QVERIFY(desc.fieldAttribute(-1) == QGL::Position);
77 QCOMPARE(desc.fieldSize(-1), 0);
78 QCOMPARE(desc.fieldOffset(-1), 0);
79}
80
81void tst_QGLVertexDescription::addField()
82{
83 QGLVertexDescription desc1;
84 desc1.addField(QGL::Normal, 3);
85 QCOMPARE(desc1.stride(), 3);
86 QCOMPARE(desc1.fieldCount(), 1);
87 QVERIFY(desc1.fieldAttribute(0) == QGL::Normal);
88 QVERIFY(desc1.fieldSize(0) == 3);
89 QVERIFY(desc1.fieldOffset(0) == 0);
90
91 QGLVertexDescription desc2;
92 desc2.addField(QGL::Normal, 3);
93 desc2.addField(QGL::TextureCoord0, 2);
94 QCOMPARE(desc2.stride(), 5);
95 QCOMPARE(desc2.fieldCount(), 2);
96 QVERIFY(desc2.fieldAttribute(0) == QGL::Normal);
97 QVERIFY(desc2.fieldSize(0) == 3);
98 QVERIFY(desc2.fieldOffset(0) == 0);
99 QVERIFY(desc2.fieldAttribute(1) == QGL::TextureCoord0);
100 QVERIFY(desc2.fieldSize(1) == 2);
101 QVERIFY(desc2.fieldOffset(1) == 3);
102
103 QGLVertexDescription desc3;
104 desc3.addField(QGL::Normal, 3);
105 desc3.addField(QGL::TextureCoord0, 2);
106 desc3.addField(QGL::Position, 1);
107 QCOMPARE(desc3.stride(), 6);
108 QCOMPARE(desc3.fieldCount(), 3);
109 QVERIFY(desc3.fieldAttribute(0) == QGL::Normal);
110 QVERIFY(desc3.fieldSize(0) == 3);
111 QVERIFY(desc3.fieldOffset(0) == 0);
112 QVERIFY(desc3.fieldAttribute(1) == QGL::TextureCoord0);
113 QVERIFY(desc3.fieldSize(1) == 2);
114 QVERIFY(desc3.fieldOffset(1) == 3);
115 QVERIFY(desc3.fieldAttribute(2) == QGL::Position);
116 QVERIFY(desc3.fieldSize(2) == 1);
117 QVERIFY(desc3.fieldOffset(2) == 5);
118
119 QGLVertexDescription desc4;
120 desc4.addField(QGL::Normal, 3);
121 desc4.addField(QGL::TextureCoord0, 2);
122 desc4.addField(QGL::Position, 1);
123 desc4.addField(QGL::Color, 4);
124 QCOMPARE(desc4.stride(), 10);
125 QCOMPARE(desc4.fieldCount(), 4);
126 QVERIFY(desc4.fieldAttribute(0) == QGL::Normal);
127 QVERIFY(desc4.fieldSize(0) == 3);
128 QVERIFY(desc4.fieldOffset(0) == 0);
129 QVERIFY(desc4.fieldAttribute(1) == QGL::TextureCoord0);
130 QVERIFY(desc4.fieldSize(1) == 2);
131 QVERIFY(desc4.fieldOffset(1) == 3);
132 QVERIFY(desc4.fieldAttribute(2) == QGL::Position);
133 QVERIFY(desc4.fieldSize(2) == 1);
134 QVERIFY(desc4.fieldOffset(2) == 5);
135 QVERIFY(desc4.fieldAttribute(3) == QGL::Color);
136 QVERIFY(desc4.fieldSize(3) == 4);
137 QVERIFY(desc4.fieldOffset(3) == 6);
138
139 desc1.addField(QGL::TextureCoord0, 2);
140 QCOMPARE(desc1.stride(), 5);
141 QCOMPARE(desc1.fieldCount(), 2);
142 QVERIFY(desc1.fieldAttribute(0) == QGL::Normal);
143 QVERIFY(desc1.fieldSize(0) == 3);
144 QVERIFY(desc1.fieldOffset(0) == 0);
145 QVERIFY(desc1.fieldAttribute(1) == QGL::TextureCoord0);
146 QVERIFY(desc1.fieldSize(1) == 2);
147 QVERIFY(desc1.fieldOffset(1) == 3);
148
149 desc1.addField(QGL::Position, 1);
150 QCOMPARE(desc1.stride(), 6);
151 QCOMPARE(desc1.fieldCount(), 3);
152 QVERIFY(desc1.fieldAttribute(0) == QGL::Normal);
153 QVERIFY(desc1.fieldSize(0) == 3);
154 QVERIFY(desc1.fieldOffset(0) == 0);
155 QVERIFY(desc1.fieldAttribute(1) == QGL::TextureCoord0);
156 QVERIFY(desc1.fieldSize(1) == 2);
157 QVERIFY(desc1.fieldOffset(1) == 3);
158 QVERIFY(desc1.fieldAttribute(2) == QGL::Position);
159 QVERIFY(desc1.fieldSize(2) == 1);
160 QVERIFY(desc1.fieldOffset(2) == 5);
161
162 desc1.addField(QGL::Color, 4);
163 QCOMPARE(desc1.stride(), 10);
164 QCOMPARE(desc1.fieldCount(), 4);
165 QVERIFY(desc1.fieldAttribute(0) == QGL::Normal);
166 QVERIFY(desc1.fieldSize(0) == 3);
167 QVERIFY(desc1.fieldOffset(0) == 0);
168 QVERIFY(desc1.fieldAttribute(1) == QGL::TextureCoord0);
169 QVERIFY(desc1.fieldSize(1) == 2);
170 QVERIFY(desc1.fieldOffset(1) == 3);
171 QVERIFY(desc1.fieldAttribute(2) == QGL::Position);
172 QVERIFY(desc1.fieldSize(2) == 1);
173 QVERIFY(desc1.fieldOffset(2) == 5);
174 QVERIFY(desc1.fieldAttribute(3) == QGL::Color);
175 QVERIFY(desc1.fieldSize(3) == 4);
176 QVERIFY(desc1.fieldOffset(3) == 6);
177
178 QCOMPARE(desc1.indexOf(QGL::Normal), 0);
179 QCOMPARE(desc1.indexOf(QGL::TextureCoord0), 1);
180 QCOMPARE(desc1.indexOf(QGL::Position), 2);
181 QCOMPARE(desc1.indexOf(QGL::Color), 3);
182 QCOMPARE(desc1.indexOf(QGL::CustomVertex0), -1);
183}
184
185QTEST_APPLESS_MAIN(tst_QGLVertexDescription)
186
187#include "tst_qglvertexdescription.moc"
  
1111 qgllightmodel \
1212 qgllightparameters \
1313 qglmaterialparameters \
14 qglvertexarray \
1514 qglvertexbuffer \
16 qglvertexdescription \
1715 qglgeometry \
1816 qglindexarray \
1917 qglpainter \
2018 qgldisplaylist \
2119 qglsection \
2220 qgeometrydata \
23 qglcube \
2421 qgloperation
22
23TO_BE_PORTED = \
24 qglcube
  
55 qglcontextscope.h \
66 qglindexarray.h \
77 qglreferencedbuffer.h \
8 qglvertexarray.h \
9 qglvertexdescription.h \
108 qgltexture2d.h \
119 qgltexturecube.h \
1210 qglvertexbuffer.h \
1414SOURCES += qglattributevalue.cpp \
1515 qglcontextscope.cpp \
1616 qglindexarray.cpp \
17 qglvertexarray.cpp \
18 qglvertexdescription.cpp \
1917 qgltexture2d.cpp \
2018 qgltexturecube.cpp \
2119 qglvertexbuffer.cpp \
  
6464 desktop OpenGL systems. The name \c ElementType is a \c typedef alias for the
6565 type of these indices.
6666
67 \sa QGLVertexArray
67 \sa QGLVertexBuffer
6868*/
6969
7070/*!
  
5151
5252QT_MODULE(Qt3d)
5353
54// Helper class for QGLIndexArray and QGLVertexArray. May go away in future.
54// Helper class for QGLIndexArray. May go away in future.
5555class Q_QT3D_EXPORT QGLReferencedBuffer : public QGLBuffer
5656{
5757public:
  
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the Qt3D module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** No Commercial Usage
11** This file contains pre-release code and may not be distributed.
12** You may use this file in accordance with the terms and conditions
13** contained in the Technology Preview License Agreement accompanying
14** this package.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** If you have questions regarding the use of this file, please contact
29** Nokia at qt-info@nokia.com.
30**
31**
32**
33**
34**
35**
36**
37**
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qglvertexarray.h"
43
44#include <QtCore/qdebug.h>
45
46QT_BEGIN_NAMESPACE
47
48/*!
49 \class QGLVertexArray
50 \brief The QGLVertexArray class manages arrays of vertex attributes.
51 \since 4.7
52 \ingroup qt3d
53 \ingroup qt3d::enablers
54
55 3D graphical applications need to deal with large numbers of vertices
56 that specify the attributes of an object in 3D space. The QGLVertexArray
57 class makes it easier to construct and manage such vertex arrays.
58
59 Vertices can have multiple types of information associated with them:
60 positions, normals, colors, texture co-ordinates, etc. The
61 QGLVertexArray class supports this through the use of fields that
62 define the layout of the data in the array.
63
64 Each field has a vertex attribute type, a size in components
65 (1, 2, 3, or 4), and an offset with each vertex definition.
66 The sum of all field sizes is the vertex array's stride().
67
68 The following example creates a vertex array with two fields:
69 a 3D position and a 2D texture co-ordinate:
70
71 \code
72 QGLVertexArray array;
73 array.addField(QGL::Position, 3);
74 array.addField(QGL::TextureCoord0, 2);
75 \endcode
76
77 Once the layout of the vertex array has been specified, field values
78 are specified using append():
79
80 \code
81 array.append(2.0f, 0.0f, 0.0f);
82 array.append(1.0f, 0.0f);
83 array.append(2.0f, 3.0f, 0.0f);
84 array.append(1.0f, 1.0f);
85 array.append(0.0f, 3.0f, 0.0f);
86 array.append(0.0f, 1.0f);
87 \endcode
88*/
89
90/*!
91 \enum QGL::VertexAttribute
92 \since 4.7
93 This enum defines the type of vertex attribute to set on an effect with QGLPainter::setVertexArray()
94
95 \value Position The primary position of the vertex.
96 \value Normal The normal at each vertex.
97 \value Color The color at each vertex.
98 \value TextureCoord0 The texture co-ordinate at each vertex for texture unit 0.
99 \value TextureCoord1 The texture co-ordinate at each vertex for texture unit 1.
100 \value TextureCoord2 The texture co-ordinate at each vertex for texture unit 2.
101 \value TextureCoord3 The texture co-ordinate at each vertex for texture unit 3.
102 \value TextureCoord4 The texture co-ordinate at each vertex for texture unit 4.
103 \value TextureCoord5 The texture co-ordinate at each vertex for texture unit 5.
104 \value TextureCoord6 The texture co-ordinate at each vertex for texture unit 6.
105 \value TextureCoord7 The texture co-ordinate at each vertex for texture unit 7.
106 \value CustomVertex0 First custom vertex attribute.
107 \value CustomVertex1 Second custom vertex attribute.
108 \value CustomVertex2 Third custom vertex attribute.
109 \value CustomVertex3 Fourth custom vertex attribute.
110 \value CustomVertex4 Fifth custom vertex attribute.
111 \value CustomVertex5 Sixth custom vertex attribute.
112 \value CustomVertex6 Seventh custom vertex attribute.
113 \value CustomVertex7 Eighth custom vertex attribute.
114*/
115
116/*!
117 \fn QGLVertexArray::QGLVertexArray()
118
119 Constructs an empty vertex array. This is usually followed
120 by calls to addField() to define the field layout. For example:
121
122 \code
123 QGLVertexArray array;
124 array.addField(QGL::Position, 3);
125 array.addField(QGL::Normal, 3);
126 array.addField(QGL::Color, 4);
127 array.addField(QGL::TextureCoord0, 2);
128 array.addField(QGL::TextureCoord1, 2);
129 \endcode
130
131 \sa addField()
132*/
133
134/*!
135 \fn QGLVertexArray::QGLVertexArray(QGL::VertexAttribute attr, int size)
136
137 Constructs an empty vertex array with a single field defined
138 by \a attr and \a size. For example:
139
140 \code
141 QGLVertexArray array(QGL::Position, 3);
142 array.append(2.0f, 0.0f, 0.0f);
143 array.append(2.0f, 3.0f, 0.0f);
144 array.append(0.0f, 3.0f, 0.0f);
145 \endcode
146
147 The \a size parameter must be between 1 and 4, inclusive.
148*/
149
150/*!
151 \fn QGLVertexArray::QGLVertexArray(QGL::VertexAttribute attr1, int size1, QGL::VertexAttribute attr2, int size2)
152
153 Constructs an empty vertex array with a two fields defined
154 by \a attr1, \a size1, \a attr2, and \a size2. For example:
155
156 \code
157 QGLVertexArray array(QGL::Position, 3, QGL::TextureCoord0, 2);
158 array.append(2.0f, 0.0f, 0.0f);
159 array.append(1.0f, 0.0f);
160 array.append(2.0f, 3.0f, 0.0f);
161 array.append(1.0f, 1.0f);
162 array.append(0.0f, 3.0f, 0.0f);
163 array.append(0.0f, 1.0f);
164 \endcode
165
166 The \a size1 and \a size2 parameters must be between 1 and 4, inclusive.
167*/
168
169/*!
170 \fn QGLVertexArray::QGLVertexArray(QGL::VertexAttribute attr1, int size1, QGL::VertexAttribute attr2, int size2, QGL::VertexAttribute attr3, int size3)
171
172 Constructs an empty vertex array with a three fields defined
173 by \a attr1, \a size1, \a attr2, \a size2, \a attr3, and \a size3.
174 For example:
175
176 \code
177 QGLVertexArray array(QGL::Position, 3, QGL::TextureCoord0, 2,
178 QGL::Color, 4);
179 array.append(2.0f, 0.0f, 0.0f);
180 array.append(1.0f, 0.0f);
181 array.append(0.5f, 0.0f, 0.0f, 1.0f);
182 array.append(2.0f, 3.0f, 0.0f);
183 array.append(1.0f, 1.0f);
184 array.append(0.0f, 0.5f, 0.0f, 1.0f);
185 array.append(0.0f, 3.0f, 0.0f);
186 array.append(0.0f, 1.0f);
187 array.append(0.0f, 0.0f, 0.5f, 1.0f);
188 \endcode
189
190 The \a size1, \a size2, and \a size3 parameters must be between
191 1 and 4, inclusive.
192*/
193
194/*!
195 \fn QGLVertexArray::QGLVertexArray(QGL::VertexAttribute attr1, int size1, QGL::VertexAttribute attr2, int size2, QGL::VertexAttribute attr3, int size3, QGL::VertexAttribute attr4, int size4)
196
197 Constructs an empty vertex array with a four fields defined
198 by \a attr1, \a size1, \a attr2, \a size2, \a attr3, \a size3,
199 \a attr4, and \a size4. For example:
200
201 \code
202 QGLVertexArray array(QGL::Position, 3, QGL::Normal, 3,
203 QGL::TextureCoord0, 2, QGL::Color, 4);
204 array.append(2.0f, 0.0f, 0.0f);
205 array.append(0.0f, 0.0f, 1.0f);
206 array.append(1.0f, 0.0f);
207 array.append(0.5f, 0.0f, 0.0f, 1.0f);
208 array.append(2.0f, 3.0f, 0.0f);
209 array.append(0.0f, 0.0f, 1.0f);
210 array.append(1.0f, 1.0f);
211 array.append(0.0f, 0.5f, 0.0f, 1.0f);
212 array.append(0.0f, 3.0f, 0.0f);
213 array.append(0.0f, 0.0f, 1.0f);
214 array.append(0.0f, 1.0f);
215 array.append(0.0f, 0.0f, 0.5f, 1.0f);
216 \endcode
217
218 The \a size1, \a size2, \a size3, and \a size4 parameters must be
219 between 1 and 4, inclusive.
220*/
221
222/*!
223 \fn QGLVertexArray::QGLVertexArray(const QGLVertexArray& other)
224
225 Constructs a copy of \a other.
226
227 This operation takes constant time, because the data contents are
228 implicitly shared. This makes returning a QGLVertexArray from a
229 function very fast. If a shared instance is modified, it will be
230 copied (copy-on-write), and that takes linear time.
231
232 \sa operator=()
233*/
234
235/*!
236 \fn QGLVertexArray::~QGLVertexArray()
237
238 Destroys this vertex array.
239*/
240
241/*!
242 \fn QGLVertexArray& QGLVertexArray::operator=(const QGLVertexArray& other)
243
244 Assigns \a other to this vertex array and returns a reference
245 to this vertex array. This operation takes constant time.
246*/
247
248/*!
249 \fn void QGLVertexArray::addField(QGL::VertexAttribute attr, int size)
250
251 Adds a field to this vertex array with the details \a attr, and \a size.
252 The offset of the field is determined from stride(). The \a size must
253 be between 1 and 4, inclusive.
254
255 If the vertex array contains existing data, this will define the layout
256 of that existing data but not change the existing data. Use the
257 interleaved() function to add fields and expand the data
258 to include space for them.
259
260 \sa stride(), fieldCount(), interleaved()
261*/
262
263/*!
264 \fn int QGLVertexArray::fieldCount() const
265
266 Returns the number of fields in this vertex array.
267
268 \sa addField(), stride()
269*/
270
271/*!
272 \fn QGLVertexDescription QGLVertexArray::fields() const
273
274 Returns the field description list.
275
276 \sa setFields()
277*/
278
279/*!
280 \fn void QGLVertexArray::setFields(const QGLVertexDescription& value)
281
282 Sets the field description list to \a value.
283
284 \sa fields()
285*/
286
287/*!
288 \fn QGLAttributeValue QGLVertexArray::attributeValue(int field) const
289
290 Returns the attribute value for the index \a field; or a null
291 QGLAttributeValue if \a field is out of range.
292*/
293
294/*!
295 \fn QGLAttributeValue QGLVertexArray::attributeValue(QGL::VertexAttribute attr) const
296
297 Returns the attribute value for the field associated with \a attr;
298 or a null QGLAttributeValue if \a attr is not a field of this array.
299*/
300
301/*!
302 \fn int QGLVertexArray::fieldIndex(QGL::VertexAttribute attr) const
303
304 Returns the index of the field associated with \a attr in this array;
305 or -1 if \a attr is not a field of this array.
306*/
307
308/*!
309 \fn int QGLVertexArray::stride() const
310
311 Returns the stride of this vertex array, which is the sum
312 of the sizes of all fields.
313
314 \sa addField()
315*/
316
317/*!
318 \fn int QGLVertexArray::vertexCount() const
319
320 Returns the number of vertices in this vertex array, which is
321 the same as componentCount() / stride(). If stride() is zero,
322 because no fields have been defined yet, then this function
323 will return componentCount().
324
325 \sa componentCount(), stride()
326*/
327
328/*!
329 \fn int QGLVertexArray::componentCount() const
330
331 Returns the number of components in this vertex array.
332
333 \sa vertexCount()
334*/
335
336/*!
337 \fn bool QGLVertexArray::isEmpty() const
338
339 Returns true if this vertex array is empty; false otherwise.
340*/
341
342/*!
343 Resizes this vertex array to \a size vertices, using stride()
344 to determine the number of components per vertex. Additional
345 components are filled with zeroes.
346
347 \sa reserve()
348*/
349void QGLVertexArray::resize(int size)
350{
351 m_data.resize(size * stride());
352}
353
354/*!
355 Reserves space in this vertex array for \a size vertices.
356 If the vertex array already contains space for \a size vertices
357 or more, this function does nothing. Note: the \a size refers
358 to vertices, not components. Use stride() to determine the
359 number of components per vertex.
360
361 The following example creates a vertex array containing 3D
362 position and 2D texture co-ordinate values, and then reserves
363 enough space for 100 vertices:
364
365 \code
366 QGLVertexArray array(QGL::Position, 3, QGL::TextureCoord0, 2);
367 array.reserve(100);
368 \endcode
369
370 \sa componentCount(), resize()
371*/
372void QGLVertexArray::reserve(int size)
373{
374 m_data.reserve(size * stride());
375}
376
377/*!
378 \fn void QGLVertexArray::append(qreal x)
379
380 Appends a 1D vertex \a x to this vertex array.
381*/
382
383/*!
384 \fn void QGLVertexArray::append(qreal x, qreal y)
385
386 Appends a 2D vertex (\a x, \a y) to this vertex array.
387*/
388
389/*!
390 \fn void QGLVertexArray::append(qreal x, qreal y, qreal z)
391
392 Appends a 3D vertex (\a x, \a y, \a z) to this vertex array.
393*/
394
395/*!
396 \fn void QGLVertexArray::append(qreal x, qreal y, qreal z, qreal w)
397
398 Appends a 4D vertex (\a x, \a y, \a z, \a w) to this vertex array.
399*/
400
401/*!
402 \fn void QGLVertexArray::append(const QVector2D& value)
403
404 Appends a 2D vertex \a value to this vertex array.
405*/
406
407/*!
408 \fn void QGLVertexArray::append(const QVector3D& value)
409
410 Appends a 3D vertex \a value to this vertex array.
411*/
412
413/*!
414 \fn void QGLVertexArray::append(const QVector4D& value)
415
416 Appends a 4D vertex \a value to this vertex array.
417*/
418
419/*!
420 \fn void QGLVertexArray::append(const QPoint& value)
421
422 Appends a 2D point \a value to this vertex array.
423*/
424
425/*!
426 \fn void QGLVertexArray::append(const QPointF& value)
427
428 Appends a 2D point \a value to this vertex array.
429*/
430
431/*!
432 \fn void QGLVertexArray::append(const QColor4B& value)
433
434 Appends a four byte color \a value to this vertex array.
435 The field should have a size of 1.
436*/
437
438/*!
439 Appends the components in \a other to this vertex array. It is
440 assumed that \a other has the same set of fields as this vertex array.
441*/
442void QGLVertexArray::append(const QGLVertexArray& other)
443{
444 detachBuffer();
445 m_data.append(other.m_data);
446}
447
448/*!
449 \fn qreal QGLVertexArray::floatAt(int vertex, int field) const
450
451 Returns the specified \a field of \a vertex as a 1D value.
452 The \a vertex should be between 0 and vertexCount() - 1,
453 and the \a field must be between 0 and fieldCount() - 1.
454
455 \sa setAt(), vector2DAt(), vector3DAt(), vector4DAt()
456*/
457
458/*!
459 \fn QVector2D QGLVertexArray::vector2DAt(int vertex, int field) const
460
461 Returns the specified \a field of \a vertex as a 2D value.
462 The \a vertex should be between 0 and vertexCount() - 1,
463 and the \a field must be between 0 and fieldCount() - 1.
464
465 \sa setAt(), floatAt(), vector3DAt(), vector4DAt()
466*/
467
468/*!
469 \fn QVector3D QGLVertexArray::vector3DAt(int vertex, int field) const
470
471 Returns the specified \a field of \a vertex as a 3D value.
472 The \a vertex should be between 0 and vertexCount() - 1,
473 and the \a field must be between 0 and fieldCount() - 1.
474
475 \sa setAt(), floatAt(), vector2DAt(), vector4DAt()
476*/
477
478/*!
479 \fn QVector4D QGLVertexArray::vector4DAt(int vertex, int field) const
480
481 Returns the specified \a field of \a vertex as a 4D value.
482 The \a vertex should be between 0 and vertexCount() - 1,
483 and the \a field must be between 0 and fieldCount() - 1.
484
485 \sa setAt(), floatAt(), vector2DAt(), vector3DAt()
486*/
487
488/*!
489 \fn QVector4D QGLVertexArray::color4bAt(int vertex, int field) const
490
491 Returns the specified \a field of \a vertex as a four byte color value.
492 The \a vertex should be between 0 and vertexCount() - 1,
493 and the \a field must be between 0 and fieldCount() - 1.
494
495 \sa setAt(), floatAt(), vector4DAt()
496*/
497
498/*!
499 \fn void QGLVertexArray::setAt(int vertex, int field, qreal x)
500
501 Sets the specified \a field of \a vertex to a 1D value \a x.
502 The \a vertex should be between 0 and vertexCount() - 1,
503 and the \a field must be between 0 and fieldCount() - 1.
504
505 \sa floatAt()
506*/
507
508/*!
509 \fn void QGLVertexArray::setAt(int vertex, int field, qreal x, qreal y)
510
511 Sets the specified \a field of \a vertex to a 2D value (\a x, \a y).
512 The \a vertex should be between 0 and vertexCount() - 1,
513 and the \a field must be between 0 and fieldCount() - 1.
514
515 \sa vector2DAt()
516*/
517
518/*!
519 \fn void QGLVertexArray::setAt(int vertex, int field, qreal x, qreal y, qreal z)
520
521 Sets the specified \a field of \a vertex to a 3D value
522 (\a x, \a y, \a z). The \a vertex should be between
523 0 and vertexCount() - 1, and the \a field must be between
524 0 and fieldCount() - 1.
525
526 \sa vector3DAt()
527*/
528
529/*!
530 \fn void QGLVertexArray::setAt(int vertex, int field, qreal x, qreal y, qreal z, qreal w)
531
532 Sets the specified \a field of \a vertex to a 4D value
533 (\a x, \a y, \a z, \a w). The \a vertex should be between
534 0 and vertexCount() - 1, and the \a field must be between
535 0 and fieldCount() - 1.
536
537 \sa vector4DAt()
538*/
539
540/*!
541 \fn void QGLVertexArray::setAt(int vertex, int field, const QVector2D& value)
542
543 Sets the specified \a field of \a vertex to a 2D \a value.
544 The \a vertex should be between 0 and vertexCount() - 1,
545 and the \a field must be between 0 and fieldCount() - 1.
546
547 \sa vector2DAt()
548*/
549
550/*!
551 \fn void QGLVertexArray::setAt(int vertex, int field, const QVector3D& value)
552
553 Sets the specified \a field of \a vertex to a 3D \a value.
554 The \a vertex should be between 0 and vertexCount() - 1,
555 and the \a field must be between 0 and fieldCount() - 1.
556
557 \sa vector3DAt()
558*/
559
560/*!
561 \fn void QGLVertexArray::setAt(int vertex, int field, const QVector4D& value)
562
563 Sets the specified \a field of \a vertex to a 4D \a value.
564 The \a vertex should be between 0 and vertexCount() - 1,
565 and the \a field must be between 0 and fieldCount() - 1.
566
567 \sa vector4DAt()
568*/
569
570/*!
571 \fn void QGLVertexArray::setAt(int vertex, int field, const QColor4B& value)
572
573 Sets the specified \a field of \a vertex to a four byte color \a value.
574 The \a vertex should be between 0 and vertexCount() - 1,
575 and the \a field must be between 0 and fieldCount() - 1.
576
577 \sa color4bAt()
578*/
579
580/*!
581 Extracts and returns a new vertex array that consists of
582 just the vertex attribute values for \a field. Returns an
583 empty vertex array if \a field is out of range.
584
585 \sa interleaved()
586*/
587QGLVertexArray QGLVertexArray::extractField(int field) const
588{
589 // Bail out if the field index is invalid.
590 if (field < 0 || field >= m_fields.fieldCount())
591 return QGLVertexArray();
592
593 // If there is only one field in this array, then return it as-is.
594 if (m_fields.fieldCount() == 1)
595 return *this;
596
597 // Construct a new array with just the selected field.
598 int size = m_fields.fieldSize(field);
599 QGLVertexArray array(m_fields.fieldAttribute(field), size);
600 int stride = m_fields.stride();
601 int count = vertexCount();
602 const float *src = m_data.constData() + m_fields.fieldOffset(field);
603 float *dst = array.m_data.extend(count * size);
604 for (int item = 0; item < count; ++item) {
605 for (int component = 0; component < size; ++component)
606 dst[component] = src[component];
607 dst += size;
608 src += stride;
609 }
610 return array;
611}
612
613/*!
614 Extracts and returns a new vertex array that consists of
615 just the vertex attribute values associated with the first
616 field whose attribute is \a attr. Returns an empty vertex
617 array if \a attr is not present.
618
619 \sa interleaved()
620*/
621QGLVertexArray QGLVertexArray::extractField(QGL::VertexAttribute attr) const
622{
623 return extractField(m_fields.indexOf(attr));
624}
625
626/*!
627 Interleaves the fields and component values in \a other into
628 this vertex array and returns the new interleaved vertex array.
629 This function is used to combine arrays of vertex attributes
630 that have been built separately.
631
632 The following example interleaves two vertex arrays containing
633 separate position and color information:
634
635 \code
636 QGLVertexArray positions(QGL::Position, 3);
637 QGLVertexArray colors(QGL::Color, 4);
638 ...
639
640 QGLVertexArray combined = positions.interleaved(colors);
641 \endcode
642
643 If this vertex array does not have the same vertexCount()
644 as \a other, then the extra components in the result will be
645 padded with zeroes.
646
647 \sa addField(), vertexCount(), extractField()
648*/
649QGLVertexArray QGLVertexArray::interleaved(const QGLVertexArray& other) const
650{
651 QGLVertexArray result;
652 result.m_fields = m_fields;
653 result.m_fields.addFields(other.m_fields);
654
655 // Determine the size of the new array.
656 int thisCount = vertexCount();
657 int otherCount = other.vertexCount();
658 int thisStride = stride();
659 int otherStride = other.stride();
660 int maxCount = qMax(thisCount, otherCount);
661 int size = maxCount * (thisStride + otherStride);
662
663 // Reserve space for the interleaved version, but don't initialize it.
664 float *data = result.m_data.extend(size);
665
666 // Copy across the elements from the source arrays, padding with
667 // zeroes if one of the source arrays is shorter than the other.
668 const float *thisData = m_data.constData();
669 const float *otherData = other.m_data.constData();
670 int component;
671 for (int index = 0; index < maxCount; ++index) {
672 if (index < thisCount) {
673 for (component = 0; component < thisStride; ++component)
674 data[component] = thisData[component];
675 } else {
676 for (component = 0; component < thisStride; ++component)
677 data[component] = 0.0f;
678 }
679 thisData += thisStride;
680 data += thisStride;
681 if (index < otherCount) {
682 for (component = 0; component < otherStride; ++component)
683 data[component] = otherData[component];
684 } else {
685 for (component = 0; component < otherStride; ++component)
686 data[component] = 0.0f;
687 }
688 otherData += otherStride;
689 data += otherStride;
690 }
691 return result;
692}
693
694/*!
695 \fn float *QGLVertexArray::data()
696
697 Returns the internal data pointer for this vertex array, for
698 direct manipulation. This will create a writable copy of the
699 array if the underlying data is shared. Returns null if the
700 array is empty.
701
702 \sa constData(), stride()
703*/
704
705/*!
706 \fn const float *QGLVertexArray::data() const
707
708 Returns the internal data pointer for this vertex array, for
709 direct reading. Returns null if the array is empty.
710
711 \sa constData(), stride()
712*/
713
714/*!
715 \fn const float *QGLVertexArray::constData() const
716
717 Returns the internal data pointer for this vertex array, for
718 direct reading. Returns null if the array is empty.
719
720 \sa data(), stride()
721*/
722
723/*!
724 \fn QGLVertexArray& QGLVertexArray::operator+=(qreal value)
725
726 Appends \a value to this vertex array.
727
728 \sa append(), operator<<()
729*/
730
731/*!
732 \fn QGLVertexArray& QGLVertexArray::operator+=(const QVector2D& value)
733
734 Appends \a value to this vertex array.
735
736 \sa append(), operator<<()
737*/
738
739/*!
740 \fn QGLVertexArray& QGLVertexArray::operator+=(const QVector3D& value)
741
742 Appends \a value to this vertex array.
743
744 \sa append(), operator<<()
745*/
746
747/*!
748 \fn QGLVertexArray& QGLVertexArray::operator+=(const QVector4D& value)
749
750 Appends \a value to this vertex array.
751
752 \sa append(), operator<<()
753*/
754
755/*!
756 \fn QGLVertexArray& QGLVertexArray::operator+=(const QGLVertexArray& other)
757
758 Appends the contents of \a other to this vertex array.
759
760 \sa append(), operator<<()
761*/
762
763/*!
764 \fn QGLVertexArray& QGLVertexArray::operator+=(const QPoint& value)
765
766 Appends \a value to this vertex array.
767
768 \sa append(), operator<<()
769*/
770
771/*!
772 \fn QGLVertexArray& QGLVertexArray::operator+=(const QPointF& value)
773
774 Appends \a value to this vertex array.
775
776 \sa append(), operator<<()
777*/
778
779/*!
780 \fn QGLVertexArray& QGLVertexArray::operator+=(const QColor4B& value)
781
782 Appends \a value to this vertex array.
783
784 \sa append(), operator<<()
785*/
786
787/*!
788 \fn QGLVertexArray& QGLVertexArray::operator<<(qreal value)
789
790 Appends \a value to this vertex array.
791
792 \sa append(), operator+=()
793*/
794
795/*!
796 \fn QGLVertexArray& QGLVertexArray::operator<<(const QVector2D& value)
797
798 Appends \a value to this vertex array.
799
800 \sa append(), operator+=()
801*/
802
803/*!
804 \fn QGLVertexArray& QGLVertexArray::operator<<(const QVector3D& value)
805
806 Appends \a value to this vertex array.
807
808 \sa append(), operator+=()
809*/
810
811/*!
812 \fn QGLVertexArray& QGLVertexArray::operator<<(const QVector4D& value)
813
814 Appends \a value to this vertex array.
815
816 \sa append(), operator+=()
817*/
818
819/*!
820 \fn QGLVertexArray& QGLVertexArray::operator<<(const QGLVertexArray& other)
821
822 Appends the contents of \a other to this vertex array.
823
824 \sa append(), operator+=()
825*/
826
827/*!
828 \fn QGLVertexArray& QGLVertexArray::operator<<(const QPoint& value)
829
830 Appends \a value to this vertex array.
831
832 \sa append(), operator+=()
833*/
834
835/*!
836 \fn QGLVertexArray& QGLVertexArray::operator<<(const QPointF& value)
837
838 Appends \a value to this vertex array.
839
840 \sa append(), operator+=()
841*/
842
843/*!
844 \fn QGLVertexArray& QGLVertexArray::operator<<(const QColor4B& value)
845
846 Appends \a value to this vertex array.
847
848 \sa append(), operator+=()
849*/
850
851/*!
852 Sets the contents of this vertex array to the \a count component
853 values from \a data. The \a data pointer is copied by this
854 function and must remain valid until the vertex array is
855 modified or discarded.
856
857 \code
858 QGLVertexArray array(QGL::Position, 3, QGL::Normal, 3);
859 array.setRawData(vertices, 300);
860 \endcode
861*/
862void QGLVertexArray::setRawData(const float *data, int count)
863{
864 m_data = QArray<float>::fromRawData(data, count);
865}
866
867/*!
868 Replaces the contents of this vertex array starting at \a vertex
869 with the components from \a data. It is assumed that \a data
870 has the same set of fields as this vertex array.
871
872 If there are more vertices in \a data than in this vertex array,
873 then additional vertices will be appended to this vertex array.
874
875 This function does nothing if there are no fields in this
876 vertex array, \a vertex is out of range, or \a data is empty.
877
878 \sa append()
879*/
880void QGLVertexArray::replace(int vertex, const QGLVertexArray& data)
881{
882 if (!m_fields.stride() || vertex < 0 || vertex > vertexCount()
883 || data.isEmpty())
884 return;
885 detachBuffer();
886 m_data.replace
887 (vertex * m_fields.stride(), data.m_data.constData(),
888 data.m_data.count());
889}
890
891void QGLVertexArray::typeCheckAppend(int size) const
892{
893 if (m_currentField < m_fields.fieldCount()) {
894 if (size != m_fields.fieldSize(m_currentField) &&
895 (m_currentField >= 32 ||
896 (m_warnings & (1 << m_currentField)) == 0)) {
897 if (m_currentField < 32)
898 m_warnings |= (1 << m_currentField);
899 qWarning("QGLVertexArray: adding a %d-component value to a %d-component field", size, m_fields.fieldSize(m_currentField));
900 }
901 ++m_currentField;
902 if (m_currentField >= m_fields.fieldCount())
903 m_currentField = 0;
904 }
905}
906
907void QGLVertexArray::typeCheckRead(int field, int size) const
908{
909 if (field >= 0 && field < m_fields.fieldCount()) {
910 if (size != m_fields.fieldSize(field) &&
911 (m_currentField >= 32 ||
912 (m_warnings & (1 << m_currentField)) == 0)) {
913 if (m_currentField < 32)
914 m_warnings |= (1 << m_currentField);
915 qWarning("QGLVertexArray: reading a %d-component value from a %d-component field", size, m_fields.fieldSize(field));
916 }
917 }
918}
919
920void QGLVertexArray::typeCheckWrite(int field, int size) const
921{
922 if (field >= 0 && field < m_fields.fieldCount()) {
923 if (size != m_fields.fieldSize(field) &&
924 (m_currentField >= 32 ||
925 (m_warnings & (1 << m_currentField)) == 0)) {
926 if (m_currentField < 32)
927 m_warnings |= (1 << m_currentField);
928 qWarning("QGLVertexArray: writing a %d-component value to a %d-component field", size, m_fields.fieldSize(field));
929 }
930 }
931}
932
933QGLVertexArray QGLVertexArray::toBufferForm() const
934{
935 // Create a simulated raw data version of the array where the
936 // raw data pointer is set to zero. This will cause later calls
937 // of "array.constData() + field.offset()" to generate an offset
938 // into a vertex buffer rather than a client-side pointer.
939 QGLVertexArray result;
940 result.m_data = QArray<float>::fromRawData(0, m_data.count());
941 result.m_fields = m_fields;
942 return result;
943}
944
945/*!
946 \fn bool QGLVertexArray::isVertexBuffer() const
947
948 Returns true if this vertex array corresponds to the contents of a
949 vertex buffer. The constData() and data() functions will return
950 zero, which is the offset of the first field in the vertex buffer.
951*/
952
953/*!
954 Returns true if this QGLVertexArray is equal to the \a other, and false otherwise.
955 Equal here means that either the \a other and this are the same array,
956 or they have the same elements, and the same field definitions.
957 This method is potentially expensive: in the worst case it will iterate over all
958 elements in both vertex arrays.
959 */
960bool QGLVertexArray::operator==(const QGLVertexArray &other) const
961{
962 if (this == &other)
963 return true;
964 if (m_fields != other.m_fields)
965 return false;
966 return m_data == other.m_data;
967}
968
969/*!
970 \fn bool QGLVertexArray::operator!=(const QGLVertexArray &other) const
971 Returns true if this QGLVertexArray is not equal to the \a other, and false otherwise.
972 This method is simply the inverse of the equality operator.
973 \sa operator==()
974 */
975
976/*!
977 Binds this array to a vertex buffer in the GL server for the
978 current GL context.
979
980 If the array has not been uploaded to the GL server, or it has
981 been modified since the last upload, the vertex buffer will be
982 re-uploaded. The first element in the array is uploaded as
983 offset 0 in the vertex buffer.
984
985 Returns true if the vertex buffer was bound, or false otherwise.
986
987 \sa release(), upload()
988*/
989bool QGLVertexArray::bind() const
990{
991 if (!upload())
992 return false;
993 return m_buffer->bind();
994}
995
996/*!
997 Releases the vertex buffer for this array from the current GL context.
998
999 This function must be called with the same QGLContext current
1000 that was current when bind() was called.
1001
1002 \sa bind()
1003*/
1004void QGLVertexArray::release() const
1005{
1006 if (m_buffer)
1007 m_buffer->release();
1008}
1009
1010/*!
1011 Uploads this array to the GL server as a vertex buffer if it
1012 has not been uploaded before or it has been modified since the
1013 last upload. Does nothing if the array is already uploaded.
1014
1015 Returns true if the array was uploaded; false if uploading
1016 was not possible (usually because vertex buffers are not
1017 supported by the GL server).
1018
1019 \sa bind(), isUploaded()
1020*/
1021bool QGLVertexArray::upload() const
1022{
1023 if (!m_buffer) {
1024 m_buffer = new QGLReferencedBuffer(QGLReferencedBuffer::VertexBuffer);
1025 if (!m_buffer->create()) {
1026 delete m_buffer;
1027 m_buffer = 0;
1028 return false;
1029 }
1030 if (m_buffer->bind()) {
1031 m_buffer->allocate(constData(), componentCount() * sizeof(float));
1032 m_buffer->release();
1033 } else {
1034 delete m_buffer;
1035 m_buffer = 0;
1036 return false;
1037 }
1038 }
1039 return true;
1040}
1041
1042/*!
1043 \fn bool QGLVertexArray::isUploaded() const
1044
1045 Returns true if this vertex array has been uploaded into a vertex
1046 buffer in the GL server by upload() or bind(); false otherwise.
1047
1048 \sa upload(), bind()
1049*/
1050
1051#ifndef QT_NO_DEBUG_STREAM
1052
1053static const char *vertAttrNames[] = {
1054 "Pos", "Norm", "Col", "Tex0",
1055 "Tex1", "Tex2", "Tex3", "Tex4",
1056 "Tex5", "Tex6", "Tex7", "Cust0",
1057 "Cust1", "Cust2", "Cust3", "Cust4",
1058 "Cust5", "Cust6", "Cust7"
1059};
1060
1061QDebug operator<<(QDebug dbg, const QGLVertexArray &vertices)
1062{
1063 dbg.nospace() << "QGLVertexArray(\n";
1064 QGLVertexDescription flds = vertices.fields();
1065 dbg << '\t' << flds;
1066 for (int i = 0; i < vertices.vertexCount(); ++i)
1067 {
1068 dbg << '\t' << i << ':' << '\n';
1069 for (int j = 0; j < flds.fieldCount(); ++j)
1070 {
1071 dbg << "\t\t" << vertAttrNames[flds.fieldAttribute(j)] << ':';
1072 if (flds.fieldAttribute(j) >= QGL::TextureCoord0 &&
1073 flds.fieldAttribute(j) <= QGL::TextureCoord7)
1074 {
1075 QVector2D v = vertices.vector2DAt(i, j);
1076 dbg << '\t' << '(' << v.x() << ", " << v.y() << ')' << '\n';
1077 }
1078 else if (flds.fieldAttribute(j) == QGL::Color)
1079 {
1080 QColor4B c = vertices.color4bAt(i, j);
1081 dbg << "\t( R:" << c.red() << ", G:" << c.green() << ", B:"
1082 << c.blue() << ", A:" << c.alpha() << ")\n";
1083 }
1084 else
1085 {
1086 QVector3D v = vertices.vector3DAt(i, j);
1087 dbg << '\t' << '(' << v.x() << ", " << v.y() << ", " << v.z() << ')' << '\n';
1088 }
1089 }
1090 }
1091 dbg << ")\n";
1092 return dbg.space();
1093}
1094
1095#endif
1096
1097QT_END_NAMESPACE
  
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the Qt3D module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** No Commercial Usage
11** This file contains pre-release code and may not be distributed.
12** You may use this file in accordance with the terms and conditions
13** contained in the Technology Preview License Agreement accompanying
14** this package.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** If you have questions regarding the use of this file, please contact
29** Nokia at qt-info@nokia.com.
30**
31**
32**
33**
34**
35**
36**
37**
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#ifndef QGLVERTEXARRAY_H
43#define QGLVERTEXARRAY_H
44
45#include <QtCore/qlist.h>
46#include "qvector2d.h"
47#include "qvector3d.h"
48#include "qvector4d.h"
49#include "qcolor4b.h"
50#include "qarray.h"
51#include "qglvertexdescription.h"
52#include "qglattributevalue.h"
53#include "qglreferencedbuffer.h"
54
55QT_BEGIN_HEADER
56
57QT_BEGIN_NAMESPACE
58
59QT_MODULE(Qt3d)
60
61class Q_QT3D_EXPORT QGLVertexArray
62{
63public:
64 inline QGLVertexArray();
65 inline QGLVertexArray(QGL::VertexAttribute attr, int size);
66 inline QGLVertexArray(QGL::VertexAttribute attr1, int size1,
67 QGL::VertexAttribute attr2, int size2);
68 inline QGLVertexArray(QGL::VertexAttribute attr1, int size1,
69 QGL::VertexAttribute attr2, int size2,
70 QGL::VertexAttribute attr3, int size3);
71 inline QGLVertexArray(QGL::VertexAttribute attr1, int size1,
72 QGL::VertexAttribute attr2, int size2,
73 QGL::VertexAttribute attr3, int size3,
74 QGL::VertexAttribute attr4, int size4);
75 inline QGLVertexArray(const QGLVertexArray& other);
76 inline ~QGLVertexArray();
77
78 inline QGLVertexArray& operator=(const QGLVertexArray& other);
79
80 inline void addField(QGL::VertexAttribute attr, int size);
81 inline int fieldCount() const;
82
83 inline QGLVertexDescription fields() const;
84 inline void setFields(const QGLVertexDescription& value);
85
86 inline QGLAttributeValue attributeValue(int field) const;
87 inline QGLAttributeValue attributeValue(QGL::VertexAttribute attr) const;
88
89 inline int fieldIndex(QGL::VertexAttribute attr) const;
90
91 inline int stride() const;
92
93 inline int vertexCount() const;
94 inline int componentCount() const;
95
96 inline bool isEmpty() const;
97
98 void resize(int size);
99 void reserve(int size);
100
101 inline void append(qreal x);
102 inline void append(qreal x, qreal y);
103 inline void append(qreal x, qreal y, qreal z);
104 inline void append(qreal x, qreal y, qreal z, qreal w);
105 inline void append(const QVector2D& value);
106 inline void append(const QVector3D& value);
107 inline void append(const QVector4D& value);
108 inline void append(const QPoint& value);
109 inline void append(const QPointF& value);
110 inline void append(const QColor4B& value);
111 void append(const QGLVertexArray& array);
112
113 inline qreal floatAt(int vertex, int field) const;
114 inline QVector2D vector2DAt(int vertex, int field) const;
115 inline QVector3D vector3DAt(int vertex, int field) const;
116 inline QVector4D vector4DAt(int vertex, int field) const;
117 inline QColor4B color4bAt(int vertex, int field) const;
118
119 inline void setAt(int vertex, int field, qreal x);
120 inline void setAt(int vertex, int field, qreal x, qreal y);
121 inline void setAt(int vertex, int field, qreal x, qreal y, qreal z);
122 inline void setAt(int vertex, int field, qreal x, qreal y, qreal z, qreal w);
123 inline void setAt(int vertex, int field, const QVector2D& value);
124 inline void setAt(int vertex, int field, const QVector3D& value);
125 inline void setAt(int vertex, int field, const QVector4D& value);
126 inline void setAt(int vertex, int field, const QColor4B& value);
127
128 QGLVertexArray extractField(int field) const;
129 QGLVertexArray extractField(QGL::VertexAttribute attr) const;
130
131 QGLVertexArray interleaved(const QGLVertexArray& other) const;
132
133 inline float *data();
134 inline const float *data() const;
135 inline const float *constData() const;
136
137 inline QGLVertexArray& operator+=(qreal value);
138 inline QGLVertexArray& operator+=(const QVector2D& value);
139 inline QGLVertexArray& operator+=(const QVector3D& value);
140 inline QGLVertexArray& operator+=(const QVector4D& value);
141 inline QGLVertexArray& operator+=(const QGLVertexArray& other);
142 inline QGLVertexArray& operator+=(const QPoint& value);
143 inline QGLVertexArray& operator+=(const QPointF& value);
144 inline QGLVertexArray& operator+=(const QColor4B& value);
145
146 inline QGLVertexArray& operator<<(qreal value);
147 inline QGLVertexArray& operator<<(const QVector2D& value);
148 inline QGLVertexArray& operator<<(const QVector3D& value);
149 inline QGLVertexArray& operator<<(const QVector4D& value);
150 inline QGLVertexArray& operator<<(const QGLVertexArray& other);
151 inline QGLVertexArray& operator<<(const QPoint& value);
152 inline QGLVertexArray& operator<<(const QPointF& value);
153 inline QGLVertexArray& operator<<(const QColor4B& value);
154
155 void setRawData(const float *data, int count);
156
157 void replace(int vertex, const QGLVertexArray& data);
158
159 inline bool isVertexBuffer() const;
160
161 bool operator==(const QGLVertexArray &rhs) const;
162 inline bool operator!=(const QGLVertexArray &rhs) const;
163
164 bool bind() const;
165 void release() const;
166
167 bool upload() const;
168 inline bool isUploaded() const;
169
170private:
171 QArray<float> m_data;
172 QGLVertexDescription m_fields;
173 mutable int m_currentField;
174 mutable int m_warnings;
175 mutable QGLReferencedBuffer *m_buffer;
176
177 inline void detachBuffer();
178
179 void typeCheckAppend(int size) const;
180 void typeCheckRead(int field, int size) const;
181 void typeCheckWrite(int field, int size) const;
182
183 QGLVertexArray toBufferForm() const;
184
185 friend class QGLAbstractEffect;
186 friend class QGLPainter;
187 friend class QGLPainterPrivate;
188};
189
190inline void QGLVertexArray::detachBuffer()
191{
192 if (m_buffer && !m_buffer->deref())
193 delete m_buffer;
194 m_buffer = 0;
195}
196
197inline QGLVertexArray::QGLVertexArray()
198 : m_currentField(0), m_warnings(0), m_buffer(0)
199{
200}
201
202inline QGLVertexArray::QGLVertexArray(QGL::VertexAttribute attr, int size)
203 : m_currentField(0), m_warnings(0), m_buffer(0)
204{
205 m_fields.addField(attr, size);
206}
207
208inline QGLVertexArray::QGLVertexArray
209 (QGL::VertexAttribute attr1, int size1,
210 QGL::VertexAttribute attr2, int size2)
211 : m_currentField(0), m_warnings(0), m_buffer(0)
212{
213 m_fields.addField(attr1, size1);
214 m_fields.addField(attr2, size2);
215}
216
217inline QGLVertexArray::QGLVertexArray
218 (QGL::VertexAttribute attr1, int size1,
219 QGL::VertexAttribute attr2, int size2,
220 QGL::VertexAttribute attr3, int size3)
221 : m_currentField(0), m_warnings(0), m_buffer(0)
222{
223 m_fields.addField(attr1, size1);
224 m_fields.addField(attr2, size2);
225 m_fields.addField(attr3, size3);
226}
227
228inline QGLVertexArray::QGLVertexArray
229 (QGL::VertexAttribute attr1, int size1,
230 QGL::VertexAttribute attr2, int size2,
231 QGL::VertexAttribute attr3, int size3,
232 QGL::VertexAttribute attr4, int size4)
233 : m_currentField(0), m_warnings(0), m_buffer(0)
234{
235 m_fields.addField(attr1, size1);
236 m_fields.addField(attr2, size2);
237 m_fields.addField(attr3, size3);
238 m_fields.addField(attr4, size4);
239}
240
241inline QGLVertexArray::QGLVertexArray(const QGLVertexArray& other)
242 : m_data(other.m_data), m_fields(other.m_fields),
243 m_currentField(other.m_currentField),
244 m_warnings(other.m_warnings),
245 m_buffer(other.m_buffer)
246{
247 if (m_buffer)
248 m_buffer->ref();
249}
250
251inline QGLVertexArray::~QGLVertexArray()
252{
253 if (m_buffer && !m_buffer->deref())
254 delete m_buffer;
255}
256
257inline QGLVertexArray& QGLVertexArray::operator=(const QGLVertexArray& other)
258{
259 if (this != &other) {
260 m_data = other.m_data;
261 m_fields = other.m_fields;
262 m_currentField = other.m_currentField;
263 m_warnings = other.m_warnings;
264 if (m_buffer != other.m_buffer) {
265 if (m_buffer && !m_buffer->deref())
266 delete m_buffer;
267 m_buffer = other.m_buffer;
268 if (m_buffer)
269 m_buffer->ref();
270 }
271 }
272 return *this;
273}
274
275inline void QGLVertexArray::addField(QGL::VertexAttribute attr, int size)
276{
277 m_fields.addField(attr, size);
278}
279
280inline int QGLVertexArray::fieldCount() const
281{
282 return m_fields.fieldCount();
283}
284
285inline QGLVertexDescription QGLVertexArray::fields() const
286{
287 return m_fields;
288}
289
290inline void QGLVertexArray::setFields(const QGLVertexDescription& value)
291{
292 m_fields = value;
293 m_currentField = 0;
294 m_warnings = 0;
295}
296
297inline QGLAttributeValue QGLVertexArray::attributeValue(int field) const
298{
299 if (field >= 0 && field < m_fields.m_fields.count()) {
300 if (m_fields.m_fields[field].size == 1 &&
301 m_fields.m_fields[field].attr == QGL::Color)
302 {
303 // special case for QColor4B
304 return QGLAttributeValue(4, GL_UNSIGNED_BYTE, m_fields.m_stride * sizeof(float),
305 m_data.constData() + m_fields.m_fields[field].offset);
306 }
307 return QGLAttributeValue
308 (m_fields.m_fields[field].size, GL_FLOAT,
309 m_fields.m_stride * sizeof(float),
310 m_data.constData() + m_fields.m_fields[field].offset);
311 } else {
312 return QGLAttributeValue();
313 }
314}
315
316inline QGLAttributeValue QGLVertexArray::attributeValue
317 (QGL::VertexAttribute attr) const
318{
319 return attributeValue(m_fields.indexOf(attr));
320}
321
322inline int QGLVertexArray::fieldIndex(QGL::VertexAttribute attr) const
323{
324 return m_fields.indexOf(attr);
325}
326
327inline int QGLVertexArray::stride() const
328{
329 return m_fields.stride();
330}
331
332inline int QGLVertexArray::vertexCount() const
333{
334 if (m_fields.stride())
335 return m_data.count() / m_fields.stride();
336 else
337 return m_data.count();
338}
339
340inline int QGLVertexArray::componentCount() const
341{
342 return m_data.count();
343}
344
345inline bool QGLVertexArray::isEmpty() const
346{
347 return m_data.isEmpty();
348}
349
350inline void QGLVertexArray::append(qreal x)
351{
352#ifndef QT_NO_DEBUG
353 typeCheckAppend(1);
354#endif
355 detachBuffer();
356 m_data.append(x);
357}
358
359inline void QGLVertexArray::append(qreal x, qreal y)
360{
361#ifndef QT_NO_DEBUG
362 typeCheckAppend(2);
363#endif
364 detachBuffer();
365 m_data.append(x, y);
366}
367
368inline void QGLVertexArray::append(qreal x, qreal y, qreal z)
369{
370#ifndef QT_NO_DEBUG
371 typeCheckAppend(3);
372#endif
373 detachBuffer();
374 m_data.append(x, y, z);
375}
376
377inline void QGLVertexArray::append(qreal x, qreal y, qreal z, qreal w)
378{
379#ifndef QT_NO_DEBUG
380 typeCheckAppend(4);
381#endif
382 detachBuffer();
383 m_data.append(x, y, z, w);
384}
385
386inline void QGLVertexArray::append(const QVector2D& value)
387{
388#ifndef QT_NO_DEBUG
389 typeCheckAppend(2);
390#endif
391 detachBuffer();
392 m_data.append(value.x(), value.y());
393}
394
395inline void QGLVertexArray::append(const QVector3D& value)
396{
397#ifndef QT_NO_DEBUG
398 typeCheckAppend(3);
399#endif
400 detachBuffer();
401 m_data.append(value.x(), value.y(), value.z());
402}
403
404inline void QGLVertexArray::append(const QVector4D& value)
405{
406#ifndef QT_NO_DEBUG
407 typeCheckAppend(4);
408#endif
409 detachBuffer();
410 m_data.append(value.x(), value.y(), value.z(), value.w());
411}
412
413inline void QGLVertexArray::append(const QPoint& value)
414{
415#ifndef QT_NO_DEBUG
416 typeCheckAppend(2);
417#endif
418 detachBuffer();
419 m_data.append(value.x(), value.y());
420}
421
422inline void QGLVertexArray::append(const QPointF& value)
423{
424#ifndef QT_NO_DEBUG
425 typeCheckAppend(2);
426#endif
427 detachBuffer();
428 m_data.append(value.x(), value.y());
429}
430
431inline void QGLVertexArray::append(const QColor4B& value)
432{
433#ifndef QT_NO_DEBUG
434 typeCheckAppend(1); // 1 float component == 4 byte components.
435#endif
436 detachBuffer();
437 int count = m_data.count();
438 m_data.resize(count + 1);
439 *reinterpret_cast<QColor4B *>(m_data.data() + count) = value;
440}
441
442inline qreal QGLVertexArray::floatAt(int vertex, int field) const
443{
444#ifndef QT_NO_DEBUG
445 typeCheckRead(field, 1);
446#endif
447 int offset = vertex * m_fields.stride() + m_fields.fieldOffset(field);
448 if (offset >= 0 && offset < m_data.count())
449 return m_data[offset];
450 else
451 return 0.0f;
452}
453
454inline QVector2D QGLVertexArray::vector2DAt(int vertex, int field) const
455{
456#ifndef QT_NO_DEBUG
457 typeCheckRead(field, 2);
458#endif
459 int offset = vertex * m_fields.stride() + m_fields.fieldOffset(field);
460 if (offset >= 0 && (offset + 1) < m_data.count()) {
461 return QVector2D(m_data[offset], m_data[offset + 1]);
462 } else {
463 return QVector2D();
464 }
465}
466
467inline QVector3D QGLVertexArray::vector3DAt(int vertex, int field) const
468{
469#ifndef QT_NO_DEBUG
470 typeCheckRead(field, 3);
471#endif
472 int offset = vertex * m_fields.stride() + m_fields.fieldOffset(field);
473 if (offset >= 0 && (offset + 2) < m_data.count()) {
474 return QVector3D
475 (m_data[offset], m_data[offset + 1], m_data[offset + 2]);
476 } else {
477 return QVector3D();
478 }
479}
480
481inline QVector4D QGLVertexArray::vector4DAt(int vertex, int field) const
482{
483#ifndef QT_NO_DEBUG
484 typeCheckRead(field, 4);
485#endif
486 int offset = vertex * m_fields.stride() + m_fields.fieldOffset(field);
487 if (offset >= 0 && (offset + 3) < m_data.count()) {
488 return QVector4D
489 (m_data[offset], m_data[offset + 1],
490 m_data[offset + 2], m_data[offset + 3]);
491 } else {
492 return QVector4D();
493 }
494}
495
496inline QColor4B QGLVertexArray::color4bAt(int vertex, int field) const
497{
498#ifndef QT_NO_DEBUG
499 typeCheckRead(field, 1); // 1 float component == 4 byte components.
500#endif
501 int offset = vertex * m_fields.stride() + m_fields.fieldOffset(field);
502 if (offset >= 0 && offset < m_data.count())
503 return *reinterpret_cast<const QColor4B *>(&(m_data[offset]));
504 else
505 return QColor4B();
506}
507
508inline void QGLVertexArray::setAt(int vertex, int field, qreal x)
509{
510#ifndef QT_NO_DEBUG
511 typeCheckWrite(field, 1);
512#endif
513 detachBuffer();
514 int offset = vertex * m_fields.stride() + m_fields.fieldOffset(field);
515 if (offset >= 0 && offset < m_data.count())
516 m_data[offset] = x;
517}
518
519inline void QGLVertexArray::setAt(int vertex, int field, qreal x, qreal y)
520{
521#ifndef QT_NO_DEBUG
522 typeCheckWrite(field, 2);
523#endif
524 detachBuffer();
525 int offset = vertex * m_fields.stride() + m_fields.fieldOffset(field);
526 if (offset >= 0 && (offset + 1) < m_data.count()) {
527 m_data[offset] = x;
528 m_data[offset + 1] = y;
529 }
530}
531
532inline void QGLVertexArray::setAt(int vertex, int field, qreal x, qreal y, qreal z)
533{
534#ifndef QT_NO_DEBUG
535 typeCheckWrite(field, 3);
536#endif
537 detachBuffer();
538 int offset = vertex * m_fields.stride() + m_fields.fieldOffset(field);
539 if (offset >= 0 && (offset + 2) < m_data.count()) {
540 m_data[offset] = x;
541 m_data[offset + 1] = y;
542 m_data[offset + 2] = z;
543 }
544}
545
546inline void QGLVertexArray::setAt(int vertex, int field, qreal x, qreal y, qreal z, qreal w)
547{
548#ifndef QT_NO_DEBUG
549 typeCheckWrite(field, 4);
550#endif
551 detachBuffer();
552 int offset = vertex * m_fields.stride() + m_fields.fieldOffset(field);
553 if (offset >= 0 && (offset + 3) < m_data.count()) {
554 m_data[offset] = x;
555 m_data[offset + 1] = y;
556 m_data[offset + 2] = z;
557 m_data[offset + 3] = w;
558 }
559}
560
561inline void QGLVertexArray::setAt(int vertex, int field, const QVector2D& value)
562{
563#ifndef QT_NO_DEBUG
564 typeCheckWrite(field, 2);
565#endif
566 detachBuffer();
567 int offset = vertex * m_fields.stride() + m_fields.fieldOffset(field);
568 if (offset >= 0 && (offset + 1) < m_data.count()) {
569 m_data[offset] = value.x();
570 m_data[offset + 1] = value.y();
571 }
572}
573
574inline void QGLVertexArray::setAt(int vertex, int field, const QVector3D& value)
575{
576#ifndef QT_NO_DEBUG
577 typeCheckWrite(field, 3);
578#endif
579 detachBuffer();
580 int offset = vertex * m_fields.stride() + m_fields.fieldOffset(field);
581 if (offset >= 0 && (offset + 2) < m_data.count()) {
582 m_data[offset] = value.x();
583 m_data[offset + 1] = value.y();
584 m_data[offset + 2] = value.z();
585 }
586}
587
588inline void QGLVertexArray::setAt(int vertex, int field, const QVector4D& value)
589{
590#ifndef QT_NO_DEBUG
591 typeCheckWrite(field, 4);
592#endif
593 detachBuffer();
594 int offset = vertex * m_fields.stride() + m_fields.fieldOffset(field);
595 if (offset >= 0 && (offset + 3) < m_data.count()) {
596 m_data[offset] = value.x();
597 m_data[offset + 1] = value.y();
598 m_data[offset + 2] = value.z();
599 m_data[offset + 3] = value.w();
600 }
601}
602
603inline void QGLVertexArray::setAt(int vertex, int field, const QColor4B& value)
604{
605#ifndef QT_NO_DEBUG
606 typeCheckWrite(field, 1); // 1 float component == 4 byte components.
607#endif
608 detachBuffer();
609 int offset = vertex * m_fields.stride() + m_fields.fieldOffset(field);
610 if (offset >= 0 && offset < m_data.count())
611 *reinterpret_cast<QColor4B *>(&(m_data[offset])) = value;
612}
613
614inline float *QGLVertexArray::data()
615{
616 if (isEmpty())
617 return 0;
618 else
619 return m_data.data();
620}
621
622inline const float *QGLVertexArray::data() const
623{
624 if (isEmpty())
625 return 0;
626 else
627 return m_data.constData();
628}
629
630inline const float *QGLVertexArray::constData() const
631{
632 if (isEmpty())
633 return 0;
634 else
635 return m_data.constData();
636}
637
638inline QGLVertexArray& QGLVertexArray::operator+=(qreal value)
639{
640 append(value);
641 return *this;
642}
643
644inline QGLVertexArray& QGLVertexArray::operator+=(const QVector2D& value)
645{
646 append(value);
647 return *this;
648}
649
650inline QGLVertexArray& QGLVertexArray::operator+=(const QVector3D& value)
651{
652 append(value);
653 return *this;
654}
655
656inline QGLVertexArray& QGLVertexArray::operator+=(const QVector4D& value)
657{
658 append(value);
659 return *this;
660}
661
662inline QGLVertexArray& QGLVertexArray::operator+=(const QGLVertexArray& other)
663{
664 append(other);
665 return *this;
666}
667
668inline QGLVertexArray& QGLVertexArray::operator+=(const QPoint& value)
669{
670 append(value.x(), value.y());
671 return *this;
672}
673
674inline QGLVertexArray& QGLVertexArray::operator+=(const QPointF& value)
675{
676 append(value.x(), value.y());
677 return *this;
678}
679
680inline QGLVertexArray& QGLVertexArray::operator+=(const QColor4B& value)
681{
682 append(value);
683 return *this;
684}
685
686inline QGLVertexArray& QGLVertexArray::operator<<(qreal value)
687{
688 append(value);
689 return *this;
690}
691
692inline QGLVertexArray& QGLVertexArray::operator<<(const QVector2D& value)
693{
694 append(value);
695 return *this;
696}
697
698inline QGLVertexArray& QGLVertexArray::operator<<(const QVector3D& value)
699{
700 append(value);
701 return *this;
702}
703
704inline QGLVertexArray& QGLVertexArray::operator<<(const QVector4D& value)
705{
706 append(value);
707 return *this;
708}
709
710inline QGLVertexArray& QGLVertexArray::operator<<(const QGLVertexArray& other)
711{
712 append(other);
713 return *this;
714}
715
716inline QGLVertexArray& QGLVertexArray::operator<<(const QPoint& value)
717{
718 append(value.x(), value.y());
719 return *this;
720}
721
722inline QGLVertexArray& QGLVertexArray::operator<<(const QPointF& value)
723{
724 append(value.x(), value.y());
725 return *this;
726}
727
728inline QGLVertexArray& QGLVertexArray::operator<<(const QColor4B& value)
729{
730 append(value);
731 return *this;
732}
733
734inline bool QGLVertexArray::isVertexBuffer() const
735{
736 return m_data.constData() == 0;
737}
738
739inline bool QGLVertexArray::operator!=(const QGLVertexArray &other) const
740{
741 return !(*this == other);
742}
743
744inline bool QGLVertexArray::isUploaded() const
745{
746 return m_buffer != 0;
747}
748
749#ifndef QT_NO_DEBUG_STREAM
750Q_QT3D_EXPORT QDebug operator<<(QDebug dbg, const QGLVertexArray &vertices);
751#endif
752
753QT_END_NAMESPACE
754
755QT_END_HEADER
756
757#endif
  
4444
4545#include <QtOpenGL/qglbuffer.h>
4646#include "qcustomdataarray.h"
47#include "qglvertexdescription.h"
47#include "qglnamespace.h"
4848#include "qglattributevalue.h"
4949#include <QtCore/qlist.h>
5050
  
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the Qt3D module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** No Commercial Usage
11** This file contains pre-release code and may not be distributed.
12** You may use this file in accordance with the terms and conditions
13** contained in the Technology Preview License Agreement accompanying
14** this package.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** If you have questions regarding the use of this file, please contact
29** Nokia at qt-info@nokia.com.
30**
31**
32**
33**
34**
35**
36**
37**
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qglvertexdescription.h"
43
44#include <QtCore/qdebug.h>
45
46QT_BEGIN_NAMESPACE
47
48/*!
49 \class QGLVertexDescription
50 \brief The QGLVertexDescription class describes the layout of a vertex within a QGLVertexArray.
51 \since 4.7
52 \ingroup qt3d
53 \ingroup qt3d::enablers
54
55 Vertices can have multiple types of information associated with them:
56 positions, normals, colors, texture co-ordinates, etc.
57 QGLVertexDescription supports this through the use of fields that
58 define the layout of the data in a corresponding QGLVertexArray.
59
60 Each field has a fieldAttribute() type, a fieldSize() in components
61 (1, 2, 3, or 4), and a fieldOffset(). The sum of all field sizes is
62 the vertex array's stride().
63
64 The following example creates a vertex description with two fields:
65 a 3D position and a 2D texture co-ordinate:
66
67 \code
68 QGLVertexDescription desc;
69 desc.addField(QGL::Position, 3);
70 desc.addField(QGL::TextureCoord0, 2);
71 \endcode
72
73 Once the layout of the vertex has been specified, field values
74 can be added to a QGLVertexArray using QGLVertexArray::append():
75
76 \code
77 QGLVertexArray array(desc);
78 array.append(2.0f, 0.0f, 0.0f);
79 array.append(1.0f, 0.0f);
80 array.append(2.0f, 3.0f, 0.0f);
81 array.append(1.0f, 1.0f);
82 array.append(0.0f, 3.0f, 0.0f);
83 array.append(0.0f, 1.0f);
84 \endcode
85
86 \sa QGLVertexArray
87*/
88
89/*!
90 \fn QGLVertexDescription::QGLVertexDescription()
91
92 Constructs an empty vertex description. Use addField() to
93 add fields to the description.
94
95 \sa addField()
96*/
97
98/*!
99 \fn QGLVertexDescription::QGLVertexDescription(const QGLVertexDescription& other)
100
101 Constructs a copy of \a other.
102*/
103
104/*!
105 \fn int QGLVertexDescription::fieldCount() const
106
107 Returns the number of fields in this vertex description.
108
109 \sa stride(), addField()
110*/
111
112/*!
113 \fn int QGLVertexDescription::stride() const
114
115 Returns the stride of this vertex description in GLfloat units.
116
117 \sa fieldCount(), addField()
118*/
119
120/*!
121 Adds a field to this vertex description with the details \a attr
122 and \a size. The offset of the field is determined from stride().
123 The \a size must be between 1 and 4, inclusive.
124
125 \sa stride(), fieldCount(), addFields(), indexOf()
126*/
127void QGLVertexDescription::addField(QGL::VertexAttribute attr, int size)
128{
129 Q_ASSERT(size >= 1 && size <= 4);
130 Field field;
131 field.attr = attr;
132 field.size = size;
133 field.offset = m_stride;
134 field.reserved = 0;
135 m_fields.append(field);
136 m_stride += size;
137}
138
139/*!
140 Adds all of the fields in \a other to this vertex description.
141
142 \sa addField()
143*/
144void QGLVertexDescription::addFields(const QGLVertexDescription& other)
145{
146 for (int posn = 0; posn < other.m_fields.count(); ++posn) {
147 Field field = other.m_fields[posn];
148 field.offset += m_stride;
149 m_fields.append(field);
150 }
151 m_stride += other.m_stride;
152}
153
154/*!
155 Returns the index of the first field in this vertex description
156 that is associated with \a attr; -1 if \a attr is not present.
157
158 \sa addField()
159*/
160int QGLVertexDescription::indexOf(QGL::VertexAttribute attr) const
161{
162 int index, posn;
163 for (index = 0, posn = 0; posn < m_fields.count(); ++index, ++posn) {
164 if (m_fields[posn].attr == attr)
165 return index;
166 }
167 return -1;
168}
169
170/*!
171 \fn QGL::VertexAttribute QGLVertexDescription::fieldAttribute(int index) const
172
173 Returns the attribute name associated with the field at \a index
174 in this vertex description; or QGL::Position if \a index is
175 out of range.
176
177 \sa fieldSize(), fieldOffset()
178*/
179
180/*!
181 \fn int QGLVertexDescription::fieldSize(int index) const
182
183 Returns the number of components (between 1 and 4) in the field at
184 \a index in this vertex description; or 0 if \a index is out of range.
185
186 \sa fieldAttribute(), fieldOffset()
187*/
188
189/*!
190 \fn int QGLVertexDescription::fieldOffset(int index) const
191
192 Returns the offset of the field at \a index in this vertex description
193 in GLfloat units; or 0 if \a index is out of range.
194
195 \sa fieldAttribute(), fieldSize()
196*/
197
198/*!
199 \fn bool QGLVertexDescription::operator==(const QGLVertexDescription& other) const
200
201 Returns true if \a other is the same as this vertex description;
202 false otherwise.
203
204 \sa operator!=()
205*/
206
207/*!
208 \fn bool QGLVertexDescription::operator!=(const QGLVertexDescription& other) const
209
210 Returns true if \a other is not the same as this vertex description;
211 false otherwise.
212
213 \sa operator==()
214*/
215#ifndef QT_NO_DEBUG_STREAM
216
217static const char *vertAttrNames[] = {
218 "Position", "Normal", "Color", "TextureCoord0",
219 "TextureCoord1", "TextureCoord2", "TextureCoord3", "TextureCoord4",
220 "TextureCoord5", "TextureCoord6", "TextureCoord7", "CustomVertex0",
221 "CustomVertex1", "CustomVertex2", "CustomVertex3", "CustomVertex4",
222 "CustomVertex5", "CustomVertex6", "CustomVertex7"
223};
224
225QDebug operator<<(QDebug dbg, const QGLVertexDescription &description)
226{
227 dbg.nospace() << "QGLVertexDescription(";
228 int i = 0;
229 for (i = 0; i < description.fieldCount() - 1; ++i)
230 dbg << i << ":" << vertAttrNames[description.fieldAttribute(i)] << ", ";
231 dbg << i << ":" << vertAttrNames[description.fieldAttribute(i)] << ")\n";
232 return dbg.space();
233}
234
235#endif
236
237QT_END_NAMESPACE
  
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the Qt3D module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** No Commercial Usage
11** This file contains pre-release code and may not be distributed.
12** You may use this file in accordance with the terms and conditions
13** contained in the Technology Preview License Agreement accompanying
14** this package.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** If you have questions regarding the use of this file, please contact
29** Nokia at qt-info@nokia.com.
30**
31**
32**
33**
34**
35**
36**
37**
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#ifndef QGLVERTEXDESCRIPTION_H
43#define QGLVERTEXDESCRIPTION_H
44
45#include <QtCore/qvector.h>
46#include "qt3dglobal.h"
47
48QT_BEGIN_HEADER
49
50QT_BEGIN_NAMESPACE
51
52QT_MODULE(Qt3d)
53
54namespace QGL
55{
56 enum VertexAttribute {
57 Position,
58 Normal,
59 Color,
60 TextureCoord0,
61 TextureCoord1,
62 TextureCoord2,
63 TextureCoord3,
64 TextureCoord4,
65 TextureCoord5,
66 TextureCoord6,
67 TextureCoord7,
68 CustomVertex0,
69 CustomVertex1,
70 CustomVertex2,
71 CustomVertex3,
72 CustomVertex4,
73 CustomVertex5,
74 CustomVertex6,
75 CustomVertex7
76 };
77};
78
79class Q_QT3D_EXPORT QGLVertexDescription
80{
81public:
82 QGLVertexDescription();
83 QGLVertexDescription(const QGLVertexDescription& other);
84
85 int fieldCount() const;
86 int stride() const;
87
88 void addField(QGL::VertexAttribute attr, int size);
89
90 void addFields(const QGLVertexDescription& other);
91
92 int indexOf(QGL::VertexAttribute attr) const;
93
94 QGL::VertexAttribute fieldAttribute(int index) const;
95 int fieldSize(int index) const;
96 int fieldOffset(int index) const;
97
98 bool operator==(const QGLVertexDescription& other) const;
99 bool operator!=(const QGLVertexDescription& other) const;
100
101private:
102 struct Field
103 {
104 QGL::VertexAttribute attr;
105 int size;
106 int offset;
107 int reserved;
108
109 bool operator==(const Field& field) const
110 {
111 return attr == field.attr && size == field.size &&
112 offset == field.offset && reserved == field.reserved;
113 }
114 };
115 QVector<Field> m_fields;
116 int m_stride;
117
118 friend class QGLVertexArray;
119};
120
121inline QGLVertexDescription::QGLVertexDescription()
122 : m_stride(0)
123{
124}
125
126inline QGLVertexDescription::QGLVertexDescription
127 (const QGLVertexDescription& other)
128 : m_fields(other.m_fields), m_stride(other.m_stride)
129{
130}
131
132inline int QGLVertexDescription::fieldCount() const
133{
134 return m_fields.count();
135}
136
137inline int QGLVertexDescription::stride() const
138{
139 return m_stride;
140}
141
142inline QGL::VertexAttribute QGLVertexDescription::fieldAttribute(int index) const
143{
144 if (index >= 0 && index < m_fields.count())
145 return m_fields[index].attr;
146 else
147 return QGL::Position;
148}
149
150inline int QGLVertexDescription::fieldSize(int index) const
151{
152 if (index >= 0 && index < m_fields.count())
153 return m_fields[index].size;
154 else
155 return 0;
156}
157
158inline int QGLVertexDescription::fieldOffset(int index) const
159{
160 if (index >= 0 && index < m_fields.count())
161 return m_fields[index].offset;
162 else
163 return 0;
164}
165
166inline bool QGLVertexDescription::operator==(const QGLVertexDescription& other) const
167{
168 return m_fields == other.m_fields && m_stride == other.m_stride;
169}
170
171inline bool QGLVertexDescription::operator!=(const QGLVertexDescription& other) const
172{
173 return !(m_fields == other.m_fields) || m_stride != other.m_stride;
174}
175
176#ifndef QT_NO_DEBUG_STREAM
177Q_QT3D_EXPORT QDebug operator<<(QDebug dbg, const QGLVertexDescription &description);
178#endif
179
180QT_END_NAMESPACE
181
182QT_END_HEADER
183
184#endif
  
372372}
373373
374374/*!
375 Returns a QGLVertexArray that contains all the data of this geometry.
376
377 NOTE: this is a temporary facility - when QGeometryData can function as
378 QGLVertexArray, uploading to the GPU and setting on QPainter then
379 this function can be removed. The bounds checking asserts should be
380 moved at that point into what ever code does the upload/setting.
381*/
382QGLVertexArray QGeometryData::toVertexArray() const
383{
384 QGLVertexArray array;
385 check();
386 if (d)
387 {
388 const quint32 mask = 0x01;
389 quint32 fields = d->fields;
390 for (int field = 0; fields; ++field, fields >>= 1)
391 {
392 if (mask & fields)
393 {
394 QGL::VertexAttribute attr = static_cast<QGL::VertexAttribute>(field);
395 array.addField(attr, d->size[field]);
396 }
397 }
398 for (int index = 0; index < d->count; ++index)
399 {
400 fields = d->fields;
401 for (int field = 0; fields; ++field, fields >>= 1)
402 {
403 if (mask & fields)
404 {
405 QGL::VertexAttribute attr = static_cast<QGL::VertexAttribute>(field);
406 if (attr < QGL::TextureCoord0)
407 {
408 if (attr == QGL::Position)
409 array.append(d->vertices.at(index));
410 else if (attr == QGL::Normal)
411 array.append(d->normals.at(index));
412 else
413 array.append(d->colors.at(index));
414 }
415 else if (attr < QGL::CustomVertex0)
416 {
417 array.append(d->textures.at(d->key[field]).at(index));
418 }
419 else
420 {
421 // TODO
422 //array.append(d->attributes.at(field).at(index));
423 }
424 }
425 }
426 }
427 }
428 return array;
429}
430
431/*!
432375 Normalize all the normal vectors in this geometry to unit length.
433376*/
434377void QGeometryData::normalizeNormals()
  
4444
4545#include "qcolor4b.h"
4646#include "qglnamespace.h"
47#include "qglvertexarray.h"
4847#include "qglindexarray.h"
48#include "qglattributevalue.h"
49#include "qcustomdataarray.h"
4950#include "qbox3d.h"
5051#include "qarray.h"
5152#include "qvectorarray.h"
5656class QGeometryDataPrivate;
5757class QLogicalVertex;
5858class QGLPainter;
59class QGLVertexBuffer;
5960
6061namespace QGL
6162{
6263 inline quint32 fieldMask(QGL::VertexAttribute f) { return (quint32)0x01 << f; }
63}
64};
6465
6566class Q_QT3D_EXPORT QGeometryData
6667{
7676 void appendGeometry(const QGeometryData &data);
7777 int appendVertex(const QLogicalVertex &v);
7878 QLogicalVertex vertexAt(int i) const;
79 QGLVertexArray toVertexArray() const;
8079 void normalizeNormals();
8180 QBox3D boundingBox() const;
8281 void setCommonNormal(const QVector3D &n);
  
391391 The finalize method also destroys all the internal vertex management
392392 data structures, with the result that no more geometry may be added to
393393 the display list. Once finalize() has finished its work, the geometry
394 data in a display list is acessible as a QGLVertexArray:
394 data in a display list is acessible as a QGLVertexBuffer:
395395
396396 \code
397397 displayList->finalize();
398 QGLVertexArray data = displayList->geometry()->vertexArray();
399 QVector3D vec = data.vector3DAt(5);
398 QGLVertexBuffer *data = displayList->geometry()->vertexBuffer();
400399 \endcode
401400
402401 The finalize() function only needs to be called once in the application
  
5151#include "qglscenenode.h"
5252#include "qlogicalvertex.h"
5353#include "qglattributevalue.h"
54#include "qglvertexdescription.h"
5554#include "qglprimitive.h"
5655
5756QT_BEGIN_HEADER
145145
146146 friend class QGLSection;
147147
148 QGLVertexArray toVertexArray() const;
149148 void setDirty(bool dirty);
150149
151150#ifndef QT_NO_DEBUG_STREAM
  
155155}
156156
157157/*!
158 Returns the vertex array for this geometry object.
159
160 \sa setVertexArray(), indexArray()
161*/
162QGLVertexArray QGLGeometry::vertexArray() const
163{
164 Q_D(const QGLGeometry);
165 return d->vertexArray;
166}
167
168/*!
169 Sets the vertex \a array for this geometry object.
170
171 \sa vertexArray(), setIndexArray(), isModified()
172*/
173void QGLGeometry::setVertexArray(const QGLVertexArray& array)
174{
175 Q_D(QGLGeometry);
176 d->vertexArray = array;
177 d->modified = true;
178}
179
180/*!
181158 Returns the vertex buffer for this geometry object.
182159
183160 \sa setVertexBuffer(), indexArray()
325325 if (!d->boundingBox.isNull() && !painter->isVisible(d->boundingBox))
326326 return;
327327
328 // Need to have some vertices to draw.
329 if (!d->vertexBuffer)
330 return;
331
328332 const QGLMaterialParameters *save = 0;
329333 bool changedTex = false;
330334 if (mPalette && mMaterial != -1)
346346 // Determine if we need to recreate the vertex buffers in the GL server.
347347 // If the last upload attempt failed, then don't try again.
348348 if (d->uploadState) {
349 if (d->vertexBuffer) {
350 if (!d->vertexBuffer->isUploaded()) {
351 if (d->vertexBuffer->vertexCount() >= d->bufferThreshold)
352 d->uploadState = upload();
353 } else if (d->modified) {
349 if (!d->vertexBuffer->isUploaded()) {
350 if (d->vertexBuffer->vertexCount() >= d->bufferThreshold)
354351 d->uploadState = upload();
355 }
356 } else {
357 if (!d->vertexArray.isUploaded()) {
358 if (d->vertexArray.vertexCount() >= d->bufferThreshold)
359 d->uploadState = upload();
360 } else if (d->modified) {
361 d->uploadState = upload();
362 }
352 } else if (d->modified) {
353 d->uploadState = upload();
363354 }
364355 }
365356 d->modified = false;
366357
367358 // Draw the geometry.
368 if (d->vertexBuffer)
369 painter->setVertexBuffer(*d->vertexBuffer);
370 else
371 painter->setVertexArray(d->vertexArray);
359 painter->setVertexBuffer(*d->vertexBuffer);
372360 if (d->indexArray.isEmpty()) {
373 if (count == 0) {
374 if (d->vertexBuffer)
375 count = d->vertexBuffer->vertexCount();
376 else
377 count = d->vertexArray.vertexCount();
378 }
361 if (count == 0)
362 count = d->vertexBuffer->vertexCount();
379363 painter->draw(d->drawingMode, count, start);
380364 } else {
381365 if (count == 0)
409409 if (d->vertexBuffer) {
410410 if (d->vertexBuffer->isUploaded() && !d->modified)
411411 return true;
412 } else {
413 if (d->vertexArray.isUploaded() && !d->modified)
414 return true;
415412 }
416413
417414 // If we know that vertex buffers are not supported, then stop now.
418418 // Try to create the vertex buffer in the GL server.
419419 if (d->vertexBuffer) {
420420 if (!d->vertexBuffer->upload()) {
421 if (haveVBOs) {
422 qWarning() << "QGLGeometry: vertex buffer objects are not "
423 "supported by the GL server";
424 }
425 haveVBOs = false;
426 return false;
427 }
428 } else {
429 if (!d->vertexArray.upload()) {
430421 if (haveVBOs) {
431422 qWarning() << "QGLGeometry: vertex buffer objects are not "
432423 "supported by the GL server";
  
4444
4545#include "qglnamespace.h"
4646#include "qglindexarray.h"
47#include "qglvertexarray.h"
4847#include "qglvertexbuffer.h"
4948#include "qbox3d.h"
5049
6767
6868 QGL::DrawingMode drawingMode() const;
6969 void setDrawingMode(QGL::DrawingMode value);
70
71 QGLVertexArray vertexArray() const;
72 void setVertexArray(const QGLVertexArray& array);
7370
7471 QGLVertexBuffer *vertexBuffer() const;
7572 void setVertexBuffer(QGLVertexBuffer *buffer);
  
8080
8181 QGL::DrawingMode drawingMode;
8282 QGLIndexArray indexArray;
83 QGLVertexArray vertexArray;
8483 QGLVertexBuffer *vertexBuffer;
8584 int bufferThreshold;
8685 mutable bool modified;
  
4141
4242#include "qglabstracteffect.h"
4343#include "qglpainter_p.h"
44#include <QtOpenGL/qglshaderprogram.h>
4445
4546QT_BEGIN_NAMESPACE
4647
459459 glVertexAttribPointer(GLuint(location), value.tupleSize(),
460460 GLenum(value.type()), GL_FALSE,
461461 value.stride(), value.data());
462#elif QT_VERSION >= 0x040700
463 program->setAttributeArray
464 (location, value.type(), value.data(),
465 value.tupleSize(), value.stride());
462466#elif !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1)
463467 Q_UNUSED(program);
464468 const QGLContext *ctx = QGLContext::currentContext();
  
4040****************************************************************************/
4141
4242#include "qgldepthbufferoptions.h"
43#include "qglvertexarray.h"
4443#include "qglpainter.h"
4544#include <QtCore/qatomic.h>
4645#include <QtOpenGL/qgl.h>
  
4040****************************************************************************/
4141
4242#include "qglmatrixstack.h"
43#include "qglvertexarray.h"
4443#include "qglpainter_p.h"
4544#include <QtOpenGL/qgl.h>
4645
  
5151*/
5252
5353/*!
54 \enum QGL::VertexAttribute
55 \since 4.7
56 This enum defines the type of vertex attribute to set on an effect with QGLPainter::setVertexArray()
57
58 \value Position The primary position of the vertex.
59 \value Normal The normal at each vertex.
60 \value Color The color at each vertex.
61 \value TextureCoord0 The texture co-ordinate at each vertex for texture unit 0.
62 \value TextureCoord1 The texture co-ordinate at each vertex for texture unit 1.
63 \value TextureCoord2 The texture co-ordinate at each vertex for texture unit 2.
64 \value TextureCoord3 The texture co-ordinate at each vertex for texture unit 3.
65 \value TextureCoord4 The texture co-ordinate at each vertex for texture unit 4.
66 \value TextureCoord5 The texture co-ordinate at each vertex for texture unit 5.
67 \value TextureCoord6 The texture co-ordinate at each vertex for texture unit 6.
68 \value TextureCoord7 The texture co-ordinate at each vertex for texture unit 7.
69 \value CustomVertex0 First custom vertex attribute.
70 \value CustomVertex1 Second custom vertex attribute.
71 \value CustomVertex2 Third custom vertex attribute.
72 \value CustomVertex3 Fourth custom vertex attribute.
73 \value CustomVertex4 Fifth custom vertex attribute.
74 \value CustomVertex5 Sixth custom vertex attribute.
75 \value CustomVertex6 Seventh custom vertex attribute.
76 \value CustomVertex7 Eighth custom vertex attribute.
77*/
78
79/*!
5480 \enum QGL::Face
5581 \since 4.7
5682 This enum defines the faces to apply an operation to.
  
5757
5858namespace QGL
5959{
60 enum VertexAttribute {
61 Position,
62 Normal,
63 Color,
64 TextureCoord0,
65 TextureCoord1,
66 TextureCoord2,
67 TextureCoord3,
68 TextureCoord4,
69 TextureCoord5,
70 TextureCoord6,
71 TextureCoord7,
72 CustomVertex0,
73 CustomVertex1,
74 CustomVertex2,
75 CustomVertex3,
76 CustomVertex4,
77 CustomVertex5,
78 CustomVertex6,
79 CustomVertex7
80 };
81
6082 enum Face
6183 {
6284 FrontFaces = 0x0404, // GL_FRONT
  
10111011
10121012#ifndef QT_NO_DEBUG
10131013
1014void QGLPainterPrivate::removeRequiredFields(const QGLVertexArray& array)
1015{
1016 int count = array.m_fields.fieldCount();
1017 for (int index = 0; index < count; ++index)
1018 requiredFields.removeAll(array.m_fields.fieldAttribute(index));
1019}
1020
10211014void QGLPainterPrivate::removeRequiredFields
10221015 (const QList<QGL::VertexAttribute>& array)
10231016{
13151315#ifndef QT_NO_DEBUG
13161316 d->removeRequiredFields(buffer.attributes());
13171317#endif
1318}
1319
1320/*!
1321 Sets vertex attributes on the current GL context based on the
1322 fields in \a array.
1323
1324 The following example draws a single triangle, where each
1325 vertex consists of a 3D position and a 2D texture co-ordinate:
1326
1327 \code
1328 QGLVertexArray array(QGL::Position, 3, QGL::TextureCoord0, 2);
1329 array.append(60.0f, 10.0f, 0.0f);
1330 array.append(0.0f, 0.0f);
1331 array.append(110.0f, 110.0f, 0.0f);
1332 array.append(1.0f, 0.0f);
1333 array.append(10.0f, 110.0f, 0.0f);
1334 array.append(1.0f, 1.0f);
1335 painter.setVertexArray(array);
1336 painter.draw(QGL::Triangles, 3);
1337 \endcode
1338
1339 If \a array has been uploaded into the GL server as a vertex
1340 buffer, then the vertex buffer will be used to set the attributes.
1341
1342 \sa draw(), setCommonNormal(), QGLVertexArray::upload()
1343*/
1344void QGLPainter::setVertexArray(const QGLVertexArray& array)
1345{
1346 Q_D(QGLPainter);
1347 QGLPAINTER_CHECK_PRIVATE();
1348 d->ensureEffect();
1349 if (array.isUploaded() && array.bind()) {
1350 QGLVertexArray bufferArray = array.toBufferForm();
1351 for (int field = 0;
1352 field < bufferArray.m_fields.fieldCount(); ++field) {
1353 d->effect->setVertexAttribute
1354 (bufferArray.m_fields.fieldAttribute(field),
1355 bufferArray.attributeValue(field));
1356 }
1357 d->removeRequiredFields(bufferArray);
1358 array.release();
1359 } else {
1360 for (int field = 0; field < array.m_fields.fieldCount(); ++field) {
1361 d->effect->setVertexAttribute
1362 (array.m_fields.fieldAttribute(field),
1363 array.attributeValue(field));
1364 }
1365 d->removeRequiredFields(array);
1366 }
13671318}
13681319
13691320/*!
  
5050#include <QtGui/qmatrix4x4.h>
5151#include "qbox3d.h"
5252#include "qglvertexbuffer.h"
53#include "qglvertexarray.h"
5453#include "qglindexarray.h"
5554#include "qgllightmodel.h"
5655#include "qgllightparameters.h"
145145 void setVertexAttribute
146146 (QGL::VertexAttribute attribute, const QGLAttributeValue& value);
147147 void setVertexBuffer(const QGLVertexBuffer& buffer);
148
149 void setVertexArray(const QGLVertexArray& array);
150148
151149 void setCommonNormal(const QVector3D& value);
152150
  
282282 QList<QGL::VertexAttribute> requiredFields;
283283 inline void setRequiredFields(const QList<QGL::VertexAttribute>& fields)
284284 { requiredFields = fields; }
285 void removeRequiredFields(const QGLVertexArray& array);
286285 void removeRequiredFields(const QList<QGL::VertexAttribute>& array);
287286 void removeRequiredField(QGL::VertexAttribute attribute)
288287 { requiredFields.removeAll(attribute); }
289288#else
290289 inline void setRequiredFields(const QList<QGL::VertexAttribute>& fields)
291290 { Q_UNUSED(fields); }
292 inline void removeRequiredFields(const QGLVertexArray& array)
293 { Q_UNUSED(array); }
294291 inline void removeRequiredFields(const QList<QGL::VertexAttribute>& array)
295292 { Q_UNUSED(array); }
296293 inline void removeRequiredField(QGL::VertexAttribute attribute)