From 80e10b0d473cccc5449b6b3b42ff5847a0fa8508 Mon Sep 17 00:00:00 2001 From: Michel Hidalgo Date: Wed, 13 Jul 2022 16:03:29 -0300 Subject: [PATCH] Ensure one texture per selection buffer per camera. (#665) Signed-off-by: Ian Chen Signed-off-by: Michel Hidalgo --- ogre2/src/Ogre2SelectionBuffer.cc | 22 +++++++++++++------- src/RayQuery_TEST.cc | 34 ++++++++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/ogre2/src/Ogre2SelectionBuffer.cc b/ogre2/src/Ogre2SelectionBuffer.cc index b5d621796..b12f2ed7b 100644 --- a/ogre2/src/Ogre2SelectionBuffer.cc +++ b/ogre2/src/Ogre2SelectionBuffer.cc @@ -222,18 +222,26 @@ void Ogre2SelectionBuffer::CreateRTTBuffer() Ogre::TextureGpuManager *textureMgr = ogreRoot->getRenderSystem()->getTextureGpuManager(); + const std::string selectionTextureName = "SelectionPassTex"; + bool hasSelectionTexture = + textureMgr->findTextureNoThrow(selectionTextureName); this->dataPtr->renderTexture = textureMgr->createOrRetrieveTexture( - "SelectionPassTex", + selectionTextureName, Ogre::GpuPageOutStrategy::SaveToSystemRam, Ogre::TextureFlags::RenderToTexture, Ogre::TextureTypes::Type2D); - this->dataPtr->renderTexture->setResolution(1, 1); - this->dataPtr->renderTexture->setNumMipmaps(1u); - this->dataPtr->renderTexture->setPixelFormat(Ogre::PFG_RGBA32_FLOAT); - - this->dataPtr->renderTexture->scheduleTransitionTo( - Ogre::GpuResidency::Resident); + if (!hasSelectionTexture) + { + this->dataPtr->renderTexture->setResolution(1, 1); + this->dataPtr->renderTexture->setNumMipmaps(1u); + this->dataPtr->renderTexture->setPixelFormat(Ogre::PFG_RGBA32_FLOAT); + + // we are reusing the same render texture so schedule transition only + // if it is not resident yet otherwise it may throw an exception + this->dataPtr->renderTexture->scheduleTransitionTo( + Ogre::GpuResidency::Resident); + } this->dataPtr->selectionCamera->addListener( this->dataPtr->materialSwitcher.get()); diff --git a/src/RayQuery_TEST.cc b/src/RayQuery_TEST.cc index 8c03b0f7c..889d076cc 100644 --- a/src/RayQuery_TEST.cc +++ b/src/RayQuery_TEST.cc @@ -88,17 +88,45 @@ void RayQueryTest::RayQuery(const std::string &_renderEngine) // set from camera CameraPtr camera = scene->CreateCamera("camera"); + camera->SetLocalPosition(math::Vector3d::Zero); + unsigned int width = 320u; + unsigned int height = 240u; + camera->SetImageWidth(width); + camera->SetImageHeight(height); + + VisualPtr root = scene->RootVisual(); + root->AddChild(camera); math::Vector2d pos(0.0, 0.0); rayQuery->SetFromCamera(camera, pos); - EXPECT_GT(rayQuery->Origin().X(), 0.0); + EXPECT_LT(0.0, rayQuery->Origin().X()); EXPECT_EQ(math::Vector3d::UnitX, rayQuery->Direction().Normalize()); RayQueryResult result = rayQuery->ClosestPoint(); EXPECT_EQ(math::Vector3d::Zero, result.point); - EXPECT_LT(result.distance, 0.0); + EXPECT_GT(0.0, result.distance); EXPECT_EQ(0u, result.objectId); - EXPECT_FALSE((result)); + EXPECT_FALSE(result); + + // testing multiple ray queries that are set from camera + CameraPtr camera2 = scene->CreateCamera("camera2"); + camera2->SetLocalPosition(math::Vector3d::Zero); + camera2->SetImageWidth(width); + camera2->SetImageHeight(height); + + root->AddChild(camera2); + math::Vector2d pos2(0.0, 0.0); + RayQueryPtr rayQuery2 = scene->CreateRayQuery(); + rayQuery2->SetFromCamera(camera2, pos2); + + EXPECT_LT(0.0, rayQuery2->Origin().X()); + EXPECT_EQ(math::Vector3d::UnitX, rayQuery2->Direction().Normalize()); + + RayQueryResult result2 = rayQuery2->ClosestPoint(); + EXPECT_EQ(math::Vector3d::Zero, result2.point); + EXPECT_GT(0.0, result2.distance); + EXPECT_EQ(0u, result2.objectId); + EXPECT_FALSE(result2); // Clean up engine->DestroyScene(scene);