Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/gameimmersion/src/modules/designtools/ScreenshotManager.cc @ 8263

Last change on this file since 8263 was 8079, checked in by landauf, 14 years ago

merged usability branch back to trunk

incomplete summary of the changes in this branch:

  • enhanced keyboard navigation in GUIs
  • implemented new graphics menu and changeable window size at runtime
  • added developer mode
  • HUD shows if game is paused, game pauses if ingame menu is opened
  • removed a few obsolete commands and hid some that are more for internal use
  • numpad works in console and gui
  • faster loading of level info
  • enhanced usage of compositors (Shader class)
  • improved camera handling, configurable FOV and aspect ratio
  • Property svn:eol-style set to native
File size: 7.9 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    @param camera
64        Pointer to the camera "looking at" the scene of interest
65    @param fileName
66        the filename of the screenshot file.
67    */
68    void ScreenshotManager::makeScreenshot() const
69    {
70        Ogre::Camera* camera = CameraManager::getInstance().getActiveCamera()->getOgreCamera();
71        std::string fileName = PathConfig::getInstance().getLogPathString() + "screenshot_" + this->getTimestamp();
72
73        //Remove all viewports, so the added Viewport(camera) ist the only
74        mRT_->removeAllViewports();
75        mRT_->addViewport(camera);
76
77        //set the viewport settings
78        Ogre::Viewport *vp = mRT_->getViewport(0);
79        vp->setClearEveryFrame(true);
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
86        if(mDisableOverlays_ && enableOverlayFlag)
87            GraphicsManager::getInstance().getViewport()->setOverlaysEnabled(false);
88
89        if(mGridSize_ <= 1)
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)
93            mRT_->update();    //render
94
95            //write the file on the Harddisk
96            mRT_->writeContentsToFile(fileName + "." + mFileExtension_);
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);
104
105            // compute the Stepsize for the drid
106            Ogre::Real frustumGridStepHorizontal  = (originalFrustumRight * 2) / mGridSize_;
107            Ogre::Real frustumGridStepVertical  = (originalFrustumTop * 2) / mGridSize_;
108
109            // process each grid
110            Ogre::Real frustumLeft, frustumRight, frustumTop, frustumBottom;
111            for (unsigned int nbScreenshots = 0; nbScreenshots < mGridSize_ * mGridSize_; nbScreenshots++)
112            {
113                int y = nbScreenshots / mGridSize_;
114                int x = nbScreenshots - y * mGridSize_;
115
116                // Shoggoth frustum extents setting
117                // compute the new frustum extents
118                frustumLeft    = originalFrustumLeft + frustumGridStepHorizontal * x;
119                frustumRight  = frustumLeft + frustumGridStepHorizontal;
120                frustumTop    = originalFrustumTop - frustumGridStepVertical * y;
121                frustumBottom  = frustumTop - frustumGridStepVertical;
122
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();
128                mRT_->update();    //render
129
130                //define the current
131                Ogre::Box subBox = Ogre::Box(x* mWindowWidth_,y * mWindowHeight_,x * mWindowWidth_ + mWindowWidth_, y * mWindowHeight_ + mWindowHeight_);
132                //copy the content from the temp buffer into the final picture PixelBox
133                //Place the tempBuffer content at the right position
134                mBuffer_->blitToMemory(mFinalPicturePB_.getSubVolume(subBox));
135
136            }
137
138            // set frustum extents to previous settings
139            camera->resetFrustumExtents();
140
141            Ogre::Image finalImage; //declare the final Image Object
142            //insert the PixelBox data into the Image Object
143            finalImage = finalImage.loadDynamicImage(static_cast<unsigned char*>(mFinalPicturePB_.data), mFinalPicturePB_.getWidth(), mFinalPicturePB_.getHeight(),Ogre::PF_B8G8R8);
144            // Save the Final image to a file
145            finalImage.save(fileName + "." + mFileExtension_);
146
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
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    */
181    std::string ScreenshotManager::getTimestamp()
182    {
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;
193        return oss.str();
194    }
195
196}
Note: See TracBrowser for help on using the repository browser.