Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Apr 11, 2011, 7:37:00 PM (14 years ago)
Author:
dafrick
Message:

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).

Location:
code/trunk/src/modules/designtools
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • code/trunk/src/modules/designtools/ScreenshotManager.cc

    r8108 r8232  
    1 /* COPYRIGHT: this code comes from http://www.ogre3d.org/wiki/index.php/High_resolution_screenshots */
     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*/
    235
    336#include "ScreenshotManager.h"
    437
     38#include <OgreCamera.h>
     39#include <OgreRenderTexture.h>
    540#include <OgreRenderWindow.h>
     41#include <OgreRoot.h>
    642#include <OgreViewport.h>
    7 #include <OgreRenderTexture.h>
    8 #include <OgreCamera.h>
    9 #include <OgreRoot.h>
    10 
    11 #include "util/ScopedSingletonManager.h"
     43// #include <X11/Xlib.h> TODO: Needed?
     44
     45#include "core/ConfigValueIncludes.h"
    1246#include "core/GraphicsManager.h"
    1347#include "core/PathConfig.h"
    1448#include "core/command/ConsoleCommand.h"
     49#include "util/ScopedSingletonManager.h"
     50#include "util/StringUtils.h"
    1551
    1652#include "CameraManager.h"
     
    1955namespace orxonox
    2056{
     57
     58    SetConsoleCommand("printScreenHD", &ScreenshotManager::makeScreenshot_s);
     59   
    2160    ManageScopedSingleton(ScreenshotManager, ScopeID::Graphics, false);
    22     SetConsoleCommand("printScreenHD", &ScreenshotManager::makeScreenshot_s);
    23 
     61
     62    /**
     63    @brief
     64        Constructor.
     65    */
    2466    ScreenshotManager::ScreenshotManager()
    2567    {
     68        RegisterRootObject(ScreenshotManager);
     69       
     70        this->setConfigValues();
     71
     72        // Flag for overlay rendering
     73        this->disableOverlays_ = true;
     74
     75        // Update the values
     76        this->update();
     77    }
     78
     79    ScreenshotManager::~ScreenshotManager()
     80    {
     81       
     82    }
     83   
     84    /**
     85    @brief
     86        Sets some config values.
     87    */
     88    void ScreenshotManager::setConfigValues(void)
     89    {
     90        // Set file extension for the Screenshot files.
     91        SetConfigValue(fileExtension_, ".png");
     92        // The grid size.
     93        SetConfigValue(gridSize_, 3);
     94    }
     95
     96    /**
     97    @brief
     98        Update internal parameters.
     99    */
     100    void ScreenshotManager::update(void)
     101    {
    26102        Ogre::RenderWindow* pRenderWindow = GraphicsManager::getInstance().getRenderWindow();
    27103
    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);
     104        // If the window size has changed
     105        if(this->windowWidth_ != pRenderWindow->getWidth() || this->windowHeight_ != pRenderWindow->getHeight())
     106        {
     107            // Update current window size
     108            this->windowWidth_   = pRenderWindow->getWidth();
     109            this->windowHeight_  = pRenderWindow->getHeight();
     110
     111            // Create temporary texture
     112            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);
     113
     114            // Get the current render target of the temporary texture
     115            this->renderTarget_ = this->tempTexture_->getBuffer()->getRenderTarget();
     116
     117            // HardwarePixelBufferSharedPtr to the buffer of the temporary texture
     118            this->buffer_ = this->tempTexture_->getBuffer();
     119
     120            // Create PixelBox
     121            this->data_ = new uint8_t[(this->windowWidth_ * this->gridSize_) * (this->windowHeight_ * this->gridSize_) * 3];
     122            this->finalPicturePB_ = Ogre::PixelBox(this->windowWidth_ * this->gridSize_, this->windowHeight_ * this->gridSize_, 1, Ogre::PF_B8G8R8, this->data_);
     123        }
     124    }
     125
     126
     127    /**
     128    @brief
     129        Make a screenshot.
     130        The screenshot is saved in the log folder.
     131    */
     132    void ScreenshotManager::makeScreenshot()
     133    {
     134        // Get the screenshot.
     135        Ogre::Image* finalImage = getScreenshot();
     136        if(finalImage != NULL)
     137        {
     138            // Save it.
     139            finalImage->save(PathConfig::getInstance().getLogPathString() + "screenshot_" + getTimestamp() + "." + this->fileExtension_);
     140            delete finalImage;
     141            COUT(3) << "Finished taking " << this->gridSize_*this->windowWidth_ << "x" << this->gridSize_*this->windowHeight_ << " pixel HD screenshot. Storing in log/." << endl;
     142        }
     143        else
     144        {
     145            COUT(1) << "There needs to be an active camera to make screenshots." << endl;
     146            return;
     147        }
     148    }
     149
     150    /**
     151    @brief
     152        Creates a screenshot and returns it.
     153    @return
     154        Returns a pointer to an Ogre::Image with the screenshot.
     155    */
     156    Ogre::Image* ScreenshotManager::getScreenshot()
     157    {
     158        if(CameraManager::getInstance().getActiveCamera() == NULL )
     159            return NULL;
     160        return this->getScreenshot(CameraManager::getInstance().getActiveCamera()->getOgreCamera());
     161    }
     162
     163    /**
     164    @brief
     165        Creates a screenshot with the given camera and returns it.
     166    @param camera
     167        A pointer to the camera the screenshot should be taken with.
     168    @return
     169        Returns a pointer to an Ogre::Image with the screenshot.
     170    */
     171    Ogre::Image* ScreenshotManager::getScreenshot(Ogre::Camera* camera)
     172    {
     173        if(camera == NULL)
     174            return NULL;
     175       
     176        // Update the internal parameters.
     177        this->update();
     178
     179        // Add the camera as viewport.
     180        this->renderTarget_->removeAllViewports();
     181        this->renderTarget_->addViewport(camera);
     182
     183        // Set the viewport settings
     184        Ogre::Viewport *vp = renderTarget_->getViewport(0);
    75185        vp->setClearEveryFrame(true);
    76186        vp->setOverlaysEnabled(false);
    77187
    78         // remind current overlay flag
     188        // Remind current overlay flag
    79189        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)
     190       
     191        // We disable overlay rendering if it is set in config file and the viewport setting is enabled
     192        if(this->disableOverlays_ && enableOverlayFlag)
    83193            GraphicsManager::getInstance().getViewport()->setOverlaysEnabled(false);
    84 
    85         if(mGridSize_ <= 1)
     194       
     195        Ogre::Image* finalImage = new Ogre::Image();
     196       
     197        if(this->gridSize_ <= 1)
    86198        {
    87199            // Simple case where the contents of the screen are taken directly
    88200            // 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_);
     201            this->renderTarget_->update(); // Render
     202           
     203            finalImage = &finalImage->loadDynamicImage(static_cast<unsigned char*>(finalPicturePB_.data), finalPicturePB_.getWidth(), finalPicturePB_.getHeight(),Ogre::PF_B8G8R8);
    93204        }
    94205        else
    95206        {
    96             //define the original frustum extents variables
     207            // Define the original frustum extents variables
    97208            Ogre::Real originalFrustumLeft, originalFrustumRight, originalFrustumTop, originalFrustumBottom;
    98             // set the original Frustum extents
     209            // Set the original Frustum extents
    99210            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
     211           
     212            // Compute the Stepsize for the grid
     213            Ogre::Real frustumGridStepHorizontal  = (originalFrustumRight * 2) / this->gridSize_;
     214            Ogre::Real frustumGridStepVertical  = (originalFrustumTop * 2) / this->gridSize_;
     215           
     216            // Process each grid
    106217            Ogre::Real frustumLeft, frustumRight, frustumTop, frustumBottom;
    107             for (unsigned int nbScreenshots = 0; nbScreenshots < mGridSize_ * mGridSize_; nbScreenshots++)
     218            for (unsigned int nbScreenshots = 0; nbScreenshots < this->gridSize_ * this->gridSize_; nbScreenshots++)
    108219            {
    109                 int y = nbScreenshots / mGridSize_;
    110                 int x = nbScreenshots - y * mGridSize_;
    111 
     220                int y = nbScreenshots / this->gridSize_;
     221                int x = nbScreenshots - y * this->gridSize_;
     222               
    112223                // Shoggoth frustum extents setting
    113                 // compute the new frustum extents
     224                // Compute the new frustum extents
    114225                frustumLeft    = originalFrustumLeft + frustumGridStepHorizontal * x;
    115226                frustumRight  = frustumLeft + frustumGridStepHorizontal;
    116227                frustumTop    = originalFrustumTop - frustumGridStepVertical * y;
    117228                frustumBottom  = frustumTop - frustumGridStepVertical;
    118 
    119                 // set the frustum extents value to the camera
     229               
     230                // Set the frustum extents value to the camera
    120231                camera->setFrustumExtents(frustumLeft, frustumRight, frustumTop, frustumBottom);
    121 
    122                 // ignore time duration between frames
     232               
     233                // Ignore time duration between frames
    123234                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 
     235                this->renderTarget_->update(); // Render
     236               
     237                // Define the current box
     238                Ogre::Box subBox = Ogre::Box(x* this->windowWidth_,y * this->windowHeight_,x * this->windowWidth_ + this->windowWidth_, y * this->windowHeight_ + this->windowHeight_);
     239                // Copy the content from the temp buffer into the final picture PixelBox
     240                // Place the tempBuffer content at the right position
     241                this->buffer_->blitToMemory(this->finalPicturePB_.getSubVolume(subBox));
     242               
     243                COUT(4) << "Created screenshot number " << nbScreenshots << " for multi grid HD screenshot." << endl;
     244               
    132245            }
    133 
    134             // set frustum extents to previous settings
     246           
     247            // Set frustum extents to previous settings
    135248            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?
     249           
     250            // Insert the PixelBox data into the Image Object
     251            finalImage->loadDynamicImage(static_cast<unsigned char*>(this->finalPicturePB_.data), this->finalPicturePB_.getWidth(), this->finalPicturePB_.getHeight(), 1, Ogre::PF_B8G8R8, false);
     252        }
     253       
     254        // Do we have to re-enable our overlays?
    146255        if(enableOverlayFlag)
    147256            GraphicsManager::getInstance().getViewport()->setOverlaysEnabled(true);
    148 
    149 
    150         // reset time since last frame to pause the scene
     257       
     258        // Reset time since last frame to pause the scene
    151259        Ogre::Root::getSingletonPtr()->clearEventTimes();
     260       
     261        return finalImage;
    152262    }
    153263
     
    160270    void ScreenshotManager::setGridSize(unsigned int size)
    161271    {
    162         if(size == this->mGridSize_)
     272        if(size == this->gridSize_)
    163273            return;
    164274
    165         this->mGridSize_ = size;
     275        this->gridSize_ = size;
    166276        // 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();
     277        this->data_ = new uint8_t[(this->windowWidth_ * this->gridSize_) * (this->windowHeight_ * this->gridSize_) * 3];
     278        this->finalPicturePB_ = Ogre::PixelBox(this->windowWidth_ * this->gridSize_, this->windowHeight_ * this->gridSize_, 1, Ogre::PF_B8G8R8, this->data_);
    190279    }
    191280
  • code/trunk/src/modules/designtools/ScreenshotManager.h

    r8079 r8232  
    1 /* COPYRIGHT: this code comes from http://www.ogre3d.org/wiki/index.php/High_resolution_screenshots */
     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.h
     32   @brief Definition of the ScreenshotManager class.
     33   @ingroup Designtools
     34*/
    235
    336#ifndef __ScreenshotManager_h__
     
    538
    639#include "DesignToolsPrereqs.h"
    7 
    8 #include <string>
    9 #include <cstring>
    10 #include <cstdlib>
    1140
    1241#include <OgrePrerequisites.h>
     
    2251    /**
    2352    @brief
    24         Class encapsulates Screenshot functionality and provides a method for making multi grid screenshots.
     53        Class encapsulates screenshot functionality and provides a method for making multi grid (i.e. HD) screenshots.
     54       
     55       
     56    @author
     57        This code comes from http://www.ogre3d.org/tikiwiki/High+resolution+screenshots which is Public Domain.
     58    @author
     59        Oli Scheuss
     60    @author
     61        Damian 'Mozork' Frick
     62    @ingroup Designtools
    2563    */
    2664    class ScreenshotManager : public OrxonoxClass, public Singleton<ScreenshotManager>
     
    3169            ScreenshotManager();
    3270            virtual ~ScreenshotManager();
     71            void setConfigValues(void); // Sets some config values.
    3372
    34             void makeScreenshot() const; //!< Creates a screenshot with the given camera.
     73            void makeScreenshot(); // Make a screenshot.
     74            Ogre::Image* getScreenshot(); // Creates a screenshot and returns it.
     75            Ogre::Image* getScreenshot(Ogre::Camera* camera); // Creates a screenshot with the given camera and returns it.
    3576
    3677            /**
    37             @brief Creates a screenshot with a given size.
    38             @param size Size is factor by which the current screen size is scaled.
     78            @brief Creates a screenshot.
    3979            */
    40             static void makeScreenshot_s(unsigned int size)
    41                 { getInstance().setGridSize(size); getInstance().makeScreenshot(); }
     80            static void makeScreenshot_s()
     81                { ScreenshotManager::getInstance().makeScreenshot(); }
    4282
    43             void setGridSize(unsigned int size); //!< Set the size of the grid.
     83            void setGridSize(unsigned int size); // Set the size of the grid.
     84            /**
     85            @brief Get the current grid size.
     86            @return Returns the size of the grid.
     87            */
     88            inline unsigned int getGridSize(void)
     89                { return this->gridSize_; }
     90           
     91        protected:
     92            void update(void); // Update internal parameters.
     93           
     94            static ScreenshotManager* singletonPtr_s;
    4495
    45         protected:
    46             static std::string getTimestamp();
     96            std::string fileExtension_; //!< The image extension used to save the screenshot.
     97            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.
     98            unsigned int windowWidth_, windowHeight_; //!< The width and height of the window.
     99            bool disableOverlays_; //!< Whether overlays should be disabled.
    47100
    48             std::string mFileExtension_;
    49             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.
    50             unsigned int mWindowWidth_, mWindowHeight_;
    51             bool mDisableOverlays_;
    52             //! temp texture with current screensize
    53             Ogre::TexturePtr mTempTex_;
    54             Ogre::RenderTexture* mRT_;
    55             Ogre::HardwarePixelBufferSharedPtr mBuffer_;
    56             //! PixelBox for a large Screenshot, if grid size is > 1
    57             Ogre::PixelBox  mFinalPicturePB_;
    58             uint8_t* data_;
     101            Ogre::TexturePtr tempTexture_; //!< Temporary texture with current screen size.
     102            Ogre::RenderTexture* renderTarget_; //!< Render target for the temporary texture.
     103            Ogre::HardwarePixelBufferSharedPtr buffer_; //!< Buffer for the temporary texture.
     104           
     105            Ogre::PixelBox finalPicturePB_; //!< PixelBox for large screenshots, contains the screenshot for gridSize_ > 1.
     106            uint8_t* data_; //!< Data pointer for the PixelBox.
    59107
    60             static ScreenshotManager* singletonPtr_s;
    61108    };
    62109
  • code/trunk/src/modules/designtools/SkyboxGenerator.cc

    r8079 r8232  
    2323 *      Gion-Andri Cantieni
    2424 *   Co-authors:
    25  *      ...
     25 *      Damian 'Mozork' Frick
    2626 *
    2727 */
    2828
     29/**
     30    @file SkyboxGenerator.cc
     31    @brief Implementation of the SkyboxGenerator class.
     32*/
     33
    2934#include "SkyboxGenerator.h"
    3035
    3136#include <string>
    32 #include <cassert>
    3337#include <OgreRenderWindow.h>
    3438#include <OgreCamera.h>
     39// #include <X11/Xlib.h> TODO: Needed?
    3540
    3641#include "util/ScopedSingletonManager.h"
     
    3843#include "core/ConfigValueIncludes.h"
    3944#include "core/GraphicsManager.h"
     45#include "core/PathConfig.h"
     46#include "core/Resource.h"
    4047#include "core/command/ConsoleCommand.h"
    4148#include "core/command/CommandExecutor.h"
     49
    4250#include "controllers/HumanController.h"
    43 #include "worldentities/CameraPosition.h"
     51#include "graphics/Camera.h"
    4452#include "worldentities/ControllableEntity.h"
    45 #include "graphics/Camera.h"
    46 
    47 
     53
     54#include "ScreenshotManager.h"
    4855
    4956namespace orxonox
     
    5461    ManageScopedSingleton(SkyboxGenerator, ScopeID::Graphics, false);
    5562
    56     SkyboxGenerator::SkyboxGenerator() : iterateOverDirections_(0)
     63    /**
     64    @brief
     65        Constructor. Registers and initializes the singleton.
     66    */
     67    SkyboxGenerator::SkyboxGenerator()
    5768    {
    5869        RegisterRootObject(SkyboxGenerator);
    5970
    6071        this->setConfigValues();
    61         this->takeScreenshot_ = false;
    62         this->captionsRemoved_ = false;
    63     }
    64 
     72       
     73        this->bGenerateSkybox_ = false;
     74        this->bCaptionsRemoved_ = false;
     75        this->bSetup_ = true;
     76        this->bWait_ = false;
     77        this->bCreateFace_ = true;
     78        this->bCleanup_ = true;
     79        this->faceCounter_ = 0;
     80       
     81        this->names_.push_back("fr");
     82        this->names_.push_back("lf");
     83        this->names_.push_back("bk");
     84        this->names_.push_back("rt");
     85        this->names_.push_back("up");
     86        this->names_.push_back("dn");
     87       
     88        this->rotations_.push_back(std::pair<int, int>(90, 0));
     89        this->rotations_.push_back(std::pair<int, int>(90, 0));
     90        this->rotations_.push_back(std::pair<int, int>(90, 0));
     91        this->rotations_.push_back(std::pair<int, int>(90, 90));
     92        this->rotations_.push_back(std::pair<int, int>(0, 180));
     93        this->rotations_.push_back(std::pair<int, int>(0, 90));
     94    }
     95
     96    /**
     97    @brief
     98        Destructor.
     99    */
    65100    SkyboxGenerator::~SkyboxGenerator()
    66101    {
     
    68103    }
    69104
     105    /**
     106    @brief
     107        Sets some config values.
     108    */
    70109    void SkyboxGenerator::setConfigValues( )
    71110    {
    72111        SetConfigValue(skyboxPrefix_, "SkyboxFile_");
    73     }
    74 
     112        SetConfigValue(imageExtension_, ".png");
     113        SetConfigValue(size_, 1024);
     114    }
     115   
     116    /**
     117    @brief
     118        Generate the 6 faces of a skybox.
     119    */
     120    void SkyboxGenerator::createSkybox()
     121    {
     122        // Pause
     123        CommandExecutor::execute("pause");
     124        // Start the skybox generation process.
     125        SkyboxGenerator::getInstance().startSkyboxGeneration();
     126    }
     127
     128    /**
     129    @brief
     130        This is where the skybox generation happens.
     131        Generating a skybox takes several (up to 10) ticks.
     132    */
    75133    void SkyboxGenerator::tick(float dt)
    76134    {
    77         if( takeScreenshot_ == true )
     135        // Whether a skybox is currently being generated.
     136        if(this->bGenerateSkybox_)
    78137        {
    79             if(!this->captionsRemoved_)
    80             {
    81                 CommandExecutor::execute("GametypeStatus displayCaption false");
    82                 this->captionsRemoved_ = true;
     138            // Wait one tick.
     139            if(this->bWait_)
     140            {
     141                this->bWait_ = false;
    83142                return;
    84143            }
    85144
    86             ControllableEntity* ce = HumanController::getLocalControllerSingleton()->getControllableEntity();
    87             Camera* camera = ce->getCamera();
    88             assert(ce);
    89 
    90             Ogre::RenderWindow* w = GraphicsManager::getInstance().getRenderWindow();
    91 
    92 
    93             switch (iterateOverDirections_)
    94             {
    95             case 0 :
    96                 fovy_ = camera->getOgreCamera()->getFOVy();
    97                 camera->getOgreCamera()->setFOVy(Degree(90));
    98                 aspectRatio_ = camera->getOgreCamera()->getAspectRatio();
    99                 camera->getOgreCamera()->setAspectRatio(1);
    100                 iterateOverDirections_++;
    101                 break;
    102             case 1 :
    103                 w->writeContentsToFile(skyboxPrefix_+"fr.png");
    104                 ce->yaw(Degree(90));
    105                 iterateOverDirections_++;
    106                 break;
    107 
    108             case 2 :
    109                 w->writeContentsToFile(skyboxPrefix_+"lf.png");
    110                 ce->yaw(Degree(90));
    111                 iterateOverDirections_++;
    112                 break;
    113 
    114             case 3 :
    115                 w->writeContentsToFile(skyboxPrefix_+"bk.png");
    116                 ce->yaw(Degree(90));
    117                 iterateOverDirections_++;
    118                 break;
    119 
    120             case 4 :
    121                 w->writeContentsToFile(skyboxPrefix_+"rt.png");
    122                 ce->yaw(Degree(90));
    123                 ce->pitch(Degree(90));
    124                 iterateOverDirections_++;
    125                 break;
    126 
    127             case 5 :
    128                 w->writeContentsToFile(skyboxPrefix_+"up.png");
    129                 ce->pitch(Degree(180));
    130                 iterateOverDirections_++;
    131                 break;
    132 
    133             case 6 :
    134                 w->writeContentsToFile(skyboxPrefix_+"dn.png");
    135                 ce->pitch(Degree(90));
    136                 iterateOverDirections_++;
    137                 break;
    138 
    139             case 7 :
    140                 camera->getOgreCamera()->setAspectRatio(aspectRatio_);
    141                 camera->getOgreCamera()->setFOVy(fovy_);
    142                 iterateOverDirections_++;
    143             case 8 :
    144                 iterateOverDirections_ =0;
    145                 takeScreenshot_ = false;
     145            ControllableEntity* entity = NULL;
     146            if(HumanController::getLocalControllerSingleton() != NULL && HumanController::getLocalControllerSingleton()->getControllableEntity() != NULL)
     147                entity = HumanController::getLocalControllerSingleton()->getControllableEntity();
     148            else
     149            {
     150                COUT(1) << "You must be in a level to generate a skybox." << endl;
     151                this->bGenerateSkybox_ = false;
     152                return;
     153            }
     154            Ogre::Camera* camera = entity->getCamera()->getOgreCamera();
     155            Ogre::RenderWindow* renderWindow = GraphicsManager::getInstance().getRenderWindow();
     156           
     157            // Setup the SkyboxGenerator to generate a skybox.
     158            if(this->bSetup_)
     159            {
     160                // If there are captions being displayed, don't.
     161                if(!this->bCaptionsRemoved_)
     162                {
     163                    CommandExecutor::execute("GametypeStatus displayCaption false");
     164                    this->bCaptionsRemoved_ = true;
     165                    return;
     166                }
     167               
     168                // Store the settings for the camera.
     169                this->fovy_ = camera->getFOVy();
     170                this->aspectRatio_ = camera->getAspectRatio();
     171                // Setup the render window.
     172                this->setupRenderWindow(renderWindow);
     173                // Add the log path to the standard resource group.
     174                Ogre::ResourceGroupManager::getSingleton().addResourceLocation(PathConfig::getInstance().getLogPathString(), "FileSystem", Resource::DEFAULT_GROUP);
     175               
     176                COUT(4) << "Setting up SkyboxGenerator..." << endl;
     177               
     178                this->bSetup_ = false;
     179                this->bWait_ = true;
     180            }
     181            // Create one of the faces. (faceCounter_ decides which)
     182            else if(this->bCreateFace_)
     183            {
     184                // Setup the camera.
     185                this->setupCamera(camera);
     186                // Take the picture using the ScreenshotManager and save it.
     187                this->saveImage(ScreenshotManager::getInstance().getScreenshot(camera), this->skyboxPrefix_+this->names_[this->faceCounter_]+this->imageExtension_);
     188                // Rotate the camera to be ready for taking the next picture.
     189                std::pair<int, int> rotate = this->rotations_[this->faceCounter_];
     190                if(rotate.first != 0)
     191                    entity->yaw(Degree(rotate.first));
     192                if(rotate.second != 0)
     193                    entity->pitch(Degree(rotate.second));
     194               
     195                COUT(4) << "Created face number " << this->faceCounter_ << "." << endl;
     196                // Check whether we've generated all 6 faces.
     197                if(++this->faceCounter_ >= 6)
     198                    this->bCreateFace_ = false;
     199            }
     200            // Cleanup after the successful creation of a skybox.
     201            else if(this->bCleanup_)
     202            {
     203                // Reset the camera parameters.
     204                camera->setAspectRatio(this->aspectRatio_);
     205                camera->setFOVy(this->fovy_);
     206                // Restore the render window.
     207                this->restoreRenderWindow(renderWindow);
     208                // Remove the log path from the standard resource group.
     209                Ogre::ResourceGroupManager::getSingleton().removeResourceLocation(PathConfig::getInstance().getLogPathString(), Resource::DEFAULT_GROUP);
     210               
     211                // Reset the flow parameters for the next skybox generation.
     212                this->bGenerateSkybox_ = false;
     213                this->bSetup_ = true;
     214                this->bWait_ = false;
     215                this->bCreateFace_ = true;
     216                this->bCleanup_ = true;
     217                this->faceCounter_ = 0;
     218               
     219                // Display captions again.
     220                CommandExecutor::execute("GametypeStatus displayCaption true");
     221                this->bCaptionsRemoved_ = false;
     222               
     223                // Unpause.
    146224                CommandExecutor::execute("pause");
    147                 CommandExecutor::execute("GametypeStatus displayCaption true");
    148                 this->captionsRemoved_ = false;
    149             }
    150 
     225               
     226                COUT(3) << "Skybox with face size " << this->size_ << "x" << this->size_ << " pixels created. Storing in log/." << endl;
     227            }
    151228        }
    152229    }
    153 
    154     void SkyboxGenerator::createSkybox( )
    155     {
    156         SkyboxGenerator::getInstance().takeScreenshot_ = true;
    157         CommandExecutor::execute("pause");
     230   
     231    /**
     232    @brief
     233        Set up the input camera to be ready to generate a skybox face.
     234    @param camera
     235        The camera to be set up.
     236    */
     237    void SkyboxGenerator::setupCamera(Ogre::Camera* camera)
     238    {
     239        camera->setFOVy(Degree(90));
     240        camera->setAspectRatio(1.0);
     241    }
     242   
     243    /**
     244    @brief
     245        Setup the input render window to be ready to generate the skybox.
     246    @param renderWindow
     247        The render window to be set up.
     248    */
     249    void SkyboxGenerator::setupRenderWindow(Ogre::RenderWindow* renderWindow)
     250    {
     251        // Store current window properties.
     252        this->windowWidth_ = renderWindow->getWidth();
     253        this->windowHeight_ = renderWindow->getHeight();
     254        this->windowFullScreen_ = renderWindow->isFullScreen();
     255        // Store current ScreenshotManager grid size.
     256        this->gridSize_ = ScreenshotManager::getInstance().getGridSize();
     257       
     258        unsigned int size = this->size_;
     259       
     260        // 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.
     261        if(this->windowHeight_ < this->size_ || this->windowWidth_ < this->size_)
     262        {
     263            unsigned int min = std::min(this->windowHeight_, this->windowWidth_);
     264            unsigned int step = 256;
     265            assert(min >= step);
     266            size = step;
     267            while(min >= size+step)
     268                size += step;
     269           
     270            unsigned int gridSize = 1;
     271            while(gridSize*size < this->size_)
     272                gridSize++;
     273           
     274            renderWindow->setFullscreen(false, size, size);
     275            ScreenshotManager::getInstance().setGridSize(gridSize);
     276        }
     277        else
     278            ScreenshotManager::getInstance().setGridSize(1);
     279
     280    }
     281   
     282    /**
     283    @brief
     284        Restore the render window.
     285        Reset the window size, reset the grid size of the ScreenshotManager.
     286    @param renderWindow
     287        The render window to be restored.
     288    */
     289    void SkyboxGenerator::restoreRenderWindow(Ogre::RenderWindow* renderWindow)
     290    {
     291        // Restore window size.
     292        renderWindow->setFullscreen(this->windowFullScreen_, this->windowWidth_, this->windowHeight_);
     293        // Restore grid size.
     294        ScreenshotManager::getInstance().setGridSize(this->gridSize_);
     295    }
     296   
     297    /**
     298    @brief
     299        Resizes and saves the input image under the input name.
     300    @param image
     301        A pointer to the image to be saved. The image is deleted afterwards,
     302    @param name
     303        The desired filename of the image.
     304    */
     305    void SkyboxGenerator::saveImage(Ogre::Image* image, const std::string& name) const
     306    {
     307        image->save(PathConfig::getInstance().getLogPathString()+name);
     308        delete image;
     309        // Loading the resizing, then saving again. This seems stupid, but resizing doesn't seem to work otherwise.
     310        // If someone figures this out, feel free to adjust.
     311        image = new Ogre::Image();
     312        image->load(name, Resource::DEFAULT_GROUP);
     313        image->resize(this->size_, this->size_);
     314        image->save(PathConfig::getInstance().getLogPathString()+name);
     315        delete image;
    158316    }
    159317}
  • code/trunk/src/modules/designtools/SkyboxGenerator.h

    r7163 r8232  
    2323 *      Gion-Andri Cantieni
    2424 *   Co-authors:
    25  *      ...
     25 *      Damian 'Mozork' Frick
    2626 *
    2727 */
    2828
     29/**
     30    @file SkyboxGenerator.h
     31    @brief Definition of the SkyboxGenerator class.
     32    @ingroup Designtools
     33*/
     34
     35#ifndef __SkyboxGenerator_h__
     36#define __SkyboxGenerator_h__
    2937
    3038#include "core/OrxonoxClass.h"
    3139#include "util/Singleton.h"
    3240#include "tools/interfaces/Tickable.h"
     41
    3342#include <OgreMath.h>
    34 
    3543
    3644namespace orxonox
    3745{
     46   
     47    /**
     48    @brief
     49        The SkyboxGenerator class is a singleton that allows for the creation of a skybox from a level by taking pictures to all 6 sides.
     50        The 6 images created by the createSkybox() method are placed in the log folder in your build directory.
     51       
     52        The image filename prefix and the file extension can both be adjusted as config values, so can the desired size of the skybox faces.
     53       
     54    @author
     55        Gion-Andri Cantieni
     56    @author
     57        Damian 'Mozork' Frick
     58    @ingroup Designtools
     59    */
    3860    class SkyboxGenerator : public virtual OrxonoxClass, public Singleton<SkyboxGenerator>, public Tickable
    3961    {
     
    4365            SkyboxGenerator();
    4466            virtual ~SkyboxGenerator();
    45             static void createSkybox( );
    46             void setConfigValues( );
    47             void tick(float dt);
     67            void tick(float dt); // This is where the skybox generation happens.
     68            static void createSkybox(void); // Generate the 6 faces of a skybox.
     69            void setConfigValues(void); // Sets some config values.
     70           
     71            /**
     72            @brief Set the size of the skybox faces to be generated.
     73            @param size The size in pixels.
     74            */
     75            inline void setSize(unsigned int size)
     76                { this->size_ = size; }
     77               
     78        protected:
     79            /**
     80            @brief Starts the generation of the skybox.
     81            */
     82            inline void startSkyboxGeneration(void)
     83                { this->bGenerateSkybox_ = true; }
    4884
    4985        private:
    50             static SkyboxGenerator* singletonPtr_s;
    51             std::string skyboxPrefix_;
    52             bool takeScreenshot_;
    53             int iterateOverDirections_;
    54             float aspectRatio_;
    55             Ogre::Radian fovy_;
    56             bool captionsRemoved_;
     86            void setupCamera(Ogre::Camera* camera); // Set up the input camera to be ready to generate a skybox face.
     87            void setupRenderWindow(Ogre::RenderWindow* renderWindow); // Setup the input render window to be ready to generate the skybox.
     88            void restoreRenderWindow(Ogre::RenderWindow* renderWindow); // Restore the render window.
     89
     90            void saveImage(Ogre::Image* image, const std::string& name) const;
     91           
     92            static SkyboxGenerator* singletonPtr_s; //!< Singleton pointer.
     93           
     94            unsigned int size_; //!< The desired size of the skybox faces.
     95            std::string skyboxPrefix_; //!< Prefix for the generated image files.
     96            std::string imageExtension_; //!< Extension of the generated image files.
     97           
     98            // FLow control variables
     99            bool bGenerateSkybox_; //!< Whether a skybox is currently being generated.
     100            bool bCaptionsRemoved_; //!< Whether the overlays have been removed.
     101            bool bSetup_; //!< Whether the render window is being setup.
     102            bool bWait_; //!< Whether we have to wait for the setup to take effect.
     103            bool bCreateFace_; //!< Whether the faces are being created,
     104            unsigned int faceCounter_; //!< Counter to keep track of which skybox face is being created.
     105            bool bCleanup_; //!< Whether the generator is being cleaned up.
     106           
     107            std::vector<std::string> names_; //!< The names of the image files for the skybox faces to be generated.
     108            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.
     109           
     110            // Storage variables
     111            float aspectRatio_; //!< The backed up aspect ratio of the camera.
     112            Ogre::Radian fovy_; //!< The backed up field of view of the camera.
     113            unsigned int windowWidth_; //!< The backed up window width.
     114            unsigned int windowHeight_; //!< The backed up window height.
     115            bool windowFullScreen_; //!< Whether the window was in fullscreen mode.
     116            unsigned int gridSize_; //!< The backed up grid size of the ScreenshotManager.
     117
    57118    };
    58119}
     120
     121#endif  // __SkyboxGenerator_h__
Note: See TracChangeset for help on using the changeset viewer.