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

OgreRenderSystem.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 // RenderSystem implementation
00027 // Note that most of this class is abstract since
00028 //  we cannot know how to implement the behaviour without
00029 //  being aware of the 3D API. However there are a few
00030 //  simple functions which can have a base implementation
00031 
00032 #include "OgreRenderSystem.h"
00033 
00034 #include "OgreRoot.h"
00035 #include "OgreViewport.h"
00036 #include "OgreException.h"
00037 #include "OgreRenderTarget.h"
00038 #include "OgreRenderWindow.h"
00039 #include "OgreMeshManager.h"
00040 #include "OgreMaterial.h"
00041 #include "OgreTimer.h"
00042 
00043 namespace Ogre {
00044 
00045     const PlaneList Renderable::msDummyPlaneList; // FIX ME: temporary
00046 
00047     //-----------------------------------------------------------------------
00048     RenderSystem::RenderSystem()
00049     {
00050         mActiveViewport = 0;
00051         mActiveRenderTarget = NULL;
00052         mTextureManager = 0;
00053         mCapabilities = 0;
00054         mVSync = true;
00055         mWBuffer = false;
00056 
00057 
00058         // This means CULL clockwise vertices, i.e. front of poly is counter-clockwise
00059         // This makes it the same as OpenGL and other right-handed systems
00060         mCullingMode = CULL_CLOCKWISE;
00061         mInvertVertexWinding = false;
00062 
00063         // instanciate RenderSystemCapabilities
00064         mCapabilities = new RenderSystemCapabilities();
00065     }
00066 
00067     //-----------------------------------------------------------------------
00068     RenderSystem::~RenderSystem()
00069     {
00070         shutdown();
00071     }
00072     //-----------------------------------------------------------------------
00073     void RenderSystem::_initRenderTargets(void)
00074     {
00075 
00076         // Init stats
00077         for(
00078             RenderTargetMap::iterator it = mRenderTargets.begin();
00079             it != mRenderTargets.end();
00080             ++it )
00081         {
00082             it->second->resetStatistics();
00083         }
00084 
00085     }
00086     //-----------------------------------------------------------------------
00087     void RenderSystem::_updateAllRenderTargets(void)
00088     {
00089         // Update all in order of priority
00090         // This ensures render-to-texture targets get updated before render windows
00091         RenderTargetPriorityMap::iterator itarg, itargend;
00092         itargend = mPrioritisedRenderTargets.end();
00093         for( itarg = mPrioritisedRenderTargets.begin(); itarg != itargend; ++itarg )
00094         {
00095             if( itarg->second->isActive() && itarg->second->isAutoUpdated())
00096                 itarg->second->update();
00097         }
00098     }
00099     //-----------------------------------------------------------------------
00100     RenderWindow* RenderSystem::initialise(bool autoCreateWindow, const String& windowTitle)
00101     {
00102         // Have I been registered by call to Root::setRenderSystem?
00111         // Subclasses should take it from here
00112         // They should ALL call this superclass method from
00113         //   their own initialise() implementations.
00114 
00115         return 0;
00116     }
00117     //---------------------------------------------------------------------------------------------
00118     void RenderSystem::destroyRenderWindow(const String& name)
00119     {
00120         destroyRenderTarget(name);
00121     }
00122     //---------------------------------------------------------------------------------------------
00123     void RenderSystem::destroyRenderTexture(const String& name)
00124     {
00125         destroyRenderTarget(name);
00126     }
00127     //---------------------------------------------------------------------------------------------
00128     void RenderSystem::destroyRenderTarget(const String& name)
00129     {
00130         RenderTarget* rt = detachRenderTarget(name);
00131         delete rt;
00132     }
00133     //---------------------------------------------------------------------------------------------
00134     void RenderSystem::attachRenderTarget( RenderTarget &target )
00135     {
00136         assert( target.getPriority() < OGRE_NUM_RENDERTARGET_GROUPS );
00137 
00138         mRenderTargets.insert( RenderTargetMap::value_type( target.getName(), &target ) );
00139         mPrioritisedRenderTargets.insert(
00140             RenderTargetPriorityMap::value_type(target.getPriority(), &target ));
00141     }
00142 
00143     //---------------------------------------------------------------------------------------------
00144     RenderTarget * RenderSystem::getRenderTarget( const String &name )
00145     {
00146         RenderTargetMap::iterator it = mRenderTargets.find( name );
00147         RenderTarget *ret = NULL;
00148 
00149         if( it != mRenderTargets.end() )
00150         {
00151             ret = it->second;
00152         }
00153 
00154         return ret;
00155     }
00156 
00157     //---------------------------------------------------------------------------------------------
00158     RenderTarget * RenderSystem::detachRenderTarget( const String &name )
00159     {
00160         RenderTargetMap::iterator it = mRenderTargets.find( name );
00161         RenderTarget *ret = NULL;
00162 
00163         if( it != mRenderTargets.end() )
00164         {
00165             ret = it->second;
00166             
00167             /* Remove the render target from the priority groups. */
00168             RenderTargetPriorityMap::iterator itarg, itargend;
00169             itargend = mPrioritisedRenderTargets.end();
00170             for( itarg = mPrioritisedRenderTargets.begin(); itarg != itargend; ++itarg )
00171             {
00172                 if( itarg->second == ret ) {
00173                     mPrioritisedRenderTargets.erase( itarg );
00174                     break;
00175                 }
00176             }
00177 
00178             mRenderTargets.erase( it );
00179         }
00180 
00181         return ret;
00182     }
00183     //-----------------------------------------------------------------------
00184     Viewport* RenderSystem::_getViewport(void)
00185     {
00186         return mActiveViewport;
00187     }
00188     //-----------------------------------------------------------------------
00189     void RenderSystem::_setTextureUnitSettings(size_t texUnit, TextureUnitState& tl)
00190     {
00191         // This method is only ever called to set a texture unit to valid details
00192         // The method _disableTextureUnit is called to turn a unit off
00193 
00194         // Texture name
00195         _setTexture(texUnit, true, tl.getTextureName());
00196 
00197         // Set texture coordinate set
00198         _setTextureCoordSet(texUnit, tl.getTextureCoordSet());
00199 
00200         // Set texture layer filtering
00201         _setTextureUnitFiltering(texUnit, 
00202             tl.getTextureFiltering(FT_MIN), 
00203             tl.getTextureFiltering(FT_MAG), 
00204             tl.getTextureFiltering(FT_MIP));
00205 
00206         // Set texture layer filtering
00207         _setTextureLayerAnisotropy(texUnit, tl.getTextureAnisotropy());
00208 
00209         // Set blend modes
00210         _setTextureBlendMode(texUnit, tl.getColourBlendMode());
00211         _setTextureBlendMode(texUnit, tl.getAlphaBlendMode());
00212 
00213         // Texture addressing mode
00214         _setTextureAddressingMode(texUnit, tl.getTextureAddressingMode() );
00215 
00216         // Set texture effects
00217         TextureUnitState::EffectMap::iterator effi;
00218         // Iterate over new effects
00219         bool anyCalcs = false;
00220         for (effi = tl.mEffects.begin(); effi != tl.mEffects.end(); ++effi)
00221         {
00222             switch (effi->second.type)
00223             {
00224             case TextureUnitState::ET_ENVIRONMENT_MAP:
00225                 if (effi->second.subtype == TextureUnitState::ENV_CURVED)
00226                 {
00227                     _setTextureCoordCalculation(texUnit, TEXCALC_ENVIRONMENT_MAP);
00228                     anyCalcs = true;
00229                 }
00230                 else if (effi->second.subtype == TextureUnitState::ENV_PLANAR)
00231                 {
00232                     _setTextureCoordCalculation(texUnit, TEXCALC_ENVIRONMENT_MAP_PLANAR);
00233                     anyCalcs = true;
00234                 }
00235                 else if (effi->second.subtype == TextureUnitState::ENV_REFLECTION)
00236                 {
00237                     _setTextureCoordCalculation(texUnit, TEXCALC_ENVIRONMENT_MAP_REFLECTION);
00238                     anyCalcs = true;
00239                 }
00240                 else if (effi->second.subtype == TextureUnitState::ENV_NORMAL)
00241                 {
00242                     _setTextureCoordCalculation(texUnit, TEXCALC_ENVIRONMENT_MAP_NORMAL);
00243                     anyCalcs = true;
00244                 }
00245                 break;
00246             case TextureUnitState::ET_SCROLL:
00247             case TextureUnitState::ET_ROTATE:
00248             case TextureUnitState::ET_TRANSFORM:
00249                 break;
00250             case TextureUnitState::ET_PROJECTIVE_TEXTURE:
00251                 _setTextureCoordCalculation(texUnit, TEXCALC_PROJECTIVE_TEXTURE, 
00252                     effi->second.frustum);
00253                 anyCalcs = true;
00254                 break;
00255             }
00256         }
00257         // Ensure any previous texcoord calc settings are reset if there are now none
00258         if (!anyCalcs)
00259         {
00260             _setTextureCoordCalculation(texUnit, TEXCALC_NONE);
00261             _setTextureCoordSet(texUnit, tl.getTextureCoordSet());
00262         }
00263 
00264         // Change tetxure matrix 
00265         _setTextureMatrix(texUnit, tl.getTextureTransform());
00266 
00267         // Set alpha rejection
00268         _setAlphaRejectSettings(tl.getAlphaRejectFunction(), 
00269             tl.getAlphaRejectValue());
00270 
00271     }
00272     //-----------------------------------------------------------------------
00273     void RenderSystem::_disableTextureUnit(size_t texUnit)
00274     {
00275         _setTexture(texUnit, false, "");
00276         _setTextureMatrix(texUnit, Matrix4::IDENTITY);
00277     }
00278     //---------------------------------------------------------------------
00279     void RenderSystem::_disableTextureUnitsFrom(size_t texUnit)
00280     {
00281         for (size_t i = texUnit; i < mCapabilities->getNumTextureUnits(); ++i)
00282         {
00283             _disableTextureUnit(i);
00284         }
00285     }
00286     //-----------------------------------------------------------------------
00287     void RenderSystem::_setTextureUnitFiltering(size_t unit, FilterOptions minFilter,
00288             FilterOptions magFilter, FilterOptions mipFilter)
00289     {
00290         _setTextureUnitFiltering(unit, FT_MIN, minFilter);
00291         _setTextureUnitFiltering(unit, FT_MAG, magFilter);
00292         _setTextureUnitFiltering(unit, FT_MIP, mipFilter);
00293     }
00294     //-----------------------------------------------------------------------
00295     CullingMode RenderSystem::_getCullingMode(void) const
00296     {
00297         return mCullingMode;
00298     }
00299     //-----------------------------------------------------------------------
00300     bool RenderSystem::getWaitForVerticalBlank(void) const
00301     {
00302         return mVSync;
00303     }
00304     //-----------------------------------------------------------------------
00305     void RenderSystem::setWaitForVerticalBlank(bool enabled)
00306     {
00307         mVSync = enabled;
00308     }
00309     bool RenderSystem::getWBufferEnabled(void) const
00310     {
00311         return mWBuffer;
00312     }
00313     //-----------------------------------------------------------------------
00314     void RenderSystem::setWBufferEnabled(bool enabled)
00315     {
00316         mWBuffer = enabled;
00317     }
00318     //-----------------------------------------------------------------------
00319     void RenderSystem::shutdown(void)
00320     {
00321         // Remove all the render targets.
00322         for( RenderTargetMap::iterator it = mRenderTargets.begin(); it != mRenderTargets.end(); ++it )
00323         {
00324             delete it->second;
00325         }
00326         mRenderTargets.clear();
00327 
00328         mPrioritisedRenderTargets.clear();
00329     }
00330     //-----------------------------------------------------------------------
00331     void RenderSystem::_beginGeometryCount(void)
00332     {
00333         mFaceCount = mVertexCount = 0;
00334 
00335     }
00336     //-----------------------------------------------------------------------
00337     unsigned int RenderSystem::_getFaceCount(void) const
00338     {
00339         return static_cast< unsigned int >( mFaceCount );
00340     }
00341     //-----------------------------------------------------------------------
00342     unsigned int RenderSystem::_getVertexCount(void) const
00343     {
00344         return static_cast< unsigned int >( mVertexCount );
00345     }
00346     //-----------------------------------------------------------------------
00347     void RenderSystem::_setWorldMatrices(const Matrix4* m, unsigned short count)
00348     {
00349         // Save these matrices for software blending later
00350         for (unsigned short i = 0; i < count; ++i)
00351         {
00352             mWorldMatrices[i] = m[i];
00353         }
00354         // Set hardware matrix to nothing
00355         _setWorldMatrix(Matrix4::IDENTITY);
00356     }
00357     //-----------------------------------------------------------------------
00358     void RenderSystem::_render(const RenderOperation& op)
00359     {
00360         // Update stats
00361         size_t val;
00362 
00363         if (op.useIndexes)
00364             val = op.indexData->indexCount;
00365         else
00366             val = op.vertexData->vertexCount;
00367 
00368         switch(op.operationType)
00369         {
00370         case RenderOperation::OT_TRIANGLE_LIST:
00371             mFaceCount += val / 3;
00372             break;
00373         case RenderOperation::OT_TRIANGLE_STRIP:
00374         case RenderOperation::OT_TRIANGLE_FAN:
00375             mFaceCount += val - 2;
00376             break;
00377         case RenderOperation::OT_POINT_LIST:
00378         case RenderOperation::OT_LINE_LIST:
00379         case RenderOperation::OT_LINE_STRIP:
00380             break;
00381         }
00382 
00383         mVertexCount += op.vertexData->vertexCount;
00384 
00385     }
00386     //-----------------------------------------------------------------------
00387     void RenderSystem::setInvertVertexWinding(bool invert)
00388     {
00389         mInvertVertexWinding = invert;
00390     }
00391     //-----------------------------------------------------------------------
00392     void RenderSystem::setClipPlane (ushort index, const Plane &p)
00393     {
00394         setClipPlane (index, p.normal.x, p.normal.y, p.normal.z, p.d);
00395     }
00396     //-----------------------------------------------------------------------
00397     void RenderSystem::_notifyCameraRemoved(const Camera* cam)
00398     {
00399         RenderTargetMap::iterator i, iend;
00400         iend = mRenderTargets.end();
00401         for (i = mRenderTargets.begin(); i != iend; ++i)
00402         {
00403             RenderTarget* target = i->second;
00404             target->_notifyCameraRemoved(cam);
00405         }
00406     }
00407 }
00408 

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:42 2004