00001 /* 00002 ----------------------------------------------------------------------------- 00003 This source file is part of OGRE 00004 (Object-oriented Graphics Rendering Engine) 00005 For the latest info, see http://www.ogre3d.org/ 00006 00007 Copyright © 2000-2002 The OGRE Team 00008 Also see acknowledgements in Readme.html 00009 00010 This program is free software; you can redistribute it and/or modify it under 00011 the terms of the GNU Lesser General Public License as published by the Free Software 00012 Foundation; either version 2 of the License, or (at your option) any later 00013 version. 00014 00015 This program is distributed in the hope that it will be useful, but WITHOUT 00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License along with 00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00022 http://www.gnu.org/copyleft/lesser.txt. 00023 ----------------------------------------------------------------------------- 00024 */ 00025 #include "OgreStableHeaders.h" 00026 #include "OgreRenderTarget.h" 00027 #include "OgreGuiElement.h" 00028 #include "OgreGuiManager.h" 00029 #include "OgreStringConverter.h" 00030 00031 #include "OgreViewport.h" 00032 #include "OgreException.h" 00033 #include "OgreLogManager.h" 00034 #include "OgreRenderTargetListener.h" 00035 #include "OgrePlatformManager.h" 00036 #include "OgreRoot.h" 00037 00038 namespace Ogre { 00039 00040 RenderTarget::RenderTarget() 00041 { 00042 // Default to no stats display 00043 mStatFlags = SF_NONE; 00044 mActive = true; 00045 mAutoUpdate = true; 00046 mPriority = OGRE_DEFAULT_RT_GROUP; 00047 mTimer = Root::getSingleton().getTimer(); 00048 resetStatistics(); 00049 } 00050 00051 RenderTarget::~RenderTarget() 00052 { 00053 // Delete viewports 00054 for (ViewportList::iterator i = mViewportList.begin(); 00055 i != mViewportList.end(); ++i) 00056 { 00057 delete (*i).second; 00058 } 00059 00060 00061 // Write closing message 00062 LogManager::getSingleton().logMessage( 00063 LML_NORMAL, 00064 "Render Target '%s' Average FPS: %f Best FPS: %f Worst FPS: %f", 00065 mName.c_str(), mStats.avgFPS, mStats.bestFPS, mStats.worstFPS ); 00066 00067 } 00068 00069 const String& RenderTarget::getName(void) const 00070 { 00071 return mName; 00072 } 00073 00074 00075 void RenderTarget::getMetrics(unsigned int& width, unsigned int& height, unsigned int& colourDepth) 00076 { 00077 width = mWidth; 00078 height = mHeight; 00079 colourDepth = mColourDepth; 00080 } 00081 00082 unsigned int RenderTarget::getWidth(void) const 00083 { 00084 return mWidth; 00085 } 00086 unsigned int RenderTarget::getHeight(void) const 00087 { 00088 return mHeight; 00089 } 00090 unsigned int RenderTarget::getColourDepth(void) const 00091 { 00092 return mColourDepth; 00093 } 00094 00095 void RenderTarget::update(void) 00096 { 00097 00098 // notify listeners (pre) 00099 firePreUpdate(); 00100 00101 mStats.triangleCount = 0; 00102 // Go through viewports in Z-order 00103 // Tell each to refresh 00104 ViewportList::iterator it = mViewportList.begin(); 00105 while (it != mViewportList.end()) 00106 { 00107 fireViewportPreUpdate((*it).second); 00108 (*it).second->update(); 00109 mStats.triangleCount += (*it).second->_getNumRenderedFaces(); 00110 fireViewportPostUpdate((*it).second); 00111 ++it; 00112 } 00113 00114 // notify listeners (post) 00115 firePostUpdate(); 00116 00117 // Update statistics (always on top) 00118 updateStats(); 00119 00120 00121 } 00122 00123 Viewport* RenderTarget::addViewport(Camera* cam, int ZOrder, float left, float top , 00124 float width , float height) 00125 { 00126 // Check no existing viewport with this Z-order 00127 ViewportList::iterator it = mViewportList.find(ZOrder); 00128 00129 if (it != mViewportList.end()) 00130 { 00131 char msg[256]; 00132 sprintf(msg, "Can't create another viewport for %s with Z-Order %i " 00133 " because a viewport exists with this Z-Order already.", 00134 this->getName().c_str(), ZOrder); 00135 Except(9999, msg, "RenderTarget::addViewport"); 00136 } 00137 // Add viewport to list 00138 // Order based on Z-Order 00139 Viewport* vp = new Viewport(cam, this, left, top, width, height, ZOrder); 00140 00141 mViewportList.insert(ViewportList::value_type(ZOrder, vp)); 00142 00143 return vp; 00144 } 00145 00146 void RenderTarget::removeViewport(int ZOrder) 00147 { 00148 ViewportList::iterator it = mViewportList.find(ZOrder); 00149 00150 if (it != mViewportList.end()) 00151 { 00152 delete (*it).second; 00153 mViewportList.erase(ZOrder); 00154 } 00155 } 00156 00157 void RenderTarget::removeAllViewports(void) 00158 { 00159 00160 00161 for (ViewportList::iterator it = mViewportList.begin(); it != mViewportList.end(); ++it) 00162 { 00163 delete (*it).second; 00164 } 00165 00166 mViewportList.clear(); 00167 00168 } 00169 void RenderTarget::setStatsDisplay(StatFlags sf) 00170 { 00171 mStatFlags = sf; 00172 } 00173 00174 void RenderTarget::getStatistics(float& lastFPS, float& avgFPS, 00175 float& bestFPS, float& worstFPS) const 00176 { 00177 00178 // Note - the will have been updated by the last render 00179 lastFPS = mStats.lastFPS; 00180 avgFPS = mStats.avgFPS; 00181 bestFPS = mStats.bestFPS; 00182 worstFPS = mStats.worstFPS; 00183 00184 00185 } 00186 00187 const RenderTarget::FrameStats& RenderTarget::getStatistics(void) const 00188 { 00189 return mStats; 00190 } 00191 00192 float RenderTarget::getLastFPS() const 00193 { 00194 return mStats.lastFPS; 00195 } 00196 float RenderTarget::getAverageFPS() const 00197 { 00198 return mStats.avgFPS; 00199 } 00200 float RenderTarget::getBestFPS() const 00201 { 00202 return mStats.bestFPS; 00203 } 00204 float RenderTarget::getWorstFPS() const 00205 { 00206 return mStats.worstFPS; 00207 } 00208 00209 size_t RenderTarget::getTriangleCount(void) const 00210 { 00211 return mStats.triangleCount; 00212 } 00213 00214 float RenderTarget::getBestFrameTime() const 00215 { 00216 return mStats.bestFrameTime; 00217 } 00218 00219 float RenderTarget::getWorstFrameTime() const 00220 { 00221 return mStats.worstFrameTime; 00222 } 00223 00224 void RenderTarget::resetStatistics(void) 00225 { 00226 mStats.avgFPS = 0.0; 00227 mStats.bestFPS = 0.0; 00228 mStats.lastFPS = 0.0; 00229 mStats.worstFPS = 999.0; 00230 mStats.triangleCount = 0; 00231 mStats.bestFrameTime = 999999; 00232 mStats.worstFrameTime = 0; 00233 00234 mLastTime = mTimer->getMilliseconds(); 00235 mLastSecond = mLastTime; 00236 mFrameCount = 0; 00237 } 00238 00239 void RenderTarget::updateStats(void) 00240 { 00241 ++mFrameCount; 00242 unsigned long thisTime = mTimer->getMilliseconds(); 00243 00244 // check frame time 00245 unsigned long frameTime = thisTime - mLastTime ; 00246 mLastTime = thisTime ; 00247 00248 mStats.bestFrameTime = std::min(mStats.bestFrameTime, frameTime); 00249 mStats.worstFrameTime = std::max(mStats.worstFrameTime, frameTime); 00250 00251 // check if new second (update only once per second) 00252 if (thisTime - mLastSecond > 1000) 00253 { 00254 // new second - not 100% precise 00255 mStats.lastFPS = (float)mFrameCount / (float)(thisTime - mLastSecond) * 1000.0; 00256 00257 if (mStats.avgFPS == 0) 00258 mStats.avgFPS = mStats.lastFPS; 00259 else 00260 mStats.avgFPS = (mStats.avgFPS + mStats.lastFPS) / 2; // not strictly correct, but good enough 00261 00262 mStats.bestFPS = std::max(mStats.bestFPS, mStats.lastFPS); 00263 mStats.worstFPS = std::min(mStats.worstFPS, mStats.lastFPS); 00264 00265 mLastSecond = thisTime ; 00266 mFrameCount = 0; 00267 00268 } 00269 00270 } 00271 00272 void RenderTarget::getCustomAttribute(const String& name, void* pData) 00273 { 00274 Except(Exception::ERR_INVALIDPARAMS, "Attribute not found.", "RenderTarget::getCustomAttribute"); 00275 } 00276 //----------------------------------------------------------------------- 00277 void RenderTarget::setDebugText(const String& text) 00278 { 00279 mDebugText = text; 00280 } 00281 //----------------------------------------------------------------------- 00282 const String & RenderTarget::getDebugText() const 00283 { 00284 return mDebugText; 00285 } 00286 //----------------------------------------------------------------------- 00287 void RenderTarget::addListener(RenderTargetListener* listener) 00288 { 00289 mListeners.push_back(listener); 00290 } 00291 //----------------------------------------------------------------------- 00292 void RenderTarget::removeListener(RenderTargetListener* listener) 00293 { 00294 RenderTargetListenerList::iterator i; 00295 for (i = mListeners.begin(); i != mListeners.end(); ++i) 00296 { 00297 if (*i == listener) 00298 { 00299 mListeners.erase(i); 00300 break; 00301 } 00302 } 00303 00304 } 00305 //----------------------------------------------------------------------- 00306 void RenderTarget::removeAllListeners(void) 00307 { 00308 mListeners.clear(); 00309 } 00310 //----------------------------------------------------------------------- 00311 void RenderTarget::firePreUpdate(void) 00312 { 00313 RenderTargetEvent evt; 00314 evt.source = this; 00315 00316 RenderTargetListenerList::iterator i, iend; 00317 i = mListeners.begin(); 00318 iend = mListeners.end(); 00319 for(; i != iend; ++i) 00320 { 00321 (*i)->preRenderTargetUpdate(evt); 00322 } 00323 00324 00325 } 00326 //----------------------------------------------------------------------- 00327 void RenderTarget::firePostUpdate(void) 00328 { 00329 RenderTargetEvent evt; 00330 evt.source = this; 00331 00332 RenderTargetListenerList::iterator i, iend; 00333 i = mListeners.begin(); 00334 iend = mListeners.end(); 00335 for(; i != iend; ++i) 00336 { 00337 (*i)->postRenderTargetUpdate(evt); 00338 } 00339 } 00340 //----------------------------------------------------------------------- 00341 unsigned short RenderTarget::getNumViewports(void) const 00342 { 00343 return (unsigned short)mViewportList.size(); 00344 00345 } 00346 //----------------------------------------------------------------------- 00347 Viewport* RenderTarget::getViewport(unsigned short index) 00348 { 00349 assert (index < mViewportList.size() && "Index out of bounds"); 00350 00351 ViewportList::iterator i = mViewportList.begin(); 00352 while (index--) 00353 ++i; 00354 return i->second; 00355 } 00356 //----------------------------------------------------------------------- 00357 bool RenderTarget::isActive() const 00358 { 00359 return mActive; 00360 } 00361 //----------------------------------------------------------------------- 00362 void RenderTarget::setActive( bool state ) 00363 { 00364 mActive = state; 00365 } 00366 //----------------------------------------------------------------------- 00367 void RenderTarget::fireViewportPreUpdate(Viewport* vp) 00368 { 00369 RenderTargetViewportEvent evt; 00370 evt.source = vp; 00371 00372 RenderTargetListenerList::iterator i, iend; 00373 i = mListeners.begin(); 00374 iend = mListeners.end(); 00375 for(; i != iend; ++i) 00376 { 00377 (*i)->preViewportUpdate(evt); 00378 } 00379 } 00380 //----------------------------------------------------------------------- 00381 void RenderTarget::fireViewportPostUpdate(Viewport* vp) 00382 { 00383 RenderTargetViewportEvent evt; 00384 evt.source = vp; 00385 00386 RenderTargetListenerList::iterator i, iend; 00387 i = mListeners.begin(); 00388 iend = mListeners.end(); 00389 for(; i != iend; ++i) 00390 { 00391 (*i)->postViewportUpdate(evt); 00392 } 00393 } 00394 //----------------------------------------------------------------------- 00395 String RenderTarget::writeContentsToTimestampedFile(const String& filenamePrefix, const String& filenameSuffix) 00396 { 00397 struct tm *pTime; 00398 time_t ctTime; time(&ctTime); 00399 pTime = localtime( &ctTime ); 00400 std::ostringstream oss; 00401 oss << std::setw(2) << std::setfill('0') << pTime->tm_mon 00402 << std::setw(2) << std::setfill('0') << pTime->tm_mday 00403 << std::setw(2) << std::setfill('0') << pTime->tm_year 00404 << "_" << std::setw(2) << std::setfill('0') << pTime->tm_hour 00405 << std::setw(2) << std::setfill('0') << pTime->tm_min 00406 << std::setw(2) << std::setfill('0') << pTime->tm_sec 00407 << std::setw(3) << std::setfill('0') << (mTimer->getMilliseconds() % 1000); 00408 String filename = filenamePrefix + String(oss.str()) + filenameSuffix; 00409 writeContentsToFile(filename); 00410 return filename; 00411 00412 } 00413 //----------------------------------------------------------------------- 00414 void RenderTarget::_notifyCameraRemoved(const Camera* cam) 00415 { 00416 ViewportList::iterator i, iend; 00417 iend = mViewportList.end(); 00418 for (i = mViewportList.begin(); i != iend; ++i) 00419 { 00420 Viewport* v = i->second; 00421 if (v->getCamera() == cam) 00422 { 00423 // disable camera link 00424 v->setCamera(0); 00425 } 00426 } 00427 } 00428 //----------------------------------------------------------------------- 00429 void RenderTarget::setAutoUpdated(bool autoup) 00430 { 00431 mAutoUpdate = autoup; 00432 } 00433 //----------------------------------------------------------------------- 00434 bool RenderTarget::isAutoUpdated(void) const 00435 { 00436 return mAutoUpdate; 00437 } 00438 00439 00440 }
Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:42 2004