RenderContext* RenderContext::LoadXML(const char* xmlFileNamePtr, const char* indentifier) { TiXmlDocument doc((ContentManager::theContentPath + xmlFileNamePtr).c_str()); if(!doc.LoadFile()) { InternalOutput::GetReference().Error( "Failed to load %s, does the file exist?\n", xmlFileNamePtr); return 0; } TiXmlHandle hDoc(&doc); TiXmlElement* elementPtr; TiXmlHandle hRoot(0); elementPtr = hDoc.FirstChildElement().Element(); if( !elementPtr ) { InternalOutput::GetReference().Error( "Failed to load %s, is the file empty?\n", xmlFileNamePtr); return 0; } std::string rootName = elementPtr->Value(); if( strcmp(rootName.c_str(), "GDRenderContext") != 0 ) { InternalOutput::GetReference().Error( "Failed to load %s, missing a GDRenderContext element\n", xmlFileNamePtr); return 0; } TiXmlElement* pMaterialElement = elementPtr->FirstChildElement("Material"); std::string materialString; std::string shaderEffectString; std::string techniqueString; std::string vertexFormatString; std::string castShadowString; std::string renderStyleString; if( pMaterialElement != 0 ) { if(pMaterialElement->GetText() != 0) materialString = pMaterialElement->GetText(); } // Error check for old Effect based shader usage TiXmlElement* pEffectElement = elementPtr->FirstChildElement("Effect"); if(nullptr == pEffectElement ) { InternalOutput::GetReference().Error( "Failed to load %s, missing Effect element", xmlFileNamePtr); return 0; } shaderEffectString = pEffectElement->GetText(); TiXmlElement* pTechniqueElement = elementPtr->FirstChildElement("Technique"); if( pTechniqueElement != 0 ) { if( pTechniqueElement->GetText() != 0 ) techniqueString = pTechniqueElement->GetText(); } if( techniqueString.length() == 0 ) techniqueString = "Basic"; TiXmlElement* pVertexFormatElement = elementPtr->FirstChildElement("VertexFormat"); if( pVertexFormatElement == 0 ) { InternalOutput::GetReference().Error( "Failed to load %s, missing a VertexFormat element\n", xmlFileNamePtr); return 0; } vertexFormatString = pVertexFormatElement->GetText(); bool isDeferredPointLightContext = false; TiXmlElement* pPointLightTechnique = elementPtr->FirstChildElement("PointLightTechnique"); if( pPointLightTechnique != 0 ) { if( pPointLightTechnique->GetText() != 0 ) { std::string technique = pPointLightTechnique->GetText(); if( technique.length() != 0 ) isDeferredPointLightContext = true; } } bool isDeferredDirLightContext = false; TiXmlElement* pDirLightTechnique = elementPtr->FirstChildElement("DirLightTechnique"); if( pDirLightTechnique != 0 ) { if( pDirLightTechnique->GetText() != 0 ) { std::string technique = pDirLightTechnique->GetText(); if( technique.length() != 0 ) isDeferredDirLightContext = true; } } bool isDeferredSpotLightContext = false; TiXmlElement* pSpotLightTechnique = elementPtr->FirstChildElement("SpotLightTechnique"); if( pSpotLightTechnique != 0 ) { if( pSpotLightTechnique->GetText() != 0 ) { std::string technique = pSpotLightTechnique->GetText(); if( technique.length() != 0 ) isDeferredSpotLightContext = true; } } bool castShadows = false; TiXmlElement* pCastShadowsEle = elementPtr->FirstChildElement("CastShadows"); if( pCastShadowsEle != 0 ) { castShadows = true; if( pCastShadowsEle->GetText() != 0 ) { if( strlen( pCastShadowsEle->GetText() ) != 0 && (_stricmp( pCastShadowsEle->GetText(), "false") == 0 || strcmp( pCastShadowsEle->GetText(), "0" ) == 0 ) ) { castShadows = false; } } } TiXmlElement* pRenderStyleElement = elementPtr->FirstChildElement("RenderStyle"); renderStyleString = pRenderStyleElement->GetText(); RenderContext* pRenderContext = 0; if( materialString.length() != 0 ) { RenderContextWithTexture* pRcWithTex = new RenderContextWithTexture; pRenderContext = pRcWithTex; if( strcmp( vertexFormatString.c_str(), "VERTEX_POS" ) == 0 ) { pRcWithTex->RenderFunc = RenderContextWithTexture::ContextPositionRenderFunc; pRcWithTex->vertexFormat = eVERTEX_POS; } else if( strcmp( vertexFormatString.c_str(), "VERTEX_POSCOLOR" ) == 0 ) { pRcWithTex->RenderFunc = RenderContextWithTexture::ContextPositionRenderFunc; pRcWithTex->vertexFormat = eVERTEX_POSCOLOR; } else if( strcmp( vertexFormatString.c_str(), "VERTEX_POSTEX" ) == 0 ) { pRcWithTex->RenderFunc = RenderContextWithTexture::ContextPositionUVRenderFunc; pRcWithTex->vertexFormat = eVERTEX_POSTEX; } else if( strcmp( vertexFormatString.c_str(), "VERTEX_POSNORMTEX" ) == 0 ) { pRcWithTex->RenderFunc = RenderContextWithTexture::ContextPosNormalUVRenderFunc; pRcWithTex->vertexFormat = eVERTEX_POSNORMTEX; } else if( strcmp( vertexFormatString.c_str(), "VERTEX_POSNORMTANTEX" ) == 0 ) { pRcWithTex->RenderFunc = RenderContextWithTexture::ContextPosNormalTangentUVRenderFunc; pRcWithTex->vertexFormat = eVERTEX_POSNORMTANTEX; } else if( strcmp( vertexFormatString.c_str(), "VERTEX_POSBONEWEIGHTNORMTEX" ) == 0 ) { pRcWithTex->RenderFunc = RenderContextWithTexture::ContextPosBoneWeightNormalUVRenderFunc; pRcWithTex->vertexFormat = eVERTEX_POSBONEWEIGHTNORMTEX; } else if( strcmp( vertexFormatString.c_str(), "VERTEX_POSBONEWEIGHTNORMTANTEX" ) == 0 ) { pRcWithTex->RenderFunc = RenderContextWithTexture::ContextPosBoneWeightNormalTanUVRenderFunc; pRcWithTex->vertexFormat = eVERTEX_POSBONEWEIGHTNORMTANTEX; } } else { pRenderContext = new RenderContext; if( "TRANSPARENT" == renderStyleString ) { if( strcmp( vertexFormatString.c_str(), "VERTEX_POS" ) == 0 ) { pRenderContext->RenderFunc = ContextTransparentPositionRenderFunc; pRenderContext->vertexFormat = eVERTEX_POS; } else if( strcmp( vertexFormatString.c_str(), "VERTEX_POSCOLOR" ) == 0 ) { pRenderContext->RenderFunc = ContextTransparentPositionColorRenderFunc; pRenderContext->vertexFormat = eVERTEX_POSCOLOR; } else if( strcmp( vertexFormatString.c_str(), "VERTEX_POSTEX" ) == 0 ) { pRenderContext->RenderFunc = ContextTransparentPositionUVRenderFunc; pRenderContext->vertexFormat = eVERTEX_POSTEX; } else if( strcmp( vertexFormatString.c_str(), "VERTEX_POSNORMTEX" ) == 0 ) { pRenderContext->RenderFunc = ContextTransparentPosNormalUVRenderFunc; pRenderContext->vertexFormat = eVERTEX_POSNORMTEX; } else if( strcmp( vertexFormatString.c_str(), "VERTEX_POSNORMTANTEX" ) == 0 ) { pRenderContext->RenderFunc = ContextTransparentPosNormalTangentUVRenderFunc; pRenderContext->vertexFormat = eVERTEX_POSNORMTANTEX; } } else { if( strcmp( vertexFormatString.c_str(), "VERTEX_POS" ) == 0 ) { pRenderContext->RenderFunc = ContextPositionRenderFunc; pRenderContext->vertexFormat = eVERTEX_POS; } else if( strcmp( vertexFormatString.c_str(), "VERTEX_POSCOLOR" ) == 0 ) { pRenderContext->RenderFunc = ContextPositionColorRenderFunc; pRenderContext->vertexFormat = eVERTEX_POSCOLOR; } else if( strcmp( vertexFormatString.c_str(), "VERTEX_POSTEX" ) == 0 ) { pRenderContext->RenderFunc = ContextPositionUVRenderFunc; pRenderContext->vertexFormat = eVERTEX_POSTEX; } else if( strcmp( vertexFormatString.c_str(), "VERTEX_POSNORMTEX" ) == 0 ) { pRenderContext->RenderFunc = ContextPosNormalUVRenderFunc; pRenderContext->vertexFormat = eVERTEX_POSNORMTEX; } else if (strcmp(vertexFormatString.c_str(), "VERTEX_POSNORMTEXNOCULL") == 0) { pRenderContext->RenderFunc = ContextPosNormalUVNoCullRenderFunc; pRenderContext->vertexFormat = eVERTEX_POSNORMTEX; } else if( strcmp( vertexFormatString.c_str(), "VERTEX_POSNORMTANTEX" ) == 0 ) { pRenderContext->RenderFunc = ContextPosNormalTangentUVRenderFunc; pRenderContext->vertexFormat = eVERTEX_POSNORMTANTEX; } else if (strcmp(vertexFormatString.c_str(), "VERTEX_POSNORMTANTEXNOCULL") == 0) { pRenderContext->RenderFunc = ContextPosNormalTangentUVNoCullRenderFunc; pRenderContext->vertexFormat = eVERTEX_POSNORMTANTEX; } else if( strcmp( vertexFormatString.c_str(), "VERTEX_POSBONEWEIGHTNORMTEX" ) == 0 ) { pRenderContext->RenderFunc = ContextPosBoneWeightNormalUVRenderFunc; pRenderContext->vertexFormat = eVERTEX_POSBONEWEIGHTNORMTEX; } else if( strcmp( vertexFormatString.c_str(), "VERTEX_POSBONEWEIGHTNORMTANTEX" ) == 0 ) { pRenderContext->RenderFunc = ContextPosBoneWeightNormalTanUVRenderFunc; pRenderContext->vertexFormat = eVERTEX_POSBONEWEIGHTNORMTANTEX; } } } if( materialString.length() != 0 ) { //std::string materialFilePath = "Resources/GDAssets"; //materialFilePath += materialString; //ContentHandle<RenderMaterial> matHandle = ContentManager::LoadXML<RenderMaterial>(materialFilePath.c_str()); } pRenderContext->castShadows = castShadows; // Set up shaders if(!pRenderContext->CreateEffect((string("ShaderEffects/") + shaderEffectString).c_str())) { InternalOutput::GetReference().Error( "Failed to load %s, shader effect, %s, failed to load\n", xmlFileNamePtr, shaderEffectString.c_str()); } ShaderTechnique *techPtr = nullptr; pRenderContext->SetRenderStageTechnique(elementPtr, "GBufferTechnique", xmlFileNamePtr, RenderContext::RS_GBUFFER); pRenderContext->SetRenderStageTechnique(elementPtr, "DepthCameraTechnique", xmlFileNamePtr, RenderContext::RS_DEPTH_CAMERA); pRenderContext->SetRenderStageTechnique(elementPtr, "DepthSpotLightTechnique", xmlFileNamePtr, RenderContext::RS_DEPTH_SPT_LIGHT); TiXmlElement* pDepthPointLightTechnique = elementPtr->FirstChildElement("DepthPointLightTechnique"); if( pDepthPointLightTechnique != 0 ) { if( pDepthPointLightTechnique->GetText() != 0 ) { std::string technique = pDepthPointLightTechnique->GetText(); if( technique.length() != 0 ) { ShaderTechnique *techPtr = pRenderContext->effectPtr.GetContent()->GetTechniqueByName( technique.c_str()); if(!techPtr) { InternalOutput::GetReference().Error( "Context %s specifies %s, but the technique does not exist in the shader\n", xmlFileNamePtr, "DepthPointLightTechnique"); } pRenderContext->SetRenderStageTechnique( RenderStage(RenderContext::RS_DEPTH_PNT_LIGHT), techPtr); } } } pRenderContext->SetRenderStageTechnique(elementPtr, "DepthDirectionalLightTechnique", xmlFileNamePtr, RenderContext::RS_DEPTH_DIR_LIGHT); pRenderContext->SetRenderStageTechnique(elementPtr, "UnlitTechnique", xmlFileNamePtr, RenderContext::RS_UNLIT); pRenderContext->SetRenderStageTechnique(elementPtr, "TransparencyTechnique", xmlFileNamePtr, RenderContext::RS_TRANSPARENT); pRenderContext->SetRenderStageTechnique(elementPtr, "GUITechnique", xmlFileNamePtr, RenderContext::RS_GUI); if( isDeferredPointLightContext ) { std::string technique = pPointLightTechnique->GetText(); if( technique.length() != 0 ) pRenderContext->SetRenderStageTechnique( RenderContext::RS_PNT_LIGHT, pRenderContext->effectPtr.GetContent()->GetTechniqueByName(technique.c_str() )); } if( isDeferredDirLightContext ) { std::string technique = pDirLightTechnique->GetText(); if( technique.length() != 0 ) pRenderContext->SetRenderStageTechnique( RenderContext::RS_DIR_LIGHT, pRenderContext->effectPtr.GetContent()->GetTechniqueByName(technique.c_str() )); } if( isDeferredSpotLightContext ) { std::string technique = pSpotLightTechnique->GetText(); if( technique.length() != 0 ) pRenderContext->SetRenderStageTechnique( RenderContext::RS_SPT_LIGHT, pRenderContext->effectPtr.GetContent()->GetTechniqueByName(technique.c_str() )); } //////////////////////////////////////////////////////////////////////////////////// // Layout verification //LayoutVerification((string("ShaderEffects/") + shaderEffectString).c_str(), vertexFormatString); // End layout verification if( pRenderContext->GetRenderStageTechnique( RenderContext::RS_TRANSPARENT ) != 0 ) pRenderContext->CreateRenderSet( true, RenderSetSorted::ZSortSmaller ); else pRenderContext->CreateRenderSet(); return pRenderContext; }