Changeset 8232 for code/trunk/src/modules/designtools/SkyboxGenerator.cc
- Timestamp:
- Apr 11, 2011, 7:37:00 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk/src/modules/designtools/SkyboxGenerator.cc
r8079 r8232 23 23 * Gion-Andri Cantieni 24 24 * Co-authors: 25 * ...25 * Damian 'Mozork' Frick 26 26 * 27 27 */ 28 28 29 /** 30 @file SkyboxGenerator.cc 31 @brief Implementation of the SkyboxGenerator class. 32 */ 33 29 34 #include "SkyboxGenerator.h" 30 35 31 36 #include <string> 32 #include <cassert>33 37 #include <OgreRenderWindow.h> 34 38 #include <OgreCamera.h> 39 // #include <X11/Xlib.h> TODO: Needed? 35 40 36 41 #include "util/ScopedSingletonManager.h" … … 38 43 #include "core/ConfigValueIncludes.h" 39 44 #include "core/GraphicsManager.h" 45 #include "core/PathConfig.h" 46 #include "core/Resource.h" 40 47 #include "core/command/ConsoleCommand.h" 41 48 #include "core/command/CommandExecutor.h" 49 42 50 #include "controllers/HumanController.h" 43 #include " worldentities/CameraPosition.h"51 #include "graphics/Camera.h" 44 52 #include "worldentities/ControllableEntity.h" 45 #include "graphics/Camera.h" 46 47 53 54 #include "ScreenshotManager.h" 48 55 49 56 namespace orxonox … … 54 61 ManageScopedSingleton(SkyboxGenerator, ScopeID::Graphics, false); 55 62 56 SkyboxGenerator::SkyboxGenerator() : iterateOverDirections_(0) 63 /** 64 @brief 65 Constructor. Registers and initializes the singleton. 66 */ 67 SkyboxGenerator::SkyboxGenerator() 57 68 { 58 69 RegisterRootObject(SkyboxGenerator); 59 70 60 71 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 */ 65 100 SkyboxGenerator::~SkyboxGenerator() 66 101 { … … 68 103 } 69 104 105 /** 106 @brief 107 Sets some config values. 108 */ 70 109 void SkyboxGenerator::setConfigValues( ) 71 110 { 72 111 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 */ 75 133 void SkyboxGenerator::tick(float dt) 76 134 { 77 if( takeScreenshot_ == true ) 135 // Whether a skybox is currently being generated. 136 if(this->bGenerateSkybox_) 78 137 { 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; 83 142 return; 84 143 } 85 144 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. 146 224 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 } 151 228 } 152 229 } 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; 158 316 } 159 317 }
Note: See TracChangeset
for help on using the changeset viewer.