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         mPriority = OGRE_DEFAULT_RT_GROUP;
00046         mTimer = Root::getSingleton().getTimer();
00047         resetStatistics();
00048     }
00049 
00050     RenderTarget::~RenderTarget()
00051     {
00052         // Delete viewports
00053         for (ViewportList::iterator i = mViewportList.begin();
00054             i != mViewportList.end(); ++i)
00055         {
00056             delete (*i).second;
00057         }
00058 
00059 
00060         // Write closing message
00061         LogManager::getSingleton().logMessage(
00062             LML_NORMAL,
00063             "Render Target '%s' Average FPS: %f Best FPS: %f Worst FPS: %f", 
00064             mName.c_str(), mStats.avgFPS, mStats.bestFPS, mStats.worstFPS );
00065 
00066     }
00067 
00068     const String& RenderTarget::getName(void) const
00069     {
00070         return mName;
00071     }
00072 
00073 
00074     void RenderTarget::getMetrics(unsigned int& width, unsigned int& height, unsigned int& colourDepth)
00075     {
00076         width = mWidth;
00077         height = mHeight;
00078         colourDepth = mColourDepth;
00079     }
00080 
00081     unsigned int RenderTarget::getWidth(void) const
00082     {
00083         return mWidth;
00084     }
00085     unsigned int RenderTarget::getHeight(void) const
00086     {
00087         return mHeight;
00088     }
00089     unsigned int RenderTarget::getColourDepth(void) const
00090     {
00091         return mColourDepth;
00092     }
00093 
00094     void RenderTarget::update(void)
00095     {
00096 
00097         // notify listeners (pre)
00098         firePreUpdate();
00099 
00100         mStats.triangleCount = 0;
00101         // Go through viewports in Z-order
00102         // Tell each to refresh
00103         ViewportList::iterator it = mViewportList.begin();
00104         while (it != mViewportList.end())
00105         {
00106             fireViewportPreUpdate((*it).second);
00107             (*it).second->update();
00108             mStats.triangleCount += (*it).second->_getNumRenderedFaces();
00109             fireViewportPostUpdate((*it).second);
00110             ++it;
00111         }
00112 
00113         // notify listeners (post)
00114         firePostUpdate();
00115 
00116         // Update statistics (always on top)
00117         updateStats();
00118 
00119 
00120     }
00121 
00122     Viewport* RenderTarget::addViewport(Camera* cam, int ZOrder, float left, float top ,
00123         float width , float height)
00124     {
00125         // Check no existing viewport with this Z-order
00126         ViewportList::iterator it = mViewportList.find(ZOrder);
00127 
00128         if (it != mViewportList.end())
00129         {
00130             char msg[256];
00131             sprintf(msg, "Can't create another viewport for %s with Z-Order %i "
00132                 " because a viewport exists with this Z-Order already.",
00133                 this->getName().c_str(), ZOrder);
00134             Except(9999, msg, "RenderTarget::addViewport");
00135         }
00136         // Add viewport to list
00137         // Order based on Z-Order
00138         Viewport* vp = new Viewport(cam, this, left, top, width, height, ZOrder);
00139 
00140         mViewportList.insert(ViewportList::value_type(ZOrder, vp));
00141 
00142         return vp;
00143     }
00144 
00145     void RenderTarget::removeViewport(int ZOrder)
00146     {
00147         ViewportList::iterator it = mViewportList.find(ZOrder);
00148 
00149         if (it != mViewportList.end())
00150         {
00151             delete (*it).second;
00152             mViewportList.erase(ZOrder);
00153         }
00154     }
00155 
00156     void RenderTarget::removeAllViewports(void)
00157     {
00158 
00159 
00160         for (ViewportList::iterator it = mViewportList.begin(); it != mViewportList.end(); ++it)
00161         {
00162             delete (*it).second;
00163         }
00164 
00165         mViewportList.clear();
00166 
00167     }
00168     void RenderTarget::setStatsDisplay(StatFlags sf)
00169     {
00170         mStatFlags = sf;
00171     }
00172 
00173     void RenderTarget::getStatistics(float& lastFPS, float& avgFPS,
00174         float& bestFPS, float& worstFPS) const
00175     {
00176 
00177         // Note - the will have been updated by the last render
00178         lastFPS = mStats.lastFPS;
00179         avgFPS = mStats.avgFPS;
00180         bestFPS = mStats.bestFPS;
00181         worstFPS = mStats.worstFPS;
00182 
00183 
00184     }
00185 
00186     const RenderTarget::FrameStats& RenderTarget::getStatistics(void) const
00187     {
00188         return mStats;
00189     }
00190 
00191     float RenderTarget::getLastFPS() const
00192     {
00193         return mStats.lastFPS;
00194     }
00195     float RenderTarget::getAverageFPS() const
00196     {
00197         return mStats.avgFPS;
00198     }
00199     float RenderTarget::getBestFPS() const
00200     {
00201         return mStats.bestFPS;
00202     }
00203     float RenderTarget::getWorstFPS() const
00204     {
00205         return mStats.worstFPS;
00206     }
00207 
00208     size_t RenderTarget::getTriangleCount(void) const
00209     {
00210         return mStats.triangleCount;
00211     }
00212 
00213     float RenderTarget::getBestFrameTime() const
00214     {
00215         return mStats.bestFrameTime;
00216     }
00217 
00218     float RenderTarget::getWorstFrameTime() const
00219     {
00220         return mStats.worstFrameTime;
00221     }
00222 
00223     void RenderTarget::resetStatistics(void)
00224     {
00225         mStats.avgFPS = 0.0;
00226         mStats.bestFPS = 0.0;
00227         mStats.lastFPS = 0.0;
00228         mStats.worstFPS = 999.0;
00229         mStats.triangleCount = 0;
00230         mStats.bestFrameTime = 999999;
00231         mStats.worstFrameTime = 0;
00232 
00233         mLastTime = mTimer->getMilliseconds();
00234         mLastSecond = mLastTime;
00235         mFrameCount = 0;
00236     }
00237 
00238     void RenderTarget::updateStats(void)
00239     {
00240         ++mFrameCount;
00241         unsigned long thisTime = mTimer->getMilliseconds();
00242 
00243         // check frame time
00244         unsigned long frameTime = thisTime - mLastTime ;
00245         mLastTime = thisTime ;
00246 
00247         mStats.bestFrameTime = std::min(mStats.bestFrameTime, frameTime);
00248         mStats.worstFrameTime = std::max(mStats.worstFrameTime, frameTime);
00249 
00250         // check if new second (update only once per second)
00251         if (thisTime - mLastSecond > 1000) 
00252         { 
00253             // new second - not 100% precise
00254             mStats.lastFPS = (float)mFrameCount / (float)(thisTime - mLastSecond) * 1000.0;
00255 
00256             if (mStats.avgFPS == 0)
00257                 mStats.avgFPS = mStats.lastFPS;
00258             else
00259                 mStats.avgFPS = (mStats.avgFPS + mStats.lastFPS) / 2; // not strictly correct, but good enough
00260 
00261             mStats.bestFPS = std::max(mStats.bestFPS, mStats.lastFPS);
00262             mStats.worstFPS = std::min(mStats.worstFPS, mStats.lastFPS);
00263 
00264             mLastSecond = thisTime ;
00265             mFrameCount  = 0;
00266 
00267         }
00268 
00269     }
00270 
00271     void RenderTarget::getCustomAttribute(const String& name, void* pData)
00272     {
00273         Except(Exception::ERR_INVALIDPARAMS, "Attribute not found.", "RenderTarget::getCustomAttribute");
00274     }
00275     //-----------------------------------------------------------------------
00276     void RenderTarget::setDebugText(const String& text)
00277     {
00278         mDebugText = text;
00279     }
00280     //-----------------------------------------------------------------------
00281     const String & RenderTarget::getDebugText() const
00282     { 
00283         return mDebugText; 
00284     }
00285     //-----------------------------------------------------------------------
00286     void RenderTarget::addListener(RenderTargetListener* listener)
00287     {
00288         mListeners.push_back(listener);
00289     }
00290     //-----------------------------------------------------------------------
00291     void RenderTarget::removeListener(RenderTargetListener* listener)
00292     {
00293         RenderTargetListenerList::iterator i;
00294         for (i = mListeners.begin(); i != mListeners.end(); ++i)
00295         {
00296             if (*i == listener)
00297             {
00298                 mListeners.erase(i);
00299                 break;
00300             }
00301         }
00302 
00303     }
00304     //-----------------------------------------------------------------------
00305     void RenderTarget::removeAllListeners(void)
00306     {
00307         mListeners.clear();
00308     }
00309     //-----------------------------------------------------------------------
00310     void RenderTarget::firePreUpdate(void)
00311     {
00312         RenderTargetEvent evt;
00313         evt.source = this;
00314 
00315         RenderTargetListenerList::iterator i, iend;
00316         i = mListeners.begin();
00317         iend = mListeners.end();
00318         for(; i != iend; ++i)
00319         {
00320             (*i)->preRenderTargetUpdate(evt);
00321         }
00322 
00323 
00324     }
00325     //-----------------------------------------------------------------------
00326     void RenderTarget::firePostUpdate(void)
00327     {
00328         RenderTargetEvent evt;
00329         evt.source = this;
00330 
00331         RenderTargetListenerList::iterator i, iend;
00332         i = mListeners.begin();
00333         iend = mListeners.end();
00334         for(; i != iend; ++i)
00335         {
00336             (*i)->postRenderTargetUpdate(evt);
00337         }
00338     }
00339     //-----------------------------------------------------------------------
00340     unsigned short RenderTarget::getNumViewports(void) const
00341     {
00342         return (unsigned short)mViewportList.size();
00343 
00344     }
00345     //-----------------------------------------------------------------------
00346     Viewport* RenderTarget::getViewport(unsigned short index)
00347     {
00348         assert (index < mViewportList.size() && "Index out of bounds");
00349 
00350         ViewportList::iterator i = mViewportList.begin();
00351         while (index--)
00352             ++i;
00353         return i->second;
00354     }
00355     //-----------------------------------------------------------------------
00356     bool RenderTarget::isActive() const
00357     {
00358         return mActive;
00359     }
00360     //-----------------------------------------------------------------------
00361     void RenderTarget::setActive( bool state )
00362     {
00363         mActive = state;
00364     }
00365     //-----------------------------------------------------------------------
00366     void RenderTarget::fireViewportPreUpdate(Viewport* vp)
00367     {
00368         RenderTargetViewportEvent evt;
00369         evt.source = vp;
00370 
00371         RenderTargetListenerList::iterator i, iend;
00372         i = mListeners.begin();
00373         iend = mListeners.end();
00374         for(; i != iend; ++i)
00375         {
00376             (*i)->preViewportUpdate(evt);
00377         }
00378     }
00379     //-----------------------------------------------------------------------
00380     void RenderTarget::fireViewportPostUpdate(Viewport* vp)
00381     {
00382         RenderTargetViewportEvent evt;
00383         evt.source = vp;
00384 
00385         RenderTargetListenerList::iterator i, iend;
00386         i = mListeners.begin();
00387         iend = mListeners.end();
00388         for(; i != iend; ++i)
00389         {
00390             (*i)->postViewportUpdate(evt);
00391         }
00392     }
00393 
00394     String RenderTarget::writeContentsToTimestampedFile(const String& filenamePrefix, const String& filenameSuffix)
00395     {
00396         struct tm *pTime;
00397         time_t ctTime; time(&ctTime);
00398         pTime = localtime( &ctTime );
00399         std::ostringstream oss;
00400         oss << std::setw(2) << std::setfill('0') << pTime->tm_mon
00401             << std::setw(2) << std::setfill('0') << pTime->tm_mday
00402             << std::setw(2) << std::setfill('0') << pTime->tm_year
00403             << "_" << std::setw(2) << std::setfill('0') << pTime->tm_hour
00404             << std::setw(2) << std::setfill('0') << pTime->tm_min
00405             << std::setw(2) << std::setfill('0') << pTime->tm_sec
00406             << std::setw(3) << std::setfill('0') << (mTimer->getMilliseconds() % 1000);
00407         String filename = filenamePrefix + String(oss.str()) + filenameSuffix;
00408         writeContentsToFile(filename);
00409         return filename;
00410 
00411     }
00412 }        

Copyright © 2002-2003 by The OGRE Team
Last modified Wed Jan 21 00:10:25 2004