Changeset 8232 for code/trunk/src/modules/designtools/ScreenshotManager.cc
- Timestamp:
- Apr 11, 2011, 7:37:00 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk/src/modules/designtools/ScreenshotManager.cc
r8108 r8232 1 /* COPYRIGHT: this code comes from http://www.ogre3d.org/wiki/index.php/High_resolution_screenshots */ 1 /* 2 * ORXONOX - the hottest 3D action shooter ever to exist 3 * > www.orxonox.net < 4 * 5 * 6 * License notice: 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License 10 * as published by the Free Software Foundation; either version 2 11 * of the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 21 * 22 * Author: 23 * This code comes from http://www.ogre3d.org/tikiwiki/High+resolution+screenshots which is Public Domain. 24 * Co-authors: 25 * Oli Scheuss 26 * Damian 'Mozork' Frick 27 * 28 */ 29 30 /** 31 @file ScreenshotManager.cc 32 @brief Implementation of the ScreenshotManager class. 33 @ingroup Designtools 34 */ 2 35 3 36 #include "ScreenshotManager.h" 4 37 38 #include <OgreCamera.h> 39 #include <OgreRenderTexture.h> 5 40 #include <OgreRenderWindow.h> 41 #include <OgreRoot.h> 6 42 #include <OgreViewport.h> 7 #include <OgreRenderTexture.h> 8 #include <OgreCamera.h> 9 #include <OgreRoot.h> 10 11 #include "util/ScopedSingletonManager.h" 43 // #include <X11/Xlib.h> TODO: Needed? 44 45 #include "core/ConfigValueIncludes.h" 12 46 #include "core/GraphicsManager.h" 13 47 #include "core/PathConfig.h" 14 48 #include "core/command/ConsoleCommand.h" 49 #include "util/ScopedSingletonManager.h" 50 #include "util/StringUtils.h" 15 51 16 52 #include "CameraManager.h" … … 19 55 namespace orxonox 20 56 { 57 58 SetConsoleCommand("printScreenHD", &ScreenshotManager::makeScreenshot_s); 59 21 60 ManageScopedSingleton(ScreenshotManager, ScopeID::Graphics, false); 22 SetConsoleCommand("printScreenHD", &ScreenshotManager::makeScreenshot_s); 23 61 62 /** 63 @brief 64 Constructor. 65 */ 24 66 ScreenshotManager::ScreenshotManager() 25 67 { 68 RegisterRootObject(ScreenshotManager); 69 70 this->setConfigValues(); 71 72 // Flag for overlay rendering 73 this->disableOverlays_ = true; 74 75 // Update the values 76 this->update(); 77 } 78 79 ScreenshotManager::~ScreenshotManager() 80 { 81 82 } 83 84 /** 85 @brief 86 Sets some config values. 87 */ 88 void ScreenshotManager::setConfigValues(void) 89 { 90 // Set file extension for the Screenshot files. 91 SetConfigValue(fileExtension_, ".png"); 92 // The grid size. 93 SetConfigValue(gridSize_, 3); 94 } 95 96 /** 97 @brief 98 Update internal parameters. 99 */ 100 void ScreenshotManager::update(void) 101 { 26 102 Ogre::RenderWindow* pRenderWindow = GraphicsManager::getInstance().getRenderWindow(); 27 103 28 //set file extension for the Screenshot files 29 this->mFileExtension_ = ".png"; 30 // the gridsize 31 this->mGridSize_ = 3; 32 // flag for overlay rendering 33 this->mDisableOverlays_ = true; 34 //get current window size 35 this->mWindowWidth_ = pRenderWindow->getWidth(); 36 this->mWindowHeight_ = pRenderWindow->getHeight(); 37 //create temporary texture 38 this->mTempTex_ = Ogre::TextureManager::getSingleton().createManual("ScreenShotTex", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, this->mWindowWidth_, this->mWindowHeight_, 0, Ogre::PF_B8G8R8, Ogre::TU_RENDERTARGET); 39 40 //get The current Render Target of the temp Texture 41 this->mRT_ = this->mTempTex_->getBuffer()->getRenderTarget(); 42 43 //HardwarePixelBufferSharedPtr to the Buffer of the temp Texture 44 this->mBuffer_ = this->mTempTex_->getBuffer(); 45 46 //create PixelBox 47 uint8_t* data_ = new uint8_t[(this->mWindowWidth_ * this->mGridSize_) * (this->mWindowHeight_ * this->mGridSize_) * 3]; 48 this->mFinalPicturePB_ = Ogre::PixelBox(this->mWindowWidth_ * this->mGridSize_, this->mWindowHeight_ * this->mGridSize_, 1, Ogre::PF_B8G8R8, data_); 49 50 } 51 52 53 ScreenshotManager::~ScreenshotManager() 54 { 55 // Don't delete data_. Somehow this pointer points anywhere but to memory location. 56 //delete[] data_; 57 } 58 59 60 /** 61 @brief 62 Creates a screenshot with the given camera. 63 */ 64 void ScreenshotManager::makeScreenshot() const 65 { 66 Ogre::Camera* camera = CameraManager::getInstance().getActiveCamera()->getOgreCamera(); 67 std::string fileName = PathConfig::getInstance().getLogPathString() + "screenshot_" + this->getTimestamp(); 68 69 //Remove all viewports, so the added Viewport(camera) ist the only 70 mRT_->removeAllViewports(); 71 mRT_->addViewport(camera); 72 73 //set the viewport settings 74 Ogre::Viewport *vp = mRT_->getViewport(0); 104 // If the window size has changed 105 if(this->windowWidth_ != pRenderWindow->getWidth() || this->windowHeight_ != pRenderWindow->getHeight()) 106 { 107 // Update current window size 108 this->windowWidth_ = pRenderWindow->getWidth(); 109 this->windowHeight_ = pRenderWindow->getHeight(); 110 111 // Create temporary texture 112 this->tempTexture_ = Ogre::TextureManager::getSingleton().createManual("ScreenShotTex", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, this->windowWidth_, this->windowHeight_, 0, Ogre::PF_B8G8R8, Ogre::TU_RENDERTARGET); 113 114 // Get the current render target of the temporary texture 115 this->renderTarget_ = this->tempTexture_->getBuffer()->getRenderTarget(); 116 117 // HardwarePixelBufferSharedPtr to the buffer of the temporary texture 118 this->buffer_ = this->tempTexture_->getBuffer(); 119 120 // Create PixelBox 121 this->data_ = new uint8_t[(this->windowWidth_ * this->gridSize_) * (this->windowHeight_ * this->gridSize_) * 3]; 122 this->finalPicturePB_ = Ogre::PixelBox(this->windowWidth_ * this->gridSize_, this->windowHeight_ * this->gridSize_, 1, Ogre::PF_B8G8R8, this->data_); 123 } 124 } 125 126 127 /** 128 @brief 129 Make a screenshot. 130 The screenshot is saved in the log folder. 131 */ 132 void ScreenshotManager::makeScreenshot() 133 { 134 // Get the screenshot. 135 Ogre::Image* finalImage = getScreenshot(); 136 if(finalImage != NULL) 137 { 138 // Save it. 139 finalImage->save(PathConfig::getInstance().getLogPathString() + "screenshot_" + getTimestamp() + "." + this->fileExtension_); 140 delete finalImage; 141 COUT(3) << "Finished taking " << this->gridSize_*this->windowWidth_ << "x" << this->gridSize_*this->windowHeight_ << " pixel HD screenshot. Storing in log/." << endl; 142 } 143 else 144 { 145 COUT(1) << "There needs to be an active camera to make screenshots." << endl; 146 return; 147 } 148 } 149 150 /** 151 @brief 152 Creates a screenshot and returns it. 153 @return 154 Returns a pointer to an Ogre::Image with the screenshot. 155 */ 156 Ogre::Image* ScreenshotManager::getScreenshot() 157 { 158 if(CameraManager::getInstance().getActiveCamera() == NULL ) 159 return NULL; 160 return this->getScreenshot(CameraManager::getInstance().getActiveCamera()->getOgreCamera()); 161 } 162 163 /** 164 @brief 165 Creates a screenshot with the given camera and returns it. 166 @param camera 167 A pointer to the camera the screenshot should be taken with. 168 @return 169 Returns a pointer to an Ogre::Image with the screenshot. 170 */ 171 Ogre::Image* ScreenshotManager::getScreenshot(Ogre::Camera* camera) 172 { 173 if(camera == NULL) 174 return NULL; 175 176 // Update the internal parameters. 177 this->update(); 178 179 // Add the camera as viewport. 180 this->renderTarget_->removeAllViewports(); 181 this->renderTarget_->addViewport(camera); 182 183 // Set the viewport settings 184 Ogre::Viewport *vp = renderTarget_->getViewport(0); 75 185 vp->setClearEveryFrame(true); 76 186 vp->setOverlaysEnabled(false); 77 187 78 // remind current overlay flag188 // Remind current overlay flag 79 189 bool enableOverlayFlag = GraphicsManager::getInstance().getViewport()->getOverlaysEnabled(); 80 81 // we disable overlay rendering if it is set in config file and the viewport setting is enabled82 if( mDisableOverlays_ && enableOverlayFlag)190 191 // We disable overlay rendering if it is set in config file and the viewport setting is enabled 192 if(this->disableOverlays_ && enableOverlayFlag) 83 193 GraphicsManager::getInstance().getViewport()->setOverlaysEnabled(false); 84 85 if(mGridSize_ <= 1) 194 195 Ogre::Image* finalImage = new Ogre::Image(); 196 197 if(this->gridSize_ <= 1) 86 198 { 87 199 // Simple case where the contents of the screen are taken directly 88 200 // Also used when an invalid value is passed within gridSize (zero or negative grid size) 89 mRT_->update(); //render 90 91 //write the file on the Harddisk 92 mRT_->writeContentsToFile(fileName + "." + mFileExtension_); 201 this->renderTarget_->update(); // Render 202 203 finalImage = &finalImage->loadDynamicImage(static_cast<unsigned char*>(finalPicturePB_.data), finalPicturePB_.getWidth(), finalPicturePB_.getHeight(),Ogre::PF_B8G8R8); 93 204 } 94 205 else 95 206 { 96 // define the original frustum extents variables207 // Define the original frustum extents variables 97 208 Ogre::Real originalFrustumLeft, originalFrustumRight, originalFrustumTop, originalFrustumBottom; 98 // set the original Frustum extents209 // Set the original Frustum extents 99 210 camera->getFrustumExtents(originalFrustumLeft, originalFrustumRight, originalFrustumTop, originalFrustumBottom); 100 101 // compute the Stepsize for the drid102 Ogre::Real frustumGridStepHorizontal = (originalFrustumRight * 2) / mGridSize_;103 Ogre::Real frustumGridStepVertical = (originalFrustumTop * 2) / mGridSize_;104 105 // process each grid211 212 // Compute the Stepsize for the grid 213 Ogre::Real frustumGridStepHorizontal = (originalFrustumRight * 2) / this->gridSize_; 214 Ogre::Real frustumGridStepVertical = (originalFrustumTop * 2) / this->gridSize_; 215 216 // Process each grid 106 217 Ogre::Real frustumLeft, frustumRight, frustumTop, frustumBottom; 107 for (unsigned int nbScreenshots = 0; nbScreenshots < mGridSize_ * mGridSize_; nbScreenshots++)218 for (unsigned int nbScreenshots = 0; nbScreenshots < this->gridSize_ * this->gridSize_; nbScreenshots++) 108 219 { 109 int y = nbScreenshots / mGridSize_;110 int x = nbScreenshots - y * mGridSize_;111 220 int y = nbScreenshots / this->gridSize_; 221 int x = nbScreenshots - y * this->gridSize_; 222 112 223 // Shoggoth frustum extents setting 113 // compute the new frustum extents224 // Compute the new frustum extents 114 225 frustumLeft = originalFrustumLeft + frustumGridStepHorizontal * x; 115 226 frustumRight = frustumLeft + frustumGridStepHorizontal; 116 227 frustumTop = originalFrustumTop - frustumGridStepVertical * y; 117 228 frustumBottom = frustumTop - frustumGridStepVertical; 118 119 // set the frustum extents value to the camera229 230 // Set the frustum extents value to the camera 120 231 camera->setFrustumExtents(frustumLeft, frustumRight, frustumTop, frustumBottom); 121 122 // ignore time duration between frames232 233 // Ignore time duration between frames 123 234 Ogre::Root::getSingletonPtr()->clearEventTimes(); 124 mRT_->update(); //render 125 126 //define the current 127 Ogre::Box subBox = Ogre::Box(x* mWindowWidth_,y * mWindowHeight_,x * mWindowWidth_ + mWindowWidth_, y * mWindowHeight_ + mWindowHeight_); 128 //copy the content from the temp buffer into the final picture PixelBox 129 //Place the tempBuffer content at the right position 130 mBuffer_->blitToMemory(mFinalPicturePB_.getSubVolume(subBox)); 131 235 this->renderTarget_->update(); // Render 236 237 // Define the current box 238 Ogre::Box subBox = Ogre::Box(x* this->windowWidth_,y * this->windowHeight_,x * this->windowWidth_ + this->windowWidth_, y * this->windowHeight_ + this->windowHeight_); 239 // Copy the content from the temp buffer into the final picture PixelBox 240 // Place the tempBuffer content at the right position 241 this->buffer_->blitToMemory(this->finalPicturePB_.getSubVolume(subBox)); 242 243 COUT(4) << "Created screenshot number " << nbScreenshots << " for multi grid HD screenshot." << endl; 244 132 245 } 133 134 // set frustum extents to previous settings246 247 // Set frustum extents to previous settings 135 248 camera->resetFrustumExtents(); 136 137 Ogre::Image finalImage; //declare the final Image Object 138 //insert the PixelBox data into the Image Object 139 finalImage = finalImage.loadDynamicImage(static_cast<unsigned char*>(mFinalPicturePB_.data), mFinalPicturePB_.getWidth(), mFinalPicturePB_.getHeight(),Ogre::PF_B8G8R8); 140 // Save the Final image to a file 141 finalImage.save(fileName + "." + mFileExtension_); 142 143 } 144 145 // do we have to re-enable our overlays? 249 250 // Insert the PixelBox data into the Image Object 251 finalImage->loadDynamicImage(static_cast<unsigned char*>(this->finalPicturePB_.data), this->finalPicturePB_.getWidth(), this->finalPicturePB_.getHeight(), 1, Ogre::PF_B8G8R8, false); 252 } 253 254 // Do we have to re-enable our overlays? 146 255 if(enableOverlayFlag) 147 256 GraphicsManager::getInstance().getViewport()->setOverlaysEnabled(true); 148 149 150 // reset time since last frame to pause the scene 257 258 // Reset time since last frame to pause the scene 151 259 Ogre::Root::getSingletonPtr()->clearEventTimes(); 260 261 return finalImage; 152 262 } 153 263 … … 160 270 void ScreenshotManager::setGridSize(unsigned int size) 161 271 { 162 if(size == this-> mGridSize_)272 if(size == this->gridSize_) 163 273 return; 164 274 165 this-> mGridSize_ = size;275 this->gridSize_ = size; 166 276 // New PixelBox for the changed size. 167 uint8_t* data_ = new uint8_t[(this->mWindowWidth_ * this->mGridSize_) * (this->mWindowHeight_ * this->mGridSize_) * 3]; 168 this->mFinalPicturePB_ = Ogre::PixelBox(this->mWindowWidth_ * this->mGridSize_, this->mWindowHeight_ * this->mGridSize_, 1, Ogre::PF_B8G8R8, data_); 169 } 170 171 /** 172 @brief 173 Get a timestamp for the curent time instant. 174 @return 175 Returns a string with the timestamp. 176 */ 177 std::string ScreenshotManager::getTimestamp() 178 { 179 struct tm *pTime; 180 time_t ctTime; time(&ctTime); 181 pTime = localtime( &ctTime ); 182 std::ostringstream oss; 183 oss << std::setw(2) << std::setfill('0') << (pTime->tm_mon + 1) 184 << std::setw(2) << std::setfill('0') << pTime->tm_mday 185 << std::setw(2) << std::setfill('0') << (pTime->tm_year + 1900) 186 << "_" << std::setw(2) << std::setfill('0') << pTime->tm_hour 187 << std::setw(2) << std::setfill('0') << pTime->tm_min 188 << std::setw(2) << std::setfill('0') << pTime->tm_sec; 189 return oss.str(); 277 this->data_ = new uint8_t[(this->windowWidth_ * this->gridSize_) * (this->windowHeight_ * this->gridSize_) * 3]; 278 this->finalPicturePB_ = Ogre::PixelBox(this->windowWidth_ * this->gridSize_, this->windowHeight_ * this->gridSize_, 1, Ogre::PF_B8G8R8, this->data_); 190 279 } 191 280
Note: See TracChangeset
for help on using the changeset viewer.