bool Material::BeginLoad(Deserializer& source) { // In headless mode, do not actually load the material, just return success Graphics* graphics = GetSubsystem<Graphics>(); if (!graphics) return true; loadXMLFile_ = new XMLFile(context_); if (loadXMLFile_->Load(source)) { // If async loading, scan the XML content beforehand for technique & texture resources // and request them to also be loaded. Can not do anything else at this point if (GetAsyncLoadState() == ASYNC_LOADING) { ResourceCache* cache = GetSubsystem<ResourceCache>(); XMLElement rootElem = loadXMLFile_->GetRoot(); XMLElement techniqueElem = rootElem.GetChild("technique"); while (techniqueElem) { cache->BackgroundLoadResource<Technique>(techniqueElem.GetAttribute("name"), true, this); techniqueElem = techniqueElem.GetNext("technique"); } XMLElement textureElem = rootElem.GetChild("texture"); while (textureElem) { String name = textureElem.GetAttribute("name"); // Detect cube maps by file extension: they are defined by an XML file /// \todo Differentiate with 3D textures by actually reading the XML content if (GetExtension(name) == ".xml") { #ifdef DESKTOP_GRAPHICS TextureUnit unit = TU_DIFFUSE; if (textureElem.HasAttribute("unit")) unit = ParseTextureUnitName(textureElem.GetAttribute("unit")); if (unit == TU_VOLUMEMAP) cache->BackgroundLoadResource<Texture3D>(name, true, this); else #endif cache->BackgroundLoadResource<TextureCube>(name, true, this); } else cache->BackgroundLoadResource<Texture2D>(name, true, this); textureElem = textureElem.GetNext("texture"); } } return true; } else { ResetToDefaults(); loadXMLFile_.Reset(); return false; } }
void RenderPathCommand::Load(const XMLElement& element) { type_ = (RenderCommandType)GetStringListIndex(element.GetAttributeLower("type").CString(), commandTypeNames, CMD_NONE); tag_ = element.GetAttribute("tag"); if (element.HasAttribute("enabled")) enabled_ = element.GetBool("enabled"); if (element.HasAttribute("metadata")) metadata_ = element.GetAttribute("metadata"); switch (type_) { case CMD_CLEAR: if (element.HasAttribute("color")) { clearFlags_ |= CLEAR_COLOR; if (element.GetAttributeLower("color") == "fog") useFogColor_ = true; else clearColor_ = element.GetColor("color"); } if (element.HasAttribute("depth")) { clearFlags_ |= CLEAR_DEPTH; clearDepth_ = element.GetFloat("depth"); } if (element.HasAttribute("stencil")) { clearFlags_ |= CLEAR_STENCIL; clearStencil_ = (unsigned)element.GetInt("stencil"); } break; case CMD_SCENEPASS: pass_ = element.GetAttribute("pass"); sortMode_ = (RenderCommandSortMode)GetStringListIndex(element.GetAttributeLower("sort").CString(), sortModeNames, SORT_FRONTTOBACK); if (element.HasAttribute("marktostencil")) markToStencil_ = element.GetBool("marktostencil"); if (element.HasAttribute("vertexlights")) vertexLights_ = element.GetBool("vertexlights"); break; case CMD_FORWARDLIGHTS: pass_ = element.GetAttribute("pass"); if (element.HasAttribute("uselitbase")) useLitBase_ = element.GetBool("uselitbase"); break; case CMD_LIGHTVOLUMES: case CMD_QUAD: vertexShaderName_ = element.GetAttribute("vs"); pixelShaderName_ = element.GetAttribute("ps"); vertexShaderDefines_ = element.GetAttribute("vsdefines"); pixelShaderDefines_ = element.GetAttribute("psdefines"); if (type_ == CMD_QUAD) { if (element.HasAttribute("blend")) { String blend = element.GetAttributeLower("blend"); blendMode_ = ((BlendMode)GetStringListIndex(blend.CString(), blendModeNames, BLEND_REPLACE)); } XMLElement parameterElem = element.GetChild("parameter"); while (parameterElem) { String name = parameterElem.GetAttribute("name"); shaderParameters_[name] = Material::ParseShaderParameterValue(parameterElem.GetAttribute("value")); parameterElem = parameterElem.GetNext("parameter"); } } break; default: break; } // By default use 1 output, which is the viewport outputs_.Resize(1); outputs_[0] = MakePair(String("viewport"), FACE_POSITIVE_X); if (element.HasAttribute("output")) outputs_[0].first_ = element.GetAttribute("output"); if (element.HasAttribute("face")) outputs_[0].second_ = (CubeMapFace)element.GetInt("face"); if (element.HasAttribute("depthstencil")) depthStencilName_ = element.GetAttribute("depthstencil"); // Check for defining multiple outputs XMLElement outputElem = element.GetChild("output"); while (outputElem) { unsigned index = (unsigned)outputElem.GetInt("index"); if (index < MAX_RENDERTARGETS) { if (index >= outputs_.Size()) outputs_.Resize(index + 1); outputs_[index].first_ = outputElem.GetAttribute("name"); outputs_[index].second_ = outputElem.HasAttribute("face") ? (CubeMapFace)outputElem.GetInt("face") : FACE_POSITIVE_X; } outputElem = outputElem.GetNext("output"); } XMLElement textureElem = element.GetChild("texture"); while (textureElem) { TextureUnit unit = TU_DIFFUSE; if (textureElem.HasAttribute("unit")) unit = ParseTextureUnitName(textureElem.GetAttribute("unit")); if (unit < MAX_TEXTURE_UNITS) { String name = textureElem.GetAttribute("name"); textureNames_[unit] = name; } textureElem = textureElem.GetNext("texture"); } }
bool Material::Load(const XMLElement& source) { ResetToDefaults(); if (source.IsNull()) { LOGERROR("Can not load material from null XML element"); return false; } ResourceCache* cache = GetSubsystem<ResourceCache>(); XMLElement techniqueElem = source.GetChild("technique"); techniques_.Clear(); while (techniqueElem) { Technique* tech = cache->GetResource<Technique>(techniqueElem.GetAttribute("name")); if (tech) { TechniqueEntry newTechnique; newTechnique.technique_ = tech; if (techniqueElem.HasAttribute("quality")) newTechnique.qualityLevel_ = techniqueElem.GetInt("quality"); if (techniqueElem.HasAttribute("loddistance")) newTechnique.lodDistance_ = techniqueElem.GetFloat("loddistance"); techniques_.Push(newTechnique); } techniqueElem = techniqueElem.GetNext("technique"); } SortTechniques(); XMLElement textureElem = source.GetChild("texture"); while (textureElem) { TextureUnit unit = TU_DIFFUSE; if (textureElem.HasAttribute("unit")) { String unitName = textureElem.GetAttributeLower("unit"); if (unitName.Length() > 1) { unit = ParseTextureUnitName(unitName); if (unit >= MAX_MATERIAL_TEXTURE_UNITS) LOGERROR("Unknown or illegal texture unit " + unitName); } else unit = (TextureUnit)Clamp(ToInt(unitName), 0, MAX_MATERIAL_TEXTURE_UNITS - 1); } if (unit != MAX_MATERIAL_TEXTURE_UNITS) { String name = textureElem.GetAttribute("name"); // Detect cube maps by file extension: they are defined by an XML file if (GetExtension(name) == ".xml") SetTexture(unit, cache->GetResource<TextureCube>(name)); else SetTexture(unit, cache->GetResource<Texture2D>(name)); } textureElem = textureElem.GetNext("texture"); } XMLElement parameterElem = source.GetChild("parameter"); while (parameterElem) { String name = parameterElem.GetAttribute("name"); SetShaderParameter(name, ParseShaderParameterValue(parameterElem.GetAttribute("value"))); parameterElem = parameterElem.GetNext("parameter"); } XMLElement cullElem = source.GetChild("cull"); if (cullElem) SetCullMode((CullMode)GetStringListIndex(cullElem.GetAttribute("value").CString(), cullModeNames, CULL_CCW)); XMLElement shadowCullElem = source.GetChild("shadowcull"); if (shadowCullElem) SetShadowCullMode((CullMode)GetStringListIndex(shadowCullElem.GetAttribute("value").CString(), cullModeNames, CULL_CCW)); XMLElement depthBiasElem = source.GetChild("depthbias"); if (depthBiasElem) SetDepthBias(BiasParameters(depthBiasElem.GetFloat("constant"), depthBiasElem.GetFloat("slopescaled"))); // Calculate memory use unsigned memoryUse = sizeof(Material); memoryUse += techniques_.Size() * sizeof(TechniqueEntry); memoryUse += MAX_MATERIAL_TEXTURE_UNITS * sizeof(SharedPtr<Texture>); memoryUse += shaderParameters_.Size() * sizeof(MaterialShaderParameter); SetMemoryUse(memoryUse); CheckOcclusion(); return true; }
void RenderPathCommand::Load(const XMLElement& element) { type_ = (RenderCommandType)GetStringListIndex(element.GetAttributeLower("type").CString(), commandTypeNames, CMD_NONE); tag_ = element.GetAttribute("tag"); if (element.HasAttribute("enabled")) enabled_ = element.GetBool("enabled"); if (element.HasAttribute("metadata")) metadata_ = element.GetAttribute("metadata"); switch (type_) { case CMD_CLEAR: if (element.HasAttribute("color")) { clearFlags_ |= CLEAR_COLOR; // Mark fog color with negative values if (element.GetAttributeLower("color") == "fog") useFogColor_ = true; else clearColor_ = element.GetColor("color"); } if (element.HasAttribute("depth")) { clearFlags_ |= CLEAR_DEPTH; clearDepth_ = element.GetFloat("depth"); } if (element.HasAttribute("stencil")) { clearFlags_ |= CLEAR_STENCIL; clearStencil_ = element.GetInt("stencil"); } break; case CMD_SCENEPASS: pass_ = element.GetAttribute("pass"); sortMode_ = (RenderCommandSortMode)GetStringListIndex(element.GetAttributeLower("sort").CString(), sortModeNames, SORT_FRONTTOBACK); if (element.HasAttribute("marktostencil")) markToStencil_ = element.GetBool("marktostencil"); if (element.HasAttribute("vertexlights")) vertexLights_ = element.GetBool("vertexlights"); if (element.HasAttribute("usescissor")) useScissor_ = element.GetBool("usescissor"); break; case CMD_FORWARDLIGHTS: pass_ = element.GetAttribute("pass"); if (element.HasAttribute("uselitbase")) useLitBase_ = element.GetBool("uselitbase"); break; case CMD_LIGHTVOLUMES: case CMD_QUAD: vertexShaderName_ = element.GetAttribute("vs"); pixelShaderName_ = element.GetAttribute("ps"); if (type_ == CMD_QUAD) { XMLElement parameterElem = element.GetChild("parameter"); while (parameterElem) { String name = parameterElem.GetAttribute("name"); Variant value = parameterElem.GetVectorVariant("value"); shaderParameters_[name] = value; parameterElem = parameterElem.GetNext("parameter"); } } break; default: break; } // By default use 1 output, which is the viewport outputNames_.Push("viewport"); if (element.HasAttribute("output")) outputNames_[0] = element.GetAttribute("output"); // Check for defining multiple outputs XMLElement outputElem = element.GetChild("output"); while (outputElem) { unsigned index = outputElem.GetInt("index"); if (index < MAX_RENDERTARGETS) { if (index >= outputNames_.Size()) outputNames_.Resize(index + 1); outputNames_[index] = outputElem.GetAttribute("name"); } outputElem = outputElem.GetNext("output"); } XMLElement textureElem = element.GetChild("texture"); while (textureElem) { TextureUnit unit = TU_DIFFUSE; if (textureElem.HasAttribute("unit")) { String unitName = textureElem.GetAttributeLower("unit"); if (unitName.Length() > 1) unit = ParseTextureUnitName(unitName); else unit = (TextureUnit)Clamp(ToInt(unitName), 0, MAX_TEXTURE_UNITS - 1); } if (unit < MAX_TEXTURE_UNITS) { String name = textureElem.GetAttribute("name"); textureNames_[unit] = name; } textureElem = textureElem.GetNext("texture"); } }
bool Material::Load(const XMLElement& source) { ResetToDefaults(); if (source.IsNull()) { LOGERROR("Can not load material from null XML element"); return false; } ResourceCache* cache = GetSubsystem<ResourceCache>(); XMLElement techniqueElem = source.GetChild("technique"); techniques_.Clear(); while (techniqueElem) { Technique* tech = cache->GetResource<Technique>(techniqueElem.GetAttribute("name")); if (tech) { TechniqueEntry newTechnique; newTechnique.technique_ = tech; if (techniqueElem.HasAttribute("quality")) newTechnique.qualityLevel_ = techniqueElem.GetInt("quality"); if (techniqueElem.HasAttribute("loddistance")) newTechnique.lodDistance_ = techniqueElem.GetFloat("loddistance"); techniques_.Push(newTechnique); } techniqueElem = techniqueElem.GetNext("technique"); } SortTechniques(); XMLElement textureElem = source.GetChild("texture"); while (textureElem) { TextureUnit unit = TU_DIFFUSE; if (textureElem.HasAttribute("unit")) unit = ParseTextureUnitName(textureElem.GetAttribute("unit")); if (unit < MAX_TEXTURE_UNITS) { String name = textureElem.GetAttribute("name"); // Detect cube maps by file extension: they are defined by an XML file /// \todo Differentiate with 3D textures by actually reading the XML content if (GetExtension(name) == ".xml") { #ifdef DESKTOP_GRAPHICS if (unit == TU_VOLUMEMAP) SetTexture(unit, cache->GetResource<Texture3D>(name)); else #endif SetTexture(unit, cache->GetResource<TextureCube>(name)); } else SetTexture(unit, cache->GetResource<Texture2D>(name)); } textureElem = textureElem.GetNext("texture"); } batchedParameterUpdate_ = true; XMLElement parameterElem = source.GetChild("parameter"); while (parameterElem) { String name = parameterElem.GetAttribute("name"); SetShaderParameter(name, ParseShaderParameterValue(parameterElem.GetAttribute("value"))); parameterElem = parameterElem.GetNext("parameter"); } batchedParameterUpdate_ = false; XMLElement parameterAnimationElem = source.GetChild("parameteranimation"); while (parameterAnimationElem) { String name = parameterAnimationElem.GetAttribute("name"); SharedPtr<ValueAnimation> animation(new ValueAnimation(context_)); if (!animation->LoadXML(parameterAnimationElem)) { LOGERROR("Could not load parameter animation"); return false; } String wrapModeString = parameterAnimationElem.GetAttribute("wrapmode"); WrapMode wrapMode = WM_LOOP; for (int i = 0; i <= WM_CLAMP; ++i) { if (wrapModeString == wrapModeNames[i]) { wrapMode = (WrapMode)i; break; } } float speed = parameterAnimationElem.GetFloat("speed"); SetShaderParameterAnimation(name, animation, wrapMode, speed); parameterAnimationElem = parameterAnimationElem.GetNext("parameteranimation"); } XMLElement cullElem = source.GetChild("cull"); if (cullElem) SetCullMode((CullMode)GetStringListIndex(cullElem.GetAttribute("value").CString(), cullModeNames, CULL_CCW)); XMLElement shadowCullElem = source.GetChild("shadowcull"); if (shadowCullElem) SetShadowCullMode((CullMode)GetStringListIndex(shadowCullElem.GetAttribute("value").CString(), cullModeNames, CULL_CCW)); XMLElement fillElem = source.GetChild("fill"); if (fillElem) SetFillMode((FillMode)GetStringListIndex(fillElem.GetAttribute("value").CString(), fillModeNames, FILL_SOLID)); XMLElement depthBiasElem = source.GetChild("depthbias"); if (depthBiasElem) SetDepthBias(BiasParameters(depthBiasElem.GetFloat("constant"), depthBiasElem.GetFloat("slopescaled"))); RefreshShaderParameterHash(); RefreshMemoryUse(); CheckOcclusion(); return true; }
bool Material::Load(Deserializer& source) { PROFILE(LoadMaterial); // In headless mode, do not actually load the material, just return success Graphics* graphics = GetSubsystem<Graphics>(); if (!graphics) return true; ResetToDefaults(); ResourceCache* cache = GetSubsystem<ResourceCache>(); SharedPtr<XMLFile> xml(new XMLFile(context_)); if (!xml->Load(source)) return false; XMLElement rootElem = xml->GetRoot(); XMLElement techniqueElem = rootElem.GetChild("technique"); techniques_.Clear(); while (techniqueElem) { Technique* tech = cache->GetResource<Technique>(techniqueElem.GetAttribute("name")); if (tech) { TechniqueEntry newTechnique; newTechnique.technique_ = tech; if (techniqueElem.HasAttribute("quality")) newTechnique.qualityLevel_ = techniqueElem.GetInt("quality"); if (techniqueElem.HasAttribute("loddistance")) newTechnique.lodDistance_ = techniqueElem.GetFloat("loddistance"); techniques_.Push(newTechnique); } techniqueElem = techniqueElem.GetNext("technique"); } XMLElement textureElem = rootElem.GetChild("texture"); while (textureElem) { TextureUnit unit = TU_DIFFUSE; if (textureElem.HasAttribute("unit")) { String unitName = textureElem.GetAttributeLower("unit"); if (unitName.Length() > 1) { unit = ParseTextureUnitName(unitName); if (unit >= MAX_MATERIAL_TEXTURE_UNITS) LOGERROR("Unknown or illegal texture unit " + unitName); } else unit = (TextureUnit)Clamp(ToInt(unitName), 0, MAX_MATERIAL_TEXTURE_UNITS - 1); } if (unit != MAX_MATERIAL_TEXTURE_UNITS) { String name = textureElem.GetAttribute("name"); // Detect cube maps by file extension: they are defined by an XML file if (GetExtension(name) == ".xml") SetTexture(unit, cache->GetResource<TextureCube>(name)); else SetTexture(unit, cache->GetResource<Texture2D>(name)); } textureElem = textureElem.GetNext("texture"); } XMLElement parameterElem = rootElem.GetChild("parameter"); while (parameterElem) { String name = parameterElem.GetAttribute("name"); Variant value = parameterElem.GetVectorVariant("value"); SetShaderParameter(name, value); parameterElem = parameterElem.GetNext("parameter"); } XMLElement cullElem = rootElem.GetChild("cull"); if (cullElem) SetCullMode((CullMode)GetStringListIndex(cullElem.GetAttribute("value").CString(), cullModeNames, CULL_CCW)); XMLElement shadowCullElem = rootElem.GetChild("shadowcull"); if (shadowCullElem) SetShadowCullMode((CullMode)GetStringListIndex(shadowCullElem.GetAttribute("value").CString(), cullModeNames, CULL_CCW)); XMLElement depthBiasElem = rootElem.GetChild("depthbias"); if (depthBiasElem) SetDepthBias(BiasParameters(depthBiasElem.GetFloat("constant"), depthBiasElem.GetFloat("slopescaled"))); // Calculate memory use unsigned memoryUse = sizeof(Material); memoryUse += techniques_.Size() * sizeof(TechniqueEntry); memoryUse += MAX_MATERIAL_TEXTURE_UNITS * sizeof(SharedPtr<Texture>); memoryUse += shaderParameters_.Size() * sizeof(MaterialShaderParameter); SetMemoryUse(memoryUse); CheckOcclusion(); return true; }