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/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
Note: See TracChangeset for help on using the changeset viewer.