Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/modules/designtools/ScreenshotManager.cc @ 8148

Last change on this file since 8148 was 8108, checked in by dafrick, 14 years ago

Merging changes from tetris branch into trunk, since they are also useful, there.

  • Property svn:eol-style set to native
File size: 7.8 KB
Line 
1/* COPYRIGHT: this code comes from http://www.ogre3d.org/wiki/index.php/High_resolution_screenshots */
2
3#include "ScreenshotManager.h"
4
5#include <OgreRenderWindow.h>
6#include <OgreViewport.h>
7#include <OgreRenderTexture.h>
8#include <OgreCamera.h>
9#include <OgreRoot.h>
10
11#include "util/ScopedSingletonManager.h"
12#include "core/GraphicsManager.h"
13#include "core/PathConfig.h"
14#include "core/command/ConsoleCommand.h"
15
16#include "CameraManager.h"
17#include "graphics/Camera.h"
18
19namespace orxonox
20{
21    ManageScopedSingleton(ScreenshotManager, ScopeID::Graphics, false);
22    SetConsoleCommand("printScreenHD", &ScreenshotManager::makeScreenshot_s);
23
24    ScreenshotManager::ScreenshotManager()
25    {
26        Ogre::RenderWindow* pRenderWindow = GraphicsManager::getInstance().getRenderWindow();
27
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);
75        vp->setClearEveryFrame(true);
76        vp->setOverlaysEnabled(false);
77
78        // remind current overlay flag
79        bool enableOverlayFlag = GraphicsManager::getInstance().getViewport()->getOverlaysEnabled();
80
81        // we disable overlay rendering if it is set in config file and the viewport setting is enabled
82        if(mDisableOverlays_ && enableOverlayFlag)
83            GraphicsManager::getInstance().getViewport()->setOverlaysEnabled(false);
84
85        if(mGridSize_ <= 1)
86        {
87            // Simple case where the contents of the screen are taken directly
88            // 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_);
93        }
94        else
95        {
96            //define the original frustum extents variables
97            Ogre::Real originalFrustumLeft, originalFrustumRight, originalFrustumTop, originalFrustumBottom;
98            // set the original Frustum extents
99            camera->getFrustumExtents(originalFrustumLeft, originalFrustumRight, originalFrustumTop, originalFrustumBottom);
100
101            // compute the Stepsize for the drid
102            Ogre::Real frustumGridStepHorizontal  = (originalFrustumRight * 2) / mGridSize_;
103            Ogre::Real frustumGridStepVertical  = (originalFrustumTop * 2) / mGridSize_;
104
105            // process each grid
106            Ogre::Real frustumLeft, frustumRight, frustumTop, frustumBottom;
107            for (unsigned int nbScreenshots = 0; nbScreenshots < mGridSize_ * mGridSize_; nbScreenshots++)
108            {
109                int y = nbScreenshots / mGridSize_;
110                int x = nbScreenshots - y * mGridSize_;
111
112                // Shoggoth frustum extents setting
113                // compute the new frustum extents
114                frustumLeft    = originalFrustumLeft + frustumGridStepHorizontal * x;
115                frustumRight  = frustumLeft + frustumGridStepHorizontal;
116                frustumTop    = originalFrustumTop - frustumGridStepVertical * y;
117                frustumBottom  = frustumTop - frustumGridStepVertical;
118
119                // set the frustum extents value to the camera
120                camera->setFrustumExtents(frustumLeft, frustumRight, frustumTop, frustumBottom);
121
122                // ignore time duration between frames
123                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
132            }
133
134            // set frustum extents to previous settings
135            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?
146        if(enableOverlayFlag)
147            GraphicsManager::getInstance().getViewport()->setOverlaysEnabled(true);
148
149
150        // reset time since last frame to pause the scene
151        Ogre::Root::getSingletonPtr()->clearEventTimes();
152    }
153
154    /**
155    @brief
156        Set the size of the grid.
157    @param size
158        The size of the grid.
159    */
160    void ScreenshotManager::setGridSize(unsigned int size)
161    {
162        if(size == this->mGridSize_)
163            return;
164
165        this->mGridSize_ = size;
166        // 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();
190    }
191
192}
Note: See TracBrowser for help on using the repository browser.