source: OGRE/trunk/ogrenew/OgreMain/src/OgreRenderSystem.cpp @ 692

Revision 692, 19.8 KB checked in by mattausch, 18 years ago (diff)

adding ogre 1.2 and dependencies

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 "OgreHardwarePixelBuffer.h"
43#include "OgreHardwareOcclusionQuery.h"
44
45namespace Ogre {
46
47    const PlaneList Renderable::msDummyPlaneList; // FIX ME: temporary
48
49    //-----------------------------------------------------------------------
50    RenderSystem::RenderSystem()
51        : mActiveRenderTarget(0)
52        , mTextureManager(0)
53        , mCapabilities(0)
54        , mActiveViewport(0)
55        // This means CULL clockwise vertices, i.e. front of poly is counter-clockwise
56        // This makes it the same as OpenGL and other right-handed systems
57        , mCullingMode(CULL_CLOCKWISE)
58        , mVSync(true)
59                , mWBuffer(false)
60        , mInvertVertexWinding(false)
61        , mCurrentPassIterationCount(0)
62        , mVertexProgramBound(false)
63        , mFragmentProgramBound(false)
64    {
65        // instanciate RenderSystemCapabilities
66        mCapabilities = new RenderSystemCapabilities();
67    }
68
69    //-----------------------------------------------------------------------
70    RenderSystem::~RenderSystem()
71    {
72        shutdown();
73                delete mCapabilities;
74                mCapabilities = 0;
75    }
76    //-----------------------------------------------------------------------
77    void RenderSystem::_initRenderTargets(void)
78    {
79
80        // Init stats
81        for(
82            RenderTargetMap::iterator it = mRenderTargets.begin();
83            it != mRenderTargets.end();
84            ++it )
85        {
86            it->second->resetStatistics();
87        }
88
89    }
90    //-----------------------------------------------------------------------
91    void RenderSystem::_updateAllRenderTargets(void)
92    {
93        // Update all in order of priority
94        // This ensures render-to-texture targets get updated before render windows
95                RenderTargetPriorityMap::iterator itarg, itargend;
96                itargend = mPrioritisedRenderTargets.end();
97                for( itarg = mPrioritisedRenderTargets.begin(); itarg != itargend; ++itarg )
98                {
99                        if( itarg->second->isActive() && itarg->second->isAutoUpdated())
100                                itarg->second->update();
101                }
102    }
103    //-----------------------------------------------------------------------
104    RenderWindow* RenderSystem::initialise(bool autoCreateWindow, const String& windowTitle)
105    {
106        // Have I been registered by call to Root::setRenderSystem?
107                /** Don't do this anymore, just allow via Root
108        RenderSystem* regPtr = Root::getSingleton().getRenderSystem();
109        if (!regPtr || regPtr != this)
110            // Register self - library user has come to me direct
111            Root::getSingleton().setRenderSystem(this);
112                */
113
114
115        // Subclasses should take it from here
116        // They should ALL call this superclass method from
117        //   their own initialise() implementations.
118       
119        mVertexProgramBound = false;
120        mFragmentProgramBound = false;
121
122        return 0;
123    }
124        //---------------------------------------------------------------------
125        RenderTexture * RenderSystem::createRenderTexture( const String & name,
126                unsigned int width, unsigned int height,
127                TextureType texType, PixelFormat internalFormat, const NameValuePairList *miscParams )
128        {
129                /// Create a new 2D texture, and return surface to render to
130        TexturePtr mTexture = TextureManager::getSingleton().createManual( name,
131                        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, texType,
132                        width, height, 0, internalFormat, TU_RENDERTARGET );
133           
134        // Ensure texture loaded and internal resources created
135        mTexture->load();
136
137        return mTexture->getBuffer()->getRenderTarget();
138        }
139    //---------------------------------------------------------------------------------------------
140    void RenderSystem::destroyRenderWindow(const String& name)
141    {
142        destroyRenderTarget(name);
143    }
144    //---------------------------------------------------------------------------------------------
145    void RenderSystem::destroyRenderTexture(const String& name)
146    {
147        destroyRenderTarget(name);
148    }
149    //---------------------------------------------------------------------------------------------
150    void RenderSystem::destroyRenderTarget(const String& name)
151    {
152        RenderTarget* rt = detachRenderTarget(name);
153        delete rt;
154    }
155    //---------------------------------------------------------------------------------------------
156    void RenderSystem::attachRenderTarget( RenderTarget &target )
157    {
158                assert( target.getPriority() < OGRE_NUM_RENDERTARGET_GROUPS );
159
160        mRenderTargets.insert( RenderTargetMap::value_type( target.getName(), &target ) );
161        mPrioritisedRenderTargets.insert(
162            RenderTargetPriorityMap::value_type(target.getPriority(), &target ));
163    }
164
165    //---------------------------------------------------------------------------------------------
166    RenderTarget * RenderSystem::getRenderTarget( const String &name )
167    {
168        RenderTargetMap::iterator it = mRenderTargets.find( name );
169        RenderTarget *ret = NULL;
170
171        if( it != mRenderTargets.end() )
172        {
173            ret = it->second;
174        }
175
176        return ret;
177    }
178
179    //---------------------------------------------------------------------------------------------
180    RenderTarget * RenderSystem::detachRenderTarget( const String &name )
181    {
182        RenderTargetMap::iterator it = mRenderTargets.find( name );
183        RenderTarget *ret = NULL;
184
185        if( it != mRenderTargets.end() )
186        {
187            ret = it->second;
188                       
189                        /* Remove the render target from the priority groups. */
190            RenderTargetPriorityMap::iterator itarg, itargend;
191            itargend = mPrioritisedRenderTargets.end();
192                        for( itarg = mPrioritisedRenderTargets.begin(); itarg != itargend; ++itarg )
193            {
194                                if( itarg->second == ret ) {
195                                        mPrioritisedRenderTargets.erase( itarg );
196                                        break;
197                                }
198            }
199
200            mRenderTargets.erase( it );
201        }
202        /// If detached render target is the active render target, reset active render target
203        if(ret == mActiveRenderTarget)
204            mActiveRenderTarget = 0;
205
206        return ret;
207    }
208    //-----------------------------------------------------------------------
209    Viewport* RenderSystem::_getViewport(void)
210    {
211        return mActiveViewport;
212    }
213    //-----------------------------------------------------------------------
214    void RenderSystem::_setTextureUnitSettings(size_t texUnit, TextureUnitState& tl)
215    {
216        // This method is only ever called to set a texture unit to valid details
217        // The method _disableTextureUnit is called to turn a unit off
218
219        // Texture name
220                if (tl.isBlank())
221                {
222                        _setTexture(texUnit, true, StringUtil::BLANK);
223                }
224                else
225                {
226                        _setTexture(texUnit, true, tl.getTextureName());
227                }
228
229        // Set texture coordinate set
230        _setTextureCoordSet(texUnit, tl.getTextureCoordSet());
231
232        // Set texture layer filtering
233        _setTextureUnitFiltering(texUnit,
234            tl.getTextureFiltering(FT_MIN),
235            tl.getTextureFiltering(FT_MAG),
236            tl.getTextureFiltering(FT_MIP));
237
238        // Set texture layer filtering
239        _setTextureLayerAnisotropy(texUnit, tl.getTextureAnisotropy());
240
241                // Set blend modes
242                // Note, colour before alpha is important
243        _setTextureBlendMode(texUnit, tl.getColourBlendMode());
244        _setTextureBlendMode(texUnit, tl.getAlphaBlendMode());
245
246        // Texture addressing mode
247        _setTextureAddressingMode(texUnit, tl.getTextureAddressingMode() );
248        // Texture border colour
249        _setTextureBorderColour(texUnit, tl.getTextureBorderColour());
250
251        // Set texture effects
252        TextureUnitState::EffectMap::iterator effi;
253        // Iterate over new effects
254        bool anyCalcs = false;
255        for (effi = tl.mEffects.begin(); effi != tl.mEffects.end(); ++effi)
256        {
257            switch (effi->second.type)
258            {
259            case TextureUnitState::ET_ENVIRONMENT_MAP:
260                if (effi->second.subtype == TextureUnitState::ENV_CURVED)
261                {
262                    _setTextureCoordCalculation(texUnit, TEXCALC_ENVIRONMENT_MAP);
263                    anyCalcs = true;
264                }
265                else if (effi->second.subtype == TextureUnitState::ENV_PLANAR)
266                {
267                    _setTextureCoordCalculation(texUnit, TEXCALC_ENVIRONMENT_MAP_PLANAR);
268                    anyCalcs = true;
269                }
270                else if (effi->second.subtype == TextureUnitState::ENV_REFLECTION)
271                {
272                    _setTextureCoordCalculation(texUnit, TEXCALC_ENVIRONMENT_MAP_REFLECTION);
273                    anyCalcs = true;
274                }
275                else if (effi->second.subtype == TextureUnitState::ENV_NORMAL)
276                {
277                    _setTextureCoordCalculation(texUnit, TEXCALC_ENVIRONMENT_MAP_NORMAL);
278                    anyCalcs = true;
279                }
280                break;
281            case TextureUnitState::ET_UVSCROLL:
282                        case TextureUnitState::ET_USCROLL:
283                        case TextureUnitState::ET_VSCROLL:
284            case TextureUnitState::ET_ROTATE:
285            case TextureUnitState::ET_TRANSFORM:
286                break;
287            case TextureUnitState::ET_PROJECTIVE_TEXTURE:
288                _setTextureCoordCalculation(texUnit, TEXCALC_PROJECTIVE_TEXTURE,
289                    effi->second.frustum);
290                anyCalcs = true;
291                break;
292            }
293        }
294        // Ensure any previous texcoord calc settings are reset if there are now none
295        if (!anyCalcs)
296        {
297            _setTextureCoordCalculation(texUnit, TEXCALC_NONE);
298            _setTextureCoordSet(texUnit, tl.getTextureCoordSet());
299        }
300
301        // Change tetxure matrix
302        _setTextureMatrix(texUnit, tl.getTextureTransform());
303
304
305    }
306    //-----------------------------------------------------------------------
307    void RenderSystem::_disableTextureUnit(size_t texUnit)
308    {
309        _setTexture(texUnit, false, "");
310        _setTextureMatrix(texUnit, Matrix4::IDENTITY);
311    }
312    //---------------------------------------------------------------------
313    void RenderSystem::_disableTextureUnitsFrom(size_t texUnit)
314    {
315        for (size_t i = texUnit; i < mCapabilities->getNumTextureUnits(); ++i)
316        {
317            _disableTextureUnit(i);
318        }
319    }
320    //-----------------------------------------------------------------------
321    void RenderSystem::_setTextureUnitFiltering(size_t unit, FilterOptions minFilter,
322            FilterOptions magFilter, FilterOptions mipFilter)
323    {
324        _setTextureUnitFiltering(unit, FT_MIN, minFilter);
325        _setTextureUnitFiltering(unit, FT_MAG, magFilter);
326        _setTextureUnitFiltering(unit, FT_MIP, mipFilter);
327    }
328    //-----------------------------------------------------------------------
329    CullingMode RenderSystem::_getCullingMode(void) const
330    {
331        return mCullingMode;
332    }
333    //-----------------------------------------------------------------------
334    bool RenderSystem::getWaitForVerticalBlank(void) const
335    {
336        return mVSync;
337    }
338    //-----------------------------------------------------------------------
339    void RenderSystem::setWaitForVerticalBlank(bool enabled)
340    {
341        mVSync = enabled;
342    }
343    bool RenderSystem::getWBufferEnabled(void) const
344    {
345        return mWBuffer;
346    }
347    //-----------------------------------------------------------------------
348    void RenderSystem::setWBufferEnabled(bool enabled)
349    {
350        mWBuffer = enabled;
351    }
352    //-----------------------------------------------------------------------
353    void RenderSystem::shutdown(void)
354    {
355                // Remove occlusion queries
356                for (HardwareOcclusionQueryList::iterator i = mHwOcclusionQueries.begin();
357                        i != mHwOcclusionQueries.end(); ++i)
358                {
359                        delete *i;
360                }
361                mHwOcclusionQueries.clear();
362
363        // Remove all the render targets.
364                // (destroy primary target last since others may depend on it)
365                RenderTarget* primary = 0;
366                for (RenderTargetMap::iterator it = mRenderTargets.begin(); it != mRenderTargets.end(); ++it)
367                {
368                        if (!primary && it->second->isPrimary())
369                                primary = it->second;
370                        else
371                                delete it->second;
372                }
373                delete primary;
374                mRenderTargets.clear();
375
376                mPrioritisedRenderTargets.clear();
377    }
378    //-----------------------------------------------------------------------
379    void RenderSystem::_beginGeometryCount(void)
380    {
381        mFaceCount = mVertexCount = 0;
382
383    }
384    //-----------------------------------------------------------------------
385    unsigned int RenderSystem::_getFaceCount(void) const
386    {
387        return static_cast< unsigned int >( mFaceCount );
388    }
389    //-----------------------------------------------------------------------
390    unsigned int RenderSystem::_getVertexCount(void) const
391    {
392        return static_cast< unsigned int >( mVertexCount );
393    }
394    //-----------------------------------------------------------------------
395        void RenderSystem::convertColourValue(const ColourValue& colour, uint32* pDest)
396        {
397                *pDest = VertexElement::convertColourValue(colour, getColourVertexElementType());
398
399        }
400    //-----------------------------------------------------------------------
401    void RenderSystem::_setWorldMatrices(const Matrix4* m, unsigned short count)
402    {
403        // Save these matrices for software blending later
404        for (unsigned short i = 0; i < count; ++i)
405        {
406            mWorldMatrices[i] = m[i];
407        }
408        // Set hardware matrix to nothing
409        _setWorldMatrix(Matrix4::IDENTITY);
410    }
411    //-----------------------------------------------------------------------
412    void RenderSystem::_render(const RenderOperation& op)
413    {
414        // Update stats
415        size_t val;
416
417        if (op.useIndexes)
418            val = op.indexData->indexCount;
419        else
420            val = op.vertexData->vertexCount;
421
422        // account for a pass having multiple iterations
423        if (mCurrentPassIterationCount > 1)
424            val *= mCurrentPassIterationCount;
425
426        switch(op.operationType)
427        {
428                case RenderOperation::OT_TRIANGLE_LIST:
429            mFaceCount += val / 3;
430            break;
431        case RenderOperation::OT_TRIANGLE_STRIP:
432        case RenderOperation::OT_TRIANGLE_FAN:
433            mFaceCount += val - 2;
434            break;
435            case RenderOperation::OT_POINT_LIST:
436            case RenderOperation::OT_LINE_LIST:
437            case RenderOperation::OT_LINE_STRIP:
438                break;
439            }
440
441        mVertexCount += op.vertexData->vertexCount;
442
443    }
444    //-----------------------------------------------------------------------
445    void RenderSystem::setInvertVertexWinding(bool invert)
446    {
447        mInvertVertexWinding = invert;
448    }
449    //-----------------------------------------------------------------------
450    void RenderSystem::setClipPlane (ushort index, const Plane &p)
451    {
452        setClipPlane (index, p.normal.x, p.normal.y, p.normal.z, p.d);
453    }
454    //-----------------------------------------------------------------------
455    void RenderSystem::_notifyCameraRemoved(const Camera* cam)
456    {
457        RenderTargetMap::iterator i, iend;
458        iend = mRenderTargets.end();
459        for (i = mRenderTargets.begin(); i != iend; ++i)
460        {
461            RenderTarget* target = i->second;
462            target->_notifyCameraRemoved(cam);
463        }
464    }
465
466        //---------------------------------------------------------------------
467    bool RenderSystem::updatePassIterationRenderState(void)
468    {
469        if (mCurrentPassIterationCount <= 1)
470            return false;
471
472        --mCurrentPassIterationCount;
473        if (!mActiveVertexGpuProgramParameters.isNull())
474        {
475            mActiveVertexGpuProgramParameters->incPassIterationNumber();
476            bindGpuProgramPassIterationParameters(GPT_VERTEX_PROGRAM);
477        }
478        if (!mActiveFragmentGpuProgramParameters.isNull())
479        {
480            mActiveFragmentGpuProgramParameters->incPassIterationNumber();
481            bindGpuProgramPassIterationParameters(GPT_FRAGMENT_PROGRAM);
482        }
483        return true;
484    }
485
486        //-----------------------------------------------------------------------
487        void RenderSystem::addListener(Listener* l)
488        {
489                mEventListeners.push_back(l);
490        }
491        //-----------------------------------------------------------------------
492        void RenderSystem::removeListener(Listener* l)
493        {
494                mEventListeners.remove(l);
495        }
496        //-----------------------------------------------------------------------
497        void RenderSystem::fireEvent(const String& name, const NameValuePairList* params)
498        {
499                for(ListenerList::iterator i = mEventListeners.begin();
500                        i != mEventListeners.end(); ++i)
501                {
502                        (*i)->eventOccurred(name, params);
503                }
504        }
505        //-----------------------------------------------------------------------
506        void RenderSystem::destroyHardwareOcclusionQuery( HardwareOcclusionQuery *hq)
507        {
508                HardwareOcclusionQueryList::iterator i =
509                        std::find(mHwOcclusionQueries.begin(), mHwOcclusionQueries.end(), hq);
510                if (i != mHwOcclusionQueries.end())
511                {
512                        mHwOcclusionQueries.erase(i);
513                        delete hq;
514                }
515        }
516        //-----------------------------------------------------------------------
517        void RenderSystem::bindGpuProgram(GpuProgram* prg)
518        {
519            switch(prg->getType())
520            {
521        case GPT_VERTEX_PROGRAM:
522            mVertexProgramBound = true;
523                break;
524        case GPT_FRAGMENT_PROGRAM:
525            mFragmentProgramBound = true;
526                break;
527            }
528        }
529        //-----------------------------------------------------------------------
530        void RenderSystem::unbindGpuProgram(GpuProgramType gptype)
531        {
532            switch(gptype)
533            {
534        case GPT_VERTEX_PROGRAM:
535            mVertexProgramBound = false;
536                break;
537        case GPT_FRAGMENT_PROGRAM:
538            mFragmentProgramBound = false;
539                break;
540            }
541        }
542        //-----------------------------------------------------------------------
543        bool RenderSystem::isGpuProgramBound(GpuProgramType gptype)
544        {
545            switch(gptype)
546            {
547        case GPT_VERTEX_PROGRAM:
548            return mVertexProgramBound;
549        case GPT_FRAGMENT_PROGRAM:
550            return mFragmentProgramBound;
551            }
552        // Make compiler happy
553        return false;
554        }
555
556}
557
Note: See TracBrowser for help on using the repository browser.