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