From 3d98714b0278a3edcefabf887624dd03c6777838 Mon Sep 17 00:00:00 2001 From: Louise Poubel Date: Wed, 24 Nov 2021 13:24:23 -0800 Subject: [PATCH 1/2] Pass per-point colors through normal buffer Signed-off-by: Louise Poubel --- .../rendering/ogre2/Ogre2DynamicRenderable.hh | 8 +++ ogre2/src/Ogre2DynamicRenderable.cc | 56 +++++++++++++++++-- ogre2/src/Ogre2LidarVisual.cc | 14 ++--- ogre2/src/Ogre2Marker.cc | 8 --- .../materials/programs/GLSL/point_fs.glsl | 6 +- .../materials/programs/GLSL/point_vs.glsl | 4 ++ 6 files changed, 70 insertions(+), 26 deletions(-) diff --git a/ogre2/include/ignition/rendering/ogre2/Ogre2DynamicRenderable.hh b/ogre2/include/ignition/rendering/ogre2/Ogre2DynamicRenderable.hh index 245ef3fd9..502bb3cc4 100644 --- a/ogre2/include/ignition/rendering/ogre2/Ogre2DynamicRenderable.hh +++ b/ogre2/include/ignition/rendering/ogre2/Ogre2DynamicRenderable.hh @@ -137,6 +137,14 @@ namespace ignition private: void GenerateNormals(Ogre::OperationType _opType, const std::vector &_vertices, float *_vbuffer); + /// \brief Helper function to generate colors per-vertex. Only applies + /// to points. The colors fill the normal slots on the vertex buffer. + /// \param[in] _opType Ogre render operation type + /// \param[in] _vertices a list of vertices + /// \param[in,out] _vbuffer vertex buffer to be filled + private: void GenerateColors(Ogre::OperationType _opType, + const std::vector &_vertices, float *_vbuffer); + /// \brief Destroy the vertex buffer private: void DestroyBuffer(); diff --git a/ogre2/src/Ogre2DynamicRenderable.cc b/ogre2/src/Ogre2DynamicRenderable.cc index 46c7a358a..623b2d2ea 100644 --- a/ogre2/src/Ogre2DynamicRenderable.cc +++ b/ogre2/src/Ogre2DynamicRenderable.cc @@ -311,7 +311,8 @@ void Ogre2DynamicRenderable::UpdateBuffer() // fill the rest of the buffer with the position of the last vertex to avoid // the geometry connecting back to 0, 0, 0 - if (vertexCount > 0 && vertexCount < this->dataPtr->vertexBufferCapacity) + if (vertexCount > 0 && vertexCount < this->dataPtr->vertexBufferCapacity && + this->dataPtr->operationType != Ogre::OperationType::OT_POINT_LIST) { math::Vector3d lastVertex = this->dataPtr->vertices[vertexCount-1]; for (unsigned int i = vertexCount; i < this->dataPtr->vertexBufferCapacity; @@ -332,6 +333,10 @@ void Ogre2DynamicRenderable::UpdateBuffer() this->GenerateNormals(this->dataPtr->operationType, this->dataPtr->vertices, vertices); + // fill colors for points + this->GenerateColors(this->dataPtr->operationType, this->dataPtr->vertices, + vertices); + // unmap buffer this->dataPtr->vertexBuffer->unmap(Ogre::UO_KEEP_PERSISTENT); @@ -359,7 +364,7 @@ void Ogre2DynamicRenderable::UpdateBuffer() this->dataPtr->ogreItem->setCastShadows( this->dataPtr->material->CastShadows()); } - else if (lowLevelMat) + if (lowLevelMat) { // the _initialise call above resets the ogre item properties so set // them again @@ -448,7 +453,7 @@ void Ogre2DynamicRenderable::AddPoint(const ignition::math::Vector3d &_pt, this->dataPtr->vertices.push_back(_pt); // todo(anyone) - // setting material works but vertex coloring does not work yet. + // setting material works but vertex coloring only works for points // It requires using an unlit datablock: // https://forums.ogre3d.org/viewtopic.php?t=93627#p539276 this->dataPtr->colors.push_back(_color); @@ -492,12 +497,12 @@ void Ogre2DynamicRenderable::SetColor(unsigned int _index, // todo(anyone) - // vertex coloring does not work yet. It requires using an unlit datablock: + // vertex coloring only works for points. + // Full implementation requires using an unlit datablock: // https://forums.ogre3d.org/viewtopic.php?t=93627#p539276 this->dataPtr->colors[_index] = _color; - // uncomment this line when colors are working - // this->dataPtr->dirty = true; + this->dataPtr->dirty = true; } ///////////////////////////////////////////////// @@ -713,3 +718,42 @@ void Ogre2DynamicRenderable::GenerateNormals(Ogre::OperationType _opType, break; } } + +////////////////////////////////////////////////// +void Ogre2DynamicRenderable::GenerateColors(Ogre::OperationType _opType, + const std::vector &_vertices, float *_vbuffer) +{ + unsigned int vertexCount = _vertices.size(); + // Skip if colors haven't been setup per-vertex correctly. + if (vertexCount != this->dataPtr->colors.size()) + return; + + // Each vertex occupies 6 elements in the vbuffer float array. Normally, + // the last 3 are reserved for normals. But for types that don't use normals, + // we use them for per-vertex coloring. + // vbuffer[i] : position x + // vbuffer[i+1] : position y + // vbuffer[i+2] : position z + // vbuffer[i+3] : color r + // vbuffer[i+4] : color g + // vbuffer[i+5] : color b + switch (_opType) + { + case Ogre::OperationType::OT_POINT_LIST: + { + for (unsigned int i = 0; i < vertexCount; ++i) + { + auto color = this->dataPtr->colors[i]; + + unsigned int idx = i * 6; + _vbuffer[idx+3] = color.R(); + _vbuffer[idx+4] = color.G(); + _vbuffer[idx+5] = color.B(); + } + + break; + } + default: + break; + } +} diff --git a/ogre2/src/Ogre2LidarVisual.cc b/ogre2/src/Ogre2LidarVisual.cc index 98a604a39..2a2b8d8a9 100644 --- a/ogre2/src/Ogre2LidarVisual.cc +++ b/ogre2/src/Ogre2LidarVisual.cc @@ -347,6 +347,8 @@ void Ogre2LidarVisual::Update() this->dataPtr->deadZoneRayFans[j]->SetPoint(0, this->offset.Pos()); } + auto pointMat = this->Scene()->Material("Lidar/BlueRay"); + unsigned count = this->horizontalCount; // Process each ray in current scan for (unsigned int i = 0; i < count; ++i) @@ -441,14 +443,16 @@ void Ogre2LidarVisual::Update() { if (this->displayNonHitting || !inf) { - this->dataPtr->points[j]->AddPoint(inf ? noHitPt: pt); + this->dataPtr->points[j]->AddPoint(inf ? noHitPt : pt, + pointMat->Diffuse()); } } else { if (this->displayNonHitting || !inf) { - this->dataPtr->points[j]->SetPoint(i, inf ? noHitPt: pt); + this->dataPtr->points[j]->SetPoint(i, inf ? noHitPt : pt); + this->dataPtr->points[j]->SetColor(i, pointMat->Diffuse()); } } } @@ -483,12 +487,6 @@ void Ogre2LidarVisual::Update() auto pass = this->dataPtr->pointsMat->getTechnique(0)->getPass(0); auto vertParams = pass->getVertexProgramParameters(); vertParams->setNamedConstant("size", static_cast(this->size)); - - // support setting color only from diffuse for now - MaterialPtr mat = this->Scene()->Material("Lidar/BlueRay"); - auto fragParams = pass->getFragmentProgramParameters(); - fragParams->setNamedConstant("color", - Ogre2Conversions::Convert(mat->Diffuse())); } // The newly created dynamic lines are having default visibility as true. diff --git a/ogre2/src/Ogre2Marker.cc b/ogre2/src/Ogre2Marker.cc index 3fa3c5151..72175a2fc 100644 --- a/ogre2/src/Ogre2Marker.cc +++ b/ogre2/src/Ogre2Marker.cc @@ -112,14 +112,6 @@ void Ogre2Marker::PreRender() auto pass = item->getSubItem(0)->getMaterial()->getTechnique(0)->getPass(0); auto vertParams = pass->getVertexProgramParameters(); vertParams->setNamedConstant("size", static_cast(this->size)); - - // support setting color only from diffuse for now - if (this->dataPtr->material) - { - auto fragParams = pass->getFragmentProgramParameters(); - fragParams->setNamedConstant("color", - Ogre2Conversions::Convert(this->dataPtr->material->Diffuse())); - } } this->dataPtr->dynamicRenderable->Update(); diff --git a/ogre2/src/media/materials/programs/GLSL/point_fs.glsl b/ogre2/src/media/materials/programs/GLSL/point_fs.glsl index a08d2c2ed..5c6d912d4 100644 --- a/ogre2/src/media/materials/programs/GLSL/point_fs.glsl +++ b/ogre2/src/media/materials/programs/GLSL/point_fs.glsl @@ -18,13 +18,11 @@ #version 330 uniform vec4 color; +in vec3 ptColor; out vec4 fragColor; void main() { - // todo(anyone) update Ogre2DynamicRenderable to support vertex coloring - // so we can set color using the line below - // fragColor = gl_Color; - fragColor = color; + fragColor = vec4(ptColor.x, ptColor.y, ptColor.z, 1); } diff --git a/ogre2/src/media/materials/programs/GLSL/point_vs.glsl b/ogre2/src/media/materials/programs/GLSL/point_vs.glsl index 139e9f7b3..bb100cac2 100644 --- a/ogre2/src/media/materials/programs/GLSL/point_vs.glsl +++ b/ogre2/src/media/materials/programs/GLSL/point_vs.glsl @@ -18,8 +18,10 @@ #version 330 in vec4 vertex; +in vec3 normal; uniform mat4 worldViewProj; uniform float size; +out vec3 ptColor; out gl_PerVertex { @@ -31,4 +33,6 @@ void main() // Calculate output position gl_Position = worldViewProj * vertex; gl_PointSize = size; + // We're abusing the normal variable to hold per-point colors + ptColor = normal; } From d88e99e51c932d9030cf219a599ea8ce10a2b8b3 Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Tue, 30 Nov 2021 17:05:02 -0800 Subject: [PATCH 2/2] Fix selection buffer crash after resizing window (#446) * fix selection buffer crash due to resize and incorrect selections Signed-off-by: Ian Chen * test updating full selection buffer texture Signed-off-by: Ian Chen * reenable visual at test Signed-off-by: Ian Chen * fix codecheck Signed-off-by: Ian Chen * testing rgb no depth, full buffer Signed-off-by: Ian Chen * use 1x1 buffer, still no depth data Signed-off-by: Ian Chen * prnt scaling factor Signed-off-by: Ian Chen * disable device ratio Signed-off-by: Ian Chen * reenable depth and utils test Signed-off-by: Ian Chen * disable utils test, add visual at test after resize Signed-off-by: Ian Chen * test texelfetch Signed-off-by: Ian Chen * back to full buffer Signed-off-by: Ian Chen * print ogre log Signed-off-by: Ian Chen * codecheck Signed-off-by: Ian Chen * fixing selection buffer mat script Signed-off-by: Ian Chen * try 1x1 buffer again Signed-off-by: Ian Chen * revert some test changes Signed-off-by: Ian Chen * uncomment tests Signed-off-by: Ian Chen * update scaling factor Signed-off-by: Ian Chen * fix removing selection mat Signed-off-by: Ian Chen * update screenScalingFactor Signed-off-by: Ian Chen * minor tweak Signed-off-by: Ian Chen Co-authored-by: Louise Poubel --- ogre2/src/Ogre2Camera.cc | 1 - ogre2/src/Ogre2RayQuery.cc | 4 + ogre2/src/Ogre2SelectionBuffer.cc | 85 ++++++++++++------- .../programs/GLSL/selection_buffer_fs.glsl | 4 +- .../scripts/selection_buffer.material | 2 + src/Utils.cc | 5 +- src/Utils_TEST.cc | 9 -- test/integration/camera.cc | 29 +++++-- test/integration/scene.cc | 8 -- 9 files changed, 90 insertions(+), 57 deletions(-) diff --git a/ogre2/src/Ogre2Camera.cc b/ogre2/src/Ogre2Camera.cc index a758c8b2a..59c91b871 100644 --- a/ogre2/src/Ogre2Camera.cc +++ b/ogre2/src/Ogre2Camera.cc @@ -278,7 +278,6 @@ VisualPtr Ogre2Camera::VisualAt(const ignition::math::Vector2i &_mousePos) ignition::math::Vector2i mousePos( static_cast(std::rint(ratio * _mousePos.X())), static_cast(std::rint(ratio * _mousePos.Y()))); - Ogre::Item *ogreItem = this->selectionBuffer->OnSelectionClick( mousePos.X(), mousePos.Y()); diff --git a/ogre2/src/Ogre2RayQuery.cc b/ogre2/src/Ogre2RayQuery.cc index df83ad85f..81edaf3ba 100644 --- a/ogre2/src/Ogre2RayQuery.cc +++ b/ogre2/src/Ogre2RayQuery.cc @@ -144,6 +144,10 @@ RayQueryResult Ogre2RayQuery::ClosestPoint(bool _forceSceneUpdate) ////////////////////////////////////////////////// RayQueryResult Ogre2RayQuery::ClosestPointBySelectionBuffer() { + // update selection buffer dimension in case window is resized + this->dataPtr->camera->SelectionBuffer()->SetDimensions( + this->dataPtr->camera->ImageWidth(), this->dataPtr->camera->ImageHeight()); + RayQueryResult result; Ogre::Item *ogreItem = nullptr; math::Vector3d point; diff --git a/ogre2/src/Ogre2SelectionBuffer.cc b/ogre2/src/Ogre2SelectionBuffer.cc index 62686ccb8..72194730c 100644 --- a/ogre2/src/Ogre2SelectionBuffer.cc +++ b/ogre2/src/Ogre2SelectionBuffer.cc @@ -88,6 +88,9 @@ class ignition::rendering::Ogre2SelectionBufferPrivate /// into a render target or render texture. public: Ogre::CompositorWorkspace *ogreCompositorWorkspace = nullptr; + /// \brief Name of the compositor workspace definition + public: std::string ogreCompWorkspaceDefName; + /// \brief The selection buffer material public: Ogre::MaterialPtr selectionMaterial; }; @@ -142,6 +145,16 @@ Ogre2SelectionBuffer::~Ogre2SelectionBuffer() { this->DeleteRTTBuffer(); + // remove selectionMaterial in destructor + // this does not need to be done in DeleteRTTBuffer as we do not need to + // reload the same material every time + if (!this->dataPtr->selectionMaterial.isNull()) + { + Ogre::MaterialManager::getSingleton().remove( + this->dataPtr->selectionMaterial->getName()); + this->dataPtr->selectionMaterial.setNull(); + } + // remove selection buffer camera this->dataPtr->sceneMgr->destroyCamera(this->dataPtr->selectionCamera); } @@ -181,10 +194,17 @@ void Ogre2SelectionBuffer::Update() ///////////////////////////////////////////////// void Ogre2SelectionBuffer::DeleteRTTBuffer() { - if (this->dataPtr->selectionMaterial) + if (this->dataPtr->ogreCompositorWorkspace) { - Ogre::MaterialManager::getSingleton().remove( - this->dataPtr->selectionMaterial->getName()); + // TODO(ahcorde): Remove the workspace. Potential leak here + this->dataPtr->ogreCompMgr->removeWorkspace( + this->dataPtr->ogreCompositorWorkspace); + + this->dataPtr->ogreCompMgr->removeWorkspaceDefinition( + this->dataPtr->ogreCompWorkspaceDefName); + this->dataPtr->ogreCompMgr->removeNodeDefinition( + this->dataPtr->ogreCompWorkspaceDefName + "/Node"); + this->dataPtr->ogreCompositorWorkspace = nullptr; } auto engine = Ogre2RenderEngine::Instance(); @@ -222,11 +242,16 @@ void Ogre2SelectionBuffer::CreateRTTBuffer() // The SelectionBuffer material is defined in script // (selection_buffer.material). std::string matSelectionName = "SelectionBuffer"; - Ogre::MaterialPtr matSelection = - Ogre::MaterialManager::getSingleton().getByName(matSelectionName); - this->dataPtr->selectionMaterial = matSelection->clone( - this->dataPtr->camera->getName() + "_" + matSelectionName); - this->dataPtr->selectionMaterial->load(); + std::string matSelectionCloneName = + this->dataPtr->camera->getName() + "_" + matSelectionName; + if (this->dataPtr->selectionMaterial.isNull()) + { + Ogre::MaterialPtr matSelection = + Ogre::MaterialManager::getSingleton().getByName(matSelectionName); + this->dataPtr->selectionMaterial = matSelection->clone( + matSelectionCloneName); + this->dataPtr->selectionMaterial->load(); + } Ogre::Pass *p = this->dataPtr->selectionMaterial->getTechnique(0)->getPass(0); Ogre::GpuProgramParametersSharedPtr psParams = p->getFragmentProgramParameters(); @@ -252,13 +277,15 @@ void Ogre2SelectionBuffer::CreateRTTBuffer() // create compositor workspace for rendering // Setup the selection buffer compositor. - const Ogre::String workspaceName = "SelectionBufferWorkspace" + + this->dataPtr->ogreCompWorkspaceDefName = "SelectionBufferWorkspace" + this->dataPtr->camera->getName(); + std::string nodeSpaceDefName = + this->dataPtr->ogreCompWorkspaceDefName + "/Node"; + Ogre::CompositorNodeDef *nodeDef = this->dataPtr->ogreCompMgr->addNodeDefinition( - "AutoGen " + Ogre::IdString(workspaceName + - "/Node").getReleaseText()); + nodeSpaceDefName); Ogre::TextureDefinitionBase::TextureDefinition *depthTexDef = nodeDef->addTextureDefinition("depthTexture"); depthTexDef->textureType = Ogre::TextureTypes::Type2D; @@ -346,7 +373,8 @@ void Ogre2SelectionBuffer::CreateRTTBuffer() } Ogre::CompositorWorkspaceDef *workDef = - this->dataPtr->ogreCompMgr->addWorkspaceDefinition(workspaceName); + this->dataPtr->ogreCompMgr->addWorkspaceDefinition( + this->dataPtr->ogreCompWorkspaceDefName); workDef->connectExternal(0, nodeDef->getName(), 0); this->dataPtr->ogreCompositorWorkspace = @@ -354,7 +382,7 @@ void Ogre2SelectionBuffer::CreateRTTBuffer() this->dataPtr->scene->OgreSceneManager(), this->dataPtr->renderTexture, this->dataPtr->selectionCamera, - workspaceName, + this->dataPtr->ogreCompWorkspaceDefName, false); } @@ -369,14 +397,6 @@ void Ogre2SelectionBuffer::SetDimensions( this->dataPtr->height = _height; this->DeleteRTTBuffer(); - - if (this->dataPtr->ogreCompositorWorkspace) - { - // TODO(ahcorde): Remove the workspace. Potential leak here - this->dataPtr->ogreCompMgr->removeWorkspace( - this->dataPtr->ogreCompositorWorkspace); - } - this->CreateRTTBuffer(); } ///////////////////////////////////////////////// @@ -398,6 +418,14 @@ bool Ogre2SelectionBuffer::ExecuteQuery(const int _x, const int _y, if (!this->dataPtr->camera) return false; + // check camera has valid projection matrix + // There could be nan values if camera was resized + Ogre::Matrix4 projectionMatrix = + this->dataPtr->camera->getProjectionMatrix(); + if (projectionMatrix.getTrans().isNaN() || + projectionMatrix.extractQuaternion().isNaN()) + return false; + const unsigned int targetWidth = this->dataPtr->width; const unsigned int targetHeight = this->dataPtr->height; @@ -405,8 +433,8 @@ bool Ogre2SelectionBuffer::ExecuteQuery(const int _x, const int _y, || _y >= static_cast(targetHeight)) return false; - // // 1x1 selection buffer, adapted from rviz - // // http://docs.ros.org/indigo/api/rviz/html/c++/selection__manager_8cpp.html + // 1x1 selection buffer, adapted from rviz + // http://docs.ros.org/indigo/api/rviz/html/c++/selection__manager_8cpp.html unsigned int width = 1; unsigned int height = 1; float x1 = static_cast(_x) / @@ -425,10 +453,10 @@ bool Ogre2SelectionBuffer::ExecuteQuery(const int _x, const int _y, transMatrix[0][3] -= x1+x2; transMatrix[1][3] += y1+y2; Ogre::Matrix4 customProjectionMatrix = - scaleMatrix * transMatrix * this->dataPtr->camera->getProjectionMatrix(); - - this->dataPtr->selectionCamera->setCustomProjectionMatrix(true, - customProjectionMatrix); + scaleMatrix * transMatrix * + this->dataPtr->camera->getProjectionMatrix(); + this->dataPtr->selectionCamera->setCustomProjectionMatrix(true, + customProjectionMatrix); this->dataPtr->selectionCamera->setPosition( this->dataPtr->camera->getDerivedPosition()); @@ -440,9 +468,8 @@ bool Ogre2SelectionBuffer::ExecuteQuery(const int _x, const int _y, Ogre::Image2 image; image.convertFromTexture(this->dataPtr->renderTexture, 0, 0); - Ogre::ColourValue pixel = image.getColourAt(0, 0, 0, 0); - // Ogre::ColourValue pixel = image.getColourAt(_x, _y, 0, 0); + float color = pixel[3]; uint32_t *rgba = reinterpret_cast(&color); unsigned int r = *rgba >> 24 & 0xFF; diff --git a/ogre2/src/media/materials/programs/GLSL/selection_buffer_fs.glsl b/ogre2/src/media/materials/programs/GLSL/selection_buffer_fs.glsl index d9acd041e..a80bcf4ad 100644 --- a/ogre2/src/media/materials/programs/GLSL/selection_buffer_fs.glsl +++ b/ogre2/src/media/materials/programs/GLSL/selection_buffer_fs.glsl @@ -25,6 +25,7 @@ in block uniform sampler2D colorTexture; uniform sampler2D depthTexture; +uniform vec4 colorTexResolution; out vec4 fragColor; @@ -58,7 +59,8 @@ void main() point = vec3(inf); // color - vec4 color = texture(colorTexture, inPs.uv0); + vec4 color = texelFetch(colorTexture, + ivec2(inPs.uv0 * colorTexResolution.xy), 0); float rgba = packFloat(color); diff --git a/ogre2/src/media/materials/scripts/selection_buffer.material b/ogre2/src/media/materials/scripts/selection_buffer.material index 18649f55d..2bcbbc00b 100644 --- a/ogre2/src/media/materials/scripts/selection_buffer.material +++ b/ogre2/src/media/materials/scripts/selection_buffer.material @@ -33,6 +33,8 @@ fragment_program selection_buffer_fs_GLSL glsl { param_named colorTexture int 0 param_named depthTexture int 1 + + param_named_auto colorTexResolution texture_size 0 } } diff --git a/src/Utils.cc b/src/Utils.cc index 0ac5902c5..394e7ab71 100644 --- a/src/Utils.cc +++ b/src/Utils.cc @@ -104,7 +104,10 @@ float screenScalingFactor() { // todo(anyone) set device pixel ratio for high dpi displays on Windows float ratio = 1.0; -#ifdef __linux__ + + // the scaling factor seems to cause issues with mouse picking. + // see https://github.com/ignitionrobotics/ign-gazebo/issues/147 +#if 0 auto closeDisplay = [](Display * display) { if (display) diff --git a/src/Utils_TEST.cc b/src/Utils_TEST.cc index d75e57daa..6406bac27 100644 --- a/src/Utils_TEST.cc +++ b/src/Utils_TEST.cc @@ -121,15 +121,6 @@ void UtilTest::ClickToScene(const std::string &_renderEngine) root->AddChild(camera); camera->Update(); - if (_renderEngine == "ogre2") - { - // tests using selection buffer fail on CI, see issue #170 - // https://github.com/ignitionrobotics/ign-rendering/issues/170 - igndbg << "Selection buffer based screenToScene test is disabled in " - << _renderEngine << "." << std::endl; - return; - } - // API without RayQueryResult and default max distance result = screenToScene(centerClick, camera, rayQuery, rayResult); diff --git a/test/integration/camera.cc b/test/integration/camera.cc index 4457e3b36..95619639d 100644 --- a/test/integration/camera.cc +++ b/test/integration/camera.cc @@ -187,14 +187,6 @@ void CameraTest::VisualAt(const std::string &_renderEngine) << _renderEngine << std::endl; return; } - else if (_renderEngine == "ogre2") - { - // VisualAt tests fail on CI, see issue #170 - // https://github.com/ignitionrobotics/ign-rendering/issues/170 - igndbg << "VisualAt test is disabled in " << _renderEngine << "." - << std::endl; - return; - } // create and populate scene RenderEngine *engine = rendering::engine(_renderEngine); @@ -285,6 +277,27 @@ void CameraTest::VisualAt(const std::string &_renderEngine) } } + // change camera size + camera->SetImageWidth(1200); + camera->SetImageHeight(800); + + // render a few frames + for (auto i = 0; i < 30; ++i) + { + camera->Update(); + } + + // test that VisualAt still works after resize + { + unsigned int x = 300u; + auto vis = camera->VisualAt(math::Vector2i(x, camera->ImageHeight() / 2)); + EXPECT_NE(nullptr, vis) << "X: " << x; + if (vis) + { + EXPECT_EQ("sphere", vis->Name()); + } + } + // Clean up engine->DestroyScene(scene); rendering::unloadEngine(engine->Name()); diff --git a/test/integration/scene.cc b/test/integration/scene.cc index ebca2cd74..79e657e3c 100644 --- a/test/integration/scene.cc +++ b/test/integration/scene.cc @@ -154,14 +154,6 @@ void SceneTest::VisualAt(const std::string &_renderEngine) << _renderEngine << std::endl; return; } - else if (_renderEngine == "ogre2") - { - // VisualAt tests fail on CI, see issue #170 - // https://github.com/ignitionrobotics/ign-rendering/issues/170 - igndbg << "VisualAt test is disabled in " << _renderEngine << "." - << std::endl; - return; - } // create and populate scene RenderEngine *engine = rendering::engine(_renderEngine);