PageRenderTime 2361ms CodeModel.GetById 2ms RepoModel.GetById 0ms app.codeStats 0ms

/Core/Dependencies/OgreSource/OgreMain/src/OgreRenderQueue.cpp

https://bitbucket.org/barakianc/nvidia-physx-and-apex-in-gge
C++ | 329 lines | 218 code | 40 blank | 71 comment | 27 complexity | 91c7d17b7a3d82e894f8bd0b7030dd05 MD5 | raw file
  1. /*
  2. -----------------------------------------------------------------------------
  3. This source file is part of OGRE
  4. (Object-oriented Graphics Rendering Engine)
  5. For the latest info, see http://www.ogre3d.org/
  6. Copyright (c) 2000-2012 Torus Knot Software Ltd
  7. Permission is hereby granted, free of charge, to any person obtaining a copy
  8. of this software and associated documentation files (the "Software"), to deal
  9. in the Software without restriction, including without limitation the rights
  10. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. copies of the Software, and to permit persons to whom the Software is
  12. furnished to do so, subject to the following conditions:
  13. The above copyright notice and this permission notice shall be included in
  14. all copies or substantial portions of the Software.
  15. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. THE SOFTWARE.
  22. -----------------------------------------------------------------------------
  23. */
  24. #include "OgreStableHeaders.h"
  25. #include "OgreRenderQueue.h"
  26. #include "OgreRenderable.h"
  27. #include "OgreMaterial.h"
  28. #include "OgreRenderQueueSortingGrouping.h"
  29. #include "OgrePass.h"
  30. #include "OgreMaterialManager.h"
  31. #include "OgreSceneManager.h"
  32. #include "OgreMovableObject.h"
  33. #include "OgreCamera.h"
  34. #include "OgreSceneManagerEnumerator.h"
  35. namespace Ogre {
  36. //---------------------------------------------------------------------
  37. RenderQueue::RenderQueue()
  38. : mSplitPassesByLightingType(false)
  39. , mSplitNoShadowPasses(false)
  40. , mShadowCastersCannotBeReceivers(false)
  41. , mRenderableListener(0)
  42. {
  43. // Create the 'main' queue up-front since we'll always need that
  44. mGroups.insert(
  45. RenderQueueGroupMap::value_type(
  46. RENDER_QUEUE_MAIN,
  47. OGRE_NEW RenderQueueGroup(this,
  48. mSplitPassesByLightingType,
  49. mSplitNoShadowPasses,
  50. mShadowCastersCannotBeReceivers)
  51. )
  52. );
  53. // set default queue
  54. mDefaultQueueGroup = RENDER_QUEUE_MAIN;
  55. mDefaultRenderablePriority = OGRE_RENDERABLE_DEFAULT_PRIORITY;
  56. }
  57. //---------------------------------------------------------------------
  58. RenderQueue::~RenderQueue()
  59. {
  60. // trigger the pending pass updates, otherwise we could leak
  61. Pass::processPendingPassUpdates();
  62. // Destroy the queues for good
  63. RenderQueueGroupMap::iterator i, iend;
  64. i = mGroups.begin();
  65. iend = mGroups.end();
  66. for (; i != iend; ++i)
  67. {
  68. OGRE_DELETE i->second;
  69. }
  70. mGroups.clear();
  71. }
  72. //-----------------------------------------------------------------------
  73. void RenderQueue::addRenderable(Renderable* pRend, uint8 groupID, ushort priority)
  74. {
  75. // Find group
  76. RenderQueueGroup* pGroup = getQueueGroup(groupID);
  77. Technique* pTech;
  78. // tell material it's been used
  79. if (!pRend->getMaterial().isNull())
  80. pRend->getMaterial()->touch();
  81. // Check material & technique supplied (the former since the default implementation
  82. // of getTechnique is based on it for backwards compatibility
  83. if(pRend->getMaterial().isNull() || !pRend->getTechnique())
  84. {
  85. // Use default base white
  86. MaterialPtr baseWhite = MaterialManager::getSingleton().getByName("BaseWhite");
  87. pTech = baseWhite->getTechnique(0);
  88. }
  89. else
  90. pTech = pRend->getTechnique();
  91. if (mRenderableListener)
  92. {
  93. // Allow listener to override technique and to abort
  94. if (!mRenderableListener->renderableQueued(pRend, groupID, priority,
  95. &pTech, this))
  96. return; // rejected
  97. // tell material it's been used (incase changed)
  98. pTech->getParent()->touch();
  99. }
  100. pGroup->addRenderable(pRend, pTech, priority);
  101. }
  102. //-----------------------------------------------------------------------
  103. void RenderQueue::clear(bool destroyPassMaps)
  104. {
  105. // Clear the queues
  106. SceneManagerEnumerator::SceneManagerIterator scnIt =
  107. SceneManagerEnumerator::getSingleton().getSceneManagerIterator();
  108. // Note: We clear dirty passes from all RenderQueues in all
  109. // SceneManagers, because the following recalculation of pass hashes
  110. // also considers all RenderQueues and could become inconsistent, otherwise.
  111. while (scnIt.hasMoreElements())
  112. {
  113. SceneManager* sceneMgr = scnIt.getNext();
  114. RenderQueue* queue = sceneMgr->getRenderQueue();
  115. RenderQueueGroupMap::iterator i, iend;
  116. i = queue->mGroups.begin();
  117. iend = queue->mGroups.end();
  118. for (; i != iend; ++i)
  119. {
  120. i->second->clear(destroyPassMaps);
  121. }
  122. }
  123. // Now trigger the pending pass updates
  124. Pass::processPendingPassUpdates();
  125. // NB this leaves the items present (but empty)
  126. // We're assuming that frame-by-frame, the same groups are likely to
  127. // be used, so no point destroying the vectors and incurring the overhead
  128. // that would cause, let them be destroyed in the destructor.
  129. }
  130. //-----------------------------------------------------------------------
  131. RenderQueue::QueueGroupIterator RenderQueue::_getQueueGroupIterator(void)
  132. {
  133. return QueueGroupIterator(mGroups.begin(), mGroups.end());
  134. }
  135. //-----------------------------------------------------------------------
  136. RenderQueue::ConstQueueGroupIterator RenderQueue::_getQueueGroupIterator(void) const
  137. {
  138. return ConstQueueGroupIterator(mGroups.begin(), mGroups.end());
  139. }
  140. //-----------------------------------------------------------------------
  141. void RenderQueue::addRenderable(Renderable* pRend, uint8 groupID)
  142. {
  143. addRenderable(pRend, groupID, mDefaultRenderablePriority);
  144. }
  145. //-----------------------------------------------------------------------
  146. void RenderQueue::addRenderable(Renderable* pRend)
  147. {
  148. addRenderable(pRend, mDefaultQueueGroup, mDefaultRenderablePriority);
  149. }
  150. //-----------------------------------------------------------------------
  151. uint8 RenderQueue::getDefaultQueueGroup(void) const
  152. {
  153. return mDefaultQueueGroup;
  154. }
  155. //-----------------------------------------------------------------------
  156. void RenderQueue::setDefaultQueueGroup(uint8 grp)
  157. {
  158. mDefaultQueueGroup = grp;
  159. }
  160. //-----------------------------------------------------------------------
  161. ushort RenderQueue::getDefaultRenderablePriority(void) const
  162. {
  163. return mDefaultRenderablePriority;
  164. }
  165. //-----------------------------------------------------------------------
  166. void RenderQueue::setDefaultRenderablePriority(ushort priority)
  167. {
  168. mDefaultRenderablePriority = priority;
  169. }
  170. //-----------------------------------------------------------------------
  171. RenderQueueGroup* RenderQueue::getQueueGroup(uint8 groupID)
  172. {
  173. // Find group
  174. RenderQueueGroupMap::iterator groupIt;
  175. RenderQueueGroup* pGroup;
  176. groupIt = mGroups.find(groupID);
  177. if (groupIt == mGroups.end())
  178. {
  179. // Insert new
  180. pGroup = OGRE_NEW RenderQueueGroup(this,
  181. mSplitPassesByLightingType,
  182. mSplitNoShadowPasses,
  183. mShadowCastersCannotBeReceivers);
  184. mGroups.insert(RenderQueueGroupMap::value_type(groupID, pGroup));
  185. }
  186. else
  187. {
  188. pGroup = groupIt->second;
  189. }
  190. return pGroup;
  191. }
  192. //-----------------------------------------------------------------------
  193. void RenderQueue::setSplitPassesByLightingType(bool split)
  194. {
  195. mSplitPassesByLightingType = split;
  196. RenderQueueGroupMap::iterator i, iend;
  197. i = mGroups.begin();
  198. iend = mGroups.end();
  199. for (; i != iend; ++i)
  200. {
  201. i->second->setSplitPassesByLightingType(split);
  202. }
  203. }
  204. //-----------------------------------------------------------------------
  205. bool RenderQueue::getSplitPassesByLightingType(void) const
  206. {
  207. return mSplitPassesByLightingType;
  208. }
  209. //-----------------------------------------------------------------------
  210. void RenderQueue::setSplitNoShadowPasses(bool split)
  211. {
  212. mSplitNoShadowPasses = split;
  213. RenderQueueGroupMap::iterator i, iend;
  214. i = mGroups.begin();
  215. iend = mGroups.end();
  216. for (; i != iend; ++i)
  217. {
  218. i->second->setSplitNoShadowPasses(split);
  219. }
  220. }
  221. //-----------------------------------------------------------------------
  222. bool RenderQueue::getSplitNoShadowPasses(void) const
  223. {
  224. return mSplitNoShadowPasses;
  225. }
  226. //-----------------------------------------------------------------------
  227. void RenderQueue::setShadowCastersCannotBeReceivers(bool ind)
  228. {
  229. mShadowCastersCannotBeReceivers = ind;
  230. RenderQueueGroupMap::iterator i, iend;
  231. i = mGroups.begin();
  232. iend = mGroups.end();
  233. for (; i != iend; ++i)
  234. {
  235. i->second->setShadowCastersCannotBeReceivers(ind);
  236. }
  237. }
  238. //-----------------------------------------------------------------------
  239. bool RenderQueue::getShadowCastersCannotBeReceivers(void) const
  240. {
  241. return mShadowCastersCannotBeReceivers;
  242. }
  243. //-----------------------------------------------------------------------
  244. void RenderQueue::merge( const RenderQueue* rhs )
  245. {
  246. ConstQueueGroupIterator it = rhs->_getQueueGroupIterator( );
  247. while( it.hasMoreElements() )
  248. {
  249. uint8 groupID = it.peekNextKey();
  250. RenderQueueGroup* pSrcGroup = it.getNext();
  251. RenderQueueGroup* pDstGroup = getQueueGroup( groupID );
  252. pDstGroup->merge( pSrcGroup );
  253. }
  254. }
  255. //---------------------------------------------------------------------
  256. void RenderQueue::processVisibleObject(MovableObject* mo,
  257. Camera* cam,
  258. bool onlyShadowCasters,
  259. VisibleObjectsBoundsInfo* visibleBounds)
  260. {
  261. mo->_notifyCurrentCamera(cam);
  262. if (mo->isVisible())
  263. {
  264. bool receiveShadows = getQueueGroup(mo->getRenderQueueGroup())->getShadowsEnabled()
  265. && mo->getReceivesShadows();
  266. if (!onlyShadowCasters || mo->getCastShadows())
  267. {
  268. mo -> _updateRenderQueue( this );
  269. if (visibleBounds)
  270. {
  271. visibleBounds->merge(mo->getWorldBoundingBox(true),
  272. mo->getWorldBoundingSphere(true), cam,
  273. receiveShadows);
  274. }
  275. }
  276. // not shadow caster, receiver only?
  277. else if (onlyShadowCasters && !mo->getCastShadows() &&
  278. receiveShadows)
  279. {
  280. visibleBounds->mergeNonRenderedButInFrustum(mo->getWorldBoundingBox(true),
  281. mo->getWorldBoundingSphere(true), cam);
  282. }
  283. }
  284. }
  285. }