From 65a2ef3e8a03589f655e67cfb6eda89e8513576e Mon Sep 17 00:00:00 2001 From: Matthew Mott Date: Sun, 31 Jan 2021 20:59:40 +0000 Subject: [PATCH] Add a test for light source rendering This test checks that the RenderableCollector::addLight() method has been invoked after rendering a light entity in full materials mode. --- radiantcore/entity/light/LightNode.cpp | 22 +++++++------------ test/Entity.cpp | 30 ++++++++++++++++++++------ 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/radiantcore/entity/light/LightNode.cpp b/radiantcore/entity/light/LightNode.cpp index 7e26cee7cd..d0e2082630 100644 --- a/radiantcore/entity/light/LightNode.cpp +++ b/radiantcore/entity/light/LightNode.cpp @@ -69,7 +69,7 @@ void LightNode::snapto(float snap) { _light.snapto(snap); } -AABB LightNode::getSelectAABB() const +AABB LightNode::getSelectAABB() const { // Use the light origin as select AAB centerpoint Vector3 extents; @@ -168,7 +168,7 @@ void LightNode::testSelectComponents(Selector& selector, SelectionTest& test, Se // Use the full rotation matrix for the test test.BeginMesh(localToWorld()); - if (_light.isProjected()) + if (_light.isProjected()) { // Test the projection components for selection _lightTargetInstance.testSelect(selector, test); @@ -177,7 +177,7 @@ void LightNode::testSelectComponents(Selector& selector, SelectionTest& test, Se _lightStartInstance.testSelect(selector, test); _lightEndInstance.testSelect(selector, test); } - else + else { // Test if the light center is hit by the click _lightCenterInstance.testSelect(selector, test); @@ -276,21 +276,16 @@ void LightNode::selectedChangedComponent(const ISelectable& selectable) { GlobalSelectionSystem().onComponentSelection(Node::getSelf(), selectable); } -/* greebo: This is the method that gets called by renderer.h. It passes the call - * on to the Light class render methods. - */ void LightNode::renderSolid(RenderableCollector& collector, const VolumeTest& volume) const { // Submit self to the renderer as an actual light source collector.addLight(_light); - // Render the visible representation of the light entity (origin, bounds etc) EntityNode::renderSolid(collector, volume); - // Re-use the same method as in wireframe rendering for the moment + // Render the visible representation of the light entity (origin, bounds etc) const bool lightIsSelected = isSelected(); renderLightVolume(collector, localToWorld(), lightIsSelected); - renderInactiveComponents(collector, volume, lightIsSelected); } @@ -300,7 +295,6 @@ void LightNode::renderWireframe(RenderableCollector& collector, const VolumeTest const bool lightIsSelected = isSelected(); renderLightVolume(collector, localToWorld(), lightIsSelected); - renderInactiveComponents(collector, volume, lightIsSelected); } @@ -371,7 +365,7 @@ void LightNode::renderComponents(RenderableCollector& collector, const VolumeTes if (_light.isProjected()) { // A projected light - + EntitySettings& settings = *EntitySettings::InstancePtr(); const Vector3& colourStartEndSelected = settings.getLightVertexColour(LightEditVertexType::StartEndSelected); @@ -497,8 +491,8 @@ void LightNode::evaluateTransform() { // When the user is mouse-moving a vertex in the orthoviews he/she is operating // in world space. It's expected that the selected vertex follows the mouse. - // Since the editable light vertices are measured in local coordinates - // we have to calculate the new position in world space first and then transform + // Since the editable light vertices are measured in local coordinates + // we have to calculate the new position in world space first and then transform // the point back into local space. if (_lightCenterInstance.isSelected()) @@ -507,7 +501,7 @@ void LightNode::evaluateTransform() Vector3 newWorldPos = localToWorld().transformPoint(_light.getDoom3Radius().m_center) + getTranslation(); _light.getDoom3Radius().m_centerTransformed = localToWorld().getFullInverse().transformPoint(newWorldPos); } - + if (_lightTargetInstance.isSelected()) { Vector3 newWorldPos = localToWorld().transformPoint(_light.target()) + getTranslation(); diff --git a/test/Entity.cpp b/test/Entity.cpp index 333a05660c..648abdb431 100644 --- a/test/Entity.cpp +++ b/test/Entity.cpp @@ -302,7 +302,9 @@ namespace {} }; - // Collection of objects needed for rendering + // Collection of objects needed for rendering. Since not all tests require + // rendering, these objects are in an auxiliary fixture created when needed + // rather than part of the EntityTest fixture used by every test. struct RenderFixture { RenderSystemPtr backend = GlobalRenderSystemFactory().createRenderSystem(); @@ -316,10 +318,11 @@ TEST_F(EntityTest, RenderUnselectedLightEntity) auto light = createByClassName("light"); RenderFixture renderF; - // Render the light in wireframe mode. This should render just the origin - // diamond. + // Render the light in wireframe mode. light->setRenderSystem(renderF.backend); light->renderWireframe(renderF.collector, renderF.volumeTest); + + // Only the light origin diamond should be rendered EXPECT_EQ(renderF.collector.renderables, 1); EXPECT_EQ(renderF.collector.lights, 0); } @@ -329,16 +332,31 @@ TEST_F(EntityTest, RenderSelectedLightEntity) auto light = createByClassName("light"); RenderFixture renderF; - // With the light selected, we should get the origin diamond, the radius and - // the center vertex. + // Select the light then render it in wireframe mode Node_getSelectable(light)->setSelected(true); - light->setRenderSystem(renderF.backend); light->renderWireframe(renderF.collector, renderF.volumeTest); + + // With the light selected, we should get the origin diamond, the radius and + // the center vertex. EXPECT_EQ(renderF.collector.renderables, 3); EXPECT_EQ(renderF.collector.lights, 0); } +TEST_F(EntityTest, RenderLightAsLightSource) +{ + auto light = createByClassName("light"); + RenderFixture renderF; + + // Render the light in full materials mode + light->setRenderSystem(renderF.backend); + light->renderSolid(renderF.collector, renderF.volumeTest); + + // We should get one renderable for the origin diamond, and one light source + EXPECT_EQ(renderF.collector.renderables, 1); + EXPECT_EQ(renderF.collector.lights, 1); +} + TEST_F(EntityTest, CreateAttachedLightEntity) { // Create the torch entity which has an attached light