Scene.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. //========================================================================
  2. // File: Scene.cpp - implements the container class for 3D Graphics scenes
  3. //
  4. // Part of the GameCode4 Application
  5. //
  6. // GameCode4 is the sample application that encapsulates much of the source code
  7. // discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
  8. // "Rez" Graham, published by Charles River Media.
  9. // ISBN-10: 1133776574 | ISBN-13: 978-1133776574
  10. //
  11. // If this source code has found it's way to you, and you think it has helped you
  12. // in any way, do the authors a favor and buy a new copy of the book - there are
  13. // detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
  14. // by clicking here:
  15. // http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
  16. //
  17. // There's a companion web site at http://www.mcshaffry.com/GameCode/
  18. //
  19. // The source code is managed and maintained through Google Code:
  20. // http://code.google.com/p/gamecode4/
  21. //
  22. // (c) Copyright 2012 Michael L. McShaffry and David Graham
  23. //
  24. // This program is free software; you can redistribute it and/or
  25. // modify it under the terms of the GNU Lesser GPL v3
  26. // as published by the Free Software Foundation.
  27. //
  28. // This program is distributed in the hope that it will be useful,
  29. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  30. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
  31. // http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
  32. //
  33. // You should have received a copy of the GNU Lesser GPL v3
  34. // along with this program; if not, write to the Free Software
  35. // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  36. //
  37. //========================================================================
  38. #include "Scene.h"
  39. #include "../Unix/GameCodeStd.h"
  40. #include "../GameCode4/GameCode.h"
  41. #include "../EventManager/EventManager.h"
  42. #include "../EventManager/Events.h"
  43. #include "../Utilities/String.h"
  44. #include "Geometry.h"
  45. #include "Lights.h"
  46. ////////////////////////////////////////////////////
  47. // Scene Implementation
  48. ////////////////////////////////////////////////////
  49. //
  50. // Scene::Scene - Chapter 16, page 539
  51. //
  52. // Note: The shared_ptr<IRenderer> was added to allow for both D3D9 and D3D11 renderer implementations.
  53. // The book only describes D3D11, so to find all the differences, just search for m_Renderer!
  54. //
  55. Scene::Scene(std::shared_ptr<IRenderer> renderer)
  56. {
  57. m_Root.reset(GCC_NEW RootNode());
  58. m_Renderer = renderer;
  59. m_LightManager = GCC_NEW LightManager;
  60. // D3DXCreateMatrixStack(0, &m_MatrixStack);
  61. m_MatrixStack.push(glm::mat4(1.0f));
  62. // [mrmike] - event delegates were added post-press
  63. IEventManager* pEventMgr = IEventManager::Get();
  64. pEventMgr->VAddListener(MakeDelegate(this, &Scene::NewRenderComponentDelegate), EvtData_New_Render_Component::sk_EventType);
  65. // pEventMgr->VAddListener(MakeDelegate(this, &Scene::DestroyActorDelegate), EvtData_Destroy_Actor::sk_EventType);
  66. // pEventMgr->VAddListener(MakeDelegate(this, &Scene::MoveActorDelegate), EvtData_Move_Actor::sk_EventType);
  67. pEventMgr->VAddListener(MakeDelegate(this, &Scene::ModifiedRenderComponentDelegate), EvtData_Modified_Render_Component::sk_EventType);
  68. }
  69. //
  70. // Scene::~Scene - Chapter 16, page 539
  71. //
  72. Scene::~Scene()
  73. {
  74. // [mrmike] - event delegates were added post-press!
  75. IEventManager* pEventMgr = IEventManager::Get();
  76. pEventMgr->VRemoveListener(MakeDelegate(this, &Scene::NewRenderComponentDelegate), EvtData_New_Render_Component::sk_EventType);
  77. // pEventMgr->VRemoveListener(MakeDelegate(this, &Scene::DestroyActorDelegate), EvtData_Destroy_Actor::sk_EventType);
  78. // pEventMgr->VRemoveListener(MakeDelegate(this, &Scene::MoveActorDelegate), EvtData_Move_Actor::sk_EventType);
  79. pEventMgr->VRemoveListener(MakeDelegate(this, &Scene::ModifiedRenderComponentDelegate), EvtData_Modified_Render_Component::sk_EventType);
  80. // SAFE_RELEASE(m_MatrixStack);
  81. SAFE_DELETE(m_LightManager);
  82. }
  83. //
  84. // Scene::OnRender - Chapter 16, page 539
  85. //
  86. int Scene::OnRender()
  87. {
  88. // The render passes usually go like this
  89. // 1. Static objects & terrain
  90. // 2. Actors (dynamic objects that can move)
  91. // 3. The Sky
  92. // 4. Anything with Alpha
  93. if (m_Root && m_Camera)
  94. {
  95. // The scene root could be anything, but it
  96. // is usually a SceneNode with the identity
  97. // matrix
  98. m_Camera->SetViewTransform(this);
  99. m_LightManager->CalcLighting(this);
  100. if (m_Root->VPreRender(this)==0)
  101. {
  102. m_Root->VRender(this);
  103. m_Root->VRenderChildren(this);
  104. m_Root->VPostRender(this);
  105. }
  106. // RenderAlphaPass();
  107. }
  108. return 0;
  109. }
  110. //
  111. // Scene::OnUpdate - Chapter 16, page 540
  112. //
  113. int Scene::OnUpdate(const int deltaMilliseconds)
  114. {
  115. if (!m_Root)
  116. return 0;
  117. static Uint64 lastTime = SDL_GetTicks();
  118. Uint64 elapsedTime = 0;
  119. Uint64 now = SDL_GetTicks();
  120. elapsedTime = now - lastTime;
  121. lastTime = now;
  122. return m_Root->VOnUpdate(this, elapsedTime);
  123. }
  124. //
  125. // Scene::OnRestore - Chapter 16, page 540
  126. //
  127. int Scene::OnRestore()
  128. {
  129. if (!m_Root)
  130. return 0;
  131. if (m_Renderer->VOnRestore() != 0)
  132. return 1;
  133. return m_Root->VOnRestore(this);
  134. }
  135. bool Scene::AddChild(ActorId id, std::shared_ptr<ISceneNode> kid)
  136. {
  137. if (id != INVALID_ACTOR_ID)
  138. {
  139. // This allows us to search for this later based on actor id
  140. m_ActorMap[id] = kid;
  141. }
  142. std::shared_ptr<LightNode> pLight = dynamic_pointer_cast<LightNode>(kid);
  143. if (pLight != NULL && m_LightManager->m_Lights.size()+1 < MAXIMUM_LIGHTS_SUPPORTED)
  144. {
  145. m_LightManager->m_Lights.push_back(pLight);
  146. }
  147. return m_Root->VAddChild(kid);
  148. }
  149. bool Scene::RemoveChild(ActorId id)
  150. {
  151. if (id == INVALID_ACTOR_ID)
  152. return false;
  153. std::shared_ptr<ISceneNode> kid = FindActor(id);
  154. std::shared_ptr<LightNode> pLight = dynamic_pointer_cast<LightNode>(kid);
  155. if (pLight != NULL)
  156. {
  157. m_LightManager->m_Lights.remove(pLight);
  158. }
  159. m_ActorMap.erase(id);
  160. return m_Root->VRemoveChild(id);
  161. }
  162. void Scene::NewRenderComponentDelegate(IEventDataPtr pEventData)
  163. {
  164. std::shared_ptr<EvtData_New_Render_Component> pCastEventData = static_pointer_cast<EvtData_New_Render_Component>(pEventData);
  165. ActorId actorId = pCastEventData->GetActorId();
  166. std::shared_ptr<SceneNode> pSceneNode(pCastEventData->GetSceneNode());
  167. // FUTURE WORK: Add better error handling here.
  168. if (pSceneNode->VOnRestore(this) != 0)
  169. {
  170. std::string error = "Failed to restore scene node to the scene for actorid " + ToStr(actorId);
  171. GCC_ERROR(error);
  172. return;
  173. }
  174. AddChild(actorId, pSceneNode);
  175. }
  176. void Scene::ModifiedRenderComponentDelegate(IEventDataPtr pEventData)
  177. {
  178. // TODO(munnellg) - implement
  179. }
  180. //
  181. // Scene::FindActor - Chapter 16, page 542
  182. //
  183. std::shared_ptr<ISceneNode> Scene::FindActor(ActorId id)
  184. {
  185. SceneActorMap::iterator i = m_ActorMap.find(id);
  186. if (i==m_ActorMap.end())
  187. {
  188. return std::shared_ptr<ISceneNode>();
  189. }
  190. return i->second;
  191. }