OpenWalnut  1.3.1
WGEScreenCapture.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WGESCREENCAPTURE_H
26 #define WGESCREENCAPTURE_H
27 
28 #include <limits>
29 
30 #include <boost/signals2.hpp>
31 #include <boost/function.hpp>
32 
33 #include <osg/Camera>
34 #include <osg/Image>
35 #include <osg/RenderInfo>
36 
37 #include "../common/WSharedObject.h"
38 #include "../common/WCondition.h"
39 
40 #include "animation/WGEAnimationFrameTimer.h"
41 
42 
43 
44 /**
45  * This class is a screen recorder. It records the frame buffer to files on a per-frame-basis. This class is NOT thread-safe due to performance
46  * reasons. You should not distribute the instance among multiple threads. It can be applied to <b>ONE</b> camera only by setting it as
47  * finalDrawCallback (osg::Camera::setFinalDrawCallback). Each camera can only use ONE final draw callback.
48  *
49  * This class is abstract. Derive your own class and handle image writing.
50  *
51  * \note This class does NOT write the images to disk. Set a callback for this.
52  *
53  * \ingroup GE
54  */
55 class WGEScreenCapture: public osg::Camera::DrawCallback
56 {
57 public:
58  /**
59  * Keeps track of several frame-counts.
60  */
61  typedef struct
62  {
63  size_t m_frames; //!< current number of frames.
64  size_t m_framesLeft; //!< the frames to take until stop.
65  }
67 
68  /**
69  * The shared access type to the FrameCounting struct.
70  */
72 
73  /**
74  * Convenience typedef
75  */
76  typedef osg::ref_ptr< WGEScreenCapture > RefPtr;
77 
78  /**
79  * Convenience typedef
80  */
81  typedef osg::ref_ptr< const WGEScreenCapture > ConstRefPtr;
82 
83  /**
84  * This callback signature is needed to subscribe to the handleImage signal.
85  */
86  typedef boost::function< void( size_t, size_t, osg::ref_ptr< osg::Image > ) > HandleImageCallbackType;
87 
88  /**
89  * Creates a screen capture callback.
90  */
92 
93  /**
94  * Destructor. Cleans up.
95  */
96  virtual ~WGEScreenCapture();
97 
98  /**
99  * Starts recording. If it already is running, nothing happens.
100  */
101  void recordStart();
102 
103  /**
104  * Stops recording. If not recording, nothing happens.
105  */
106  void recordStop();
107 
108  /**
109  * Checks if there are frames left for recording.
110  *
111  * \return true if yes.
112  */
113  bool isRecording();
114 
115  /**
116  * Makes a screenshot with the <b>next</b> frame. This is a shortcut for record( 1 ).
117  */
118  void screenshot();
119 
120  /**
121  * Resets the frame-counter to 0.
122  */
123  void resetFrameCounter();
124 
125  /**
126  * The draw callback operator. Gets called by OSG in draw traversal.
127  *
128  * \param renderInfo the OSG renderinfo
129  */
130  virtual void operator()( osg::RenderInfo& renderInfo ) const; // NOLINT - osg wants this to be a non-const reference
131 
132  /**
133  * The condition returned here is actually the change condition of the frame counter. This can be used to update GUI or something as it
134  * contains frame-counts, recording information and so on (updated per frame).
135  *
136  * \return the condition
137  */
139 
140  /**
141  * Returns the current recording information. Release the lock after you grabbed the info you need.
142  *
143  * \return the info struct - read ticket
144  */
146 
147  /**
148  * Returns a timer getting ticked on each recorded frame. This can then be used for animations for example.
149  *
150  * \return the timer.
151  */
153 
154  /**
155  * Subscribes a specified function to the new-image-signal. This gets emitted every time a new image was grabbed.
156  *
157  * \param callback the callback
158  *
159  * \return the connection.
160  */
161  boost::signals2::connection subscribeSignal( HandleImageCallbackType callback );
162 
163 protected:
164  /**
165  * The function handles new images. Implement it.
166  *
167  * \param framesLeft how much frames to come
168  * \param totalFrames the total number of frames until now
169  * \param image the image
170  */
171  virtual void handleImage( size_t framesLeft, size_t totalFrames, osg::ref_ptr< osg::Image > image ) const;
172 
173  /**
174  * Starts recording. If already recording, it continues recording.
175  *
176  * \param frames the number of frames to record. 0 means stop, 1 is a single screenshot.
177  */
178  void record( size_t frames = std::numeric_limits< size_t >::max() );
179 
180 private:
181  /**
182  * Counts the frames to take.
183  */
185 
186  /**
187  * The frame timer. Ticket on each recorded frame.
188  */
190 
191  /**
192  * The type of the signal for handleSignal.
193  */
194  typedef boost::signals2::signal< void( size_t, size_t, osg::ref_ptr< osg::Image > ) > HandleImageSignalType;
195 
196  /**
197  * The signal emitted on every new grabbed image.
198  */
200 };
201 
202 #endif // WGESCREENCAPTURE_H