OpenWalnut 1.3.1
|
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 "animation/WGEAnimationFrameTimer.h" 00041 00042 00043 00044 /** 00045 * 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 00046 * reasons. You should not distribute the instance among multiple threads. It can be applied to <b>ONE</b> camera only by setting it as 00047 * finalDrawCallback (osg::Camera::setFinalDrawCallback). Each camera can only use ONE final draw callback. 00048 * 00049 * This class is abstract. Derive your own class and handle image writing. 00050 * 00051 * \note This class does NOT write the images to disk. Set a callback for this. 00052 * 00053 * \ingroup GE 00054 */ 00055 class WGEScreenCapture: public osg::Camera::DrawCallback 00056 { 00057 public: 00058 /** 00059 * Keeps track of several frame-counts. 00060 */ 00061 typedef struct 00062 { 00063 size_t m_frames; //!< current number of frames. 00064 size_t m_framesLeft; //!< the frames to take until stop. 00065 } 00066 RecordingInformation; 00067 00068 /** 00069 * The shared access type to the FrameCounting struct. 00070 */ 00071 typedef WSharedObject< RecordingInformation > SharedRecordingInformation; 00072 00073 /** 00074 * Convenience typedef 00075 */ 00076 typedef osg::ref_ptr< WGEScreenCapture > RefPtr; 00077 00078 /** 00079 * Convenience typedef 00080 */ 00081 typedef osg::ref_ptr< const WGEScreenCapture > ConstRefPtr; 00082 00083 /** 00084 * This callback signature is needed to subscribe to the handleImage signal. 00085 */ 00086 typedef boost::function< void( size_t, size_t, osg::ref_ptr< osg::Image > ) > HandleImageCallbackType; 00087 00088 /** 00089 * Creates a screen capture callback. 00090 */ 00091 WGEScreenCapture(); 00092 00093 /** 00094 * Destructor. Cleans up. 00095 */ 00096 virtual ~WGEScreenCapture(); 00097 00098 /** 00099 * Starts recording. If it already is running, nothing happens. 00100 */ 00101 void recordStart(); 00102 00103 /** 00104 * Stops recording. If not recording, nothing happens. 00105 */ 00106 void recordStop(); 00107 00108 /** 00109 * Checks if there are frames left for recording. 00110 * 00111 * \return true if yes. 00112 */ 00113 bool isRecording(); 00114 00115 /** 00116 * Makes a screenshot with the <b>next</b> frame. This is a shortcut for record( 1 ). 00117 */ 00118 void screenshot(); 00119 00120 /** 00121 * Resets the frame-counter to 0. 00122 */ 00123 void resetFrameCounter(); 00124 00125 /** 00126 * The draw callback operator. Gets called by OSG in draw traversal. 00127 * 00128 * \param renderInfo the OSG renderinfo 00129 */ 00130 virtual void operator()( osg::RenderInfo& renderInfo ) const; // NOLINT - osg wants this to be a non-const reference 00131 00132 /** 00133 * The condition returned here is actually the change condition of the frame counter. This can be used to update GUI or something as it 00134 * contains frame-counts, recording information and so on (updated per frame). 00135 * 00136 * \return the condition 00137 */ 00138 WCondition::ConstSPtr getRecordCondition() const; 00139 00140 /** 00141 * Returns the current recording information. Release the lock after you grabbed the info you need. 00142 * 00143 * \return the info struct - read ticket 00144 */ 00145 SharedRecordingInformation::ReadTicket getRecordingInformation() const; 00146 00147 /** 00148 * Returns a timer getting ticked on each recorded frame. This can then be used for animations for example. 00149 * 00150 * \return the timer. 00151 */ 00152 WGEAnimationFrameTimer::ConstSPtr getFrameTimer() const; 00153 00154 /** 00155 * Subscribes a specified function to the new-image-signal. This gets emitted every time a new image was grabbed. 00156 * 00157 * \param callback the callback 00158 * 00159 * \return the connection. 00160 */ 00161 boost::signals2::connection subscribeSignal( HandleImageCallbackType callback ); 00162 00163 protected: 00164 /** 00165 * The function handles new images. Implement it. 00166 * 00167 * \param framesLeft how much frames to come 00168 * \param totalFrames the total number of frames until now 00169 * \param image the image 00170 */ 00171 virtual void handleImage( size_t framesLeft, size_t totalFrames, osg::ref_ptr< osg::Image > image ) const; 00172 00173 /** 00174 * Starts recording. If already recording, it continues recording. 00175 * 00176 * \param frames the number of frames to record. 0 means stop, 1 is a single screenshot. 00177 */ 00178 void record( size_t frames = std::numeric_limits< size_t >::max() ); 00179 00180 private: 00181 /** 00182 * Counts the frames to take. 00183 */ 00184 SharedRecordingInformation m_recordingInformation; 00185 00186 /** 00187 * The frame timer. Ticket on each recorded frame. 00188 */ 00189 WGEAnimationFrameTimer::SPtr m_timer; 00190 00191 /** 00192 * The type of the signal for handleSignal. 00193 */ 00194 typedef boost::signals2::signal< void( size_t, size_t, osg::ref_ptr< osg::Image > ) > HandleImageSignalType; 00195 00196 /** 00197 * The signal emitted on every new grabbed image. 00198 */ 00199 HandleImageSignalType m_signalHandleImage; 00200 }; 00201 00202 #endif // WGESCREENCAPTURE_H