Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Apr 11, 2011, 7:37:00 PM (13 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).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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}
Note: See TracChangeset for help on using the changeset viewer.