source: OGRE/trunk/ogre_changes/obsolete/OgreMain/src/OgreRenderSystem.cpp @ 657

Revision 657, 16.3 KB checked in by mattausch, 18 years ago (diff)

added ogre dependencies and patched ogre sources

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-2005 The OGRE Team
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-----------------------------------------------------------------------------
24*/
25#include "OgreStableHeaders.h"
26// RenderSystem implementation
27// Note that most of this class is abstract since
28//  we cannot know how to implement the behaviour without
29//  being aware of the 3D API. However there are a few
30//  simple functions which can have a base implementation
31
32#include "OgreRenderSystem.h"
33
34#include "OgreRoot.h"
35#include "OgreViewport.h"
36#include "OgreException.h"
37#include "OgreRenderTarget.h"
38#include "OgreRenderWindow.h"
39#include "OgreMeshManager.h"
40#include "OgreMaterial.h"
41#include "OgreTimer.h"
42#include "OgreHardwareOcclusionQuery.h"
43
44namespace Ogre {
45
46    const PlaneList Renderable::msDummyPlaneList; // FIX ME: temporary
47
48    //-----------------------------------------------------------------------
49    RenderSystem::RenderSystem()
50    {
51        mActiveViewport = 0;
52                mActiveRenderTarget = NULL;
53        mTextureManager = 0;
54        mCapabilities = 0;
55        mVSync = true;
56                mWBuffer = false;
57
58
59        // This means CULL clockwise vertices, i.e. front of poly is counter-clockwise
60        // This makes it the same as OpenGL and other right-handed systems
61        mCullingMode = CULL_CLOCKWISE;
62        mInvertVertexWinding = false;
63
64        // instanciate RenderSystemCapabilities
65        mCapabilities = new RenderSystemCapabilities();
66    }
67
68    //-----------------------------------------------------------------------
69    RenderSystem::~RenderSystem()
70    {
71        shutdown();
72                delete mCapabilities;
73                mCapabilities = 0;
74    }
75    //-----------------------------------------------------------------------
76    void RenderSystem::_initRenderTargets(void)
77    {
78
79        // Init stats
80        for(
81            RenderTargetMap::iterator it = mRenderTargets.begin();
82            it != mRenderTargets.end();
83            ++it )
84        {
85            it->second->resetStatistics();
86        }
87
88    }
89    //-----------------------------------------------------------------------
90    void RenderSystem::_updateAllRenderTargets(void)
91    {
92        // Update all in order of priority
93        // This ensures render-to-texture targets get updated before render windows
94                RenderTargetPriorityMap::iterator itarg, itargend;
95                itargend = mPrioritisedRenderTargets.end();
96                for( itarg = mPrioritisedRenderTargets.begin(); itarg != itargend; ++itarg )
97                {
98                        if( itarg->second->isActive() && itarg->second->isAutoUpdated())
99                                itarg->second->update();
100                }
101    }
102    //-----------------------------------------------------------------------
103    RenderWindow* RenderSystem::initialise(bool autoCreateWindow, const String& windowTitle)
104    {
105        // Have I been registered by call to Root::setRenderSystem?
106                /** Don't do this anymore, just allow via Root
107        RenderSystem* regPtr = Root::getSingleton().getRenderSystem();
108        if (!regPtr || regPtr != this)
109            // Register self - library user has come to me direct
110            Root::getSingleton().setRenderSystem(this);
111                */
112
113
114        // Subclasses should take it from here
115        // They should ALL call this superclass method from
116        //   their own initialise() implementations.
117
118        return 0;
119    }
120    //---------------------------------------------------------------------------------------------
121    void RenderSystem::destroyRenderWindow(const String& name)
122    {
123        destroyRenderTarget(name);
124    }
125    //---------------------------------------------------------------------------------------------
126    void RenderSystem::destroyRenderTexture(const String& name)
127    {
128        destroyRenderTarget(name);
129    }
130    //---------------------------------------------------------------------------------------------
131    void RenderSystem::destroyRenderTarget(const String& name)
132    {
133        RenderTarget* rt = detachRenderTarget(name);
134        delete rt;
135    }
136    //---------------------------------------------------------------------------------------------
137    void RenderSystem::attachRenderTarget( RenderTarget &target )
138    {
139                assert( target.getPriority() < OGRE_NUM_RENDERTARGET_GROUPS );
140
141        mRenderTargets.insert( RenderTargetMap::value_type( target.getName(), &target ) );
142        mPrioritisedRenderTargets.insert(
143            RenderTargetPriorityMap::value_type(target.getPriority(), &target ));
144    }
145
146    //---------------------------------------------------------------------------------------------
147    RenderTarget * RenderSystem::getRenderTarget( const String &name )
148    {
149        RenderTargetMap::iterator it = mRenderTargets.find( name );
150        RenderTarget *ret = NULL;
151
152        if( it != mRenderTargets.end() )
153        {
154            ret = it->second;
155        }
156
157        return ret;
158    }
159
160    //---------------------------------------------------------------------------------------------
161    RenderTarget * RenderSystem::detachRenderTarget( const String &name )
162    {
163        RenderTargetMap::iterator it = mRenderTargets.find( name );
164        RenderTarget *ret = NULL;
165
166        if( it != mRenderTargets.end() )
167        {
168            ret = it->second;
169                       
170                        /* Remove the render target from the priority groups. */
171            RenderTargetPriorityMap::iterator itarg, itargend;
172            itargend = mPrioritisedRenderTargets.end();
173                        for( itarg = mPrioritisedRenderTargets.begin(); itarg != itargend; ++itarg )
174            {
175                                if( itarg->second == ret ) {
176                                        mPrioritisedRenderTargets.erase( itarg );
177                                        break;
178                                }
179            }
180
181            mRenderTargets.erase( it );
182        }
183
184        return ret;
185    }
186    //-----------------------------------------------------------------------
187    Viewport* RenderSystem::_getViewport(void)
188    {
189        return mActiveViewport;
190    }
191    //-----------------------------------------------------------------------
192    void RenderSystem::_setTextureUnitSettings(size_t texUnit, TextureUnitState& tl)
193    {
194        // This method is only ever called to set a texture unit to valid details
195        // The method _disableTextureUnit is called to turn a unit off
196
197        // Texture name
198                if (tl.isBlank())
199                {
200                        _setTexture(texUnit, true, StringUtil::BLANK);
201                }
202                else
203                {
204                        _setTexture(texUnit, true, tl.getTextureName());
205                }
206
207        // Set texture coordinate set
208        _setTextureCoordSet(texUnit, tl.getTextureCoordSet());
209
210        // Set texture layer filtering
211        _setTextureUnitFiltering(texUnit,
212            tl.getTextureFiltering(FT_MIN),
213            tl.getTextureFiltering(FT_MAG),
214            tl.getTextureFiltering(FT_MIP));
215
216        // Set texture layer filtering
217        _setTextureLayerAnisotropy(texUnit, tl.getTextureAnisotropy());
218
219                // Set blend modes
220                // Note, colour before alpha is important
221        _setTextureBlendMode(texUnit, tl.getColourBlendMode());
222        _setTextureBlendMode(texUnit, tl.getAlphaBlendMode());
223
224        // Texture addressing mode
225        _setTextureAddressingMode(texUnit, tl.getTextureAddressingMode() );
226
227        // Set texture effects
228        TextureUnitState::EffectMap::iterator effi;
229        // Iterate over new effects
230        bool anyCalcs = false;
231        for (effi = tl.mEffects.begin(); effi != tl.mEffects.end(); ++effi)
232        {
233            switch (effi->second.type)
234            {
235            case TextureUnitState::ET_ENVIRONMENT_MAP:
236                if (effi->second.subtype == TextureUnitState::ENV_CURVED)
237                {
238                    _setTextureCoordCalculation(texUnit, TEXCALC_ENVIRONMENT_MAP);
239                    anyCalcs = true;
240                }
241                else if (effi->second.subtype == TextureUnitState::ENV_PLANAR)
242                {
243                    _setTextureCoordCalculation(texUnit, TEXCALC_ENVIRONMENT_MAP_PLANAR);
244                    anyCalcs = true;
245                }
246                else if (effi->second.subtype == TextureUnitState::ENV_REFLECTION)
247                {
248                    _setTextureCoordCalculation(texUnit, TEXCALC_ENVIRONMENT_MAP_REFLECTION);
249                    anyCalcs = true;
250                }
251                else if (effi->second.subtype == TextureUnitState::ENV_NORMAL)
252                {
253                    _setTextureCoordCalculation(texUnit, TEXCALC_ENVIRONMENT_MAP_NORMAL);
254                    anyCalcs = true;
255                }
256                break;
257            case TextureUnitState::ET_SCROLL:
258            case TextureUnitState::ET_ROTATE:
259            case TextureUnitState::ET_TRANSFORM:
260                break;
261            case TextureUnitState::ET_PROJECTIVE_TEXTURE:
262                _setTextureCoordCalculation(texUnit, TEXCALC_PROJECTIVE_TEXTURE,
263                    effi->second.frustum);
264                anyCalcs = true;
265                break;
266            }
267        }
268        // Ensure any previous texcoord calc settings are reset if there are now none
269        if (!anyCalcs)
270        {
271            _setTextureCoordCalculation(texUnit, TEXCALC_NONE);
272            _setTextureCoordSet(texUnit, tl.getTextureCoordSet());
273        }
274
275        // Change tetxure matrix
276        _setTextureMatrix(texUnit, tl.getTextureTransform());
277
278
279    }
280    //-----------------------------------------------------------------------
281    void RenderSystem::_disableTextureUnit(size_t texUnit)
282    {
283        _setTexture(texUnit, false, "");
284        _setTextureMatrix(texUnit, Matrix4::IDENTITY);
285    }
286    //---------------------------------------------------------------------
287    void RenderSystem::_disableTextureUnitsFrom(size_t texUnit)
288    {
289        for (size_t i = texUnit; i < mCapabilities->getNumTextureUnits(); ++i)
290        {
291            _disableTextureUnit(i);
292        }
293    }
294    //-----------------------------------------------------------------------
295    void RenderSystem::_setTextureUnitFiltering(size_t unit, FilterOptions minFilter,
296            FilterOptions magFilter, FilterOptions mipFilter)
297    {
298        _setTextureUnitFiltering(unit, FT_MIN, minFilter);
299        _setTextureUnitFiltering(unit, FT_MAG, magFilter);
300        _setTextureUnitFiltering(unit, FT_MIP, mipFilter);
301    }
302    //-----------------------------------------------------------------------
303    CullingMode RenderSystem::_getCullingMode(void) const
304    {
305        return mCullingMode;
306    }
307    //-----------------------------------------------------------------------
308    bool RenderSystem::getWaitForVerticalBlank(void) const
309    {
310        return mVSync;
311    }
312    //-----------------------------------------------------------------------
313    void RenderSystem::setWaitForVerticalBlank(bool enabled)
314    {
315        mVSync = enabled;
316    }
317    bool RenderSystem::getWBufferEnabled(void) const
318    {
319        return mWBuffer;
320    }
321    //-----------------------------------------------------------------------
322    void RenderSystem::setWBufferEnabled(bool enabled)
323    {
324        mWBuffer = enabled;
325    }
326    //-----------------------------------------------------------------------
327    void RenderSystem::shutdown(void)
328    {
329                // Remove occlusion queries
330                for (HardwareOcclusionQueryList::iterator i = mHwOcclusionQueries.begin();
331                        i != mHwOcclusionQueries.end(); ++i)
332                {
333                        delete *i;
334                }
335                mHwOcclusionQueries.clear();
336
337        // Remove all the render targets.
338                // (destroy primary target last since others may depend on it)
339                RenderTarget* primary = 0;
340                for (RenderTargetMap::iterator it = mRenderTargets.begin(); it != mRenderTargets.end(); ++it)
341                {
342                        if (!primary && it->second->isPrimary())
343                                primary = it->second;
344                        else
345                                delete it->second;
346                }
347                delete primary;
348                mRenderTargets.clear();
349
350                mPrioritisedRenderTargets.clear();
351    }
352    //-----------------------------------------------------------------------
353    void RenderSystem::_beginGeometryCount(void)
354    {
355        mFaceCount = mVertexCount = 0;
356
357    }
358    //-----------------------------------------------------------------------
359    unsigned int RenderSystem::_getFaceCount(void) const
360    {
361        return static_cast< unsigned int >( mFaceCount );
362    }
363    //-----------------------------------------------------------------------
364    unsigned int RenderSystem::_getVertexCount(void) const
365    {
366        return static_cast< unsigned int >( mVertexCount );
367    }
368    //-----------------------------------------------------------------------
369    void RenderSystem::_setWorldMatrices(const Matrix4* m, unsigned short count)
370    {
371        // Save these matrices for software blending later
372        for (unsigned short i = 0; i < count; ++i)
373        {
374            mWorldMatrices[i] = m[i];
375        }
376        // Set hardware matrix to nothing
377        _setWorldMatrix(Matrix4::IDENTITY);
378    }
379    //-----------------------------------------------------------------------
380    void RenderSystem::_render(const RenderOperation& op)
381    {
382        // Update stats
383        size_t val;
384
385        if (op.useIndexes)
386            val = op.indexData->indexCount;
387        else
388            val = op.vertexData->vertexCount;
389
390        switch(op.operationType)
391        {
392                case RenderOperation::OT_TRIANGLE_LIST:
393            mFaceCount += val / 3;
394            break;
395        case RenderOperation::OT_TRIANGLE_STRIP:
396        case RenderOperation::OT_TRIANGLE_FAN:
397            mFaceCount += val - 2;
398            break;
399            case RenderOperation::OT_POINT_LIST:
400            case RenderOperation::OT_LINE_LIST:
401            case RenderOperation::OT_LINE_STRIP:
402                break;
403            }
404
405        mVertexCount += op.vertexData->vertexCount;
406
407    }
408    //-----------------------------------------------------------------------
409    void RenderSystem::setInvertVertexWinding(bool invert)
410    {
411        mInvertVertexWinding = invert;
412    }
413    //-----------------------------------------------------------------------
414    void RenderSystem::setClipPlane (ushort index, const Plane &p)
415    {
416        setClipPlane (index, p.normal.x, p.normal.y, p.normal.z, p.d);
417    }
418    //-----------------------------------------------------------------------
419    void RenderSystem::_notifyCameraRemoved(const Camera* cam)
420    {
421        RenderTargetMap::iterator i, iend;
422        iend = mRenderTargets.end();
423        for (i = mRenderTargets.begin(); i != iend; ++i)
424        {
425            RenderTarget* target = i->second;
426            target->_notifyCameraRemoved(cam);
427        }
428    }
429        //-----------------------------------------------------------------------
430        void RenderSystem::addListener(Listener* l)
431        {
432                mEventListeners.push_back(l);
433        }
434        //-----------------------------------------------------------------------
435        void RenderSystem::removeListener(Listener* l)
436        {
437                mEventListeners.remove(l);
438        }
439        //-----------------------------------------------------------------------
440        void RenderSystem::fireEvent(const String& name, const NameValuePairList* params)
441        {
442                for(ListenerList::iterator i = mEventListeners.begin();
443                        i != mEventListeners.end(); ++i)
444                {
445                        (*i)->eventOccurred(name, params);
446                }
447        }
448        //-----------------------------------------------------------------------
449        void RenderSystem::destroyHardwareOcclusionQuery( HardwareOcclusionQuery *hq)
450        {
451                for (HardwareOcclusionQueryList::iterator i = mHwOcclusionQueries.begin();
452                        i != mHwOcclusionQueries.end(); ++i)
453                {
454                        if (*i == hq)
455                        {
456                                delete *i;
457                                mHwOcclusionQueries.erase(i);
458                                break;
459                        }
460                }
461        }
462
463}
464
Note: See TracBrowser for help on using the repository browser.