I’m looking for a way to basically create a screenshot of the current frame but stored in memory, e.g. a BufferedImage, not a .jpg on file. I tried TestRenderToMemory.java, but when I save the BufferedImage, it results in a corrupted image:
I tried to make a modified version of ScreenshotAppState which almost works, except I need a way to manually call postFrame() or to manually render the next frame, but I can’t figure that out.
So, is there a straightforward way to grab the current frame as a BufferedImage? If I can either fix TestRenderToMemory or find out how to manually render the next frame, that would be clear up my issue.
Thanks for the clarification. I made a modified version of ScreenshotAppState.java that saves the image in a variable instead of to disk, but the problem is that it’s always one frame behind: E.g. if I move a cube then grab a screenshot, the resulting image is the cube’s old position. I found that if I wait a little bit between the action and the screenshot then it works fine, but I never know how long to wait.
I understand I can’t call postFrame(), so the problem is that when I grab the frame’s image, I don’t know when the BufferedImage is finished being created (so if I access it too early I get the old frame); I know it’s ready by the end of postFrame(), but I have no way to signal when postFrame() finishes. Is there a way to execute some code as soon as postFrame() finishes?
I’m using JME to generate images of rendered 3D scenes and using them for computer vision tasks, so my ideal pipeline is to generate a scene, grab the image, process it, then repeat, but the frame issue means that most times I’ll be processing an older scene (the online sequence of scenes is important, so they cannot be generated ahead of time).
To clarify, it’s okay that the screenshot is a frame behind, but the problem is that I can only access the image after postFrame() finishes, but I don’t know when that happens.
My class is BufferedImageAppState, which is almost identical to ScreenshotAppState but instead of postFrame() writing to disk, it writes the byte buffer to an instance variable BufferedImage image. The problem is that if I do the following (in pseudocode, using the fields and properties of ScreenshotAppState) :
takeScreenshot()
print capture
view image
The printed output is true. This means that I viewed the image before postFrame() could reset capture = false and read the frame buffer. Consequently, this means no new image was created, so I view whatever the last image created was (note that this means I could create an image of a scene, then make 100 new scenes, but when I try to make another image, I see the last one I made). So what I really need is:
takeScreenshot()
print capture
*somehow wait for postFrame() to execute*
print capture
view image
So that the printed output is true,false, which means postFrame() did execute. Is there no way to know when postFrame() finishes? My makeshift solution is to use a while loop to wait until capture changes boolean value, but this causes some nasty side effects I’d rather avoid. I apologize for the verboseness; does this clarify the problem?
Yes, thanks, but I need to execute code immediately after the completion of postFrame(); I can’t append code at the bottom of postFrame() because I must return a value, which can’t be done while working within postFrame().