| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- //========================================================================
- // File: Scene.cpp - implements the container class for 3D Graphics scenes
- //
- // Part of the GameCode4 Application
- //
- // GameCode4 is the sample application that encapsulates much of the source code
- // discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
- // "Rez" Graham, published by Charles River Media.
- // ISBN-10: 1133776574 | ISBN-13: 978-1133776574
- //
- // If this source code has found it's way to you, and you think it has helped you
- // in any way, do the authors a favor and buy a new copy of the book - there are
- // detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
- // by clicking here:
- // http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
- //
- // There's a companion web site at http://www.mcshaffry.com/GameCode/
- //
- // The source code is managed and maintained through Google Code:
- // http://code.google.com/p/gamecode4/
- //
- // (c) Copyright 2012 Michael L. McShaffry and David Graham
- //
- // This program is free software; you can redistribute it and/or
- // modify it under the terms of the GNU Lesser GPL v3
- // as published by the Free Software Foundation.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- // http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
- //
- // You should have received a copy of the GNU Lesser GPL v3
- // along with this program; if not, write to the Free Software
- // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- //
- //========================================================================
- #include "Scene.h"
- #include "../Unix/GameCodeStd.h"
- #include "../GameCode4/GameCode.h"
- #include "../EventManager/EventManager.h"
- #include "../EventManager/Events.h"
- #include "../Utilities/String.h"
- #include "Geometry.h"
- #include "Lights.h"
- ////////////////////////////////////////////////////
- // Scene Implementation
- ////////////////////////////////////////////////////
- //
- // Scene::Scene - Chapter 16, page 539
- //
- // Note: The shared_ptr<IRenderer> was added to allow for both D3D9 and D3D11 renderer implementations.
- // The book only describes D3D11, so to find all the differences, just search for m_Renderer!
- //
- Scene::Scene(std::shared_ptr<IRenderer> renderer)
- {
- m_Root.reset(GCC_NEW RootNode());
- m_Renderer = renderer;
- m_LightManager = GCC_NEW LightManager;
- // D3DXCreateMatrixStack(0, &m_MatrixStack);
- m_MatrixStack.push(glm::mat4(1.0f));
-
- // [mrmike] - event delegates were added post-press
- IEventManager* pEventMgr = IEventManager::Get();
- pEventMgr->VAddListener(MakeDelegate(this, &Scene::NewRenderComponentDelegate), EvtData_New_Render_Component::sk_EventType);
- // pEventMgr->VAddListener(MakeDelegate(this, &Scene::DestroyActorDelegate), EvtData_Destroy_Actor::sk_EventType);
- // pEventMgr->VAddListener(MakeDelegate(this, &Scene::MoveActorDelegate), EvtData_Move_Actor::sk_EventType);
- pEventMgr->VAddListener(MakeDelegate(this, &Scene::ModifiedRenderComponentDelegate), EvtData_Modified_Render_Component::sk_EventType);
- }
- //
- // Scene::~Scene - Chapter 16, page 539
- //
- Scene::~Scene()
- {
- // [mrmike] - event delegates were added post-press!
- IEventManager* pEventMgr = IEventManager::Get();
- pEventMgr->VRemoveListener(MakeDelegate(this, &Scene::NewRenderComponentDelegate), EvtData_New_Render_Component::sk_EventType);
- // pEventMgr->VRemoveListener(MakeDelegate(this, &Scene::DestroyActorDelegate), EvtData_Destroy_Actor::sk_EventType);
- // pEventMgr->VRemoveListener(MakeDelegate(this, &Scene::MoveActorDelegate), EvtData_Move_Actor::sk_EventType);
- pEventMgr->VRemoveListener(MakeDelegate(this, &Scene::ModifiedRenderComponentDelegate), EvtData_Modified_Render_Component::sk_EventType);
- // SAFE_RELEASE(m_MatrixStack);
- SAFE_DELETE(m_LightManager);
- }
- //
- // Scene::OnRender - Chapter 16, page 539
- //
- int Scene::OnRender()
- {
- // The render passes usually go like this
- // 1. Static objects & terrain
- // 2. Actors (dynamic objects that can move)
- // 3. The Sky
- // 4. Anything with Alpha
- if (m_Root && m_Camera)
- {
- // The scene root could be anything, but it
- // is usually a SceneNode with the identity
- // matrix
- m_Camera->SetViewTransform(this);
- m_LightManager->CalcLighting(this);
- if (m_Root->VPreRender(this)==0)
- {
- m_Root->VRender(this);
- m_Root->VRenderChildren(this);
- m_Root->VPostRender(this);
- }
- // RenderAlphaPass();
- }
- return 0;
- }
- //
- // Scene::OnUpdate - Chapter 16, page 540
- //
- int Scene::OnUpdate(const int deltaMilliseconds)
- {
- if (!m_Root)
- return 0;
- static Uint64 lastTime = SDL_GetTicks();
- Uint64 elapsedTime = 0;
- Uint64 now = SDL_GetTicks();
- elapsedTime = now - lastTime;
- lastTime = now;
- return m_Root->VOnUpdate(this, elapsedTime);
- }
- //
- // Scene::OnRestore - Chapter 16, page 540
- //
- int Scene::OnRestore()
- {
- if (!m_Root)
- return 0;
- if (m_Renderer->VOnRestore() != 0)
- return 1;
- return m_Root->VOnRestore(this);
- }
- bool Scene::AddChild(ActorId id, std::shared_ptr<ISceneNode> kid)
- {
- if (id != INVALID_ACTOR_ID)
- {
- // This allows us to search for this later based on actor id
- m_ActorMap[id] = kid;
- }
- std::shared_ptr<LightNode> pLight = dynamic_pointer_cast<LightNode>(kid);
- if (pLight != NULL && m_LightManager->m_Lights.size()+1 < MAXIMUM_LIGHTS_SUPPORTED)
- {
- m_LightManager->m_Lights.push_back(pLight);
- }
- return m_Root->VAddChild(kid);
- }
- bool Scene::RemoveChild(ActorId id)
- {
- if (id == INVALID_ACTOR_ID)
- return false;
- std::shared_ptr<ISceneNode> kid = FindActor(id);
- std::shared_ptr<LightNode> pLight = dynamic_pointer_cast<LightNode>(kid);
- if (pLight != NULL)
- {
- m_LightManager->m_Lights.remove(pLight);
- }
- m_ActorMap.erase(id);
- return m_Root->VRemoveChild(id);
- }
- void Scene::NewRenderComponentDelegate(IEventDataPtr pEventData)
- {
- std::shared_ptr<EvtData_New_Render_Component> pCastEventData = static_pointer_cast<EvtData_New_Render_Component>(pEventData);
- ActorId actorId = pCastEventData->GetActorId();
- std::shared_ptr<SceneNode> pSceneNode(pCastEventData->GetSceneNode());
- // FUTURE WORK: Add better error handling here.
- if (pSceneNode->VOnRestore(this) != 0)
- {
- std::string error = "Failed to restore scene node to the scene for actorid " + ToStr(actorId);
- GCC_ERROR(error);
- return;
- }
- AddChild(actorId, pSceneNode);
- }
- void Scene::ModifiedRenderComponentDelegate(IEventDataPtr pEventData)
- {
- // TODO(munnellg) - implement
- }
- //
- // Scene::FindActor - Chapter 16, page 542
- //
- std::shared_ptr<ISceneNode> Scene::FindActor(ActorId id)
- {
- SceneActorMap::iterator i = m_ActorMap.find(id);
- if (i==m_ActorMap.end())
- {
- return std::shared_ptr<ISceneNode>();
- }
- return i->second;
- }
|