OpenWalnut  1.4.0
WGEScreenCapture.h
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #ifndef WGESCREENCAPTURE_H
00026 #define WGESCREENCAPTURE_H
00027 
00028 #include <limits>
00029 
00030 #include <boost/signals2.hpp>
00031 #include <boost/function.hpp>
00032 
00033 #include <osg/Camera>
00034 #include <osg/Image>
00035 #include <osg/RenderInfo>
00036 
00037 #include "../common/WSharedObject.h"
00038 #include "../common/WCondition.h"
00039 
00040 #include "WGECamera.h"
00041 
00042 #include "animation/WGEAnimationFrameTimer.h"
00043 
00044 
00045 
00046 /**
00047  * 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
00048  * reasons. You should not distribute the instance among multiple threads. It can be applied to <b>ONE</b> camera only by setting it as
00049  * finalDrawCallback (WGECamera::setFinalDrawCallback). Each camera can only use ONE final draw callback.
00050  *
00051  * This class is abstract. Derive your own class and handle image writing.
00052  *
00053  * \note This class does NOT write the images to disk. Set a callback for this.
00054  *
00055  * \ingroup GE
00056  */
00057 class WGEScreenCapture: public WGECamera::DrawCallback
00058 {
00059 public:
00060     /**
00061      * Keeps track of several frame-counts.
00062      */
00063     typedef struct
00064     {
00065         size_t m_frames;        //!< current number of frames.
00066         size_t m_framesLeft;    //!< the frames to take until stop.
00067     }
00068     RecordingInformation;
00069 
00070     /**
00071      * The shared access type to the FrameCounting struct.
00072      */
00073     typedef WSharedObject< RecordingInformation > SharedRecordingInformation;
00074 
00075     /**
00076      * Convenience typedef
00077      */
00078     typedef osg::ref_ptr< WGEScreenCapture > RefPtr;
00079 
00080     /**
00081      * Convenience typedef
00082      */
00083     typedef osg::ref_ptr< const WGEScreenCapture > ConstRefPtr;
00084 
00085     /**
00086      * This callback signature is needed to subscribe to the handleImage signal.
00087      */
00088     typedef boost::function< void( size_t, size_t, osg::ref_ptr< osg::Image > ) > HandleImageCallbackType;
00089 
00090     /**
00091      * Creates a screen capture callback.
00092      */
00093     WGEScreenCapture();
00094 
00095     /**
00096      * Destructor. Cleans up.
00097      */
00098     virtual ~WGEScreenCapture();
00099 
00100     /**
00101      * Starts recording. If it already is running, nothing happens.
00102      */
00103     void recordStart();
00104 
00105     /**
00106      * Stops recording. If not recording, nothing happens.
00107      */
00108     void recordStop();
00109 
00110     /**
00111      * Checks if there are frames left for recording.
00112      *
00113      * \return true if yes.
00114      */
00115     bool isRecording();
00116 
00117     /**
00118      * Makes a screenshot with the <b>next</b> frame. This is a shortcut for record( 1 ).
00119      */
00120     void screenshot();
00121 
00122     /**
00123      * Resets the frame-counter to 0.
00124      */
00125     void resetFrameCounter();
00126 
00127     /**
00128      * The draw callback operator. Gets called by OSG in draw traversal.
00129      *
00130      * \param renderInfo the OSG renderinfo
00131      */
00132     virtual void operator()( osg::RenderInfo& renderInfo ) const;   // NOLINT - osg wants this to be a non-const reference
00133 
00134     /**
00135      * The condition returned here is actually the change condition of the frame counter. This can be used to update GUI or something as it
00136      * contains frame-counts, recording information and so on (updated per frame).
00137      *
00138      * \return the condition
00139      */
00140     WCondition::ConstSPtr getRecordCondition() const;
00141 
00142     /**
00143      * Returns the current recording information. Release the lock after you grabbed the info you need.
00144      *
00145      * \return the info struct - read ticket
00146      */
00147     SharedRecordingInformation::ReadTicket getRecordingInformation() const;
00148 
00149     /**
00150      * Returns a timer getting ticked on each recorded frame. This can then be used for animations for example.
00151      *
00152      * \return the timer.
00153      */
00154     WGEAnimationFrameTimer::ConstSPtr getFrameTimer() const;
00155 
00156     /**
00157      * Subscribes a specified function to the new-image-signal. This gets emitted every time a new image was grabbed.
00158      *
00159      * \param callback the callback
00160      *
00161      * \return the connection.
00162      */
00163     boost::signals2::connection subscribeSignal( HandleImageCallbackType callback );
00164 
00165 protected:
00166     /**
00167      * The function handles new images. Implement it.
00168      *
00169      * \param framesLeft how much frames to come
00170      * \param totalFrames the total number of frames until now
00171      * \param image the image
00172      */
00173     virtual void handleImage( size_t framesLeft, size_t totalFrames, osg::ref_ptr< osg::Image > image ) const;
00174 
00175     /**
00176      * Starts recording. If already recording, it continues recording.
00177      *
00178      * \param frames the number of frames to record. 0 means stop, 1 is a single screenshot.
00179      */
00180     void record( size_t frames = std::numeric_limits< size_t >::max() );
00181 
00182 private:
00183     /**
00184      * Counts the frames to take.
00185      */
00186     SharedRecordingInformation m_recordingInformation;
00187 
00188     /**
00189      * The frame timer. Ticket on each recorded frame.
00190      */
00191     WGEAnimationFrameTimer::SPtr m_timer;
00192 
00193     /**
00194      * The type of the signal for handleSignal.
00195      */
00196     typedef boost::signals2::signal< void( size_t, size_t, osg::ref_ptr< osg::Image > ) > HandleImageSignalType;
00197 
00198     /**
00199      * The signal emitted on every new grabbed image.
00200      */
00201     HandleImageSignalType m_signalHandleImage;
00202 };
00203 
00204 #endif  // WGESCREENCAPTURE_H