@@ -42,26 +42,22 @@ namespace rendering
42
42
{
43
43
inline namespace IGNITION_RENDERING_VERSION_NAMESPACE {
44
44
// / \brief Helper class to assign unique colors to renderables
45
- class Ogre2SegmentationMaterialSwitcher : public Ogre ::RenderTargetListener
45
+ class Ogre2SegmentationMaterialSwitcher : public Ogre ::Camera::Listener
46
46
{
47
47
// / \brief Constructor
48
48
// / \param[in] _scene Ogre scene to be rendered
49
49
public: explicit Ogre2SegmentationMaterialSwitcher (Ogre2ScenePtr _scene);
50
50
51
51
// / \brief Destructor
52
- public: ~Ogre2SegmentationMaterialSwitcher () = default ;
52
+ public: virtual ~Ogre2SegmentationMaterialSwitcher () = default ;
53
53
54
- // / \brief Ogre's pre render update callback
55
- // / \param[in] _evt Ogre render target event containing information about
56
- // / the source render target.
57
- public: virtual void preRenderTargetUpdate (
58
- const Ogre::RenderTargetEvent &_evt) override ;
54
+ // / \brief Callback when a camera is about to be rendered
55
+ // / \param[in] _cam Ogre render camara which is about to render.
56
+ public: virtual void cameraPreRenderScene (Ogre::Camera *_cam) override ;
59
57
60
- // / \brief Ogre's post render update callback
61
- // / \param[in] _evt Ogre render target event containing information about
62
- // / the source render target.
63
- public: virtual void postRenderTargetUpdate (
64
- const Ogre::RenderTargetEvent &_evt) override ;
58
+ // / \brief Callback when a camera is finished being rendered
59
+ // / \param[in] _cam Ogre camera that was rendered
60
+ public: virtual void cameraPostRenderScene (Ogre::Camera *_cam) override ;
65
61
66
62
// / \brief Convert label of semantic map to a unique color for colored map and
67
63
// / add the color of the label to the taken colors if it doesn't exist
@@ -156,13 +152,7 @@ class ignition::rendering::Ogre2SegmentationCameraPrivate
156
152
public: std::string workspaceDefinition;
157
153
158
154
// / \brief Render Texture to store the final segmentation data
159
- public: Ogre::RenderTexture *ogreRenderTexture {nullptr };
160
-
161
- // / \brief Texture to create the render texture from.
162
- public: Ogre::TexturePtr ogreTexture;
163
-
164
- // / \brief Pixel Box to copy render texture data to a buffer
165
- public: Ogre::PixelBox *pixelBox {nullptr };
155
+ public: Ogre::TextureGpu *ogreRenderTexture {nullptr };
166
156
167
157
// / \brief buffer to store render texture data & to be sent to listeners
168
158
public: uint8_t *buffer = nullptr ;
@@ -181,7 +171,7 @@ class ignition::rendering::Ogre2SegmentationCameraPrivate
181
171
const std::string &_format)> newSegmentationFrame;
182
172
183
173
// / \brief Image / Render Texture Format
184
- public: const Ogre::PixelFormat format = Ogre::PF_R8G8B8 ;
174
+ public: const Ogre::PixelFormatGpu format = Ogre::PFG_RGB8_UNORM ;
185
175
};
186
176
187
177
using namespace ignition ;
@@ -293,8 +283,8 @@ VisualPtr Ogre2SegmentationMaterialSwitcher::TopLevelModelVisual(
293
283
}
294
284
295
285
// //////////////////////////////////////////////
296
- void Ogre2SegmentationMaterialSwitcher::preRenderTargetUpdate (
297
- const Ogre::RenderTargetEvent & /* _evt */ )
286
+ void Ogre2SegmentationMaterialSwitcher::cameraPreRenderScene (
287
+ Ogre::Camera * )
298
288
{
299
289
this ->colorToLabel .clear ();
300
290
this ->datablockMap .clear ();
@@ -458,8 +448,8 @@ void Ogre2SegmentationMaterialSwitcher::preRenderTargetUpdate(
458
448
}
459
449
460
450
// ///////////////////////////////////////////////
461
- void Ogre2SegmentationMaterialSwitcher::postRenderTargetUpdate (
462
- const Ogre::RenderTargetEvent & /* _evt */ )
451
+ void Ogre2SegmentationMaterialSwitcher::cameraPostRenderScene (
452
+ Ogre::Camera * )
463
453
{
464
454
// restore item to use pbs hlms material
465
455
for (const auto &[subItem, dataBlock] : this ->datablockMap )
@@ -540,8 +530,9 @@ void Ogre2SegmentationCamera::Destroy()
540
530
// remove thermal texture, material, compositor
541
531
if (this ->dataPtr ->ogreRenderTexture )
542
532
{
543
- Ogre::TextureManager::getSingleton ().remove (
544
- this ->dataPtr ->ogreRenderTexture ->getName ());
533
+ ogreRoot->getRenderSystem ()->getTextureGpuManager ()->destroyTexture (
534
+ this ->dataPtr ->ogreRenderTexture );
535
+ this ->dataPtr ->ogreRenderTexture = nullptr ;
545
536
}
546
537
if (this ->dataPtr ->ogreCompositorWorkspace )
547
538
{
@@ -570,10 +561,6 @@ void Ogre2SegmentationCamera::Destroy()
570
561
}
571
562
}
572
563
573
- if (this ->dataPtr ->pixelBox )
574
- delete this ->dataPtr ->pixelBox ;
575
- this ->dataPtr ->pixelBox = nullptr ;
576
-
577
564
if (this ->dataPtr ->materialSwitcher )
578
565
delete this ->dataPtr ->materialSwitcher ;
579
566
this ->dataPtr ->materialSwitcher = nullptr ;
@@ -600,27 +587,28 @@ void Ogre2SegmentationCamera::CreateSegmentationTexture()
600
587
auto width = this ->ImageWidth ();
601
588
auto height = this ->ImageHeight ();
602
589
603
- // texture
604
- this ->dataPtr ->ogreTexture =
605
- Ogre::TextureManager::getSingleton ().createManual (
606
- " SegmentationCameraTexture" ,
607
- Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
608
- Ogre::TEX_TYPE_2D, width, height, 0 , this ->dataPtr ->format ,
609
- Ogre::TU_RENDERTARGET
610
- );
590
+ auto engine = Ogre2RenderEngine::Instance ();
591
+ auto ogreRoot = engine->OgreRoot ();
592
+ Ogre::TextureGpuManager *textureMgr =
593
+ ogreRoot->getRenderSystem ()->getTextureGpuManager ();
611
594
612
595
// render texture
613
- auto hardwareBuffer = this ->dataPtr ->ogreTexture ->getBuffer ();
614
- this ->dataPtr ->ogreRenderTexture = hardwareBuffer->getRenderTarget ();
596
+ this ->dataPtr ->ogreRenderTexture = textureMgr->createOrRetrieveTexture (
597
+ " SegmentationCameraTexture" ,
598
+ Ogre::GpuPageOutStrategy::SaveToSystemRam,
599
+ Ogre::TextureFlags::RenderToTexture,
600
+ Ogre::TextureTypes::Type2D);
601
+ this ->dataPtr ->ogreRenderTexture ->setResolution (width, height);
602
+ this ->dataPtr ->ogreRenderTexture ->setNumMipmaps (1u );
603
+ this ->dataPtr ->ogreRenderTexture ->setPixelFormat (this ->dataPtr ->format );
604
+ this ->dataPtr ->ogreRenderTexture ->scheduleTransitionTo (
605
+ Ogre::GpuResidency::Resident);
615
606
616
607
// switch the material to a unique color for each object
617
608
// in the pre render & get the original material again in the post render
618
- this ->dataPtr ->ogreRenderTexture ->addListener (
619
- this ->dataPtr ->materialSwitcher );
609
+ this ->ogreCamera ->addListener (this ->dataPtr ->materialSwitcher );
620
610
621
611
// workspace
622
- auto engine = Ogre2RenderEngine::Instance ();
623
- auto ogreRoot = engine->OgreRoot ();
624
612
this ->dataPtr ->ogreCompositorManager = ogreRoot->getCompositorManager2 ();
625
613
626
614
this ->dataPtr ->workspaceDefinition = " SegmentationCameraWorkspace_" +
@@ -652,15 +640,9 @@ void Ogre2SegmentationCamera::CreateSegmentationTexture()
652
640
renderScenePass)->setVisibilityMask (IGN_VISIBILITY_ALL);
653
641
654
642
// buffer to store render texture data
655
- auto bufferSize = Ogre::PixelUtil::getMemorySize (
656
- width, height, 1 , this ->dataPtr ->format );
657
643
if (this ->dataPtr ->buffer )
658
644
delete [] this ->dataPtr ->buffer ;
659
- this ->dataPtr ->buffer = new uint8_t [bufferSize];
660
- if (this ->dataPtr ->pixelBox )
661
- delete this ->dataPtr ->pixelBox ;
662
- this ->dataPtr ->pixelBox = new Ogre::PixelBox (width, height, 1 ,
663
- this ->dataPtr ->format , this ->dataPtr ->buffer );
645
+ this ->dataPtr ->buffer = new uint8_t [width * height * 3 * sizeof (uint8_t )];
664
646
}
665
647
666
648
// ///////////////////////////////////////////////
@@ -676,24 +658,34 @@ void Ogre2SegmentationCamera::Render()
676
658
// ///////////////////////////////////////////////
677
659
void Ogre2SegmentationCamera::PostRender ()
678
660
{
679
- // copy render texture data to the pixel box & its buffer
680
- this ->dataPtr ->ogreRenderTexture ->copyContentsToMemory (
681
- *this ->dataPtr ->pixelBox ,
682
- Ogre::RenderTarget::FB_FRONT
683
- );
684
-
685
661
// return if no one is listening to the new frame
686
662
if (this ->dataPtr ->newSegmentationFrame .ConnectionCount () == 0 )
687
663
return ;
688
664
689
- uint width = this ->ImageWidth ();
690
- uint height = this ->ImageHeight ();
691
- uint channelCount = 3 ;
665
+ unsigned int width = this ->ImageWidth ();
666
+ unsigned int height = this ->ImageHeight ();
667
+ unsigned int channelCount = 3 ;
668
+ unsigned int bytesPerChannel = PixelUtil::BytesPerChannel (PF_R8G8B8);
669
+
670
+ Ogre::Image2 image;
671
+ image.convertFromTexture (this ->dataPtr ->ogreRenderTexture , 0u , 0u );
672
+ Ogre::TextureBox box = image.getData (0u );
673
+
674
+ // copy data row by row. The texture box may not be a contiguous region of
675
+ // a texture
676
+ uint8_t *segmentationBuffer = static_cast <uint8_t *>(box.data );
677
+ for (unsigned int i = 0 ; i < height; ++i)
678
+ {
679
+ unsigned int rawDataRowIdx = i * box.bytesPerRow / bytesPerChannel;
680
+ unsigned int rowIdx = i * width * channelCount;
681
+ memcpy (&this ->dataPtr ->buffer [rowIdx], &segmentationBuffer[rawDataRowIdx],
682
+ width * channelCount * bytesPerChannel);
683
+ }
692
684
693
685
this ->dataPtr ->newSegmentationFrame (
694
686
this ->dataPtr ->buffer ,
695
687
width, height, channelCount,
696
- Ogre:: PixelUtil::getFormatName ( this -> dataPtr -> format )
688
+ PixelUtil::Name (PF_R8G8B8 )
697
689
);
698
690
}
699
691
@@ -709,13 +701,30 @@ void Ogre2SegmentationCamera::Capture(Image &_image)
709
701
return ;
710
702
}
711
703
712
- // image buffer
713
- void *data = _image.Data ();
714
-
715
- // pixel box to copy data from the render texture to the image buffer
716
- Ogre::PixelBox ogrePixelBox (width, height, 1 , this ->dataPtr ->format , data);
717
- this ->dataPtr ->ogreRenderTexture ->copyContentsToMemory (
718
- ogrePixelBox, Ogre::RenderTarget::FB_FRONT);
704
+ // I'm not sure what to cast _image.Data to (void * isn't going to work here),
705
+ // so for now, this is commented out since it doesn't compile
706
+ /*
707
+ * unsigned int bytesPerChannel = PixelUtil::BytesPerChannel(_image.Format());
708
+ * unsigned int channelCount = _image.Depth();
709
+ *
710
+ * // image buffer
711
+ * void *imgData = _image.Data();
712
+ *
713
+ * // copy data from the render texture to the image buffer
714
+ * Ogre::Image2 image;
715
+ * image.convertFromTexture(this->dataPtr->ogreRenderTexture, 0u, 0u);
716
+ * Ogre::TextureBox box = image.getData(0);
717
+ * void *bufferTmp = static_cast<void *>(box.data);
718
+ * // copy data row by row. The texture box may not be a contiguous region of
719
+ * // a texture
720
+ * for (unsigned int i = 0; i < height; ++i)
721
+ * {
722
+ * unsigned int rawDataRowIdx = i * box.bytesPerRow / bytesPerChannel;
723
+ * unsigned int rowIdx = i * width * channelCount;
724
+ * memcpy(&imgData[rowIdx], &bufferTmp[rawDataRowIdx],
725
+ * width * channelCount * bytesPerChannel);
726
+ * }
727
+ */
719
728
}
720
729
721
730
// ///////////////////////////////////////////////
0 commit comments