From 981e5a23f62703a6e615dfe2a62b02d52ff523ce Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Wed, 19 Nov 2014 16:13:13 +0100 Subject: Unit tests for QGraphicsUtils Helps make sure that the methods are working as expected before being used by the renderer. Change-Id: If335bf4c7f9cb95d5e7b1f9bd862d438e71a3fe1 Reviewed-by: Sean Harmer --- .../auto/render/qgraphicsutils/qgraphicsutils.pro | 9 + .../render/qgraphicsutils/tst_qgraphicsutils.cpp | 368 +++++++++++++++++++++ tests/auto/render/render.pro | 4 +- 3 files changed, 380 insertions(+), 1 deletion(-) create mode 100644 tests/auto/render/qgraphicsutils/qgraphicsutils.pro create mode 100644 tests/auto/render/qgraphicsutils/tst_qgraphicsutils.cpp (limited to 'tests/auto') diff --git a/tests/auto/render/qgraphicsutils/qgraphicsutils.pro b/tests/auto/render/qgraphicsutils/qgraphicsutils.pro new file mode 100644 index 000000000..6ab00ad6a --- /dev/null +++ b/tests/auto/render/qgraphicsutils/qgraphicsutils.pro @@ -0,0 +1,9 @@ +TEMPLATE = app + +TARGET = tst_qgraphicsutils + +QT += 3dcore 3dcore-private 3drenderer 3drenderer-private testlib + +CONFIG += testcase + +SOURCES += tst_qgraphicsutils.cpp diff --git a/tests/auto/render/qgraphicsutils/tst_qgraphicsutils.cpp b/tests/auto/render/qgraphicsutils/tst_qgraphicsutils.cpp new file mode 100644 index 000000000..83947a9a9 --- /dev/null +++ b/tests/auto/render/qgraphicsutils/tst_qgraphicsutils.cpp @@ -0,0 +1,368 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +class tst_QGraphicsUtils : public QObject +{ + Q_OBJECT +private slots: + void fillScalarInDataArray(); + void fillArray(); + void fillScalarWithOffsets(); + void fillMatrix4x4(); + void fillMatrix3x4(); + void fillMatrix4x3(); + void fillMatrixArray(); +}; + +void tst_QGraphicsUtils::fillScalarInDataArray() +{ + Qt3D::Render::ShaderUniform description; + + description.m_size = 1; + description.m_offset = 0; + description.m_arrayStride = 10; + + QVector4D testVector(8.0f, 8.0f, 3.0f, 1.0f); + const GLfloat *vectorData = Qt3D::Render::QGraphicsUtils::valueArrayFromVariant(testVector, 1, 4); + + for (int i = 0; i < 4; i++) { + if (i == 0) + QVERIFY(vectorData[i] == testVector.x()); + else if (i == 1) + QVERIFY(vectorData[i] == testVector.y()); + else if (i == 2) + QVERIFY(vectorData[i] == testVector.z()); + else if (i == 3) + QVERIFY(vectorData[i] == testVector.w()); + } + + QByteArray data(description.m_size * 4 * sizeof(GLfloat), 0); + char *innerData = data.data(); + + // Checked that we are not overflowing + Qt3D::Render::QGraphicsUtils::fillDataArray(innerData, vectorData, description, 2); + for (int i = 0; i < 4; ++i) { + if (i < 2) + QVERIFY(vectorData[i] == ((GLfloat*)innerData)[i]); + else + QVERIFY(((GLfloat*)innerData)[i] == 0.0f); + } + + // Check that all values are copied + Qt3D::Render::QGraphicsUtils::fillDataArray(innerData, vectorData, description, 4); + for (int i = 0; i < 4; ++i) + QVERIFY(vectorData[i] == ((GLfloat*)innerData)[i]); + + // check that offsetting works + description.m_offset = 16; + data = QByteArray(description.m_size * 8 * sizeof(GLfloat), 0); + innerData = data.data(); + + Qt3D::Render::QGraphicsUtils::fillDataArray(innerData, vectorData, description, 4); + for (int i = 0; i < 8; ++i) { + if (i < 4) + QVERIFY(((GLfloat*)innerData)[i] == 0.0f); + else + QVERIFY(vectorData[i - 4] == ((GLfloat*)innerData)[i]); + } +} + +void tst_QGraphicsUtils::fillArray() +{ + QVector4D testVector(8.0f, 8.0f, 3.0f, 1.0f); + QVector4D testVector2(3.0f, 5.0f, 0.0f, 7.0f); + QVector4D testVector3(4.0f, 5.0f, 4.0f, 2.0f); + + QVariantList variantList = QVariantList() << testVector << testVector2 << testVector3; + const GLfloat *vectorData = Qt3D::Render::QGraphicsUtils::valueArrayFromVariant(QVariant(variantList), 3, 4); + + Qt3D::Render::ShaderUniform description; + + description.m_size = 3; + description.m_offset = 16; + description.m_arrayStride = 16; + + QByteArray data(description.m_size * (4 + description.m_arrayStride) * sizeof(GLfloat) + description.m_offset, 0); + char *innerData = data.data(); + Qt3D::Render::QGraphicsUtils::fillDataArray(innerData, vectorData, description, 4); + + int offset = description.m_offset / sizeof(GLfloat); + int stride = description.m_arrayStride / sizeof(GLfloat); + + GLfloat *innerDataFloat = (GLfloat*)innerData; + + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 4; ++j) { + int idx = i * 4 + j; + QVERIFY(innerDataFloat[offset + j] == vectorData[idx]); + } + offset += stride; + } +} + +void tst_QGraphicsUtils::fillScalarWithOffsets() +{ + // Simulates Uniform Block + + // uniform Block { + // vec3 position; // Offset 0 - 12 bytes + // vec3 direction; // Offset 16 - 12 bytes + // vec4 color; // Offset 32 - 16 bytes + // float intensity; // Offset 48 - bytes + // } // total size 64 bytes + + QVector3D position(8.0f, 8.0f, 3.0f); + QVector3D direction(3.0f, 5.0f, 2.0f); + QVector4D color(4.0f, 5.0f, 4.0f, 1.0f); + float intensity = 1.0f; + + Qt3D::Render::ShaderUniform posUniform; + posUniform.m_size = 1; + posUniform.m_arrayStride = 0; + posUniform.m_matrixStride = 0; + posUniform.m_offset = 0; + + Qt3D::Render::ShaderUniform dirUniform; + dirUniform.m_size = 1; + dirUniform.m_arrayStride = 0; + dirUniform.m_matrixStride = 0; + dirUniform.m_offset = 16; + + Qt3D::Render::ShaderUniform colUniform; + colUniform.m_size = 1; + colUniform.m_arrayStride = 0; + colUniform.m_matrixStride = 0; + colUniform.m_offset = 32; + + Qt3D::Render::ShaderUniform intUniform; + intUniform.m_size = 1; + intUniform.m_arrayStride = 0; + intUniform.m_matrixStride = 0; + intUniform.m_offset = 48; + + QVector data(16); + void *innerData = data.data(); + + Qt3D::Render::QGraphicsUtils::fillDataArray(innerData, + Qt3D::Render::QGraphicsUtils::valueArrayFromVariant(position, 1, 3), + posUniform, 3); + Qt3D::Render::QGraphicsUtils::fillDataArray(innerData, + Qt3D::Render::QGraphicsUtils::valueArrayFromVariant(direction, 1, 3), + dirUniform, 3); + Qt3D::Render::QGraphicsUtils::fillDataArray(innerData, + Qt3D::Render::QGraphicsUtils::valueArrayFromVariant(color, 1, 4), + colUniform, 4); + Qt3D::Render::QGraphicsUtils::fillDataArray(innerData, + Qt3D::Render::QGraphicsUtils::valueArrayFromVariant(intensity, 1, 1), + intUniform, 1); + + GLfloat *floatData = (GLfloat*)innerData; + + // Check first 16 bytes - position + QVERIFY(floatData[0] == position.x()); + QVERIFY(floatData[1] == position.y()); + QVERIFY(floatData[2] == position.z()); + QVERIFY(floatData[3] == 0.0f); + // Check 16 - 32 bytes - direction + QVERIFY(floatData[4] == direction.x()); + QVERIFY(floatData[5] == direction.y()); + QVERIFY(floatData[6] == direction.z()); + QVERIFY(floatData[7] == 0.0f); + // Check 32 - 48 bytes - color + QVERIFY(floatData[8] == color.x()); + QVERIFY(floatData[9] == color.y()); + QVERIFY(floatData[10] == color.z()); + QVERIFY(floatData[11] == color.w()); + // Check 48 - 64 bytes - intensity + QVERIFY(floatData[12] == intensity); + QVERIFY(floatData[13] == 0.0f); + QVERIFY(floatData[14] == 0.0f); + QVERIFY(floatData[15] == 0.0f); +} + +void tst_QGraphicsUtils::fillMatrix4x4() +{ + // row major + QMatrix4x4 mat(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f); + + // column major + const GLfloat *matData = Qt3D::Render::QGraphicsUtils::valueArrayFromVariant(mat, 1, 16); + + Qt3D::Render::ShaderUniform description; + + description.m_size = 1; + description.m_offset = 0; + description.m_arrayStride = 0; + description.m_matrixStride = 16; + + + QByteArray data(description.m_size * 16 * sizeof(GLfloat), 0); + char *innerData = data.data(); + Qt3D::Render::QGraphicsUtils::fillDataMatrixArray(innerData, matData, description, 4, 4); + // Check for no offset/no stride + for (int i = 0; i < 16; ++i) + QVERIFY((((GLfloat *)innerData)[i]) == matData[i]); + + description.m_offset = 12; + data = QByteArray((description.m_size * 16 + description.m_offset) * sizeof(GLfloat), 0); + innerData = data.data(); + Qt3D::Render::QGraphicsUtils::fillDataMatrixArray(innerData, matData, description, 4, 4); + // Check with 12 offset/no stride + for (int i = 0; i < 16; ++i) + QVERIFY((((GLfloat *)innerData)[3 + i]) == matData[i]); + + description.m_matrixStride = 16; + data = QByteArray((description.m_size * 16 + 4 * description.m_matrixStride + description.m_offset) * sizeof(GLfloat), 0); + innerData = data.data(); + Qt3D::Render::QGraphicsUtils::fillDataMatrixArray(innerData, matData, description, 4, 4); + // Check with 10 offset/ 16 stride + int offset = description.m_offset / sizeof(GLfloat); + int matrixStride = description.m_matrixStride / sizeof(GLfloat); + + for (int col = 0; col < 4; ++col) { + for (int row = 0; row < 4; ++row) + QVERIFY((((GLfloat *)innerData)[offset + row]) == matData[col * 4 + row]); + offset += matrixStride; + } +} + +void tst_QGraphicsUtils::fillMatrix3x4() +{ + QMatrix3x4 mat; + + mat.fill(6.0f); + const GLfloat *matData = Qt3D::Render::QGraphicsUtils::valueArrayFromVariant(QVariant::fromValue(mat), 1, 12); + + Qt3D::Render::ShaderUniform description; + + description.m_size = 1; + description.m_offset = 16; + description.m_arrayStride = 0; + description.m_matrixStride = 12; + + QByteArray data((description.m_size * 12 + 3 * description.m_matrixStride + description.m_offset) * sizeof(GLfloat), 0); + char *innerData = data.data(); + Qt3D::Render::QGraphicsUtils::fillDataMatrixArray(innerData, matData, description, 3, 4); + // Check with 16 offset/ 12 stride + int offset = description.m_offset / sizeof(GLfloat); + int matrixStride = description.m_matrixStride / sizeof(GLfloat); + + for (int col = 0; col < 3; ++col) { + for (int row = 0; row < 4; ++row) + QVERIFY((((GLfloat *)innerData)[offset + row]) == matData[col * 4 + row]); + offset += matrixStride; + } +} + +void tst_QGraphicsUtils::fillMatrix4x3() +{ + QMatrix4x3 mat; + + mat.fill(6.0f); + const GLfloat *matData = Qt3D::Render::QGraphicsUtils::valueArrayFromVariant(QVariant::fromValue(mat), 1, 12); + + Qt3D::Render::ShaderUniform description; + + description.m_size = 1; + description.m_offset = 16; + description.m_arrayStride = 0; + description.m_matrixStride = 16; + + QByteArray data((description.m_size * 12 + 4 * description.m_matrixStride + description.m_offset) * sizeof(GLfloat), 0); + char *innerData = data.data(); + Qt3D::Render::QGraphicsUtils::fillDataMatrixArray(innerData, matData, description, 4, 3); + // Check with 16 offset/ 16 stride + int offset = description.m_offset / sizeof(GLfloat); + int matrixStride = description.m_matrixStride / sizeof(GLfloat); + + for (int col = 0; col < 4; ++col) { + for (int row = 0; row < 3; ++row) + QVERIFY((((GLfloat *)innerData)[offset + row]) == matData[col * 3 + row]); + offset += matrixStride; + } +} + +void tst_QGraphicsUtils::fillMatrixArray() +{ + QMatrix4x3 mat1; + QMatrix4x3 mat2; + QMatrix4x3 mat3; + mat1.fill(6.0f); + mat2.fill(2.0f); + mat3.fill(7.0f); + + QVariantList matrices = QVariantList() << QVariant::fromValue(mat1) << QVariant::fromValue(mat2) << QVariant::fromValue(mat3); + + const GLfloat *matData = Qt3D::Render::QGraphicsUtils::valueArrayFromVariant(QVariant::fromValue(matrices), 3, 12); + + Qt3D::Render::ShaderUniform description; + + description.m_size = 3; + description.m_offset = 12; + description.m_arrayStride = 4; + description.m_matrixStride = 16; + + QByteArray data((description.m_size * (12 + 4 * description.m_matrixStride + description.m_arrayStride) + description.m_offset) * sizeof(GLfloat), 0); + char *innerData = data.data(); + Qt3D::Render::QGraphicsUtils::fillDataMatrixArray(innerData, matData, description, 4, 3); + // Check with 12 offset/ 4 array stride / 16 matrix stride + int offset = description.m_offset / sizeof(GLfloat); + int matrixStride = description.m_matrixStride / sizeof(GLfloat); + int arrayStride = description.m_arrayStride / sizeof(GLfloat); + + for (int i = 0; i < 3; ++i) { + for (int col = 0; col < 4; ++col) { + for (int row = 0; row < 3; ++row) { + int idx = i * 4 * 3 + col * 3 + row; + QVERIFY((((GLfloat *)innerData)[offset + row]) == matData[idx]); + } + offset += matrixStride; + } + offset += arrayStride; + } +} + +QTEST_APPLESS_MAIN(tst_QGraphicsUtils) + +#include "tst_qgraphicsutils.moc" diff --git a/tests/auto/render/render.pro b/tests/auto/render/render.pro index 8b1621a6a..c45764b05 100644 --- a/tests/auto/render/render.pro +++ b/tests/auto/render/render.pro @@ -1,5 +1,7 @@ TEMPLATE = subdirs contains(QT_CONFIG, private_tests) { - SUBDIRS = renderqueues + SUBDIRS += \ + renderqueues \ + qgraphicsutils } -- cgit v1.2.3