[Orxonox-commit 3546] r8232 - in code/trunk: data/gui/scripts src/libraries/util src/modules/designtools

dafrick at orxonox.net dafrick at orxonox.net
Mon Apr 11 19:37:01 CEST 2011


Author: dafrick
Date: 2011-04-11 19:37:00 +0200 (Mon, 11 Apr 2011)
New Revision: 8232

Modified:
   code/trunk/data/gui/scripts/KeyBindMenu.lua
   code/trunk/src/libraries/util/StringUtils.cc
   code/trunk/src/libraries/util/StringUtils.h
   code/trunk/src/modules/designtools/ScreenshotManager.cc
   code/trunk/src/modules/designtools/ScreenshotManager.h
   code/trunk/src/modules/designtools/SkyboxGenerator.cc
   code/trunk/src/modules/designtools/SkyboxGenerator.h
Log:
Extending and reorganizing ScreenshotManager and SkyboxGenerator.
The SkyboxGenerator now takes HD screenshots, thus the size of the faces generated by the SkyboxGenerator can now be specified freely (through a config value).


Modified: code/trunk/data/gui/scripts/KeyBindMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/KeyBindMenu.lua	2011-04-11 04:39:04 UTC (rev 8231)
+++ code/trunk/data/gui/scripts/KeyBindMenu.lua	2011-04-11 17:37:00 UTC (rev 8232)
@@ -36,7 +36,8 @@
     table.insert(commandList, "pause")
     table.insert(commandList, "printScreen")
     if orxonox.GUIManager:inDevMode() then
-        table.insert(commandList, "printScreenHD 3")
+        table.insert(commandList, "printScreenHD")
+        table.insert(commandList, "createSkybox")
     end
 
     nameList = {}
@@ -71,6 +72,7 @@
     table.insert(nameList, "Screenshot")
     if orxonox.GUIManager:inDevMode() then
         table.insert(nameList, "HD screenshot")
+        table.insert(nameList, "Create Skybox")
     end
 
     linesList = {}

Modified: code/trunk/src/libraries/util/StringUtils.cc
===================================================================
--- code/trunk/src/libraries/util/StringUtils.cc	2011-04-11 04:39:04 UTC (rev 8231)
+++ code/trunk/src/libraries/util/StringUtils.cc	2011-04-11 17:37:00 UTC (rev 8232)
@@ -34,6 +34,7 @@
 #include "StringUtils.h"
 
 #include <cctype>
+#include <ctime>
 #include <boost/scoped_array.hpp>
 #include "Convert.h"
 #include "Math.h"
@@ -515,4 +516,25 @@
 
         return matrix[(rows-1)*cols + cols-1];
     }
+    
+    /**
+    @brief
+        Get a timestamp for the curent time instant.
+    @return
+        Returns a string with the timestamp.
+    */
+    std::string getTimestamp(void)
+    {
+        struct tm *pTime;
+        time_t ctTime; std::time(&ctTime);
+        pTime = std::localtime( &ctTime );
+        std::ostringstream oss;
+        oss << std::setw(2) << std::setfill('0') << (pTime->tm_mon + 1)
+            << std::setw(2) << std::setfill('0') << pTime->tm_mday
+            << std::setw(2) << std::setfill('0') << (pTime->tm_year + 1900)
+            << "_" << std::setw(2) << std::setfill('0') << pTime->tm_hour
+            << std::setw(2) << std::setfill('0') << pTime->tm_min
+            << std::setw(2) << std::setfill('0') << pTime->tm_sec;
+        return oss.str();
+    }
 }

Modified: code/trunk/src/libraries/util/StringUtils.h
===================================================================
--- code/trunk/src/libraries/util/StringUtils.h	2011-04-11 04:39:04 UTC (rev 8231)
+++ code/trunk/src/libraries/util/StringUtils.h	2011-04-11 17:37:00 UTC (rev 8232)
@@ -47,7 +47,7 @@
 {
     extern _UtilExport std::string BLANKSTRING;
 
-    _UtilExport std::string getUniqueNumberString();
+    _UtilExport std::string  getUniqueNumberString();
 
     _UtilExport void         strip(std::string* str);
     _UtilExport std::string  getStripped(const std::string& str);
@@ -87,6 +87,8 @@
     _UtilExport size_t       replaceCharacters(std::string& str, char target, char replacement);
 
     _UtilExport unsigned int getLevenshteinDistance(const std::string& str1, const std::string& str2);
+    
+    _UtilExport std::string  getTimestamp(void);
 }
 
 #endif /* _StringUtils_H__ */

Modified: code/trunk/src/modules/designtools/ScreenshotManager.cc
===================================================================
--- code/trunk/src/modules/designtools/ScreenshotManager.cc	2011-04-11 04:39:04 UTC (rev 8231)
+++ code/trunk/src/modules/designtools/ScreenshotManager.cc	2011-04-11 17:37:00 UTC (rev 8232)
@@ -1,154 +1,264 @@
-/* COPYRIGHT: this code comes from http://www.ogre3d.org/wiki/index.php/High_resolution_screenshots */
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      This code comes from http://www.ogre3d.org/tikiwiki/High+resolution+screenshots which is Public Domain.
+ *   Co-authors:
+ *      Oli Scheuss
+ *      Damian 'Mozork' Frick
+ *
+ */
 
+/**
+   @file ScreenshotManager.cc
+   @brief Implementation of the ScreenshotManager class.
+   @ingroup Designtools
+*/
+
 #include "ScreenshotManager.h"
 
+#include <OgreCamera.h>
+#include <OgreRenderTexture.h>
 #include <OgreRenderWindow.h>
+#include <OgreRoot.h>
 #include <OgreViewport.h>
-#include <OgreRenderTexture.h>
-#include <OgreCamera.h>
-#include <OgreRoot.h>
+// #include <X11/Xlib.h> TODO: Needed?
 
-#include "util/ScopedSingletonManager.h"
+#include "core/ConfigValueIncludes.h"
 #include "core/GraphicsManager.h"
 #include "core/PathConfig.h"
 #include "core/command/ConsoleCommand.h"
+#include "util/ScopedSingletonManager.h"
+#include "util/StringUtils.h"
 
 #include "CameraManager.h"
 #include "graphics/Camera.h"
 
 namespace orxonox
 {
+
+    SetConsoleCommand("printScreenHD", &ScreenshotManager::makeScreenshot_s);
+    
     ManageScopedSingleton(ScreenshotManager, ScopeID::Graphics, false);
-    SetConsoleCommand("printScreenHD", &ScreenshotManager::makeScreenshot_s);
 
+    /**
+    @brief
+        Constructor. 
+    */
     ScreenshotManager::ScreenshotManager()
     {
+        RegisterRootObject(ScreenshotManager);
+        
+        this->setConfigValues();
+
+        // Flag for overlay rendering
+        this->disableOverlays_ = true;
+
+        // Update the values
+        this->update();
+    }
+
+    ScreenshotManager::~ScreenshotManager()
+    {
+        
+    }
+    
+    /**
+    @brief
+        Sets some config values.
+    */
+    void ScreenshotManager::setConfigValues(void)
+    {
+        // Set file extension for the Screenshot files.
+        SetConfigValue(fileExtension_, ".png");
+        // The grid size.
+        SetConfigValue(gridSize_, 3);
+    }
+
+    /**
+    @brief
+        Update internal parameters.
+    */
+    void ScreenshotManager::update(void)
+    {
         Ogre::RenderWindow* pRenderWindow = GraphicsManager::getInstance().getRenderWindow();
 
-        //set file extension for the Screenshot files
-        this->mFileExtension_  = ".png";
-        // the gridsize
-        this->mGridSize_ = 3;
-        // flag for overlay rendering
-        this->mDisableOverlays_ = true;
-        //get current window size
-        this->mWindowWidth_   = pRenderWindow->getWidth();
-        this->mWindowHeight_  = pRenderWindow->getHeight();
-        //create temporary texture
-        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);
+        // If the window size has changed
+        if(this->windowWidth_ != pRenderWindow->getWidth() || this->windowHeight_ != pRenderWindow->getHeight())
+        {
+            // Update current window size
+            this->windowWidth_   = pRenderWindow->getWidth();
+            this->windowHeight_  = pRenderWindow->getHeight();
 
-        //get The current Render Target of the temp Texture
-        this->mRT_ = this->mTempTex_->getBuffer()->getRenderTarget();
+            // Create temporary texture
+            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);
 
-        //HardwarePixelBufferSharedPtr to the Buffer of the temp Texture
-        this->mBuffer_ = this->mTempTex_->getBuffer();
+            // Get the current render target of the temporary texture
+            this->renderTarget_ = this->tempTexture_->getBuffer()->getRenderTarget();
 
-        //create PixelBox
-        uint8_t* data_ = new uint8_t[(this->mWindowWidth_ * this->mGridSize_) * (this->mWindowHeight_ * this->mGridSize_) * 3];
-        this->mFinalPicturePB_ = Ogre::PixelBox(this->mWindowWidth_ * this->mGridSize_, this->mWindowHeight_ * this->mGridSize_, 1, Ogre::PF_B8G8R8, data_);
+            // HardwarePixelBufferSharedPtr to the buffer of the temporary texture
+            this->buffer_ = this->tempTexture_->getBuffer();
 
+            // Create PixelBox
+            this->data_ = new uint8_t[(this->windowWidth_ * this->gridSize_) * (this->windowHeight_ * this->gridSize_) * 3];
+            this->finalPicturePB_ = Ogre::PixelBox(this->windowWidth_ * this->gridSize_, this->windowHeight_ * this->gridSize_, 1, Ogre::PF_B8G8R8, this->data_);
+        }
     }
 
 
-    ScreenshotManager::~ScreenshotManager()
+    /**
+    @brief
+        Make a screenshot.
+        The screenshot is saved in the log folder.
+    */
+    void ScreenshotManager::makeScreenshot()
     {
-        // Don't delete data_. Somehow this pointer points anywhere but to memory location.
-        //delete[] data_;
+        // Get the screenshot.
+        Ogre::Image* finalImage = getScreenshot();
+        if(finalImage != NULL)
+        {
+            // Save it.
+            finalImage->save(PathConfig::getInstance().getLogPathString() + "screenshot_" + getTimestamp() + "." + this->fileExtension_);
+            delete finalImage;
+            COUT(3) << "Finished taking " << this->gridSize_*this->windowWidth_ << "x" << this->gridSize_*this->windowHeight_ << " pixel HD screenshot. Storing in log/." << endl;
+        }
+        else
+        {
+            COUT(1) << "There needs to be an active camera to make screenshots." << endl;
+            return;
+        }
     }
 
+    /**
+    @brief
+        Creates a screenshot and returns it.
+    @return
+        Returns a pointer to an Ogre::Image with the screenshot.
+    */
+    Ogre::Image* ScreenshotManager::getScreenshot()
+    {
+        if(CameraManager::getInstance().getActiveCamera() == NULL )
+            return NULL;
+        return this->getScreenshot(CameraManager::getInstance().getActiveCamera()->getOgreCamera());
+    }
 
     /**
     @brief
-        Creates a screenshot with the given camera.
+        Creates a screenshot with the given camera and returns it.
+    @param camera
+        A pointer to the camera the screenshot should be taken with.
+    @return
+        Returns a pointer to an Ogre::Image with the screenshot.
     */
-    void ScreenshotManager::makeScreenshot() const
+    Ogre::Image* ScreenshotManager::getScreenshot(Ogre::Camera* camera)
     {
-        Ogre::Camera* camera = CameraManager::getInstance().getActiveCamera()->getOgreCamera();
-        std::string fileName = PathConfig::getInstance().getLogPathString() + "screenshot_" + this->getTimestamp();
+        if(camera == NULL)
+            return NULL;
+        
+        // Update the internal parameters.
+        this->update();
 
-        //Remove all viewports, so the added Viewport(camera) ist the only
-        mRT_->removeAllViewports();
-        mRT_->addViewport(camera);
+        // Add the camera as viewport.
+        this->renderTarget_->removeAllViewports();
+        this->renderTarget_->addViewport(camera);
 
-        //set the viewport settings
-        Ogre::Viewport *vp = mRT_->getViewport(0);
+        // Set the viewport settings
+        Ogre::Viewport *vp = renderTarget_->getViewport(0);
         vp->setClearEveryFrame(true);
         vp->setOverlaysEnabled(false);
 
-        // remind current overlay flag
+        // Remind current overlay flag
         bool enableOverlayFlag = GraphicsManager::getInstance().getViewport()->getOverlaysEnabled();
-
-        // we disable overlay rendering if it is set in config file and the viewport setting is enabled
-        if(mDisableOverlays_ && enableOverlayFlag)
+        
+        // We disable overlay rendering if it is set in config file and the viewport setting is enabled
+        if(this->disableOverlays_ && enableOverlayFlag)
             GraphicsManager::getInstance().getViewport()->setOverlaysEnabled(false);
-
-        if(mGridSize_ <= 1)
+        
+        Ogre::Image* finalImage = new Ogre::Image();
+        
+        if(this->gridSize_ <= 1)
         {
             // Simple case where the contents of the screen are taken directly
             // Also used when an invalid value is passed within gridSize (zero or negative grid size)
-            mRT_->update();    //render
-
-            //write the file on the Harddisk
-            mRT_->writeContentsToFile(fileName + "." + mFileExtension_);
+            this->renderTarget_->update(); // Render
+            
+            finalImage = &finalImage->loadDynamicImage(static_cast<unsigned char*>(finalPicturePB_.data), finalPicturePB_.getWidth(), finalPicturePB_.getHeight(),Ogre::PF_B8G8R8);
         }
         else
         {
-            //define the original frustum extents variables
+            // Define the original frustum extents variables
             Ogre::Real originalFrustumLeft, originalFrustumRight, originalFrustumTop, originalFrustumBottom;
-            // set the original Frustum extents
+            // Set the original Frustum extents
             camera->getFrustumExtents(originalFrustumLeft, originalFrustumRight, originalFrustumTop, originalFrustumBottom);
-
-            // compute the Stepsize for the drid
-            Ogre::Real frustumGridStepHorizontal  = (originalFrustumRight * 2) / mGridSize_;
-            Ogre::Real frustumGridStepVertical  = (originalFrustumTop * 2) / mGridSize_;
-
-            // process each grid
+            
+            // Compute the Stepsize for the grid
+            Ogre::Real frustumGridStepHorizontal  = (originalFrustumRight * 2) / this->gridSize_;
+            Ogre::Real frustumGridStepVertical  = (originalFrustumTop * 2) / this->gridSize_;
+            
+            // Process each grid
             Ogre::Real frustumLeft, frustumRight, frustumTop, frustumBottom;
-            for (unsigned int nbScreenshots = 0; nbScreenshots < mGridSize_ * mGridSize_; nbScreenshots++)
+            for (unsigned int nbScreenshots = 0; nbScreenshots < this->gridSize_ * this->gridSize_; nbScreenshots++)
             {
-                int y = nbScreenshots / mGridSize_;
-                int x = nbScreenshots - y * mGridSize_;
-
+                int y = nbScreenshots / this->gridSize_;
+                int x = nbScreenshots - y * this->gridSize_;
+                
                 // Shoggoth frustum extents setting
-                // compute the new frustum extents
+                // Compute the new frustum extents
                 frustumLeft    = originalFrustumLeft + frustumGridStepHorizontal * x;
                 frustumRight  = frustumLeft + frustumGridStepHorizontal;
                 frustumTop    = originalFrustumTop - frustumGridStepVertical * y;
                 frustumBottom  = frustumTop - frustumGridStepVertical;
-
-                // set the frustum extents value to the camera
+                
+                // Set the frustum extents value to the camera
                 camera->setFrustumExtents(frustumLeft, frustumRight, frustumTop, frustumBottom);
-
-                // ignore time duration between frames
+                
+                // Ignore time duration between frames
                 Ogre::Root::getSingletonPtr()->clearEventTimes();
-                mRT_->update();    //render
-
-                //define the current
-                Ogre::Box subBox = Ogre::Box(x* mWindowWidth_,y * mWindowHeight_,x * mWindowWidth_ + mWindowWidth_, y * mWindowHeight_ + mWindowHeight_);
-                //copy the content from the temp buffer into the final picture PixelBox
-                //Place the tempBuffer content at the right position
-                mBuffer_->blitToMemory(mFinalPicturePB_.getSubVolume(subBox));
-
+                this->renderTarget_->update(); // Render
+                
+                // Define the current box
+                Ogre::Box subBox = Ogre::Box(x* this->windowWidth_,y * this->windowHeight_,x * this->windowWidth_ + this->windowWidth_, y * this->windowHeight_ + this->windowHeight_);
+                // Copy the content from the temp buffer into the final picture PixelBox
+                // Place the tempBuffer content at the right position
+                this->buffer_->blitToMemory(this->finalPicturePB_.getSubVolume(subBox));
+                
+                COUT(4) << "Created screenshot number " << nbScreenshots << " for multi grid HD screenshot." << endl;
+                
             }
-
-            // set frustum extents to previous settings
+            
+            // Set frustum extents to previous settings
             camera->resetFrustumExtents();
-
-            Ogre::Image finalImage; //declare the final Image Object
-            //insert the PixelBox data into the Image Object
-            finalImage = finalImage.loadDynamicImage(static_cast<unsigned char*>(mFinalPicturePB_.data), mFinalPicturePB_.getWidth(), mFinalPicturePB_.getHeight(),Ogre::PF_B8G8R8);
-            // Save the Final image to a file
-            finalImage.save(fileName + "." + mFileExtension_);
-
+            
+            // Insert the PixelBox data into the Image Object
+            finalImage->loadDynamicImage(static_cast<unsigned char*>(this->finalPicturePB_.data), this->finalPicturePB_.getWidth(), this->finalPicturePB_.getHeight(), 1, Ogre::PF_B8G8R8, false);
         }
-
-        // do we have to re-enable our overlays?
+        
+        // Do we have to re-enable our overlays?
         if(enableOverlayFlag)
             GraphicsManager::getInstance().getViewport()->setOverlaysEnabled(true);
-
-
-        // reset time since last frame to pause the scene
+        
+        // Reset time since last frame to pause the scene
         Ogre::Root::getSingletonPtr()->clearEventTimes();
+        
+        return finalImage;
     }
 
     /**
@@ -159,34 +269,13 @@
     */
     void ScreenshotManager::setGridSize(unsigned int size)
     {
-        if(size == this->mGridSize_)
+        if(size == this->gridSize_)
             return;
 
-        this->mGridSize_ = size;
+        this->gridSize_ = size;
         // New PixelBox for the changed size.
-        uint8_t* data_ = new uint8_t[(this->mWindowWidth_ * this->mGridSize_) * (this->mWindowHeight_ * this->mGridSize_) * 3];
-        this->mFinalPicturePB_ = Ogre::PixelBox(this->mWindowWidth_ * this->mGridSize_, this->mWindowHeight_ * this->mGridSize_, 1, Ogre::PF_B8G8R8, data_);
+        this->data_ = new uint8_t[(this->windowWidth_ * this->gridSize_) * (this->windowHeight_ * this->gridSize_) * 3];
+        this->finalPicturePB_ = Ogre::PixelBox(this->windowWidth_ * this->gridSize_, this->windowHeight_ * this->gridSize_, 1, Ogre::PF_B8G8R8, this->data_);
     }
 
-    /**
-    @brief
-        Get a timestamp for the curent time instant.
-    @return
-        Returns a string with the timestamp.
-    */
-    std::string ScreenshotManager::getTimestamp()
-    {
-        struct tm *pTime;
-        time_t ctTime; time(&ctTime);
-        pTime = localtime( &ctTime );
-        std::ostringstream oss;
-        oss << std::setw(2) << std::setfill('0') << (pTime->tm_mon + 1)
-            << std::setw(2) << std::setfill('0') << pTime->tm_mday
-            << std::setw(2) << std::setfill('0') << (pTime->tm_year + 1900)
-            << "_" << std::setw(2) << std::setfill('0') << pTime->tm_hour
-            << std::setw(2) << std::setfill('0') << pTime->tm_min
-            << std::setw(2) << std::setfill('0') << pTime->tm_sec;
-        return oss.str();
-    }
-
 }

Modified: code/trunk/src/modules/designtools/ScreenshotManager.h
===================================================================
--- code/trunk/src/modules/designtools/ScreenshotManager.h	2011-04-11 04:39:04 UTC (rev 8231)
+++ code/trunk/src/modules/designtools/ScreenshotManager.h	2011-04-11 17:37:00 UTC (rev 8232)
@@ -1,14 +1,43 @@
-/* COPYRIGHT: this code comes from http://www.ogre3d.org/wiki/index.php/High_resolution_screenshots */
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      This code comes from http://www.ogre3d.org/tikiwiki/High+resolution+screenshots which is Public Domain.
+ *   Co-authors:
+ *      Oli Scheuss
+ *      Damian 'Mozork' Frick
+ *
+ */
 
+/**
+   @file ScreenshotManager.h
+   @brief Definition of the ScreenshotManager class.
+   @ingroup Designtools
+*/
+
 #ifndef __ScreenshotManager_h__
 #define __ScreenshotManager_h__
 
 #include "DesignToolsPrereqs.h"
 
-#include <string>
-#include <cstring>
-#include <cstdlib>
-
 #include <OgrePrerequisites.h>
 #include <OgreTexture.h>
 #include <OgreHardwarePixelBuffer.h>
@@ -21,7 +50,16 @@
 
     /**
     @brief
-        Class encapsulates Screenshot functionality and provides a method for making multi grid screenshots.
+        Class encapsulates screenshot functionality and provides a method for making multi grid (i.e. HD) screenshots.
+        
+        
+    @author
+        This code comes from http://www.ogre3d.org/tikiwiki/High+resolution+screenshots which is Public Domain.
+    @author
+        Oli Scheuss
+    @author
+        Damian 'Mozork' Frick
+    @ingroup Designtools
     */
     class ScreenshotManager : public OrxonoxClass, public Singleton<ScreenshotManager>
     {
@@ -30,34 +68,43 @@
         public:
             ScreenshotManager();
             virtual ~ScreenshotManager();
+            void setConfigValues(void); // Sets some config values.
 
-            void makeScreenshot() const; //!< Creates a screenshot with the given camera.
+            void makeScreenshot(); // Make a screenshot.
+            Ogre::Image* getScreenshot(); // Creates a screenshot and returns it.
+            Ogre::Image* getScreenshot(Ogre::Camera* camera); // Creates a screenshot with the given camera and returns it.
 
             /**
-            @brief Creates a screenshot with a given size.
-            @param size Size is factor by which the current screen size is scaled.
+            @brief Creates a screenshot.
             */
-            static void makeScreenshot_s(unsigned int size)
-                { getInstance().setGridSize(size); getInstance().makeScreenshot(); }
+            static void makeScreenshot_s()
+                { ScreenshotManager::getInstance().makeScreenshot(); }
 
-            void setGridSize(unsigned int size); //!< Set the size of the grid.
-
+            void setGridSize(unsigned int size); // Set the size of the grid.
+            /**
+            @brief Get the current grid size.
+            @return Returns the size of the grid.
+            */
+            inline unsigned int getGridSize(void)
+                { return this->gridSize_; }
+            
         protected:
-            static std::string getTimestamp();
+            void update(void); // Update internal parameters.
+            
+            static ScreenshotManager* singletonPtr_s;
 
-            std::string mFileExtension_;
-            unsigned int mGridSize_; //!< The magnification factor.  A 2 will create a 2x2 grid, doubling the size of the screenshot.  A 3 will create a 3x3 grid, tripling the size of the screenshot.
-            unsigned int mWindowWidth_, mWindowHeight_;
-            bool mDisableOverlays_;
-            //! temp texture with current screensize
-            Ogre::TexturePtr mTempTex_;
-            Ogre::RenderTexture* mRT_;
-            Ogre::HardwarePixelBufferSharedPtr mBuffer_;
-            //! PixelBox for a large Screenshot, if grid size is > 1
-            Ogre::PixelBox  mFinalPicturePB_;
-            uint8_t* data_;
+            std::string fileExtension_; //!< The image extension used to save the screenshot.
+            unsigned int gridSize_; //!< The magnification factor.  A 2 will create a 2x2 grid, doubling the size of the screenshot.  A 3 will create a 3x3 grid, tripling the size of the screenshot.
+            unsigned int windowWidth_, windowHeight_; //!< The width and height of the window.
+            bool disableOverlays_; //!< Whether overlays should be disabled.
 
-            static ScreenshotManager* singletonPtr_s;
+            Ogre::TexturePtr tempTexture_; //!< Temporary texture with current screen size.
+            Ogre::RenderTexture* renderTarget_; //!< Render target for the temporary texture.
+            Ogre::HardwarePixelBufferSharedPtr buffer_; //!< Buffer for the temporary texture.
+            
+            Ogre::PixelBox finalPicturePB_; //!< PixelBox for large screenshots, contains the screenshot for gridSize_ > 1.
+            uint8_t* data_; //!< Data pointer for the PixelBox.
+
     };
 
 }

Modified: code/trunk/src/modules/designtools/SkyboxGenerator.cc
===================================================================
--- code/trunk/src/modules/designtools/SkyboxGenerator.cc	2011-04-11 04:39:04 UTC (rev 8231)
+++ code/trunk/src/modules/designtools/SkyboxGenerator.cc	2011-04-11 17:37:00 UTC (rev 8232)
@@ -22,30 +22,37 @@
  *   Author:
  *      Gion-Andri Cantieni
  *   Co-authors:
- *      ...
+ *      Damian 'Mozork' Frick
  *
  */
 
+/**
+    @file SkyboxGenerator.cc
+    @brief Implementation of the SkyboxGenerator class.
+*/
+
 #include "SkyboxGenerator.h"
 
 #include <string>
-#include <cassert>
 #include <OgreRenderWindow.h>
 #include <OgreCamera.h>
+// #include <X11/Xlib.h> TODO: Needed?
 
 #include "util/ScopedSingletonManager.h"
 #include "core/CoreIncludes.h"
 #include "core/ConfigValueIncludes.h"
 #include "core/GraphicsManager.h"
+#include "core/PathConfig.h"
+#include "core/Resource.h"
 #include "core/command/ConsoleCommand.h"
 #include "core/command/CommandExecutor.h"
+
 #include "controllers/HumanController.h"
-#include "worldentities/CameraPosition.h"
+#include "graphics/Camera.h"
 #include "worldentities/ControllableEntity.h"
-#include "graphics/Camera.h"
 
+#include "ScreenshotManager.h"
 
-
 namespace orxonox
 {
 
@@ -53,107 +60,258 @@
 
     ManageScopedSingleton(SkyboxGenerator, ScopeID::Graphics, false);
 
-    SkyboxGenerator::SkyboxGenerator() : iterateOverDirections_(0)
+    /**
+    @brief
+        Constructor. Registers and initializes the singleton.
+    */
+    SkyboxGenerator::SkyboxGenerator()
     {
         RegisterRootObject(SkyboxGenerator);
 
         this->setConfigValues();
-        this->takeScreenshot_ = false;
-        this->captionsRemoved_ = false;
+        
+        this->bGenerateSkybox_ = false;
+        this->bCaptionsRemoved_ = false;
+        this->bSetup_ = true;
+        this->bWait_ = false;
+        this->bCreateFace_ = true;
+        this->bCleanup_ = true;
+        this->faceCounter_ = 0;
+        
+        this->names_.push_back("fr");
+        this->names_.push_back("lf");
+        this->names_.push_back("bk");
+        this->names_.push_back("rt");
+        this->names_.push_back("up");
+        this->names_.push_back("dn");
+        
+        this->rotations_.push_back(std::pair<int, int>(90, 0));
+        this->rotations_.push_back(std::pair<int, int>(90, 0));
+        this->rotations_.push_back(std::pair<int, int>(90, 0));
+        this->rotations_.push_back(std::pair<int, int>(90, 90));
+        this->rotations_.push_back(std::pair<int, int>(0, 180));
+        this->rotations_.push_back(std::pair<int, int>(0, 90));
     }
 
+    /**
+    @brief
+        Destructor.
+    */
     SkyboxGenerator::~SkyboxGenerator()
     {
 
     }
 
+    /**
+    @brief
+        Sets some config values.
+    */
     void SkyboxGenerator::setConfigValues( )
     {
         SetConfigValue(skyboxPrefix_, "SkyboxFile_");
+        SetConfigValue(imageExtension_, ".png");
+        SetConfigValue(size_, 1024);
     }
+    
+    /**
+    @brief
+        Generate the 6 faces of a skybox.
+    */
+    void SkyboxGenerator::createSkybox()
+    {
+        // Pause
+        CommandExecutor::execute("pause");
+        // Start the skybox generation process.
+        SkyboxGenerator::getInstance().startSkyboxGeneration();
+    }
 
+    /**
+    @brief
+        This is where the skybox generation happens.
+        Generating a skybox takes several (up to 10) ticks.
+    */
     void SkyboxGenerator::tick(float dt)
     {
-        if( takeScreenshot_ == true )
+        // Whether a skybox is currently being generated.
+        if(this->bGenerateSkybox_)
         {
-            if(!this->captionsRemoved_)
+            // Wait one tick.
+            if(this->bWait_)
             {
-                CommandExecutor::execute("GametypeStatus displayCaption false");
-                this->captionsRemoved_ = true;
+                this->bWait_ = false;
                 return;
             }
 
-            ControllableEntity* ce = HumanController::getLocalControllerSingleton()->getControllableEntity();
-            Camera* camera = ce->getCamera();
-            assert(ce);
-
-            Ogre::RenderWindow* w = GraphicsManager::getInstance().getRenderWindow();
-
-
-            switch (iterateOverDirections_)
+            ControllableEntity* entity = NULL;
+            if(HumanController::getLocalControllerSingleton() != NULL && HumanController::getLocalControllerSingleton()->getControllableEntity() != NULL)
+                entity = HumanController::getLocalControllerSingleton()->getControllableEntity();
+            else
             {
-            case 0 :
-                fovy_ = camera->getOgreCamera()->getFOVy();
-                camera->getOgreCamera()->setFOVy(Degree(90));
-                aspectRatio_ = camera->getOgreCamera()->getAspectRatio();
-                camera->getOgreCamera()->setAspectRatio(1);
-                iterateOverDirections_++;
-                break;
-            case 1 :
-                w->writeContentsToFile(skyboxPrefix_+"fr.png");
-                ce->yaw(Degree(90));
-                iterateOverDirections_++;
-                break;
-
-            case 2 :
-                w->writeContentsToFile(skyboxPrefix_+"lf.png");
-                ce->yaw(Degree(90));
-                iterateOverDirections_++;
-                break;
-
-            case 3 :
-                w->writeContentsToFile(skyboxPrefix_+"bk.png");
-                ce->yaw(Degree(90));
-                iterateOverDirections_++;
-                break;
-
-            case 4 :
-                w->writeContentsToFile(skyboxPrefix_+"rt.png");
-                ce->yaw(Degree(90));
-                ce->pitch(Degree(90));
-                iterateOverDirections_++;
-                break;
-
-            case 5 :
-                w->writeContentsToFile(skyboxPrefix_+"up.png");
-                ce->pitch(Degree(180));
-                iterateOverDirections_++;
-                break;
-
-            case 6 :
-                w->writeContentsToFile(skyboxPrefix_+"dn.png");
-                ce->pitch(Degree(90));
-                iterateOverDirections_++;
-                break;
-
-            case 7 :
-                camera->getOgreCamera()->setAspectRatio(aspectRatio_);
-                camera->getOgreCamera()->setFOVy(fovy_);
-                iterateOverDirections_++;
-            case 8 :
-                iterateOverDirections_ =0;
-                takeScreenshot_ = false;
+                COUT(1) << "You must be in a level to generate a skybox." << endl;
+                this->bGenerateSkybox_ = false;
+                return;
+            }
+            Ogre::Camera* camera = entity->getCamera()->getOgreCamera();
+            Ogre::RenderWindow* renderWindow = GraphicsManager::getInstance().getRenderWindow();
+            
+            // Setup the SkyboxGenerator to generate a skybox.
+            if(this->bSetup_)
+            {
+                // If there are captions being displayed, don't.
+                if(!this->bCaptionsRemoved_)
+                {
+                    CommandExecutor::execute("GametypeStatus displayCaption false");
+                    this->bCaptionsRemoved_ = true;
+                    return;
+                }
+                
+                // Store the settings for the camera.
+                this->fovy_ = camera->getFOVy();
+                this->aspectRatio_ = camera->getAspectRatio();
+                // Setup the render window.
+                this->setupRenderWindow(renderWindow);
+                // Add the log path to the standard resource group.
+                Ogre::ResourceGroupManager::getSingleton().addResourceLocation(PathConfig::getInstance().getLogPathString(), "FileSystem", Resource::DEFAULT_GROUP);
+                
+                COUT(4) << "Setting up SkyboxGenerator..." << endl;
+                
+                this->bSetup_ = false;
+                this->bWait_ = true;
+            }
+            // Create one of the faces. (faceCounter_ decides which)
+            else if(this->bCreateFace_)
+            {
+                // Setup the camera.
+                this->setupCamera(camera);
+                // Take the picture using the ScreenshotManager and save it.
+                this->saveImage(ScreenshotManager::getInstance().getScreenshot(camera), this->skyboxPrefix_+this->names_[this->faceCounter_]+this->imageExtension_);
+                // Rotate the camera to be ready for taking the next picture.
+                std::pair<int, int> rotate = this->rotations_[this->faceCounter_];
+                if(rotate.first != 0)
+                    entity->yaw(Degree(rotate.first));
+                if(rotate.second != 0)
+                    entity->pitch(Degree(rotate.second));
+                
+                COUT(4) << "Created face number " << this->faceCounter_ << "." << endl;
+                // Check whether we've generated all 6 faces.
+                if(++this->faceCounter_ >= 6)
+                    this->bCreateFace_ = false;
+            }
+            // Cleanup after the successful creation of a skybox.
+            else if(this->bCleanup_)
+            {
+                // Reset the camera parameters.
+                camera->setAspectRatio(this->aspectRatio_);
+                camera->setFOVy(this->fovy_);
+                // Restore the render window.
+                this->restoreRenderWindow(renderWindow);
+                // Remove the log path from the standard resource group.
+                Ogre::ResourceGroupManager::getSingleton().removeResourceLocation(PathConfig::getInstance().getLogPathString(), Resource::DEFAULT_GROUP);
+                
+                // Reset the flow parameters for the next skybox generation.
+                this->bGenerateSkybox_ = false;
+                this->bSetup_ = true;
+                this->bWait_ = false;
+                this->bCreateFace_ = true;
+                this->bCleanup_ = true;
+                this->faceCounter_ = 0;
+                
+                // Display captions again.
+                CommandExecutor::execute("GametypeStatus displayCaption true");
+                this->bCaptionsRemoved_ = false;
+                
+                // Unpause.
                 CommandExecutor::execute("pause");
-                CommandExecutor::execute("GametypeStatus displayCaption true");
-                this->captionsRemoved_ = false;
+                
+                COUT(3) << "Skybox with face size " << this->size_ << "x" << this->size_ << " pixels created. Storing in log/." << endl;
             }
-
         }
     }
+    
+    /**
+    @brief
+        Set up the input camera to be ready to generate a skybox face.
+    @param camera
+        The camera to be set up.
+    */
+    void SkyboxGenerator::setupCamera(Ogre::Camera* camera)
+    {
+        camera->setFOVy(Degree(90));
+        camera->setAspectRatio(1.0);
+    }
+    
+    /**
+    @brief
+        Setup the input render window to be ready to generate the skybox.
+    @param renderWindow
+        The render window to be set up.
+    */
+    void SkyboxGenerator::setupRenderWindow(Ogre::RenderWindow* renderWindow)
+    {
+        // Store current window properties.
+        this->windowWidth_ = renderWindow->getWidth();
+        this->windowHeight_ = renderWindow->getHeight();
+        this->windowFullScreen_ = renderWindow->isFullScreen();
+        // Store current ScreenshotManager grid size.
+        this->gridSize_ = ScreenshotManager::getInstance().getGridSize();
+        
+        unsigned int size = this->size_;
+        
+        // If the desired skybox face size is bigger than what the current render window can accommodate we find a size that is a multiple of 256, that fits into the current render window adjust the grid size of the ScreenshotManager such that the screenshots generated are at least as big as we need. 
+        if(this->windowHeight_ < this->size_ || this->windowWidth_ < this->size_)
+        {
+            unsigned int min = std::min(this->windowHeight_, this->windowWidth_);
+            unsigned int step = 256;
+            assert(min >= step);
+            size = step;
+            while(min >= size+step)
+                size += step;
+            
+            unsigned int gridSize = 1;
+            while(gridSize*size < this->size_)
+                gridSize++;
+            
+            renderWindow->setFullscreen(false, size, size);
+            ScreenshotManager::getInstance().setGridSize(gridSize);
+        }
+        else
+            ScreenshotManager::getInstance().setGridSize(1);
 
-    void SkyboxGenerator::createSkybox( )
+    }
+    
+    /**
+    @brief
+        Restore the render window.
+        Reset the window size, reset the grid size of the ScreenshotManager.
+    @param renderWindow
+        The render window to be restored.
+    */
+    void SkyboxGenerator::restoreRenderWindow(Ogre::RenderWindow* renderWindow)
     {
-        SkyboxGenerator::getInstance().takeScreenshot_ = true;
-        CommandExecutor::execute("pause");
+        // Restore window size.
+        renderWindow->setFullscreen(this->windowFullScreen_, this->windowWidth_, this->windowHeight_);
+        // Restore grid size.
+        ScreenshotManager::getInstance().setGridSize(this->gridSize_);
     }
+    
+    /**
+    @brief
+        Resizes and saves the input image under the input name.
+    @param image
+        A pointer to the image to be saved. The image is deleted afterwards,
+    @param name
+        The desired filename of the image.
+    */
+    void SkyboxGenerator::saveImage(Ogre::Image* image, const std::string& name) const
+    {
+        image->save(PathConfig::getInstance().getLogPathString()+name);
+        delete image;
+        // Loading the resizing, then saving again. This seems stupid, but resizing doesn't seem to work otherwise.
+        // If someone figures this out, feel free to adjust.
+        image = new Ogre::Image();
+        image->load(name, Resource::DEFAULT_GROUP);
+        image->resize(this->size_, this->size_);
+        image->save(PathConfig::getInstance().getLogPathString()+name);
+        delete image;
+    }
 }

Modified: code/trunk/src/modules/designtools/SkyboxGenerator.h
===================================================================
--- code/trunk/src/modules/designtools/SkyboxGenerator.h	2011-04-11 04:39:04 UTC (rev 8231)
+++ code/trunk/src/modules/designtools/SkyboxGenerator.h	2011-04-11 17:37:00 UTC (rev 8232)
@@ -22,19 +22,41 @@
  *   Author:
  *      Gion-Andri Cantieni
  *   Co-authors:
- *      ...
+ *      Damian 'Mozork' Frick
  *
  */
 
+/**
+    @file SkyboxGenerator.h
+    @brief Definition of the SkyboxGenerator class.
+    @ingroup Designtools
+*/
 
+#ifndef __SkyboxGenerator_h__
+#define __SkyboxGenerator_h__
+
 #include "core/OrxonoxClass.h"
 #include "util/Singleton.h"
 #include "tools/interfaces/Tickable.h"
+
 #include <OgreMath.h>
 
-
 namespace orxonox
 {
+    
+    /**
+    @brief
+        The SkyboxGenerator class is a singleton that allows for the creation of a skybox from a level by taking pictures to all 6 sides.
+        The 6 images created by the createSkybox() method are placed in the log folder in your build directory.
+        
+        The image filename prefix and the file extension can both be adjusted as config values, so can the desired size of the skybox faces.
+        
+    @author
+        Gion-Andri Cantieni
+    @author
+        Damian 'Mozork' Frick
+    @ingroup Designtools
+    */
     class SkyboxGenerator : public virtual OrxonoxClass, public Singleton<SkyboxGenerator>, public Tickable
     {
         friend class Singleton<SkyboxGenerator>;
@@ -42,17 +64,58 @@
         public:
             SkyboxGenerator();
             virtual ~SkyboxGenerator();
-            static void createSkybox( );
-            void setConfigValues( );
-            void tick(float dt);
+            void tick(float dt); // This is where the skybox generation happens.
+            static void createSkybox(void); // Generate the 6 faces of a skybox.
+            void setConfigValues(void); // Sets some config values.
+            
+            /**
+            @brief Set the size of the skybox faces to be generated.
+            @param size The size in pixels.
+            */
+            inline void setSize(unsigned int size)
+                { this->size_ = size; }
+                
+        protected:
+            /**
+            @brief Starts the generation of the skybox.
+            */
+            inline void startSkyboxGeneration(void)
+                { this->bGenerateSkybox_ = true; }
 
         private:
-            static SkyboxGenerator* singletonPtr_s;
-            std::string skyboxPrefix_;
-            bool takeScreenshot_;
-            int iterateOverDirections_;
-            float aspectRatio_;
-            Ogre::Radian fovy_;
-            bool captionsRemoved_;
+            void setupCamera(Ogre::Camera* camera); // Set up the input camera to be ready to generate a skybox face.
+            void setupRenderWindow(Ogre::RenderWindow* renderWindow); // Setup the input render window to be ready to generate the skybox.
+            void restoreRenderWindow(Ogre::RenderWindow* renderWindow); // Restore the render window.
+
+            void saveImage(Ogre::Image* image, const std::string& name) const;
+            
+            static SkyboxGenerator* singletonPtr_s; //!< Singleton pointer.
+            
+            unsigned int size_; //!< The desired size of the skybox faces.
+            std::string skyboxPrefix_; //!< Prefix for the generated image files.
+            std::string imageExtension_; //!< Extension of the generated image files.
+            
+            // FLow control variables
+            bool bGenerateSkybox_; //!< Whether a skybox is currently being generated.
+            bool bCaptionsRemoved_; //!< Whether the overlays have been removed.
+            bool bSetup_; //!< Whether the render window is being setup.
+            bool bWait_; //!< Whether we have to wait for the setup to take effect.
+            bool bCreateFace_; //!< Whether the faces are being created,
+            unsigned int faceCounter_; //!< Counter to keep track of which skybox face is being created.
+            bool bCleanup_; //!< Whether the generator is being cleaned up.
+            
+            std::vector<std::string> names_; //!< The names of the image files for the skybox faces to be generated.
+            std::vector< std::pair<int, int> > rotations_; //!< The rotation in yaw an pitch direction that is applied to the camera after a specific face has been generated.
+            
+            // Storage variables
+            float aspectRatio_; //!< The backed up aspect ratio of the camera.
+            Ogre::Radian fovy_; //!< The backed up field of view of the camera.
+            unsigned int windowWidth_; //!< The backed up window width.
+            unsigned int windowHeight_; //!< The backed up window height.
+            bool windowFullScreen_; //!< Whether the window was in fullscreen mode.
+            unsigned int gridSize_; //!< The backed up grid size of the ScreenshotManager.
+
     };
 }
+
+#endif  // __SkyboxGenerator_h__
\ No newline at end of file




More information about the Orxonox-commit mailing list