// Copyright (C) 2020 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include #include #include #include #include #include class tst_QQuick3DSpotLight : public QObject { Q_OBJECT // Work-around to get access to updateSpatialNode class Light : public QQuick3DSpotLight { public: using QQuick3DSpotLight::updateSpatialNode; }; private slots: void testProperties(); void testScope(); }; void tst_QQuick3DSpotLight::testProperties() { Light light; auto node = static_cast(light.updateSpatialNode(nullptr)); const auto originalNode = node; // for comparisons later... QVERIFY(node); // lightType QCOMPARE(QSSGRenderLight::Type::SpotLight, node->type); const float brightness = 0.5f; light.setBrightness(brightness); node = static_cast(light.updateSpatialNode(node)); QCOMPARE(originalNode, node); QCOMPARE(brightness, node->m_brightness); QCOMPARE(light.brightness(), node->m_brightness); const float constantFade = 0.4f; light.setConstantFade(constantFade); node = static_cast(light.updateSpatialNode(node)); QCOMPARE(constantFade, node->m_constantFade); QCOMPARE(light.constantFade(), node->m_constantFade); const float linearFade = 0.4f; light.setLinearFade(linearFade); node = static_cast(light.updateSpatialNode(node)); QCOMPARE(linearFade, node->m_linearFade); QCOMPARE(light.linearFade(), node->m_linearFade); const float quadraticFade = 0.4f; light.setQuadraticFade(quadraticFade); node = static_cast(light.updateSpatialNode(node)); QCOMPARE(quadraticFade, node->m_quadraticFade); QCOMPARE(light.quadraticFade(), node->m_quadraticFade); const float shadowBias = 0.5f; light.setShadowBias(shadowBias); node = static_cast(light.updateSpatialNode(node)); QCOMPARE(shadowBias, node->m_shadowBias); QCOMPARE(light.shadowBias(), node->m_shadowBias); const float shadowFactor = 4.0f; light.setShadowFactor(shadowFactor); node = static_cast(light.updateSpatialNode(node)); QCOMPARE(shadowFactor, node->m_shadowFactor); QCOMPARE(light.shadowFactor(), node->m_shadowFactor); const float shadowMapFar = 2000.0f; light.setShadowMapFar(shadowMapFar); node = static_cast(light.updateSpatialNode(node)); QCOMPARE(shadowMapFar, node->m_shadowMapFar); QCOMPARE(light.shadowMapFar(), node->m_shadowMapFar); const float shadowFilter = 20.0f; light.setShadowFilter(shadowFilter); node = static_cast(light.updateSpatialNode(node)); QCOMPARE(shadowFilter, node->m_shadowFilter); QCOMPARE(light.shadowFilter(), node->m_shadowFilter); const QQuick3DAbstractLight::QSSGShadowMapQuality qualities[] = { QQuick3DAbstractLight::QSSGShadowMapQuality::ShadowMapQualityLow, QQuick3DAbstractLight::QSSGShadowMapQuality::ShadowMapQualityMedium, QQuick3DAbstractLight::QSSGShadowMapQuality::ShadowMapQualityHigh, QQuick3DAbstractLight::QSSGShadowMapQuality::ShadowMapQualityVeryHigh, QQuick3DAbstractLight::QSSGShadowMapQuality::ShadowMapQualityUltra }; const unsigned int mappedResolutions[] = {256, 512, 1024, 2048, 4096}; for (int i = 0; i < 5; ++i) { const auto shadowMapQuality = qualities[i]; const auto mappedResolution = mappedResolutions[i]; light.setShadowMapQuality(shadowMapQuality); node = static_cast(light.updateSpatialNode(node)); QCOMPARE(mappedResolution, node->m_shadowMapRes); QCOMPARE(light.shadowMapQuality(), shadowMapQuality); } const QQuick3DAbstractLight::QSSGSoftShadowQuality ssq = QQuick3DAbstractLight::QSSGSoftShadowQuality::PCF16; light.setSoftShadowQuality(ssq); node = static_cast(light.updateSpatialNode(node)); QCOMPARE(light.softShadowQuality(), ssq); const float pcfFactor = 5.0f; light.setPcfFactor(pcfFactor); node = static_cast(light.updateSpatialNode(node)); QCOMPARE(light.pcfFactor(), pcfFactor); light.setCastsShadow(true); node = static_cast(light.updateSpatialNode(node)); QVERIFY(node->m_castShadow); light.setCastsShadow(false); node = static_cast(light.updateSpatialNode(node)); QVERIFY(!node->m_castShadow); QVERIFY(!node->m_use32BitShadowmap); light.setUse32BitShadowmap(true); node = static_cast(light.updateSpatialNode(node)); QVERIFY(node->m_use32BitShadowmap); float coneAngle = 60.0f; float innerConeAngle = 20.0f; QColor color1("#12345678"); QVector3D color1Vec3 = QSSGUtils::color::sRGBToLinear(color1).toVector3D(); QColor color2("#cccccccc"); QVector3D color2Vec3 = QSSGUtils::color::sRGBToLinear(color2).toVector3D(); light.setColor(color1); light.setAmbientColor(color2); light.setConeAngle(coneAngle); light.setInnerConeAngle(innerConeAngle); node = static_cast(light.updateSpatialNode(node)); QCOMPARE(originalNode, node); QCOMPARE(color1, light.color()); QCOMPARE(color2, light.ambientColor()); // Note: none of these colors contain alpha QCOMPARE(color1Vec3, node->m_diffuseColor); QCOMPARE(color1Vec3, node->m_specularColor); QCOMPARE(color2Vec3, node->m_ambientColor); // light's coneAngles are from edge to edge // while qssgrenderlight's are from center to edge QCOMPARE(coneAngle, node->m_coneAngle * 2); QCOMPARE(innerConeAngle, node->m_innerConeAngle * 2); } void tst_QQuick3DSpotLight::testScope() { Light light; auto node = static_cast(light.updateSpatialNode(nullptr)); QVERIFY(node); QQuick3DNode nodeItem; QVERIFY(!light.scope()); light.setScope(&nodeItem); QVERIFY(light.scope()); node = static_cast(light.updateSpatialNode(node)); auto scope = static_cast( QQuick3DObjectPrivate::get(light.scope())->spatialNode); QCOMPARE(scope, node->m_scope); } QTEST_APPLESS_MAIN(tst_QQuick3DSpotLight) #include "tst_qquick3dspotlight.moc"