Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/src/OgreRenderTarget.cpp @ 5

Last change on this file since 5 was 5, checked in by anonymous, 17 years ago

=hoffentlich gehts jetzt

File size: 14.2 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4(Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29#include "OgreStableHeaders.h"
30#include "OgreRenderTarget.h"
31#include "OgreStringConverter.h"
32
33#include "OgreViewport.h"
34#include "OgreException.h"
35#include "OgreLogManager.h"
36#include "OgreRenderTargetListener.h"
37#include "OgreRoot.h"
38
39namespace Ogre {
40
41    RenderTarget::RenderTarget()
42                :mPriority(OGRE_DEFAULT_RT_GROUP),
43                mActive(true),
44                mAutoUpdate(true)
45    {
46        mTimer = Root::getSingleton().getTimer();
47        resetStatistics();
48    }
49
50    RenderTarget::~RenderTarget()
51    {
52        // Delete viewports
53        for (ViewportList::iterator i = mViewportList.begin();
54            i != mViewportList.end(); ++i)
55        {
56            fireViewportRemoved(i->second);
57            delete (*i).second;
58        }
59
60
61        // Write closing message
62                StringUtil::StrStreamType msg;
63                msg << "Render Target '" << mName << "' "
64                        << "Average FPS: " << mStats.avgFPS << " "
65                        << "Best FPS: " << mStats.bestFPS << " "
66                        << "Worst FPS: " << mStats.worstFPS; 
67        LogManager::getSingleton().logMessage(msg.str());
68
69    }
70
71    const String& RenderTarget::getName(void) const
72    {
73        return mName;
74    }
75
76
77    void RenderTarget::getMetrics(unsigned int& width, unsigned int& height, unsigned int& colourDepth)
78    {
79        width = mWidth;
80        height = mHeight;
81        colourDepth = mColourDepth;
82    }
83
84    unsigned int RenderTarget::getWidth(void) const
85    {
86        return mWidth;
87    }
88    unsigned int RenderTarget::getHeight(void) const
89    {
90        return mHeight;
91    }
92    unsigned int RenderTarget::getColourDepth(void) const
93    {
94        return mColourDepth;
95    }
96
97    void RenderTarget::update(void)
98    {
99
100        // notify listeners (pre)
101        firePreUpdate();
102
103        mStats.triangleCount = 0;
104        mStats.batchCount = 0;
105        // Go through viewports in Z-order
106        // Tell each to refresh
107        ViewportList::iterator it = mViewportList.begin();
108        while (it != mViewportList.end())
109        {
110            fireViewportPreUpdate((*it).second);
111            (*it).second->update();
112            mStats.triangleCount += (*it).second->_getNumRenderedFaces();
113            mStats.batchCount += (*it).second->_getNumRenderedBatches();
114            fireViewportPostUpdate((*it).second);
115            ++it;
116        }
117
118        // notify listeners (post)
119        firePostUpdate();
120
121        // Update statistics (always on top)
122        updateStats();
123
124
125    }
126
127    Viewport* RenderTarget::addViewport(Camera* cam, int ZOrder, float left, float top ,
128        float width , float height)
129    {
130        // Check no existing viewport with this Z-order
131        ViewportList::iterator it = mViewportList.find(ZOrder);
132
133        if (it != mViewportList.end())
134        {
135                        StringUtil::StrStreamType str;
136                        str << "Can't create another viewport for "
137                                << mName << " with Z-Order " << ZOrder
138                                << " because a viewport exists with this Z-Order already.";
139                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, str.str(), "RenderTarget::addViewport");
140        }
141        // Add viewport to list
142        // Order based on Z-Order
143        Viewport* vp = new Viewport(cam, this, left, top, width, height, ZOrder);
144
145        mViewportList.insert(ViewportList::value_type(ZOrder, vp));
146
147                fireViewportAdded(vp);
148
149        return vp;
150    }
151        //-----------------------------------------------------------------------
152    void RenderTarget::removeViewport(int ZOrder)
153    {
154        ViewportList::iterator it = mViewportList.find(ZOrder);
155
156        if (it != mViewportList.end())
157        {
158                        fireViewportRemoved((*it).second);
159            delete (*it).second;
160            mViewportList.erase(ZOrder);
161        }
162    }
163
164    void RenderTarget::removeAllViewports(void)
165    {
166
167
168        for (ViewportList::iterator it = mViewportList.begin(); it != mViewportList.end(); ++it)
169        {
170            fireViewportRemoved(it->second);
171            delete (*it).second;
172        }
173
174        mViewportList.clear();
175
176    }
177
178    void RenderTarget::getStatistics(float& lastFPS, float& avgFPS,
179        float& bestFPS, float& worstFPS) const
180    {
181
182        // Note - the will have been updated by the last render
183        lastFPS = mStats.lastFPS;
184        avgFPS = mStats.avgFPS;
185        bestFPS = mStats.bestFPS;
186        worstFPS = mStats.worstFPS;
187
188
189    }
190
191    const RenderTarget::FrameStats& RenderTarget::getStatistics(void) const
192    {
193        return mStats;
194    }
195
196    float RenderTarget::getLastFPS() const
197    {
198        return mStats.lastFPS;
199    }
200    float RenderTarget::getAverageFPS() const
201    {
202        return mStats.avgFPS;
203    }
204    float RenderTarget::getBestFPS() const
205    {
206        return mStats.bestFPS;
207    }
208    float RenderTarget::getWorstFPS() const
209    {
210        return mStats.worstFPS;
211    }
212
213    size_t RenderTarget::getTriangleCount(void) const
214    {
215        return mStats.triangleCount;
216    }
217
218    size_t RenderTarget::getBatchCount(void) const
219    {
220        return mStats.batchCount;
221    }
222
223    float RenderTarget::getBestFrameTime() const
224    {
225        return mStats.bestFrameTime;
226    }
227
228    float RenderTarget::getWorstFrameTime() const
229    {
230        return mStats.worstFrameTime;
231    }
232
233    void RenderTarget::resetStatistics(void)
234    {
235        mStats.avgFPS = 0.0;
236        mStats.bestFPS = 0.0;
237        mStats.lastFPS = 0.0;
238        mStats.worstFPS = 999.0;
239        mStats.triangleCount = 0;
240        mStats.batchCount = 0;
241        mStats.bestFrameTime = 999999;
242        mStats.worstFrameTime = 0;
243
244        mLastTime = mTimer->getMilliseconds();
245        mLastSecond = mLastTime;
246        mFrameCount = 0;
247    }
248
249    void RenderTarget::updateStats(void)
250    {
251        ++mFrameCount;
252        unsigned long thisTime = mTimer->getMilliseconds();
253
254        // check frame time
255        unsigned long frameTime = thisTime - mLastTime ;
256        mLastTime = thisTime ;
257
258        mStats.bestFrameTime = std::min(mStats.bestFrameTime, frameTime);
259        mStats.worstFrameTime = std::max(mStats.worstFrameTime, frameTime);
260
261        // check if new second (update only once per second)
262        if (thisTime - mLastSecond > 1000) 
263        { 
264            // new second - not 100% precise
265            mStats.lastFPS = (float)mFrameCount / (float)(thisTime - mLastSecond) * 1000.0;
266
267            if (mStats.avgFPS == 0)
268                mStats.avgFPS = mStats.lastFPS;
269            else
270                mStats.avgFPS = (mStats.avgFPS + mStats.lastFPS) / 2; // not strictly correct, but good enough
271
272            mStats.bestFPS = std::max(mStats.bestFPS, mStats.lastFPS);
273            mStats.worstFPS = std::min(mStats.worstFPS, mStats.lastFPS);
274
275            mLastSecond = thisTime ;
276            mFrameCount  = 0;
277
278        }
279
280    }
281
282    void RenderTarget::getCustomAttribute(const String& name, void* pData)
283    {
284        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Attribute not found.", "RenderTarget::getCustomAttribute");
285    }
286    //-----------------------------------------------------------------------
287    void RenderTarget::addListener(RenderTargetListener* listener)
288    {
289        mListeners.push_back(listener);
290    }
291    //-----------------------------------------------------------------------
292    void RenderTarget::removeListener(RenderTargetListener* listener)
293    {
294        RenderTargetListenerList::iterator i;
295        for (i = mListeners.begin(); i != mListeners.end(); ++i)
296        {
297            if (*i == listener)
298            {
299                mListeners.erase(i);
300                break;
301            }
302        }
303
304    }
305    //-----------------------------------------------------------------------
306    void RenderTarget::removeAllListeners(void)
307    {
308        mListeners.clear();
309    }
310    //-----------------------------------------------------------------------
311    void RenderTarget::firePreUpdate(void)
312    {
313        RenderTargetEvent evt;
314        evt.source = this;
315
316        RenderTargetListenerList::iterator i, iend;
317        i = mListeners.begin();
318        iend = mListeners.end();
319        for(; i != iend; ++i)
320        {
321            (*i)->preRenderTargetUpdate(evt);
322        }
323
324
325    }
326    //-----------------------------------------------------------------------
327    void RenderTarget::firePostUpdate(void)
328    {
329        RenderTargetEvent evt;
330        evt.source = this;
331
332        RenderTargetListenerList::iterator i, iend;
333        i = mListeners.begin();
334        iend = mListeners.end();
335        for(; i != iend; ++i)
336        {
337            (*i)->postRenderTargetUpdate(evt);
338        }
339    }
340    //-----------------------------------------------------------------------
341    unsigned short RenderTarget::getNumViewports(void) const
342    {
343        return (unsigned short)mViewportList.size();
344
345    }
346    //-----------------------------------------------------------------------
347    Viewport* RenderTarget::getViewport(unsigned short index)
348    {
349        assert (index < mViewportList.size() && "Index out of bounds");
350
351        ViewportList::iterator i = mViewportList.begin();
352        while (index--)
353            ++i;
354        return i->second;
355    }
356    //-----------------------------------------------------------------------
357    bool RenderTarget::isActive() const
358    {
359        return mActive;
360    }
361    //-----------------------------------------------------------------------
362    void RenderTarget::setActive( bool state )
363    {
364        mActive = state;
365    }
366    //-----------------------------------------------------------------------
367    void RenderTarget::fireViewportPreUpdate(Viewport* vp)
368    {
369        RenderTargetViewportEvent evt;
370        evt.source = vp;
371
372        RenderTargetListenerList::iterator i, iend;
373        i = mListeners.begin();
374        iend = mListeners.end();
375        for(; i != iend; ++i)
376        {
377            (*i)->preViewportUpdate(evt);
378        }
379    }
380    //-----------------------------------------------------------------------
381    void RenderTarget::fireViewportPostUpdate(Viewport* vp)
382    {
383        RenderTargetViewportEvent evt;
384        evt.source = vp;
385
386        RenderTargetListenerList::iterator i, iend;
387        i = mListeners.begin();
388        iend = mListeners.end();
389        for(; i != iend; ++i)
390        {
391            (*i)->postViewportUpdate(evt);
392        }
393    }
394        //-----------------------------------------------------------------------
395        void RenderTarget::fireViewportAdded(Viewport* vp)
396        {
397                RenderTargetViewportEvent evt;
398                evt.source = vp;
399
400                RenderTargetListenerList::iterator i, iend;
401                i = mListeners.begin();
402                iend = mListeners.end();
403                for(; i != iend; ++i)
404                {
405                        (*i)->viewportAdded(evt);
406                }
407        }
408        //-----------------------------------------------------------------------
409        void RenderTarget::fireViewportRemoved(Viewport* vp)
410        {
411                RenderTargetViewportEvent evt;
412                evt.source = vp;
413
414                // Make a temp copy of the listeners
415                // some will want to remove themselves as listeners when they get this
416                RenderTargetListenerList tempList = mListeners;
417
418                RenderTargetListenerList::iterator i, iend;
419                i = tempList.begin();
420                iend = tempList.end();
421                for(; i != iend; ++i)
422                {
423                        (*i)->viewportRemoved(evt);
424                }
425        }
426    //-----------------------------------------------------------------------
427    String RenderTarget::writeContentsToTimestampedFile(const String& filenamePrefix, const String& filenameSuffix)
428    {
429        struct tm *pTime;
430        time_t ctTime; time(&ctTime);
431        pTime = localtime( &ctTime );
432        std::ostringstream oss;
433        oss     << std::setw(2) << std::setfill('0') << (pTime->tm_mon + 1)
434            << std::setw(2) << std::setfill('0') << pTime->tm_mday
435            << std::setw(2) << std::setfill('0') << (pTime->tm_year + 1900)
436            << "_" << std::setw(2) << std::setfill('0') << pTime->tm_hour
437            << std::setw(2) << std::setfill('0') << pTime->tm_min
438            << std::setw(2) << std::setfill('0') << pTime->tm_sec
439            << std::setw(3) << std::setfill('0') << (mTimer->getMilliseconds() % 1000);
440        String filename = filenamePrefix + String(oss.str()) + filenameSuffix;
441        writeContentsToFile(filename);
442        return filename;
443
444    }
445    //-----------------------------------------------------------------------
446    void RenderTarget::_notifyCameraRemoved(const Camera* cam)
447    {
448        ViewportList::iterator i, iend;
449        iend = mViewportList.end();
450        for (i = mViewportList.begin(); i != iend; ++i)
451        {
452            Viewport* v = i->second;
453            if (v->getCamera() == cam)
454            {
455                // disable camera link
456                v->setCamera(0);
457            }
458        }
459    }
460    //-----------------------------------------------------------------------
461    void RenderTarget::setAutoUpdated(bool autoup)
462    {
463        mAutoUpdate = autoup;
464    }
465    //-----------------------------------------------------------------------
466    bool RenderTarget::isAutoUpdated(void) const
467    {
468        return mAutoUpdate;
469    }
470    //-----------------------------------------------------------------------
471    bool RenderTarget::isPrimary(void) const
472    {
473        // RenderWindow will override and return true for the primary window
474        return false;
475    }
476    //-----------------------------------------------------------------------
477    RenderTarget::Impl *RenderTarget::_getImpl()
478    {
479        return 0;
480    }
481
482}       
Note: See TracBrowser for help on using the repository browser.