Commit 02b5213289ed51b32a0e2376b947610e2e8e4646
- Diff rendering mode:
- inline
- side by side
demos/pageflip/pageflip.cpp
(12 / 5)
|   | |||
| 217 | 217 | pageFlipMath.setShowPageReverse(false); | |
| 218 | 218 | pageFlipMath.compute(posn); | |
| 219 | 219 | ||
| 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); | ||
| 223 | 226 | ||
| 224 | 227 | #if defined(QT_OPENGL_ES_1) | |
| 225 | 228 | painter.setStandardEffect(QGL::FlatReplaceTexture2D); | |
| … | … | ||
| 232 | 232 | painter.setColor(colors[colorIndex]); | |
| 233 | 233 | painter.setTexture(0, &(textures[colorIndex])); | |
| 234 | 234 | 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); | ||
| 236 | 238 | setAlphaValue(1.0f); | |
| 237 | 239 | painter.update(); | |
| 238 | 240 | pageFlipMath.drawPage(0); | |
| … | … | ||
| 265 | 265 | painter.setTexture(1, (QGLTexture2D *)0); | |
| 266 | 266 | ||
| 267 | 267 | 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); | ||
| 269 | 271 | painter.setColor(QColor(0, 0, 0, 255)); | |
| 270 | 272 | painter.update(); | |
| 271 | 273 | pageFlipMath.drawOutline(2); |
|   | |||
| 85 | 85 | const GLfloat *vertexArray() const { return vertices[0][0]; } | |
| 86 | 86 | ||
| 87 | 87 | // Get the vertex array stride in bytes. | |
| 88 | int stride() const { return 5 * 5 * sizeof(GLfloat); } | ||
| 88 | int stride() const { return 5 * sizeof(GLfloat); } | ||
| 89 | 89 | ||
| 90 | 90 | // Draw a specific page. | |
| 91 | 91 | void drawPage(int page) const; |
|   | |||
| 41 | 41 | ||
| 42 | 42 | #include "qglheightmap.h" | |
| 43 | 43 | #include <QVector3D> | |
| 44 | #include "qglvertexarray.h" | ||
| 45 | 44 | #include "qgldisplaylist.h" | |
| 46 | 45 | #include "qgloperation.h" | |
| 47 | 46 |
|   | |||
| 44 | 44 | #include "qglcube.h" | |
| 45 | 45 | #include "qglteapot.h" | |
| 46 | 46 | #include "qglsphere.h" | |
| 47 | #include "qglvertexarray.h" | ||
| 48 | 47 | #include <math.h> | |
| 49 | 48 | #include <QVector3D> | |
| 50 | 49 | #include "qglheightmap.h" |
examples/spot/triplane.cpp
(5 / 3)
|   | |||
| 41 | 41 | ||
| 42 | 42 | #include "triplane.h" | |
| 43 | 43 | ||
| 44 | #include "qglvertexarray.h" | ||
| 44 | #include "qglvertexbuffer.h" | ||
| 45 | 45 | #include "qglindexarray.h" | |
| 46 | 46 | #include "qglpainter.h" | |
| 47 | 47 | #include "qline3d.h" | |
| … | … | ||
| 110 | 110 | // pointers to minimize copies) to do the next column | |
| 111 | 111 | QLine3D *l0 = &sideLine; | |
| 112 | 112 | QLine3D *l1 = &nxSideLine; | |
| 113 | QGLVertexArray vertices(QGL::Position, 3); | ||
| 113 | QVector3DArray vertices; | ||
| 114 | 114 | for (int col = 0; col < divisions; ++col) | |
| 115 | 115 | { | |
| 116 | 116 | // ternary ops here are avoiding fmuls & rounding errors at bounds | |
| … | … | ||
| 127 | 127 | vertices.append(l1->point(t)); | |
| 128 | 128 | } | |
| 129 | 129 | qSwap(l0, l1); | |
| 130 | g->setVertexArray(vertices); | ||
| 130 | QGLVertexBuffer *buffer = new QGLVertexBuffer(); | ||
| 131 | buffer->addAttribute(QGL::Position, vertices); | ||
| 132 | g->setVertexBuffer(buffer); | ||
| 131 | 133 | mStrips.append(g); | |
| 132 | 134 | } | |
| 133 | 135 |
|   | |||
| 870 | 870 | ||
| 871 | 871 | QCOMPARE(displayList.sections().count(), 0); | |
| 872 | 872 | ||
| 873 | #if 0 // TODO: needs to check the vertex buffer instead | ||
| 873 | 874 | QGeometryData *geom = node->geometry(); | |
| 874 | 875 | ||
| 875 | 876 | QGLVertexArray verts = geom->toVertexArray(); | |
| … | … | ||
| 920 | 920 | QCOMPARE(verts2.vector3DAt(tri, desc.indexOf(QGL::Position)), e); | |
| 921 | 921 | QCOMPARE(verts2.vector3DAt(tri, desc.indexOf(QGL::Normal)), n10); | |
| 922 | 922 | QCOMPARE(verts2.vector2DAt(tri, desc.indexOf(QGL::TextureCoord0)), ta); | |
| 923 | #endif | ||
| 923 | 924 | } | |
| 924 | 925 | ||
| 925 | 926 | QTEST_APPLESS_MAIN(tst_QGLDisplayList) |
|   | |||
| 58 | 58 | { | |
| 59 | 59 | QGLGeometry geom; | |
| 60 | 60 | QCOMPARE(geom.drawingMode(), QGL::NoDrawingMode); | |
| 61 | QVERIFY(geom.vertexArray().isEmpty()); | ||
| 62 | 61 | QVERIFY(geom.indexArray().isEmpty()); | |
| 63 | 62 | QCOMPARE(geom.bufferThreshold(), 32); | |
| 64 | 63 | QVERIFY(geom.boundingBox().isNull()); | |
| … | … | ||
| 65 | 65 | ||
| 66 | 66 | void tst_QGLGeometry::accessors() | |
| 67 | 67 | { | |
| 68 | QGLVertexArray array; | ||
| 69 | 68 | 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); | ||
| 76 | 69 | QGLIndexArray indexes; | |
| 77 | 70 | indexes.append(1, 2, 3, 4); | |
| 78 | 71 | geom.setIndexArray(indexes); |
|   | |||
| 82 | 82 | } | |
| 83 | 83 | ||
| 84 | 84 | // Draw a set of triangles from a vertex array. | |
| 85 | void QGLSimulator::drawTriangles(const QGLVertexArray& array) | ||
| 85 | void QGLSimulator::drawTriangles(const QVector2DArray& array) | ||
| 86 | 86 | { | |
| 87 | 87 | QVector<QPointF> points; | |
| 88 | 88 | ||
| 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 | } | ||
| 93 | 93 | ||
| 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 | |||
| 97 | void 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]; | ||
| 100 | 103 | points.append(project(v)); | |
| 101 | 104 | } | |
| 102 | 105 |
|   | |||
| 46 | 46 | #include <QtGui/qcolor.h> | |
| 47 | 47 | #include <QtGui/qmatrix4x4.h> | |
| 48 | 48 | #include <QtGui/qvector3d.h> | |
| 49 | #include "qglvertexarray.h" | ||
| 49 | #include "qvectorarray.h" | ||
| 50 | 50 | ||
| 51 | 51 | class QGLSimulator | |
| 52 | 52 | { | |
| … | … | ||
| 70 | 70 | ||
| 71 | 71 | void setColor(const QColor& color); | |
| 72 | 72 | ||
| 73 | void drawTriangles(const QGLVertexArray& array); | ||
| 73 | void drawTriangles(const QVector2DArray& array); | ||
| 74 | void drawTriangles(const QVector3DArray& array); | ||
| 74 | 75 | ||
| 75 | 76 | private: | |
| 76 | 77 | QPainter *m_painter; |
|   | |||
| 118 | 118 | painter.projectionMatrix().ortho(widget->rect()); | |
| 119 | 119 | painter.modelViewMatrix().setToIdentity(); | |
| 120 | 120 | ||
| 121 | QGLVertexArray vertices(QGL::Position, 2); | ||
| 121 | QVector2DArray vertices; | ||
| 122 | 122 | vertices.append(10, 100); | |
| 123 | 123 | vertices.append(500, 100); | |
| 124 | 124 | vertices.append(500, 500); | |
| 125 | 125 | ||
| 126 | 126 | painter.setStandardEffect(QGL::FlatColor); | |
| 127 | 127 | painter.setColor(Qt::green); | |
| 128 | painter.setVertexArray(vertices); | ||
| 128 | painter.setVertexAttribute(QGL::Position, vertices); | ||
| 129 | 129 | painter.draw(QGL::Triangles, 3); | |
| 130 | 130 | } | |
| 131 | 131 | ||
| … | … | ||
| 140 | 140 | proj.ortho(widget->rect()); | |
| 141 | 141 | sim.setProjectionMatrix(proj); | |
| 142 | 142 | ||
| 143 | QGLVertexArray vertices(QGL::Position, 2); | ||
| 143 | QVector2DArray vertices; | ||
| 144 | 144 | vertices.append(10, 100); | |
| 145 | 145 | vertices.append(500, 100); | |
| 146 | 146 | vertices.append(500, 500); |
|   | |||
| 1 | load(qttest_p4.prf) | ||
| 2 | TARGET=qglvertexarray | ||
| 3 | TEMPLATE=app | ||
| 4 | QT += testlib | ||
| 5 | CONFIG += unittest warn_on | ||
| 6 | |||
| 7 | SOURCES += tst_qglvertexarray.cpp | ||
| 8 | |||
| 9 | LIBS += -L../../../../lib -L../../../../bin | ||
| 10 | |||
| 11 | include(../../../../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 | |||
| 45 | class tst_QGLVertexArray : public QObject | ||
| 46 | { | ||
| 47 | Q_OBJECT | ||
| 48 | public: | ||
| 49 | tst_QGLVertexArray() {} | ||
| 50 | ~tst_QGLVertexArray() {} | ||
| 51 | |||
| 52 | private 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 | |||
| 69 | void 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 | |||
| 113 | void 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 | |||
| 226 | void 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 | |||
| 282 | void 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 | |||
| 336 | void 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 | |||
| 396 | void 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 | |||
| 464 | void 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 | |||
| 539 | void 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 | |||
| 555 | void 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 | |||
| 604 | void 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 | |||
| 633 | void 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 | |||
| 662 | void 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 | |||
| 686 | void 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 | |||
| 727 | void 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 | |||
| 758 | QTEST_APPLESS_MAIN(tst_QGLVertexArray) | ||
| 759 | |||
| 760 | #include "tst_qglvertexarray.moc" |
|   | |||
| 1 | load(qttest_p4.prf) | ||
| 2 | TARGET=qglvertexdescription | ||
| 3 | TEMPLATE=app | ||
| 4 | QT += testlib | ||
| 5 | CONFIG += unittest warn_on | ||
| 6 | |||
| 7 | SOURCES += tst_qglvertexdescription.cpp | ||
| 8 | |||
| 9 | LIBS += -L../../../../lib -L../../../../bin | ||
| 10 | |||
| 11 | include(../../../../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 | |||
| 45 | class tst_QGLVertexDescription : public QObject | ||
| 46 | { | ||
| 47 | Q_OBJECT | ||
| 48 | public: | ||
| 49 | tst_QGLVertexDescription() {} | ||
| 50 | ~tst_QGLVertexDescription() {} | ||
| 51 | |||
| 52 | private slots: | ||
| 53 | void create(); | ||
| 54 | void addField(); | ||
| 55 | }; | ||
| 56 | |||
| 57 | void 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 | |||
| 81 | void 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 | |||
| 185 | QTEST_APPLESS_MAIN(tst_QGLVertexDescription) | ||
| 186 | |||
| 187 | #include "tst_qglvertexdescription.moc" |
tests/auto/threed/threed.pro
(3 / 3)
|   | |||
| 11 | 11 | qgllightmodel \ | |
| 12 | 12 | qgllightparameters \ | |
| 13 | 13 | qglmaterialparameters \ | |
| 14 | qglvertexarray \ | ||
| 15 | 14 | qglvertexbuffer \ | |
| 16 | qglvertexdescription \ | ||
| 17 | 15 | qglgeometry \ | |
| 18 | 16 | qglindexarray \ | |
| 19 | 17 | qglpainter \ | |
| 20 | 18 | qgldisplaylist \ | |
| 21 | 19 | qglsection \ | |
| 22 | 20 | qgeometrydata \ | |
| 23 | qglcube \ | ||
| 24 | 21 | qgloperation | |
| 22 | |||
| 23 | TO_BE_PORTED = \ | ||
| 24 | qglcube |
threed/enablers/enablers.pri
(0 / 4)
|   | |||
| 5 | 5 | qglcontextscope.h \ | |
| 6 | 6 | qglindexarray.h \ | |
| 7 | 7 | qglreferencedbuffer.h \ | |
| 8 | qglvertexarray.h \ | ||
| 9 | qglvertexdescription.h \ | ||
| 10 | 8 | qgltexture2d.h \ | |
| 11 | 9 | qgltexturecube.h \ | |
| 12 | 10 | qglvertexbuffer.h \ | |
| … | … | ||
| 14 | 14 | SOURCES += qglattributevalue.cpp \ | |
| 15 | 15 | qglcontextscope.cpp \ | |
| 16 | 16 | qglindexarray.cpp \ | |
| 17 | qglvertexarray.cpp \ | ||
| 18 | qglvertexdescription.cpp \ | ||
| 19 | 17 | qgltexture2d.cpp \ | |
| 20 | 18 | qgltexturecube.cpp \ | |
| 21 | 19 | qglvertexbuffer.cpp \ |
|   | |||
| 64 | 64 | desktop OpenGL systems. The name \c ElementType is a \c typedef alias for the | |
| 65 | 65 | type of these indices. | |
| 66 | 66 | ||
| 67 | \sa QGLVertexArray | ||
| 67 | \sa QGLVertexBuffer | ||
| 68 | 68 | */ | |
| 69 | 69 | ||
| 70 | 70 | /*! |
|   | |||
| 51 | 51 | ||
| 52 | 52 | QT_MODULE(Qt3d) | |
| 53 | 53 | ||
| 54 | // Helper class for QGLIndexArray and QGLVertexArray. May go away in future. | ||
| 54 | // Helper class for QGLIndexArray. May go away in future. | ||
| 55 | 55 | class Q_QT3D_EXPORT QGLReferencedBuffer : public QGLBuffer | |
| 56 | 56 | { | |
| 57 | 57 | public: |
threed/enablers/qglvertexarray.cpp
(0 / 1097)
|   | |||
| 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 | |||
| 46 | QT_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 | */ | ||
| 349 | void 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 | */ | ||
| 372 | void 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 | */ | ||
| 442 | void 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 | */ | ||
| 587 | QGLVertexArray 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 | */ | ||
| 621 | QGLVertexArray 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 | */ | ||
| 649 | QGLVertexArray 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 | */ | ||
| 862 | void 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 | */ | ||
| 880 | void 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 | |||
| 891 | void 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 | |||
| 907 | void 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 | |||
| 920 | void 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 | |||
| 933 | QGLVertexArray 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 | */ | ||
| 960 | bool 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 | */ | ||
| 989 | bool 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 | */ | ||
| 1004 | void 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 | */ | ||
| 1021 | bool 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 | |||
| 1053 | static 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 | |||
| 1061 | QDebug 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 | |||
| 1097 | QT_END_NAMESPACE |
threed/enablers/qglvertexarray.h
(0 / 757)
|   | |||
| 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 | |||
| 55 | QT_BEGIN_HEADER | ||
| 56 | |||
| 57 | QT_BEGIN_NAMESPACE | ||
| 58 | |||
| 59 | QT_MODULE(Qt3d) | ||
| 60 | |||
| 61 | class Q_QT3D_EXPORT QGLVertexArray | ||
| 62 | { | ||
| 63 | public: | ||
| 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 | |||
| 170 | private: | ||
| 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 | |||
| 190 | inline void QGLVertexArray::detachBuffer() | ||
| 191 | { | ||
| 192 | if (m_buffer && !m_buffer->deref()) | ||
| 193 | delete m_buffer; | ||
| 194 | m_buffer = 0; | ||
| 195 | } | ||
| 196 | |||
| 197 | inline QGLVertexArray::QGLVertexArray() | ||
| 198 | : m_currentField(0), m_warnings(0), m_buffer(0) | ||
| 199 | { | ||
| 200 | } | ||
| 201 | |||
| 202 | inline 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 | |||
| 208 | inline 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 | |||
| 217 | inline 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 | |||
| 228 | inline 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 | |||
| 241 | inline 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 | |||
| 251 | inline QGLVertexArray::~QGLVertexArray() | ||
| 252 | { | ||
| 253 | if (m_buffer && !m_buffer->deref()) | ||
| 254 | delete m_buffer; | ||
| 255 | } | ||
| 256 | |||
| 257 | inline 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 | |||
| 275 | inline void QGLVertexArray::addField(QGL::VertexAttribute attr, int size) | ||
| 276 | { | ||
| 277 | m_fields.addField(attr, size); | ||
| 278 | } | ||
| 279 | |||
| 280 | inline int QGLVertexArray::fieldCount() const | ||
| 281 | { | ||
| 282 | return m_fields.fieldCount(); | ||
| 283 | } | ||
| 284 | |||
| 285 | inline QGLVertexDescription QGLVertexArray::fields() const | ||
| 286 | { | ||
| 287 | return m_fields; | ||
| 288 | } | ||
| 289 | |||
| 290 | inline void QGLVertexArray::setFields(const QGLVertexDescription& value) | ||
| 291 | { | ||
| 292 | m_fields = value; | ||
| 293 | m_currentField = 0; | ||
| 294 | m_warnings = 0; | ||
| 295 | } | ||
| 296 | |||
| 297 | inline 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 | |||
| 316 | inline QGLAttributeValue QGLVertexArray::attributeValue | ||
| 317 | (QGL::VertexAttribute attr) const | ||
| 318 | { | ||
| 319 | return attributeValue(m_fields.indexOf(attr)); | ||
| 320 | } | ||
| 321 | |||
| 322 | inline int QGLVertexArray::fieldIndex(QGL::VertexAttribute attr) const | ||
| 323 | { | ||
| 324 | return m_fields.indexOf(attr); | ||
| 325 | } | ||
| 326 | |||
| 327 | inline int QGLVertexArray::stride() const | ||
| 328 | { | ||
| 329 | return m_fields.stride(); | ||
| 330 | } | ||
| 331 | |||
| 332 | inline 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 | |||
| 340 | inline int QGLVertexArray::componentCount() const | ||
| 341 | { | ||
| 342 | return m_data.count(); | ||
| 343 | } | ||
| 344 | |||
| 345 | inline bool QGLVertexArray::isEmpty() const | ||
| 346 | { | ||
| 347 | return m_data.isEmpty(); | ||
| 348 | } | ||
| 349 | |||
| 350 | inline 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 | |||
| 359 | inline 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 | |||
| 368 | inline 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 | |||
| 377 | inline 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 | |||
| 386 | inline 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 | |||
| 395 | inline 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 | |||
| 404 | inline 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 | |||
| 413 | inline 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 | |||
| 422 | inline 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 | |||
| 431 | inline 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 | |||
| 442 | inline 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 | |||
| 454 | inline 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 | |||
| 467 | inline 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 | |||
| 481 | inline 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 | |||
| 496 | inline 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 | |||
| 508 | inline 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 | |||
| 519 | inline 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 | |||
| 532 | inline 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 | |||
| 546 | inline 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 | |||
| 561 | inline 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 | |||
| 574 | inline 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 | |||
| 588 | inline 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 | |||
| 603 | inline 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 | |||
| 614 | inline float *QGLVertexArray::data() | ||
| 615 | { | ||
| 616 | if (isEmpty()) | ||
| 617 | return 0; | ||
| 618 | else | ||
| 619 | return m_data.data(); | ||
| 620 | } | ||
| 621 | |||
| 622 | inline const float *QGLVertexArray::data() const | ||
| 623 | { | ||
| 624 | if (isEmpty()) | ||
| 625 | return 0; | ||
| 626 | else | ||
| 627 | return m_data.constData(); | ||
| 628 | } | ||
| 629 | |||
| 630 | inline const float *QGLVertexArray::constData() const | ||
| 631 | { | ||
| 632 | if (isEmpty()) | ||
| 633 | return 0; | ||
| 634 | else | ||
| 635 | return m_data.constData(); | ||
| 636 | } | ||
| 637 | |||
| 638 | inline QGLVertexArray& QGLVertexArray::operator+=(qreal value) | ||
| 639 | { | ||
| 640 | append(value); | ||
| 641 | return *this; | ||
| 642 | } | ||
| 643 | |||
| 644 | inline QGLVertexArray& QGLVertexArray::operator+=(const QVector2D& value) | ||
| 645 | { | ||
| 646 | append(value); | ||
| 647 | return *this; | ||
| 648 | } | ||
| 649 | |||
| 650 | inline QGLVertexArray& QGLVertexArray::operator+=(const QVector3D& value) | ||
| 651 | { | ||
| 652 | append(value); | ||
| 653 | return *this; | ||
| 654 | } | ||
| 655 | |||
| 656 | inline QGLVertexArray& QGLVertexArray::operator+=(const QVector4D& value) | ||
| 657 | { | ||
| 658 | append(value); | ||
| 659 | return *this; | ||
| 660 | } | ||
| 661 | |||
| 662 | inline QGLVertexArray& QGLVertexArray::operator+=(const QGLVertexArray& other) | ||
| 663 | { | ||
| 664 | append(other); | ||
| 665 | return *this; | ||
| 666 | } | ||
| 667 | |||
| 668 | inline QGLVertexArray& QGLVertexArray::operator+=(const QPoint& value) | ||
| 669 | { | ||
| 670 | append(value.x(), value.y()); | ||
| 671 | return *this; | ||
| 672 | } | ||
| 673 | |||
| 674 | inline QGLVertexArray& QGLVertexArray::operator+=(const QPointF& value) | ||
| 675 | { | ||
| 676 | append(value.x(), value.y()); | ||
| 677 | return *this; | ||
| 678 | } | ||
| 679 | |||
| 680 | inline QGLVertexArray& QGLVertexArray::operator+=(const QColor4B& value) | ||
| 681 | { | ||
| 682 | append(value); | ||
| 683 | return *this; | ||
| 684 | } | ||
| 685 | |||
| 686 | inline QGLVertexArray& QGLVertexArray::operator<<(qreal value) | ||
| 687 | { | ||
| 688 | append(value); | ||
| 689 | return *this; | ||
| 690 | } | ||
| 691 | |||
| 692 | inline QGLVertexArray& QGLVertexArray::operator<<(const QVector2D& value) | ||
| 693 | { | ||
| 694 | append(value); | ||
| 695 | return *this; | ||
| 696 | } | ||
| 697 | |||
| 698 | inline QGLVertexArray& QGLVertexArray::operator<<(const QVector3D& value) | ||
| 699 | { | ||
| 700 | append(value); | ||
| 701 | return *this; | ||
| 702 | } | ||
| 703 | |||
| 704 | inline QGLVertexArray& QGLVertexArray::operator<<(const QVector4D& value) | ||
| 705 | { | ||
| 706 | append(value); | ||
| 707 | return *this; | ||
| 708 | } | ||
| 709 | |||
| 710 | inline QGLVertexArray& QGLVertexArray::operator<<(const QGLVertexArray& other) | ||
| 711 | { | ||
| 712 | append(other); | ||
| 713 | return *this; | ||
| 714 | } | ||
| 715 | |||
| 716 | inline QGLVertexArray& QGLVertexArray::operator<<(const QPoint& value) | ||
| 717 | { | ||
| 718 | append(value.x(), value.y()); | ||
| 719 | return *this; | ||
| 720 | } | ||
| 721 | |||
| 722 | inline QGLVertexArray& QGLVertexArray::operator<<(const QPointF& value) | ||
| 723 | { | ||
| 724 | append(value.x(), value.y()); | ||
| 725 | return *this; | ||
| 726 | } | ||
| 727 | |||
| 728 | inline QGLVertexArray& QGLVertexArray::operator<<(const QColor4B& value) | ||
| 729 | { | ||
| 730 | append(value); | ||
| 731 | return *this; | ||
| 732 | } | ||
| 733 | |||
| 734 | inline bool QGLVertexArray::isVertexBuffer() const | ||
| 735 | { | ||
| 736 | return m_data.constData() == 0; | ||
| 737 | } | ||
| 738 | |||
| 739 | inline bool QGLVertexArray::operator!=(const QGLVertexArray &other) const | ||
| 740 | { | ||
| 741 | return !(*this == other); | ||
| 742 | } | ||
| 743 | |||
| 744 | inline bool QGLVertexArray::isUploaded() const | ||
| 745 | { | ||
| 746 | return m_buffer != 0; | ||
| 747 | } | ||
| 748 | |||
| 749 | #ifndef QT_NO_DEBUG_STREAM | ||
| 750 | Q_QT3D_EXPORT QDebug operator<<(QDebug dbg, const QGLVertexArray &vertices); | ||
| 751 | #endif | ||
| 752 | |||
| 753 | QT_END_NAMESPACE | ||
| 754 | |||
| 755 | QT_END_HEADER | ||
| 756 | |||
| 757 | #endif |
|   | |||
| 44 | 44 | ||
| 45 | 45 | #include <QtOpenGL/qglbuffer.h> | |
| 46 | 46 | #include "qcustomdataarray.h" | |
| 47 | #include "qglvertexdescription.h" | ||
| 47 | #include "qglnamespace.h" | ||
| 48 | 48 | #include "qglattributevalue.h" | |
| 49 | 49 | #include <QtCore/qlist.h> | |
| 50 | 50 |
|   | |||
| 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 | |||
| 46 | QT_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 | */ | ||
| 127 | void 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 | */ | ||
| 144 | void 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 | */ | ||
| 160 | int 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 | |||
| 217 | static 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 | |||
| 225 | QDebug 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 | |||
| 237 | QT_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 | |||
| 48 | QT_BEGIN_HEADER | ||
| 49 | |||
| 50 | QT_BEGIN_NAMESPACE | ||
| 51 | |||
| 52 | QT_MODULE(Qt3d) | ||
| 53 | |||
| 54 | namespace 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 | |||
| 79 | class Q_QT3D_EXPORT QGLVertexDescription | ||
| 80 | { | ||
| 81 | public: | ||
| 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 | |||
| 101 | private: | ||
| 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 | |||
| 121 | inline QGLVertexDescription::QGLVertexDescription() | ||
| 122 | : m_stride(0) | ||
| 123 | { | ||
| 124 | } | ||
| 125 | |||
| 126 | inline QGLVertexDescription::QGLVertexDescription | ||
| 127 | (const QGLVertexDescription& other) | ||
| 128 | : m_fields(other.m_fields), m_stride(other.m_stride) | ||
| 129 | { | ||
| 130 | } | ||
| 131 | |||
| 132 | inline int QGLVertexDescription::fieldCount() const | ||
| 133 | { | ||
| 134 | return m_fields.count(); | ||
| 135 | } | ||
| 136 | |||
| 137 | inline int QGLVertexDescription::stride() const | ||
| 138 | { | ||
| 139 | return m_stride; | ||
| 140 | } | ||
| 141 | |||
| 142 | inline 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 | |||
| 150 | inline 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 | |||
| 158 | inline 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 | |||
| 166 | inline bool QGLVertexDescription::operator==(const QGLVertexDescription& other) const | ||
| 167 | { | ||
| 168 | return m_fields == other.m_fields && m_stride == other.m_stride; | ||
| 169 | } | ||
| 170 | |||
| 171 | inline 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 | ||
| 177 | Q_QT3D_EXPORT QDebug operator<<(QDebug dbg, const QGLVertexDescription &description); | ||
| 178 | #endif | ||
| 179 | |||
| 180 | QT_END_NAMESPACE | ||
| 181 | |||
| 182 | QT_END_HEADER | ||
| 183 | |||
| 184 | #endif |
|   | |||
| 372 | 372 | } | |
| 373 | 373 | ||
| 374 | 374 | /*! | |
| 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 | */ | ||
| 382 | QGLVertexArray 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 | /*! | ||
| 432 | 375 | Normalize all the normal vectors in this geometry to unit length. | |
| 433 | 376 | */ | |
| 434 | 377 | void QGeometryData::normalizeNormals() |
|   | |||
| 44 | 44 | ||
| 45 | 45 | #include "qcolor4b.h" | |
| 46 | 46 | #include "qglnamespace.h" | |
| 47 | #include "qglvertexarray.h" | ||
| 48 | 47 | #include "qglindexarray.h" | |
| 48 | #include "qglattributevalue.h" | ||
| 49 | #include "qcustomdataarray.h" | ||
| 49 | 50 | #include "qbox3d.h" | |
| 50 | 51 | #include "qarray.h" | |
| 51 | 52 | #include "qvectorarray.h" | |
| … | … | ||
| 56 | 56 | class QGeometryDataPrivate; | |
| 57 | 57 | class QLogicalVertex; | |
| 58 | 58 | class QGLPainter; | |
| 59 | class QGLVertexBuffer; | ||
| 59 | 60 | ||
| 60 | 61 | namespace QGL | |
| 61 | 62 | { | |
| 62 | 63 | inline quint32 fieldMask(QGL::VertexAttribute f) { return (quint32)0x01 << f; } | |
| 63 | } | ||
| 64 | }; | ||
| 64 | 65 | ||
| 65 | 66 | class Q_QT3D_EXPORT QGeometryData | |
| 66 | 67 | { | |
| … | … | ||
| 76 | 76 | void appendGeometry(const QGeometryData &data); | |
| 77 | 77 | int appendVertex(const QLogicalVertex &v); | |
| 78 | 78 | QLogicalVertex vertexAt(int i) const; | |
| 79 | QGLVertexArray toVertexArray() const; | ||
| 80 | 79 | void normalizeNormals(); | |
| 81 | 80 | QBox3D boundingBox() const; | |
| 82 | 81 | void setCommonNormal(const QVector3D &n); |
|   | |||
| 391 | 391 | The finalize method also destroys all the internal vertex management | |
| 392 | 392 | data structures, with the result that no more geometry may be added to | |
| 393 | 393 | 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: | ||
| 395 | 395 | ||
| 396 | 396 | \code | |
| 397 | 397 | displayList->finalize(); | |
| 398 | QGLVertexArray data = displayList->geometry()->vertexArray(); | ||
| 399 | QVector3D vec = data.vector3DAt(5); | ||
| 398 | QGLVertexBuffer *data = displayList->geometry()->vertexBuffer(); | ||
| 400 | 399 | \endcode | |
| 401 | 400 | ||
| 402 | 401 | The finalize() function only needs to be called once in the application |
|   | |||
| 51 | 51 | #include "qglscenenode.h" | |
| 52 | 52 | #include "qlogicalvertex.h" | |
| 53 | 53 | #include "qglattributevalue.h" | |
| 54 | #include "qglvertexdescription.h" | ||
| 55 | 54 | #include "qglprimitive.h" | |
| 56 | 55 | ||
| 57 | 56 | QT_BEGIN_HEADER | |
| … | … | ||
| 145 | 145 | ||
| 146 | 146 | friend class QGLSection; | |
| 147 | 147 | ||
| 148 | QGLVertexArray toVertexArray() const; | ||
| 149 | 148 | void setDirty(bool dirty); | |
| 150 | 149 | ||
| 151 | 150 | #ifndef QT_NO_DEBUG_STREAM |
threed/geometry/qglgeometry.cpp
(11 / 58)
|   | |||
| 155 | 155 | } | |
| 156 | 156 | ||
| 157 | 157 | /*! | |
| 158 | Returns the vertex array for this geometry object. | ||
| 159 | |||
| 160 | \sa setVertexArray(), indexArray() | ||
| 161 | */ | ||
| 162 | QGLVertexArray 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 | */ | ||
| 173 | void QGLGeometry::setVertexArray(const QGLVertexArray& array) | ||
| 174 | { | ||
| 175 | Q_D(QGLGeometry); | ||
| 176 | d->vertexArray = array; | ||
| 177 | d->modified = true; | ||
| 178 | } | ||
| 179 | |||
| 180 | /*! | ||
| 181 | 158 | Returns the vertex buffer for this geometry object. | |
| 182 | 159 | ||
| 183 | 160 | \sa setVertexBuffer(), indexArray() | |
| … | … | ||
| 325 | 325 | if (!d->boundingBox.isNull() && !painter->isVisible(d->boundingBox)) | |
| 326 | 326 | return; | |
| 327 | 327 | ||
| 328 | // Need to have some vertices to draw. | ||
| 329 | if (!d->vertexBuffer) | ||
| 330 | return; | ||
| 331 | |||
| 328 | 332 | const QGLMaterialParameters *save = 0; | |
| 329 | 333 | bool changedTex = false; | |
| 330 | 334 | if (mPalette && mMaterial != -1) | |
| … | … | ||
| 346 | 346 | // Determine if we need to recreate the vertex buffers in the GL server. | |
| 347 | 347 | // If the last upload attempt failed, then don't try again. | |
| 348 | 348 | 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) | ||
| 354 | 351 | 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(); | ||
| 363 | 354 | } | |
| 364 | 355 | } | |
| 365 | 356 | d->modified = false; | |
| 366 | 357 | ||
| 367 | 358 | // Draw the geometry. | |
| 368 | if (d->vertexBuffer) | ||
| 369 | painter->setVertexBuffer(*d->vertexBuffer); | ||
| 370 | else | ||
| 371 | painter->setVertexArray(d->vertexArray); | ||
| 359 | painter->setVertexBuffer(*d->vertexBuffer); | ||
| 372 | 360 | 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(); | ||
| 379 | 363 | painter->draw(d->drawingMode, count, start); | |
| 380 | 364 | } else { | |
| 381 | 365 | if (count == 0) | |
| … | … | ||
| 409 | 409 | if (d->vertexBuffer) { | |
| 410 | 410 | if (d->vertexBuffer->isUploaded() && !d->modified) | |
| 411 | 411 | return true; | |
| 412 | } else { | ||
| 413 | if (d->vertexArray.isUploaded() && !d->modified) | ||
| 414 | return true; | ||
| 415 | 412 | } | |
| 416 | 413 | ||
| 417 | 414 | // If we know that vertex buffers are not supported, then stop now. | |
| … | … | ||
| 418 | 418 | // Try to create the vertex buffer in the GL server. | |
| 419 | 419 | if (d->vertexBuffer) { | |
| 420 | 420 | 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()) { | ||
| 430 | 421 | if (haveVBOs) { | |
| 431 | 422 | qWarning() << "QGLGeometry: vertex buffer objects are not " | |
| 432 | 423 | "supported by the GL server"; |
|   | |||
| 44 | 44 | ||
| 45 | 45 | #include "qglnamespace.h" | |
| 46 | 46 | #include "qglindexarray.h" | |
| 47 | #include "qglvertexarray.h" | ||
| 48 | 47 | #include "qglvertexbuffer.h" | |
| 49 | 48 | #include "qbox3d.h" | |
| 50 | 49 | ||
| … | … | ||
| 67 | 67 | ||
| 68 | 68 | QGL::DrawingMode drawingMode() const; | |
| 69 | 69 | void setDrawingMode(QGL::DrawingMode value); | |
| 70 | |||
| 71 | QGLVertexArray vertexArray() const; | ||
| 72 | void setVertexArray(const QGLVertexArray& array); | ||
| 73 | 70 | ||
| 74 | 71 | QGLVertexBuffer *vertexBuffer() const; | |
| 75 | 72 | void setVertexBuffer(QGLVertexBuffer *buffer); |
|   | |||
| 80 | 80 | ||
| 81 | 81 | QGL::DrawingMode drawingMode; | |
| 82 | 82 | QGLIndexArray indexArray; | |
| 83 | QGLVertexArray vertexArray; | ||
| 84 | 83 | QGLVertexBuffer *vertexBuffer; | |
| 85 | 84 | int bufferThreshold; | |
| 86 | 85 | mutable bool modified; |
|   | |||
| 41 | 41 | ||
| 42 | 42 | #include "qglabstracteffect.h" | |
| 43 | 43 | #include "qglpainter_p.h" | |
| 44 | #include <QtOpenGL/qglshaderprogram.h> | ||
| 44 | 45 | ||
| 45 | 46 | QT_BEGIN_NAMESPACE | |
| 46 | 47 | ||
| … | … | ||
| 459 | 459 | glVertexAttribPointer(GLuint(location), value.tupleSize(), | |
| 460 | 460 | GLenum(value.type()), GL_FALSE, | |
| 461 | 461 | value.stride(), value.data()); | |
| 462 | #elif QT_VERSION >= 0x040700 | ||
| 463 | program->setAttributeArray | ||
| 464 | (location, value.type(), value.data(), | ||
| 465 | value.tupleSize(), value.stride()); | ||
| 462 | 466 | #elif !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1) | |
| 463 | 467 | Q_UNUSED(program); | |
| 464 | 468 | const QGLContext *ctx = QGLContext::currentContext(); |
|   | |||
| 40 | 40 | ****************************************************************************/ | |
| 41 | 41 | ||
| 42 | 42 | #include "qgldepthbufferoptions.h" | |
| 43 | #include "qglvertexarray.h" | ||
| 44 | 43 | #include "qglpainter.h" | |
| 45 | 44 | #include <QtCore/qatomic.h> | |
| 46 | 45 | #include <QtOpenGL/qgl.h> |
|   | |||
| 40 | 40 | ****************************************************************************/ | |
| 41 | 41 | ||
| 42 | 42 | #include "qglmatrixstack.h" | |
| 43 | #include "qglvertexarray.h" | ||
| 44 | 43 | #include "qglpainter_p.h" | |
| 45 | 44 | #include <QtOpenGL/qgl.h> | |
| 46 | 45 |
threed/painting/qglnamespace.cpp
(26 / 0)
|   | |||
| 51 | 51 | */ | |
| 52 | 52 | ||
| 53 | 53 | /*! | |
| 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 | /*! | ||
| 54 | 80 | \enum QGL::Face | |
| 55 | 81 | \since 4.7 | |
| 56 | 82 | This enum defines the faces to apply an operation to. |
threed/painting/qglnamespace.h
(22 / 0)
|   | |||
| 57 | 57 | ||
| 58 | 58 | namespace QGL | |
| 59 | 59 | { | |
| 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 | |||
| 60 | 82 | enum Face | |
| 61 | 83 | { | |
| 62 | 84 | FrontFaces = 0x0404, // GL_FRONT |
threed/painting/qglpainter.cpp
(0 / 56)
|   | |||
| 1011 | 1011 | ||
| 1012 | 1012 | #ifndef QT_NO_DEBUG | |
| 1013 | 1013 | ||
| 1014 | void 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 | |||
| 1021 | 1014 | void QGLPainterPrivate::removeRequiredFields | |
| 1022 | 1015 | (const QList<QGL::VertexAttribute>& array) | |
| 1023 | 1016 | { | |
| … | … | ||
| 1315 | 1315 | #ifndef QT_NO_DEBUG | |
| 1316 | 1316 | d->removeRequiredFields(buffer.attributes()); | |
| 1317 | 1317 | #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 | */ | ||
| 1344 | void 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 | } | ||
| 1367 | 1318 | } | |
| 1368 | 1319 | ||
| 1369 | 1320 | /*! |
threed/painting/qglpainter.h
(0 / 3)
|   | |||
| 50 | 50 | #include <QtGui/qmatrix4x4.h> | |
| 51 | 51 | #include "qbox3d.h" | |
| 52 | 52 | #include "qglvertexbuffer.h" | |
| 53 | #include "qglvertexarray.h" | ||
| 54 | 53 | #include "qglindexarray.h" | |
| 55 | 54 | #include "qgllightmodel.h" | |
| 56 | 55 | #include "qgllightparameters.h" | |
| … | … | ||
| 145 | 145 | void setVertexAttribute | |
| 146 | 146 | (QGL::VertexAttribute attribute, const QGLAttributeValue& value); | |
| 147 | 147 | void setVertexBuffer(const QGLVertexBuffer& buffer); | |
| 148 | |||
| 149 | void setVertexArray(const QGLVertexArray& array); | ||
| 150 | 148 | ||
| 151 | 149 | void setCommonNormal(const QVector3D& value); | |
| 152 | 150 |
|   | |||
| 282 | 282 | QList<QGL::VertexAttribute> requiredFields; | |
| 283 | 283 | inline void setRequiredFields(const QList<QGL::VertexAttribute>& fields) | |
| 284 | 284 | { requiredFields = fields; } | |
| 285 | void removeRequiredFields(const QGLVertexArray& array); | ||
| 286 | 285 | void removeRequiredFields(const QList<QGL::VertexAttribute>& array); | |
| 287 | 286 | void removeRequiredField(QGL::VertexAttribute attribute) | |
| 288 | 287 | { requiredFields.removeAll(attribute); } | |
| 289 | 288 | #else | |
| 290 | 289 | inline void setRequiredFields(const QList<QGL::VertexAttribute>& fields) | |
| 291 | 290 | { Q_UNUSED(fields); } | |
| 292 | inline void removeRequiredFields(const QGLVertexArray& array) | ||
| 293 | { Q_UNUSED(array); } | ||
| 294 | 291 | inline void removeRequiredFields(const QList<QGL::VertexAttribute>& array) | |
| 295 | 292 | { Q_UNUSED(array); } | |
| 296 | 293 | inline void removeRequiredField(QGL::VertexAttribute attribute) |

