#pragma once //======================================================================== // RenderComponent.cpp : classes that define renderable components of actors like Meshes, Skyboxes, Lights, etc. // Author: David "Rez" Graham // // 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 "../Unix/GameCodeStd.h" #include "../Graphics3D/Mesh.h" #include "../Graphics3D/Sky.h" #include "../EventManager/Events.h" #include "RenderComponent.h" #include "TransformComponent.h" // const char* MeshRenderComponent::g_Name = "MeshRenderComponent"; // const char* SphereRenderComponent::g_Name = "SphereRenderComponent"; const char* TeapotRenderComponent::g_Name = "TeapotRenderComponent"; const char* GridRenderComponent::g_Name = "GridRenderComponent"; const char* LightRenderComponent::g_Name = "LightRenderComponent"; const char* SkyRenderComponent::g_Name = "SkyRenderComponent"; //--------------------------------------------------------------------------------------------------------------------- // RenderComponent //--------------------------------------------------------------------------------------------------------------------- bool BaseRenderComponent::VInit(TiXmlElement* pData) { // color TiXmlElement* pColorNode = pData->FirstChildElement("Color"); if (pColorNode) m_color = LoadColor(pColorNode); return VDelegateInit(pData); } void BaseRenderComponent::VPostInit(void) { std::shared_ptr pSceneNode(VGetSceneNode()); std::shared_ptr pEvent(GCC_NEW EvtData_New_Render_Component(m_pOwner->GetId(), pSceneNode)); IEventManager::Get()->VTriggerEvent(pEvent); } void BaseRenderComponent::VOnChanged(void) { std::shared_ptr pEvent(GCC_NEW EvtData_Modified_Render_Component(m_pOwner->GetId())); IEventManager::Get()->VTriggerEvent(pEvent); } TiXmlElement* BaseRenderComponent::VGenerateXml(void) { TiXmlElement* pBaseElement = VCreateBaseElement(); // color TiXmlElement* pColor = GCC_NEW TiXmlElement("Color"); pColor->SetAttribute("r", ToStr(m_color.r).c_str()); pColor->SetAttribute("g", ToStr(m_color.g).c_str()); pColor->SetAttribute("b", ToStr(m_color.b).c_str()); pColor->SetAttribute("a", ToStr(m_color.a).c_str()); pBaseElement->LinkEndChild(pColor); // create XML for inherited classes VCreateInheritedXmlElements(pBaseElement); return pBaseElement; } std::shared_ptr BaseRenderComponent::VGetSceneNode(void) { if (!m_pSceneNode) m_pSceneNode = VCreateSceneNode(); return m_pSceneNode; } Color BaseRenderComponent::LoadColor(TiXmlElement* pData) { Color color; double r = 1.0; double g = 1.0; double b = 1.0; double a = 1.0; pData->Attribute("r", &r); pData->Attribute("g", &g); pData->Attribute("b", &b); pData->Attribute("a", &a); color.r = (float)r; color.g = (float)g; color.b = (float)b; color.a = (float)a; return color; } //--------------------------------------------------------------------------------------------------------------------- // TeapotRenderComponent //--------------------------------------------------------------------------------------------------------------------- std::shared_ptr TeapotRenderComponent::VCreateSceneNode(void) { // get the transform component std::shared_ptr pTransformComponent = MakeStrongPtr(m_pOwner->GetComponent(TransformComponent::g_Name)); if (pTransformComponent) { WeakBaseRenderComponentPtr weakThis(this); glm::mat4 rot90 = geometry::BuildRotationY(GCC_PI/2.0f); std::shared_ptr parent(GCC_NEW SceneNode(m_pOwner->GetId(), weakThis, RenderPass_Actor, pTransformComponent->GetTransform())); std::shared_ptr teapot(GCC_NEW OpenGLTeapotMeshNode(INVALID_ACTOR_ID, weakThis, RenderPass_Actor, rot90)); parent->VAddChild(teapot); return parent; } return std::shared_ptr(); } void TeapotRenderComponent::VCreateInheritedXmlElements(TiXmlElement *) { } //--------------------------------------------------------------------------------------------------------------------- // GridRenderComponent //--------------------------------------------------------------------------------------------------------------------- GridRenderComponent::GridRenderComponent(void) { m_textureResource = ""; m_squares = 0; } bool GridRenderComponent::VDelegateInit(TiXmlElement* pData) { TiXmlElement* pTexture = pData->FirstChildElement("Texture"); if (pTexture) { m_textureResource = pTexture->FirstChild()->Value(); } TiXmlElement* pDivision = pData->FirstChildElement("Division"); if (pDivision) { m_squares = atoi(pDivision->FirstChild()->Value()); } return true; } std::shared_ptr GridRenderComponent::VCreateSceneNode(void) { std::shared_ptr pTransformComponent = MakeStrongPtr(m_pOwner->GetComponent(TransformComponent::g_Name)); if (pTransformComponent) { WeakBaseRenderComponentPtr weakThis(this); return std::shared_ptr(GCC_NEW OpenGLGrid(m_pOwner->GetId(), weakThis, pTransformComponent->GetTransform())); } return std::shared_ptr(); } void GridRenderComponent::VCreateInheritedXmlElements(TiXmlElement *pBaseElement) { TiXmlElement* pTextureNode = GCC_NEW TiXmlElement("Texture"); TiXmlText* pTextureText = GCC_NEW TiXmlText(m_textureResource.c_str()); pTextureNode->LinkEndChild(pTextureText); pBaseElement->LinkEndChild(pTextureNode); TiXmlElement* pDivisionNode = GCC_NEW TiXmlElement("Division"); TiXmlText* pDivisionText = GCC_NEW TiXmlText(ToStr(m_squares).c_str()); pDivisionNode->LinkEndChild(pDivisionText); pBaseElement->LinkEndChild(pDivisionNode); } //--------------------------------------------------------------------------------------------------------------------- // LightRenderComponent //--------------------------------------------------------------------------------------------------------------------- LightRenderComponent::LightRenderComponent(void) { } bool LightRenderComponent::VDelegateInit(TiXmlElement* pData) { TiXmlElement* pLight = pData->FirstChildElement("Light"); double temp; TiXmlElement* pAttenuationNode = NULL; pAttenuationNode = pLight->FirstChildElement("Attenuation"); if (pAttenuationNode) { double temp; pAttenuationNode->Attribute("const", &temp); m_Props.m_Attenuation[0] = (float) temp; pAttenuationNode->Attribute("linear", &temp); m_Props.m_Attenuation[1] = (float) temp; pAttenuationNode->Attribute("exp", &temp); m_Props.m_Attenuation[2] = (float) temp; } TiXmlElement* pShapeNode = NULL; pShapeNode = pLight->FirstChildElement("Shape"); if (pShapeNode) { pShapeNode->Attribute("range", &temp); m_Props.m_Range = (float) temp; pShapeNode->Attribute("falloff", &temp); m_Props.m_Falloff = (float) temp; pShapeNode->Attribute("theta", &temp); m_Props.m_Theta = (float) temp; pShapeNode->Attribute("phi", &temp); m_Props.m_Phi = (float) temp; } return true; } std::shared_ptr LightRenderComponent::VCreateSceneNode(void) { std::shared_ptr pTransformComponent = MakeStrongPtr(m_pOwner->GetComponent(TransformComponent::g_Name)); if (pTransformComponent) { WeakBaseRenderComponentPtr weakThis(this); return std::shared_ptr(GCC_NEW OpenGLLightNode46(m_pOwner->GetId(), weakThis, m_Props, pTransformComponent->GetTransform())); } return std::shared_ptr(); } void LightRenderComponent::VCreateInheritedXmlElements(TiXmlElement *pBaseElement) { TiXmlElement* pSceneNode = GCC_NEW TiXmlElement("Light"); // attenuation TiXmlElement* pAttenuation = GCC_NEW TiXmlElement("Attenuation"); pAttenuation->SetAttribute("const", ToStr(m_Props.m_Attenuation[0]).c_str()); pAttenuation->SetAttribute("linear", ToStr(m_Props.m_Attenuation[1]).c_str()); pAttenuation->SetAttribute("exp", ToStr(m_Props.m_Attenuation[2]).c_str()); pSceneNode->LinkEndChild(pAttenuation); // shape TiXmlElement* pShape = GCC_NEW TiXmlElement("Shape"); pShape->SetAttribute("range", ToStr(m_Props.m_Range).c_str()); pShape->SetAttribute("falloff", ToStr(m_Props.m_Falloff).c_str()); pShape->SetAttribute("theta", ToStr(m_Props.m_Theta).c_str()); pShape->SetAttribute("phi", ToStr(m_Props.m_Phi).c_str()); pSceneNode->LinkEndChild(pShape); pBaseElement->LinkEndChild(pSceneNode); } SkyRenderComponent::SkyRenderComponent(void) { } bool SkyRenderComponent::VDelegateInit(TiXmlElement* pData) { TiXmlElement* pTexture = pData->FirstChildElement("Texture"); if (pTexture) { m_textureResource = pTexture->FirstChild()->Value(); } return true; } std::shared_ptr SkyRenderComponent::VCreateSceneNode(void) { std::shared_ptr sky; if (GameCodeApp::GetRendererImpl()==GameCodeApp::Renderer_OpenGL46) { sky = std::shared_ptr(GCC_NEW OpenGLSkyNode46(m_textureResource.c_str() )); } else { GCC_ERROR("Unknown Renderer Implementation in VLoadGameDelegate"); } return sky; } void SkyRenderComponent::VCreateInheritedXmlElements(TiXmlElement *pBaseElement) { TiXmlElement* pTextureNode = GCC_NEW TiXmlElement("Texture"); TiXmlText* pTextureText = GCC_NEW TiXmlText(m_textureResource.c_str()); pTextureNode->LinkEndChild(pTextureText); pBaseElement->LinkEndChild(pTextureNode); }