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