To get rendering results in Ogre, you can use the RenderTarget Copycontentstomemory method, for example:
New Char 4 ]; Ogre::P ixelbox*new1, Ogre::P f_x8r8g8b8, SRC);
Mwindow->copycontentstomemory (*pixbox, Ogre::rendertarget::fb_auto);
Mwindow for the current render window Renderwindow, if using RTT (render to texture) is the same process
It is important to note that the export format should be PF_X8R8G8B8 to avoid performance loss due to format conversion
Unfortunately, this method is surprisingly slow to find in practice.
A hundred-frame scene has dropped to twenty or thirty frames because of the sentence.
In general, it's a slow process to copy data from GPU graphics to CPU memory, but it's too slow to be too dramatic.
Look at the implementation of the Copycontentstomemory, which is probably the following (simplified):
voidD3d9device::copycontentstomemory (ConstPixelbox &DST) {IDirect3DSurface9*surface =NULL; D3dlocked_rect Lrect; Mdevice->createoffscreenplainsurface (width, height, format, d3dpool_systemmem, surface,0); IDirect3DSurface9*Backsurface; Mdevice->getbackbuffer (0,0,d3dbackbuffer_type_mono,&backsurface); Mdevice-getrendertargetdata (backsurface, surface); Surface->lockrect (&Lrect, NULL, d3dlock_readonly); memcpy (Dst.data, Lrect.pbits, Dst.getwidth ()* Dst.getheight () *4); Surface-UnlockRect ();
Surface-Release (); TMP-Release (); }
To create an off-screen surface in memory (D3DPOOL_SYSTEMMEM)
The data in the back buffer is then copied to the surface (Getrendertargetdata)
Finally lock the surface get memory pointer complete data copy
Where complete the steps to copy data from GPU memory to CPU RAM are Getrendertargetdata
There's no problem with that, it's standard practice.
Tested to find that the Getrendertargetdata method takes 0 milliseconds, which means fast enough
The actual bottleneck is on the LockRect method, where each call in the test scenario reaches more than 30 milliseconds
In principle, the surface is created in memory and is not used in the scene, and the lock should not have any consumption
When using the D3D test directly, it was also found that the method was 0, and I couldn't figure out what the reason was.
...
A few twists and ends, think of an unconventional solution:
Lock, unlock, and retrieve the data area pointer the first time you create a off-screen surface, and then use the pointer to complete the data copy directly
This is true because the off-screen surface created does not actually need to be locked
every just called Getrendertargetdata copy data from GPU memory
With Ogre, this is a bit of a hassle, because Ogre does not support direct access Direct3D
Code to modify the ogre and Rendersystem_direct3d9 plugins
But this is the best way for people to solve this problem now.
Get efficiency issues with rendering results for Ogre or D3D