void Material::SetShaderParameterAnimation(const String& name, ValueAnimation* animation, WrapMode wrapMode, float speed) { ShaderParameterAnimationInfo* info = GetShaderParameterAnimationInfo(name); if (animation) { if (info && info->GetAnimation() == animation) { info->SetWrapMode(wrapMode); info->SetSpeed(speed); return; } if (shaderParameters_.Find(name) == shaderParameters_.End()) { LOGERROR(GetName() + " has no shader parameter: " + name); return; } StringHash nameHash(name); shaderParameterAnimationInfos_[nameHash] = new ShaderParameterAnimationInfo(this, name, animation, wrapMode, speed); UpdateEventSubscription(); } else { if (info) { StringHash nameHash(name); shaderParameterAnimationInfos_.Erase(nameHash); UpdateEventSubscription(); } } }
void Material::SetShaderParameter(const String& name, const Variant& value) { MaterialShaderParameter newParam; newParam.name_ = name; newParam.value_ = value; StringHash nameHash(name); shaderParameters_[nameHash] = newParam; if (nameHash == PSP_MATSPECCOLOR) { VariantType type = value.GetType(); if (type == VAR_VECTOR3) { const Vector3& vec = value.GetVector3(); specular_ = vec.x_ > 0.0f || vec.y_ > 0.0f || vec.z_ > 0.0f; } else if (type == VAR_VECTOR4) { const Vector4& vec = value.GetVector4(); specular_ = vec.x_ > 0.0f || vec.y_ > 0.0f || vec.z_ > 0.0f; } } if (!batchedParameterUpdate_) { RefreshShaderParameterHash(); RefreshMemoryUse(); } }
void ResourceCache::ReleasePackageResources(PackageFile* package, bool force) { HashSet<ShortStringHash> affectedGroups; const HashMap<String, PackageEntry>& entries = package->GetEntries(); for (HashMap<String, PackageEntry>::ConstIterator i = entries.Begin(); i != entries.End(); ++i) { StringHash nameHash(i->first_); // We do not know the actual resource type, so search all type containers for (HashMap<ShortStringHash, ResourceGroup>::Iterator j = resourceGroups_.Begin(); j != resourceGroups_.End(); ++j) { HashMap<StringHash, SharedPtr<Resource> >::Iterator k = j->second_.resources_.Find(nameHash); if (k != j->second_.resources_.End()) { // If other references exist, do not release, unless forced if (k->second_.Refs() == 1 || force) { j->second_.resources_.Erase(k); affectedGroups.Insert(j->first_); } break; } } } for (HashSet<ShortStringHash>::Iterator i = affectedGroups.Begin(); i != affectedGroups.End(); ++i) UpdateResourceGroup(*i); }
void Material::RemoveShaderParameter(const String& name) { StringHash nameHash(name); shaderParameters_.Erase(nameHash); if (nameHash == PSP_MATSPECCOLOR) specular_ = false; }
ShaderParameterAnimationInfo* Material::GetShaderParameterAnimationInfo(const String& name) const { StringHash nameHash(name); HashMap<StringHash, SharedPtr<ShaderParameterAnimationInfo> >::ConstIterator i = shaderParameterAnimationInfos_.Find(nameHash); if (i == shaderParameterAnimationInfos_.End()) return 0; return i->second_; }
void RenderPath::SetShaderParameter(const String& name, const Variant& value) { StringHash nameHash(name); for (unsigned i = 0; i < commands_.Size(); ++i) { HashMap<StringHash, Variant>::Iterator j = commands_[i].shaderParameters_.Find(nameHash); if (j != commands_[i].shaderParameters_.End()) j->second_ = value; } }
AnimationTrack* Animation::CreateTrack(const String& name) { /// \todo When tracks / keyframes are created dynamically, memory use is not updated StringHash nameHash(name); AnimationTrack* oldTrack = GetTrack(nameHash); if (oldTrack) return oldTrack; AnimationTrack& newTrack = tracks_[nameHash]; newTrack.name_ = name; newTrack.nameHash_ = nameHash; return &newTrack; }
const Variant& RenderPath::GetShaderParameter(const String& name) const { StringHash nameHash(name); for (unsigned i = 0; i < commands_.Size(); ++i) { HashMap<StringHash, Variant>::ConstIterator j = commands_[i].shaderParameters_.Find(nameHash); if (j != commands_[i].shaderParameters_.End()) return j->second_; } return Variant::EMPTY; }
bool Technique::BeginLoad(Deserializer& source) { passes_.Clear(); SetMemoryUse(sizeof(Technique)); SharedPtr<XMLFile> xml(new XMLFile(context_)); if (!xml->Load(source)) return false; XMLElement rootElem = xml->GetRoot(); if (rootElem.HasAttribute("sm3")) isSM3_ = rootElem.GetBool("sm3"); String globalVS = rootElem.GetAttribute("vs"); String globalPS = rootElem.GetAttribute("ps"); String globalVSDefines = rootElem.GetAttribute("vsdefines"); String globalPSDefines = rootElem.GetAttribute("psdefines"); // End with space so that the pass-specific defines can be appended if (!globalVSDefines.Empty()) globalVSDefines += ' '; if (!globalPSDefines.Empty()) globalPSDefines += ' '; bool globalAlphaMask = false; if (rootElem.HasAttribute("alphamask")) globalAlphaMask = rootElem.GetBool("alphamask"); unsigned numPasses = 0; XMLElement passElem = rootElem.GetChild("pass"); while (passElem) { if (passElem.HasAttribute("name")) { StringHash nameHash(passElem.GetAttribute("name")); Pass* newPass = CreatePass(nameHash); ++numPasses; if (passElem.HasAttribute("sm3")) newPass->SetIsSM3(passElem.GetBool("sm3")); // Append global defines only when pass does not redefine the shader if (passElem.HasAttribute("vs")) { newPass->SetVertexShader(passElem.GetAttribute("vs")); newPass->SetVertexShaderDefines(passElem.GetAttribute("vsdefines")); } else { newPass->SetVertexShader(globalVS); newPass->SetVertexShaderDefines(globalVSDefines + passElem.GetAttribute("vsdefines")); } if (passElem.HasAttribute("ps")) { newPass->SetPixelShader(passElem.GetAttribute("ps")); newPass->SetPixelShaderDefines(passElem.GetAttribute("psdefines")); } else { newPass->SetPixelShader(globalPS); newPass->SetPixelShaderDefines(globalPSDefines + passElem.GetAttribute("psdefines")); } if (passElem.HasAttribute("lighting")) { String lighting = passElem.GetAttributeLower("lighting"); newPass->SetLightingMode((PassLightingMode)GetStringListIndex(lighting.CString(), lightingModeNames, LIGHTING_UNLIT)); } if (passElem.HasAttribute("blend")) { String blend = passElem.GetAttributeLower("blend"); newPass->SetBlendMode((BlendMode)GetStringListIndex(blend.CString(), blendModeNames, BLEND_REPLACE)); } if (passElem.HasAttribute("depthtest")) { String depthTest = passElem.GetAttributeLower("depthtest"); if (depthTest == "false") newPass->SetDepthTestMode(CMP_ALWAYS); else newPass->SetDepthTestMode((CompareMode)GetStringListIndex(depthTest.CString(), compareModeNames, CMP_LESS)); } if (passElem.HasAttribute("depthwrite")) newPass->SetDepthWrite(passElem.GetBool("depthwrite")); if (passElem.HasAttribute("alphamask")) newPass->SetAlphaMask(passElem.GetBool("alphamask")); else newPass->SetAlphaMask(globalAlphaMask); } else LOGERROR("Missing pass name"); passElem = passElem.GetNext("pass"); } // Calculate memory use now SetMemoryUse(sizeof(Technique) + numPasses * sizeof(Pass)); return true; }
ShaderVariation* Shader::GetVariation(ShaderType type, const String& name) { StringHash nameHash(name); if (type == VS) { if (vsParser_.HasCombination(name)) { HashMap<StringHash, SharedPtr<ShaderVariation> >::Iterator i = vsVariations_.Find(nameHash); // Create the shader variation now if not created yet if (i == vsVariations_.End()) { ShaderCombination combination = vsParser_.GetCombination(name); i = vsVariations_.Insert(MakePair(nameHash, SharedPtr<ShaderVariation>(new ShaderVariation(this, VS)))); String path, fileName, extension; SplitPath(GetName(), path, fileName, extension); String fullName = path + fileName + "_" + name; if (fullName.EndsWith("_")) fullName.Resize(fullName.Length() - 1); i->second_->SetName(fullName); i->second_->SetSourceCode(vsSourceCode_, vsSourceCodeLength_); i->second_->SetDefines(combination.defines_, combination.defineValues_); SetMemoryUse(GetMemoryUse() + sizeof(ShaderVariation)); } return i->second_; } else return 0; } else { if (psParser_.HasCombination(name)) { HashMap<StringHash, SharedPtr<ShaderVariation> >::Iterator i = psVariations_.Find(nameHash); // Create the shader variation now if not created yet if (i == psVariations_.End()) { ShaderCombination combination = psParser_.GetCombination(name); i = psVariations_.Insert(MakePair(nameHash, SharedPtr<ShaderVariation>(new ShaderVariation(this, PS)))); String path, fileName, extension; SplitPath(GetName(), path, fileName, extension); String fullName = path + fileName + "_" + name; if (fullName.EndsWith("_")) fullName.Resize(fullName.Length() - 1); i->second_->SetName(fullName); i->second_->SetSourceCode(psSourceCode_, psSourceCodeLength_); i->second_->SetDefines(combination.defines_, combination.defineValues_); SetMemoryUse(GetMemoryUse() + sizeof(ShaderVariation)); } return i->second_; } else return 0; } }
bool Technique::Load(Deserializer& source) { PROFILE(LoadTechnique); SharedPtr<XMLFile> xml(new XMLFile(context_)); if (!xml->Load(source)) return false; XMLElement rootElem = xml->GetRoot(); if (rootElem.HasAttribute("sm3")) isSM3_ = rootElem.GetBool("sm3"); unsigned numPasses = 0; XMLElement passElem = rootElem.GetChild("pass"); while (passElem) { if (passElem.HasAttribute("name")) { StringHash nameHash(passElem.GetAttribute("name")); Pass* newPass = CreatePass(nameHash); ++numPasses; if (passElem.HasAttribute("vs")) newPass->SetVertexShader(passElem.GetAttribute("vs")); if (passElem.HasAttribute("ps")) newPass->SetPixelShader(passElem.GetAttribute("ps")); if (passElem.HasAttribute("lighting")) { String lighting = passElem.GetAttributeLower("lighting"); newPass->SetLightingMode((PassLightingMode)GetStringListIndex(lighting.CString(), lightingModeNames, LIGHTING_UNLIT)); } if (passElem.HasAttribute("blend")) { String blend = passElem.GetAttributeLower("blend"); newPass->SetBlendMode((BlendMode)GetStringListIndex(blend.CString(), blendModeNames, BLEND_REPLACE)); } if (passElem.HasAttribute("depthtest")) { String depthTest = passElem.GetAttributeLower("depthtest"); if (depthTest == "false") newPass->SetDepthTestMode(CMP_ALWAYS); else newPass->SetDepthTestMode((CompareMode)GetStringListIndex(depthTest.CString(), compareModeNames, CMP_LESS)); } if (passElem.HasAttribute("depthwrite")) newPass->SetDepthWrite(passElem.GetBool("depthwrite")); if (passElem.HasAttribute("alphamask")) newPass->SetAlphaMask(passElem.GetBool("alphamask")); } else LOGERROR("Missing pass name"); passElem = passElem.GetNext("pass"); } // Calculate memory use unsigned memoryUse = sizeof(Technique) + numPasses * sizeof(Pass); SetMemoryUse(memoryUse); return true; }
void SstGlobalSym::Put( ExeMaker& eMaker, const uint cSeg ) /***************************************************************/ { if ( _symbolInfo.isEmpty() ) { eMaker.DumpToExe( (unsigned_16) 0 ); eMaker.DumpToExe( (unsigned_16) 0 ); eMaker.DumpToExe( (unsigned_32) 0 ); eMaker.DumpToExe( (unsigned_32) 0 ); eMaker.DumpToExe( (unsigned_32) 0 ); return; } unsigned_32 currentOffset = 0; /* cerr << "entered SstGlobalSym::Put()\n"; cerr << "creating nameHash for "; cerr << _symbolInfo.entries(); cerr << " symbols.\n"; cerr.flush(); */ eMaker.DumpToExe( (unsigned_16) DEFAULT_NAME_HASH ); eMaker.DumpToExe( (unsigned_16) DEFAULT_ADDR_HASH ); streampos pos = eMaker.TellPos(); eMaker.Reserve(3*LONG_WORD); NameHashTable nameHash(_symbolInfo.entries()); /* cerr << "NameHashTable complete\n"; cerr.flush(); */ AddrHashTable addrHash(cSeg); /* cerr << "AddrHashTable complete\n"; cerr.flush(); */ //WCPtrConstSListIter<SymbolStruct> iter(_symbolInfo); SymbolStruct* currentPtr = NULL; long cnt=0, mcnt; mcnt = _symbolInfo.entries(); /* cerr << "_symbolInfo has "; cerr << mcnt; cerr << " entries.\n"; cerr.flush(); */ //while ( ++iter ) { while ( cnt++ < mcnt) { /* cerr << "global Symbol count: "; cerr << cnt; cerr << "\n"; cerr.flush(); */ //currentPtr = iter.current(); currentPtr = _symbolInfo.get(cnt); //cerr << "OK\n"; //cerr.flush(); currentPtr -> SetOffset(currentOffset); if ( currentPtr -> cSum() == NO_CHKSUM ) { if ( addrHash.TryToInsert(currentPtr) ) { currentOffset += SymbolSubsection::PageAlign(eMaker,currentPtr->Length(),currentOffset); currentOffset += currentPtr -> Length(); currentPtr -> Put(eMaker); } } else if ( nameHash.TryToInsert(currentPtr) ) { currentOffset += SymbolSubsection::PageAlign(eMaker,currentPtr->Length(),currentOffset); currentOffset += currentPtr -> Length(); currentPtr -> Put(eMaker); addrHash.TryToInsert(currentPtr); } } currentOffset += SymbolSubsection::DumpPageAlign(eMaker,LONG_WORD,0xff); unsigned_32 preNameHasPos = eMaker.TellPos(); nameHash.Put(eMaker); unsigned_32 suNameHasPos = eMaker.TellPos(); addrHash.Put(eMaker); unsigned_32 currentPos = eMaker.TellPos(); eMaker.SeekTo(pos); eMaker.DumpToExe(currentOffset); eMaker.DumpToExe(suNameHasPos - preNameHasPos); eMaker.DumpToExe(currentPos - suNameHasPos); eMaker.SeekTo(currentPos); }