#pragma once //======================================================================== // SceneNodes.h - defines the base class for the 3D graphics scene graph, and // derived classes like RootNode, Alpha scene nodes, Camera, Grids, etc. // // 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 "../GameCode4/interfaces.h" #include "Geometry.h" #include "Material.h" #include "Shaders.h" #include #include #include // Forward declarations class SceneNode; class Scene; // class RayCast; // class MovementController; // class IResourceExtraData; // class ActorComponent; class BaseRenderComponent; // FUTURE WORK - Smart pointers don't work right....going to use a naked pointer for now! typedef BaseRenderComponent* WeakBaseRenderComponentPtr; //////////////////////////////////////////////////// // // AlphaType - Chapter X, page Y // // This enum defines the different types of alpha blending // types that can be set on a scene node. // // //////////////////////////////////////////////////// enum AlphaType { AlphaOpaque, AlphaTexture, AlphaMaterial, AlphaVertex }; ////////////////////////////////////////////////////////////////////// // class SceneNodeProperties - Chapter 16, page 527 // // This class is contained in the SceneNode class, and gains // easy access to common scene node properties such as its ActorId // or render pass, with a single ISceneNode::VGet() method. // ////////////////////////////////////////////////////////////////////// class SceneNodeProperties { friend class SceneNode; protected: ActorId m_ActorId; std::string m_Name; glm::mat4 m_ToWorld, m_FromWorld; float m_Radius; RenderPass m_RenderPass; Material m_Material; AlphaType m_AlphaType; void SetAlpha(const float alpha) { m_AlphaType=AlphaMaterial; m_Material.SetAlpha(alpha); } public: SceneNodeProperties(void); const ActorId &GetActorId() const { return m_ActorId; } glm::mat4 const &ToWorld() const { return m_ToWorld; } glm::mat4 const &FromWorld() const { return m_FromWorld; } void Transform(glm::mat4 *toWorld, glm::mat4 *fromWorld) const; const char * Name() const { return m_Name.c_str(); } bool HasAlpha() const { return m_Material.HasAlpha(); } float Alpha() const { return m_Material.GetAlpha(); } AlphaType GetAlphaType() const { return m_AlphaType; } RenderPass GetRenderPass() const { return m_RenderPass; } float Radius() const { return m_Radius; } Material GetMaterial() const { return m_Material; } }; ////////////////////////////////////////////////////////////// // // SceneNodeList - Chapter 16, page 529 // // Every scene node has a list of its children - this // is implemented as a vector since it is expected that // we won't add/delete nodes very often, and we'll want // fast random access to each child. // ////////////////////////////////////////////////////////////// typedef std::vector > SceneNodeList; ////////////////////////////////////////////////////////////// // // SceneNode - Chapter 16, page 529 // // Implements ISceneNode. Forms the base class for any node // that can exist in the 3D scene graph managed by class Scene. // ////////////////////////////////////////////////////////////// class SceneNode : public ISceneNode { friend class Scene; protected: SceneNodeList m_Children; SceneNode *m_pParent; SceneNodeProperties m_Props; WeakBaseRenderComponentPtr m_RenderComponent; public: SceneNode( ActorId actorId, WeakBaseRenderComponentPtr renderComponent, RenderPass renderPass, const glm::mat4 to, std::optional from=std::nullopt ); virtual ~SceneNode(); virtual const SceneNodeProperties* const VGet() const { return &m_Props; } virtual void VSetTransform( const glm::mat4 toWorld, std::optional fromWorld=std::nullopt ); virtual int VOnRestore(Scene *pScene); virtual int VOnUpdate(Scene *, uint64_t const elapsedMs); virtual int VPreRender(Scene *pScene); virtual bool VIsVisible(Scene *pScene) const; virtual int VRender(Scene *pScene) { return 0; } virtual int VRenderChildren(Scene *pScene); virtual int VPostRender(Scene *pScene); virtual bool VAddChild(std::shared_ptr kid); virtual bool VRemoveChild(ActorId id); glm::vec3 GetDirection() const { return geometry::GetDirection(m_Props.m_ToWorld); } void SetRadius(const float radius) { m_Props.m_Radius = radius; } void SetMaterial(const Material &mat) { m_Props.m_Material = mat; } }; //////////////////////////////////////////////////// // // class RootNode - Chapter 16, page 545 // // This is the root node of the scene graph. // //////////////////////////////////////////////////// class RootNode : public SceneNode { public: RootNode(); virtual bool VAddChild(std::shared_ptr kid); virtual int VRenderChildren(Scene *pScene); virtual bool VRemoveChild(ActorId id); virtual bool VIsVisible(Scene *pScene) const { return true; } }; //////////////////////////////////////////////////// // // class CameraNode - Chapter 16, page 548 // // A camera node controls the D3D view transform and holds the view // frustum definition // //////////////////////////////////////////////////// class CameraNode : public SceneNode { public: CameraNode(glm::mat4 const t, Frustum const &frustum) : SceneNode(INVALID_ACTOR_ID, WeakBaseRenderComponentPtr(), RenderPass_0, t), m_Frustum(frustum), m_bActive(true), m_DebugCamera(false), m_pTarget(std::shared_ptr()), m_CamOffsetVector(0.0f, 1.0f, 10.0f, 0.0f) { } virtual int VRender(Scene *pScene); virtual int VOnRestore(Scene *pScene); virtual bool VIsVisible(Scene *pScene) { return m_bActive; } void SetTarget(std::shared_ptr pTarget) { m_pTarget = pTarget; } void ClearTarget() { m_pTarget = std::shared_ptr(); } std::shared_ptr GetTarget() { return m_pTarget; } glm::mat4 GetWorldViewProjection(Scene *pScene); int SetViewTransform(Scene *pScene); protected: Frustum m_Frustum; glm::mat4 m_Projection; glm::mat4 m_View; bool m_bActive; bool m_DebugCamera; std::shared_ptr m_pTarget; glm::vec4 m_CamOffsetVector; //Direction of camera relative to target. }; //////////////////////////////////////////////////// // // D3DGrid9 Description // // A slightly modified version of Grid from // the beginning 3D chapter // //////////////////////////////////////////////////// class OpenGLGrid : public SceneNode { protected: size_t m_numIndices; unsigned int m_numVerts; unsigned int m_numPolys; GLuint m_vbo; GLuint m_vao; GLuint m_ebo; OpenGLShaderProgram m_ShaderProgram; public: bool m_bTextureHasAlpha; OpenGLGrid(ActorId actorId, WeakBaseRenderComponentPtr renderComponent, glm::mat4 pMatrix); virtual ~OpenGLGrid(); virtual int VOnRestore(Scene *pScene); virtual int VRender(Scene *pScene); virtual int VOnUpdate(Scene *pScene, unsigned long elapsedMs) { return 0; } // virtual int VPick(Scene *pScene, RayCast *pRayCast) { return 1; } bool VHasAlpha() const { return m_bTextureHasAlpha; } };