Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OgreRenderTarget.cpp

Go to the documentation of this file.
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