Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/environment2/src/modules/designtools/ScreenshotManager.cc @ 8474

Last change on this file since 8474 was 8351, checked in by rgrieder, 14 years ago

Merged kicklib2 branch back to trunk (includes former branches ois_update, mac_osx and kicklib).

Notes for updating

Linux:
You don't need an extra package for CEGUILua and Tolua, it's already shipped with CEGUI.
However you do need to make sure that the OgreRenderer is installed too with CEGUI 0.7 (may be a separate package).
Also, Orxonox now recognises if you install the CgProgramManager (a separate package available on newer Ubuntu on Debian systems).

Windows:
Download the new dependency packages versioned 6.0 and use these. If you have problems with that or if you don't like the in game console problem mentioned below, you can download the new 4.3 version of the packages (only available for Visual Studio 2005/2008).

Key new features:

  • *Support for Mac OS X*
  • Visual Studio 2010 support
  • Bullet library update to 2.77
  • OIS library update to 1.3
  • Support for CEGUI 0.7 —> Support for Arch Linux and even SuSE
  • Improved install target
  • Compiles now with GCC 4.6
  • Ogre Cg Shader plugin activated for Linux if available
  • And of course lots of bug fixes

There are also some regressions:

  • No support for CEGUI 0.5, Ogre 1.4 and boost 1.35 - 1.39 any more
  • In game console is not working in main menu for CEGUI 0.7
  • Tolua (just the C lib, not the application) and CEGUILua libraries are no longer in our repository. —> You will need to get these as well when compiling Orxonox
  • And of course lots of new bugs we don't yet know about
  • Property svn:eol-style set to native
File size: 10.5 KB
Line 
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*/
35
36#include "ScreenshotManager.h"
37
38#include <OgreCamera.h>
39#include <OgreRenderTexture.h>
40#include <OgreRenderWindow.h>
41#include <OgreRoot.h>
42#include <OgreViewport.h>
43
44#include "core/ConfigValueIncludes.h"
45#include "core/GraphicsManager.h"
46#include "core/PathConfig.h"
47#include "core/Resource.h"
48#include "core/command/ConsoleCommand.h"
49#include "util/ScopedSingletonManager.h"
50#include "util/StringUtils.h"
51
52#include "CameraManager.h"
53#include "graphics/Camera.h"
54
55// #include <X11/Xlib.h> TODO: Needed?
56
57namespace orxonox
58{
59
60    SetConsoleCommand("printScreenHD", &ScreenshotManager::makeScreenshot_s);
61   
62    ManageScopedSingleton(ScreenshotManager, ScopeID::Graphics, false);
63
64    /**
65    @brief
66        Constructor.
67    */
68    ScreenshotManager::ScreenshotManager()
69    {
70        RegisterRootObject(ScreenshotManager);
71       
72        this->setConfigValues();
73
74        // Flag for overlay rendering
75        this->disableOverlays_ = true;
76
77        // Update the values
78        this->update();
79    }
80
81    ScreenshotManager::~ScreenshotManager()
82    {
83       
84    }
85   
86    /**
87    @brief
88        Sets some config values.
89    */
90    void ScreenshotManager::setConfigValues(void)
91    {
92        // Set file extension for the Screenshot files.
93        SetConfigValue(fileExtension_, ".png");
94        // The grid size.
95        SetConfigValue(gridSize_, 3);
96    }
97
98    /**
99    @brief
100        Update internal parameters.
101    */
102    void ScreenshotManager::update(void)
103    {
104        Ogre::RenderWindow* pRenderWindow = GraphicsManager::getInstance().getRenderWindow();
105
106        // If the window size has changed
107        if(this->windowWidth_ != pRenderWindow->getWidth() || this->windowHeight_ != pRenderWindow->getHeight())
108        {
109            // Update current window size
110            this->windowWidth_   = pRenderWindow->getWidth();
111            this->windowHeight_  = pRenderWindow->getHeight();
112
113            // Create temporary texture
114            this->tempTexture_ = Ogre::TextureManager::getSingleton().createManual("ScreenShotTex",
115                Resource::getDefaultResourceGroup(), Ogre::TEX_TYPE_2D, this->windowWidth_,
116                this->windowHeight_, 0, Ogre::PF_B8G8R8, Ogre::TU_RENDERTARGET);
117
118            // Get the current render target of the temporary texture
119            this->renderTarget_ = this->tempTexture_->getBuffer()->getRenderTarget();
120
121            // HardwarePixelBufferSharedPtr to the buffer of the temporary texture
122            this->buffer_ = this->tempTexture_->getBuffer();
123
124            // Create PixelBox
125            this->data_ = new uint8_t[(this->windowWidth_ * this->gridSize_) * (this->windowHeight_ * this->gridSize_) * 3];
126            this->finalPicturePB_ = Ogre::PixelBox(this->windowWidth_ * this->gridSize_, this->windowHeight_ * this->gridSize_, 1, Ogre::PF_B8G8R8, this->data_);
127        }
128    }
129
130
131    /**
132    @brief
133        Make a screenshot.
134        The screenshot is saved in the log folder.
135    */
136    void ScreenshotManager::makeScreenshot()
137    {
138        // Get the screenshot.
139        Ogre::Image* finalImage = getScreenshot();
140        if(finalImage != NULL)
141        {
142            // Save it.
143            finalImage->save(PathConfig::getInstance().getLogPathString() + "screenshot_" + getTimestamp() + "." + this->fileExtension_);
144            delete finalImage;
145            COUT(3) << "Finished taking " << this->gridSize_*this->windowWidth_ << "x" << this->gridSize_*this->windowHeight_ << " pixel HD screenshot. Storing in log/." << endl;
146        }
147        else
148        {
149            COUT(1) << "There needs to be an active camera to make screenshots." << endl;
150            return;
151        }
152    }
153
154    /**
155    @brief
156        Creates a screenshot and returns it.
157    @return
158        Returns a pointer to an Ogre::Image with the screenshot.
159    */
160    Ogre::Image* ScreenshotManager::getScreenshot()
161    {
162        if(CameraManager::getInstance().getActiveCamera() == NULL )
163            return NULL;
164        return this->getScreenshot(CameraManager::getInstance().getActiveCamera()->getOgreCamera());
165    }
166
167    /**
168    @brief
169        Creates a screenshot with the given camera and returns it.
170    @param camera
171        A pointer to the camera the screenshot should be taken with.
172    @return
173        Returns a pointer to an Ogre::Image with the screenshot.
174    */
175    Ogre::Image* ScreenshotManager::getScreenshot(Ogre::Camera* camera)
176    {
177        if(camera == NULL)
178            return NULL;
179       
180        // Update the internal parameters.
181        this->update();
182
183        // Add the camera as viewport.
184        this->renderTarget_->removeAllViewports();
185        this->renderTarget_->addViewport(camera);
186
187        // Set the viewport settings
188        Ogre::Viewport *vp = renderTarget_->getViewport(0);
189        vp->setClearEveryFrame(true);
190        vp->setOverlaysEnabled(false);
191
192        // Remind current overlay flag
193        bool enableOverlayFlag = GraphicsManager::getInstance().getViewport()->getOverlaysEnabled();
194       
195        // We disable overlay rendering if it is set in config file and the viewport setting is enabled
196        if(this->disableOverlays_ && enableOverlayFlag)
197            GraphicsManager::getInstance().getViewport()->setOverlaysEnabled(false);
198       
199        Ogre::Image* finalImage = new Ogre::Image();
200       
201        if(this->gridSize_ <= 1)
202        {
203            // Simple case where the contents of the screen are taken directly
204            // Also used when an invalid value is passed within gridSize (zero or negative grid size)
205            this->renderTarget_->update(); // Render
206           
207            finalImage = &finalImage->loadDynamicImage(static_cast<unsigned char*>(finalPicturePB_.data), finalPicturePB_.getWidth(), finalPicturePB_.getHeight(),Ogre::PF_B8G8R8);
208        }
209        else
210        {
211            // Define the original frustum extents variables
212            Ogre::Real originalFrustumLeft, originalFrustumRight, originalFrustumTop, originalFrustumBottom;
213            // Set the original Frustum extents
214            camera->getFrustumExtents(originalFrustumLeft, originalFrustumRight, originalFrustumTop, originalFrustumBottom);
215           
216            // Compute the Stepsize for the grid
217            Ogre::Real frustumGridStepHorizontal  = (originalFrustumRight * 2) / this->gridSize_;
218            Ogre::Real frustumGridStepVertical  = (originalFrustumTop * 2) / this->gridSize_;
219           
220            // Process each grid
221            Ogre::Real frustumLeft, frustumRight, frustumTop, frustumBottom;
222            for (unsigned int nbScreenshots = 0; nbScreenshots < this->gridSize_ * this->gridSize_; nbScreenshots++)
223            {
224                int y = nbScreenshots / this->gridSize_;
225                int x = nbScreenshots - y * this->gridSize_;
226               
227                // Shoggoth frustum extents setting
228                // Compute the new frustum extents
229                frustumLeft    = originalFrustumLeft + frustumGridStepHorizontal * x;
230                frustumRight  = frustumLeft + frustumGridStepHorizontal;
231                frustumTop    = originalFrustumTop - frustumGridStepVertical * y;
232                frustumBottom  = frustumTop - frustumGridStepVertical;
233               
234                // Set the frustum extents value to the camera
235                camera->setFrustumExtents(frustumLeft, frustumRight, frustumTop, frustumBottom);
236               
237                // Ignore time duration between frames
238                Ogre::Root::getSingletonPtr()->clearEventTimes();
239                this->renderTarget_->update(); // Render
240               
241                // Define the current box
242                Ogre::Box subBox = Ogre::Box(x* this->windowWidth_,y * this->windowHeight_,x * this->windowWidth_ + this->windowWidth_, y * this->windowHeight_ + this->windowHeight_);
243                // Copy the content from the temp buffer into the final picture PixelBox
244                // Place the tempBuffer content at the right position
245                this->buffer_->blitToMemory(this->finalPicturePB_.getSubVolume(subBox));
246               
247                COUT(4) << "Created screenshot number " << nbScreenshots << " for multi grid HD screenshot." << endl;
248               
249            }
250           
251            // Set frustum extents to previous settings
252            camera->resetFrustumExtents();
253           
254            // Insert the PixelBox data into the Image Object
255            finalImage->loadDynamicImage(static_cast<unsigned char*>(this->finalPicturePB_.data), this->finalPicturePB_.getWidth(), this->finalPicturePB_.getHeight(), 1, Ogre::PF_B8G8R8, false);
256        }
257       
258        // Do we have to re-enable our overlays?
259        if(enableOverlayFlag)
260            GraphicsManager::getInstance().getViewport()->setOverlaysEnabled(true);
261       
262        // Reset time since last frame to pause the scene
263        Ogre::Root::getSingletonPtr()->clearEventTimes();
264       
265        return finalImage;
266    }
267
268    /**
269    @brief
270        Set the size of the grid.
271    @param size
272        The size of the grid.
273    */
274    void ScreenshotManager::setGridSize(unsigned int size)
275    {
276        if(size == this->gridSize_)
277            return;
278
279        this->gridSize_ = size;
280        // New PixelBox for the changed size.
281        this->data_ = new uint8_t[(this->windowWidth_ * this->gridSize_) * (this->windowHeight_ * this->gridSize_) * 3];
282        this->finalPicturePB_ = Ogre::PixelBox(this->windowWidth_ * this->gridSize_, this->windowHeight_ * this->gridSize_, 1, Ogre::PF_B8G8R8, this->data_);
283    }
284
285}
Note: See TracBrowser for help on using the repository browser.