From Jean-Sebastien Guay, "I've made a change to the ScreenCaptureHandler's addCallbackToViewer method, so that it iterates over GraphicsContexts instead of GraphicsWindows. When the viewer has a pbuffer (for offscreen rendering without a window) then it wouldn't add the WindowCaptureCallback to that context since it wasn't in the list returned by ViewerBase::getWindows(). And anyways, I originally wrote the code, and I didn't see any reason why I did it with windows instead of contexts...

I've needed to run a recorded simulation offscreen and save it to a sequence of images, and the ScreenCaptureHandler seemed to be the simplest way to do that, and with this change it's possible.


Another change: I've also added the ability to specify continuous capture of all frames, or a certain number of frames. ScreenCaptureHandler now has a setFramesToCapture(int) method. The argument will be interpreted as:

0  : don't capture
<0 : capture continuously
>0 : capture that number of frames then stop

I also added startCapture() and stopCapture() methods so that user code can start capturing (either continuously or the given number of frames) at a given point in their program. setFramesToCapture() won't start capturing, you have to call startCapture() afterwards. The handler also now has another key to toggle continuous capture (defaults to 'C').

Note that continuous capture will of course only work if the CaptureOperation writes to different files (for example, a WriteToFile with SEQUENTIAL_NUMBER mode) or does something different each time... Otherwise it will just overwrite of course. :-)

I've also taken the chance to refactor the addCallbackToViewer() method a bit too, since finding the right camera is needed in two places now.

I've tested all cases (I think). If you want to try, in osgviewer.cpp and replace the line

 // add the screen capture handler
 viewer.addEventHandler(new osgViewer::ScreenCaptureHandler);

with

 // add the screen capture handler
 osgViewer::ScreenCaptureHandler* captureHandler = new
     osgViewer::ScreenCaptureHandler(
         new osgViewer::ScreenCaptureHandler::WriteToFile(
             "screenshot", "jpg",
     osgViewer::ScreenCaptureHandler::WriteToFile::SEQUENTIAL_NUMBER),
     -1);
 viewer.addEventHandler(captureHandler);
 captureHandler->startCapture();

And vary the "-1" (put 0, 10, 50) and then use the 'c' and 'C' keys and see how it reacts.
"
This commit is contained in:
Robert Osfield
2009-11-19 12:01:49 +00:00
parent 4f6be906b3
commit b4a5edd82e
2 changed files with 230 additions and 88 deletions

View File

@@ -323,7 +323,7 @@ class OSGVIEWER_EXPORT ScreenCaptureHandler : public osgGA::GUIEventHandler
// ... any others?
};
WriteToFile(const std::string& filename, const std::string& extension, SavePolicy savePolicy = OVERWRITE);
WriteToFile(const std::string& filename, const std::string& extension, SavePolicy savePolicy = SEQUENTIAL_NUMBER);
virtual void operator()(const osg::Image& image, const unsigned int context_id);
@@ -342,12 +342,15 @@ class OSGVIEWER_EXPORT ScreenCaptureHandler : public osgGA::GUIEventHandler
std::vector<unsigned int> _contextSaveCounter;
};
ScreenCaptureHandler(CaptureOperation* defaultOperation = 0);
/** @param numFrames >0: capture that number of frames. <0: capture all frames, call stopCapture() to stop it. */
ScreenCaptureHandler(CaptureOperation* defaultOperation = 0, int numFrames = 1);
void setKeyEventTakeScreenShot(int key) { _keyEventTakeScreenShot = key; }
int getKeyEventTakeScreenShot() const { return _keyEventTakeScreenShot; }
void setKeyEventToggleContinuousCapture(int key) { _keyEventToggleContinuousCapture = key; }
int getKeyEventToggleContinuousCapture() const { return _keyEventToggleContinuousCapture; }
void setCaptureOperation(CaptureOperation* operation);
CaptureOperation* getCaptureOperation() const;
@@ -358,17 +361,37 @@ class OSGVIEWER_EXPORT ScreenCaptureHandler : public osgGA::GUIEventHandler
/** Capture the given viewer's views on the next frame. */
virtual void captureNextFrame(osgViewer::ViewerBase& viewer);
/** Set the number of frames to capture.
@param numFrames >0: capture that number of frames. <0: capture all frames, call stopCapture() to stop it. */
void setFramesToCapture(int numFrames);
/** Get the number of frames to capture. */
int getFramesToCapture() const;
/** Start capturing any viewer(s) the handler is attached to at the
end of the next frame. */
void startCapture();
/** Stop capturing. */
void stopCapture();
/** Get the keyboard and mouse usage of this manipulator.*/
virtual void getUsage(osg::ApplicationUsage& usage) const;
protected:
bool _startCapture;
bool _stopCapture;
int _keyEventTakeScreenShot;
int _keyEventToggleContinuousCapture;
// there could be a key to start taking screenshots every new frame
osg::ref_ptr<CaptureOperation> _operation;
osg::ref_ptr<osg::Camera::DrawCallback> _callback;
void addCallbackToViewer(osgViewer::ViewerBase& viewer);
void removeCallbackFromViewer(osgViewer::ViewerBase& viewer);
osg::Camera* findAppropriateCameraForCallback(osgViewer::ViewerBase& viewer);
};
/** InteractiveImage is an event handler that computes the mouse coordinates in an images coordinate frame