Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/usability/src/modules/designtools/ScreenshotManager.cc @ 8501

Last change on this file since 8501 was 8077, checked in by dafrick, 14 years ago

Improving documentation of ScreenshotManager.

  • Property svn:eol-style set to native
File size: 7.9 KB
RevLine 
[7015]1/* COPYRIGHT: this code comes from http://www.ogre3d.org/wiki/index.php/High_resolution_screenshots */
2
3#include "ScreenshotManager.h"
[7041]4
[7015]5#include <OgreRenderWindow.h>
6#include <OgreViewport.h>
7#include <OgreRenderTexture.h>
8#include <OgreCamera.h>
9#include <OgreRoot.h>
10
[7284]11#include "util/ScopedSingletonManager.h"
[7015]12#include "core/GraphicsManager.h"
[7041]13#include "core/PathConfig.h"
[7284]14#include "core/command/ConsoleCommand.h"
[7015]15
[7041]16#include "CameraManager.h"
17#include "graphics/Camera.h"
[7015]18
19namespace orxonox
20{
[7041]21    ManageScopedSingleton(ScreenshotManager, ScopeID::Graphics, false);
[7284]22    SetConsoleCommand("printScreenHD", &ScreenshotManager::makeScreenshot_s);
[7015]23
[7041]24    ScreenshotManager::ScreenshotManager()
[7015]25    {
[7041]26        Ogre::RenderWindow* pRenderWindow = GraphicsManager::getInstance().getRenderWindow();
27
[7015]28        //set file extension for the Screenshot files
[8076]29        this->mFileExtension_  = ".png";
[7015]30        // the gridsize
[8076]31        this->mGridSize_ = 3;
[7015]32        // flag for overlay rendering
[8076]33        this->mDisableOverlays_ = true;
[7015]34        //get current window size
[8076]35        this->mWindowWidth_   = pRenderWindow->getWidth();
36        this->mWindowHeight_  = pRenderWindow->getHeight();
[7015]37        //create temporary texture
[8076]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);
[7076]39
[7015]40        //get The current Render Target of the temp Texture
[8076]41        this->mRT_ = this->mTempTex_->getBuffer()->getRenderTarget();
[7015]42
[7076]43        //HardwarePixelBufferSharedPtr to the Buffer of the temp Texture
[8076]44        this->mBuffer_ = this->mTempTex_->getBuffer();
[7015]45
46        //create PixelBox
[8076]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_);
[7015]49
50    }
51
52
53    ScreenshotManager::~ScreenshotManager()
54    {
[7041]55        // Don't delete data_. Somehow this pointer points anywhere but to memory location.
56        //delete[] data_;
[7015]57    }
58
59
[8076]60    /**
[8077]61    @brief
62        Creates a screenshot with the given camera.
63    @param camera
64        Pointer to the camera "looking at" the scene of interest
65    @param fileName
66        the filename of the screenshot file.
67    */
[7041]68    void ScreenshotManager::makeScreenshot() const
[7015]69    {
[7041]70        Ogre::Camera* camera = CameraManager::getInstance().getActiveCamera()->getOgreCamera();
71        std::string fileName = PathConfig::getInstance().getLogPathString() + "screenshot_" + this->getTimestamp();
[7015]72
[7076]73        //Remove all viewports, so the added Viewport(camera) ist the only
[8076]74        mRT_->removeAllViewports();
75        mRT_->addViewport(camera);
[7076]76
[7015]77        //set the viewport settings
[8076]78        Ogre::Viewport *vp = mRT_->getViewport(0);
[7076]79        vp->setClearEveryFrame(true);
[7015]80        vp->setOverlaysEnabled(false);
81
82        // remind current overlay flag
83        bool enableOverlayFlag = GraphicsManager::getInstance().getViewport()->getOverlaysEnabled();
84
85        // we disable overlay rendering if it is set in config file and the viewport setting is enabled
[8076]86        if(mDisableOverlays_ && enableOverlayFlag)
[7015]87            GraphicsManager::getInstance().getViewport()->setOverlaysEnabled(false);
88
[8076]89        if(mGridSize_ <= 1)
[7015]90        {
91            // Simple case where the contents of the screen are taken directly
92            // Also used when an invalid value is passed within gridSize (zero or negative grid size)
[8076]93            mRT_->update();    //render
[7015]94
95            //write the file on the Harddisk
[8076]96            mRT_->writeContentsToFile(fileName + "." + mFileExtension_);
[7015]97        }
98        else
99        {
100            //define the original frustum extents variables
101            Ogre::Real originalFrustumLeft, originalFrustumRight, originalFrustumTop, originalFrustumBottom;
102            // set the original Frustum extents
103            camera->getFrustumExtents(originalFrustumLeft, originalFrustumRight, originalFrustumTop, originalFrustumBottom);
[7076]104
[7015]105            // compute the Stepsize for the drid
[8076]106            Ogre::Real frustumGridStepHorizontal  = (originalFrustumRight * 2) / mGridSize_;
107            Ogre::Real frustumGridStepVertical  = (originalFrustumTop * 2) / mGridSize_;
[7015]108
109            // process each grid
110            Ogre::Real frustumLeft, frustumRight, frustumTop, frustumBottom;
[8076]111            for (unsigned int nbScreenshots = 0; nbScreenshots < mGridSize_ * mGridSize_; nbScreenshots++)
[7076]112            {
[8076]113                int y = nbScreenshots / mGridSize_;
114                int x = nbScreenshots - y * mGridSize_;
[7076]115
[7015]116                // Shoggoth frustum extents setting
117                // compute the new frustum extents
[7039]118                frustumLeft    = originalFrustumLeft + frustumGridStepHorizontal * x;
119                frustumRight  = frustumLeft + frustumGridStepHorizontal;
120                frustumTop    = originalFrustumTop - frustumGridStepVertical * y;
121                frustumBottom  = frustumTop - frustumGridStepVertical;
[7076]122
[7015]123                // set the frustum extents value to the camera
124                camera->setFrustumExtents(frustumLeft, frustumRight, frustumTop, frustumBottom);
125
126                // ignore time duration between frames
127                Ogre::Root::getSingletonPtr()->clearEventTimes();
[8076]128                mRT_->update();    //render
[7076]129
130                //define the current
[8076]131                Ogre::Box subBox = Ogre::Box(x* mWindowWidth_,y * mWindowHeight_,x * mWindowWidth_ + mWindowWidth_, y * mWindowHeight_ + mWindowHeight_);
[7076]132                //copy the content from the temp buffer into the final picture PixelBox
[7015]133                //Place the tempBuffer content at the right position
[8076]134                mBuffer_->blitToMemory(mFinalPicturePB_.getSubVolume(subBox));
[7015]135
136            }
[7076]137
[7015]138            // set frustum extents to previous settings
139            camera->resetFrustumExtents();
[7076]140
[7015]141            Ogre::Image finalImage; //declare the final Image Object
142            //insert the PixelBox data into the Image Object
[8076]143            finalImage = finalImage.loadDynamicImage(static_cast<unsigned char*>(mFinalPicturePB_.data), mFinalPicturePB_.getWidth(), mFinalPicturePB_.getHeight(),Ogre::PF_B8G8R8);
[7015]144            // Save the Final image to a file
[8076]145            finalImage.save(fileName + "." + mFileExtension_);
[7076]146
[7015]147        }
148
149        // do we have to re-enable our overlays?
150        if(enableOverlayFlag)
151            GraphicsManager::getInstance().getViewport()->setOverlaysEnabled(true);
152
153
154        // reset time since last frame to pause the scene
155        Ogre::Root::getSingletonPtr()->clearEventTimes();
156    }
157
[8077]158    /**
159    @brief
160        Set the size of the grid.
161    @param size
162        The size of the grid.
163    */
164    void ScreenshotManager::setGridSize(unsigned int size)
165    {
166        if(size == this->mGridSize_)
167            return;
168
169        this->mGridSize_ = size;
170        // New PixelBox for the changed size.
171        uint8_t* data_ = new uint8_t[(this->mWindowWidth_ * this->mGridSize_) * (this->mWindowHeight_ * this->mGridSize_) * 3];
172        this->mFinalPicturePB_ = Ogre::PixelBox(this->mWindowWidth_ * this->mGridSize_, this->mWindowHeight_ * this->mGridSize_, 1, Ogre::PF_B8G8R8, data_);
173    }
174
175    /**
176    @brief
177        Get a timestamp for the curent time instant.
178    @return
179        Returns a string with the timestamp.
180    */
[7041]181    std::string ScreenshotManager::getTimestamp()
182    {
[7129]183        struct tm *pTime;
184        time_t ctTime; time(&ctTime);
185        pTime = localtime( &ctTime );
186        std::ostringstream oss;
187        oss << std::setw(2) << std::setfill('0') << (pTime->tm_mon + 1)
188            << std::setw(2) << std::setfill('0') << pTime->tm_mday
189            << std::setw(2) << std::setfill('0') << (pTime->tm_year + 1900)
190            << "_" << std::setw(2) << std::setfill('0') << pTime->tm_hour
191            << std::setw(2) << std::setfill('0') << pTime->tm_min
192            << std::setw(2) << std::setfill('0') << pTime->tm_sec;
[7041]193        return oss.str();
194    }
195
[7015]196}
Note: See TracBrowser for help on using the repository browser.