[2.3] Error with writeContentsToFile

Discussion area about developing with Ogre-Next (2.1, 2.2 and beyond)


Post Reply
crjc
Gnoblar
Posts: 14
Joined: Sat Oct 10, 2020 10:19 pm

[2.3] Error with writeContentsToFile

Post by crjc »

What is the correct way to save the render window's texture to disk?

I have attempted the below with the Metal render system on MacOS.

Code: Select all

renderWindow->getTexture()->writeContentsToFile("./test.png", 0, 0);
Not quite sure if I have missed something, as I get the following error:

Code: Select all

-[MTLDebugBlitCommandEncoder validateCopyFromTexture:sourceSlice:sourceLevel:sourceOrigin:sourceSize:toBuffer:destinationOffset:destinationBytesPerRow:destinationBytesPerImage:options:]:851: failed assertion `sourceTexture must not be nil.'
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: [2.3] Error with writeContentsToFile

Post by dark_sylinc »

In the case of Metal (and probably Vulkan too, but Vulkan capture from window is still WIP) capture needs to happen after rendering and before swapBuffers().

Thus either:
  1. You render everything to a temporary offscreen RenderTexture which doesn't have this limitation (and later copy everything to the window via a pass_quad) or...
  2. Register a FrameListener listener with Root, and use FrameListener::frameRenderingQueued to call writeContentsToFile; since this happens between rendering and swapping.. I didn't try this option so it should work I think, but I can't be 100% sure.
  3. Like before, but instead of FrameListener::frameRenderingQueued, use CompositorWorkspaceListener::workspacePosUpdate
crjc
Gnoblar
Posts: 14
Joined: Sat Oct 10, 2020 10:19 pm

Re: [2.3] Error with writeContentsToFile

Post by crjc »

Thanks for confirming.

I have scrapped the RenderWindow as I just need an offscreen Render Texture. However, Ogre's writeContentsToFile is just outputting a completely transparent texture.

This snippet creates the render texture and adds the workspace:

Code: Select all

   texture = textureManager->createTexture("RTex", "RTex",
                                                 Ogre::GpuPageOutStrategy::Discard,
                                                 Ogre::TextureFlags::RenderToTexture,
                                                 Ogre::TextureTypes::Type2D);

    texture->setPixelFormat(Ogre::PixelFormatGpu::PFG_RGBA8_UNORM);
    texture->setResolution(1024, 1024);
    texture->scheduleTransitionTo(Ogre::GpuResidency::Resident);
    
    workspace = compositorManager->addWorkspace( sceneManager, texture, camera, "WorkspaceTest", true );
And here I get the completely transparent image from writeContentsToFile.
I assume I am missing something here:
(apologies if it is something simple)

Code: Select all

 	ogreRoot->renderOneFrame();
 	
 	// Also tried this from an older thread in this forum
 	/*
        workspace->_beginUpdate( true );
        workspace->_update();
        workspace->_endUpdate( true );
 	*/
 	
	workspace->getFinalTarget()->writeContentsToFile("output.png", 0, 0);
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: [2.3] Error with writeContentsToFile

Post by dark_sylinc »

I don't see anything wrong, this is likely an Ogre bug.

Did you try doing this every frame (i.e. try to capture output0.png, output1.png)? I suspect a flushing issue but that should not happen.

Also please check the following: That the downloaded texture is actually correct but alpha is 0 (i.e. open it in an editor, set the alpha to 255 and see if the picture appears)
Post Reply