2014-05-05 14:50:33 +08:00
|
|
|
|
/****************************************************************************
|
|
|
|
|
Copyright (c) 2011-2013,WebJet Business Division,CYOU
|
|
|
|
|
|
|
|
|
|
http://www.genesis-3d.com.cn
|
|
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
|
THE SOFTWARE.
|
|
|
|
|
****************************************************************************/
|
|
|
|
|
#include "stdneb.h"
|
|
|
|
|
#include "materialinstance.h"
|
|
|
|
|
#include "addons/resource/resourcemanager.h"
|
|
|
|
|
#include "serialization/serializeserver.h"
|
|
|
|
|
#include "materialmaker/GenesisMaterial.h"
|
|
|
|
|
#include "materialmaker/parser/GenesisShaderParser.h"
|
|
|
|
|
#include "io/memorystream.h"
|
|
|
|
|
#include "io/iointerfaceprotocol.h"
|
|
|
|
|
#include "io/iointerface.h"
|
|
|
|
|
|
|
|
|
|
#include "MaterialManager.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace Graphic
|
|
|
|
|
{
|
|
|
|
|
const Resources::ResourceId s_strMatMngFile ("asset:AllMaterialInfo.mng");
|
|
|
|
|
const Resources::ResourceId s_strMatInstancePath("asset:");
|
|
|
|
|
const Resources::ResourceId s_strMatInstanceFile ("NewMaterial");
|
|
|
|
|
const Resources::ResourceId s_strMatInstanceFileExt (".material");
|
|
|
|
|
const Resources::ResourceId DefalutShaderID("shd:Common_Diffuse.shader");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__ImplementClass( MaterialInstanceManager, 'MIMA', Core::RefCounted);
|
|
|
|
|
|
|
|
|
|
MaterialInstanceManager::MaterialInstanceManager():m_usedMaterialNameIdx(0)
|
|
|
|
|
{
|
|
|
|
|
//empty
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
MaterialInstanceManager::~MaterialInstanceManager()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
GPtr<Graphic::MaterialInstance>
|
|
|
|
|
MaterialInstanceManager::CreateMaterialInstance( const Resources::ResourceId& shaderID )
|
|
|
|
|
{
|
|
|
|
|
if ( !shaderID.IsValid() )
|
|
|
|
|
{
|
|
|
|
|
n_error("invalid shaderID!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GPtr<MaterialInstance> pAppMaterial = _CreateMaterialInstance( shaderID );
|
|
|
|
|
if ( !pAppMaterial.isvalid() )
|
|
|
|
|
{
|
|
|
|
|
n_error("can't create AppMaterial!");
|
|
|
|
|
//return MaterialInstance::Create();
|
|
|
|
|
}
|
|
|
|
|
return pAppMaterial;
|
|
|
|
|
}
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
GPtr<Graphic::MaterialInstance>
|
|
|
|
|
MaterialInstanceManager::UpdateShader(const Resources::ResourceId& shaderID)
|
|
|
|
|
{
|
|
|
|
|
IndexT index = m_graphicMaterialMap.FindIndex(shaderID);
|
|
|
|
|
GPtr<Graphic::Material> mat = GenesisMaterialMaker::MakeFromShader(shaderID);
|
|
|
|
|
|
|
|
|
|
if (InvalidIndex != index)
|
|
|
|
|
m_graphicMaterialMap.Erase(shaderID);
|
|
|
|
|
|
|
|
|
|
m_graphicMaterialMap.Add(shaderID,mat);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GPtr<MaterialInstance> aMat = MaterialInstance::Create();
|
|
|
|
|
_InitMaterialInstance(aMat,shaderID,mat);
|
|
|
|
|
return aMat;
|
|
|
|
|
}
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
void
|
|
|
|
|
MaterialInstanceManager::_SetMaterialID(GPtr<Graphic::MaterialInstance>& matIns)
|
|
|
|
|
{
|
|
|
|
|
if ( !matIns )
|
|
|
|
|
{
|
|
|
|
|
n_assert(0);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Util::Guid guid;
|
|
|
|
|
guid.Generate();
|
|
|
|
|
|
|
|
|
|
Util::String guidStr = guid.AsString();
|
|
|
|
|
|
|
|
|
|
//android platform guid generate repate,so hack solve
|
|
|
|
|
{
|
|
|
|
|
static int s_count = 0;
|
|
|
|
|
++s_count;
|
|
|
|
|
if ( s_count < 0 )
|
|
|
|
|
{
|
|
|
|
|
s_count = 0;
|
|
|
|
|
}
|
|
|
|
|
guidStr.AppendInt(s_count);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Util::String strMatID = s_strMatInstancePath.Value();
|
|
|
|
|
strMatID = strMatID + guidStr + s_strMatInstanceFileExt.Value();
|
|
|
|
|
//strMatID.Format("%s%s%d%s",s_strMatInstancePath.Value(),s_strMatInstanceFile.Value(),GetMaterialNameIdx(),s_strMatInstanceFileExt.Value());
|
|
|
|
|
Resources::ResourceId matID(strMatID.Get());
|
|
|
|
|
|
|
|
|
|
matIns->SetMaterialID(matID);
|
|
|
|
|
|
|
|
|
|
m_graphicMaterialInstanceMap.Add(matIns->GetMaterialID(),matIns);
|
|
|
|
|
}
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
GPtr<MaterialInstance>
|
|
|
|
|
MaterialInstanceManager::_CreateMaterialInstance( const Resources::ResourceId& shaderID )
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ij<EFBFBD><C4B3><EFBFBD><EFBFBD><EFBFBD>ʵĸ<CAB5><C4B8><EFBFBD>
|
|
|
|
|
GPtr<MaterialInstance> aMat = 0;
|
|
|
|
|
aMat = _CreateNewMaterialInstance(shaderID);
|
|
|
|
|
_SetMaterialID(aMat);
|
|
|
|
|
|
|
|
|
|
return aMat;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
GPtr<Graphic::MaterialInstance>
|
|
|
|
|
MaterialInstanceManager::_CreateNewMaterialInstance( const Resources::ResourceId& shaderID )
|
|
|
|
|
{// ע<><D7A2><EFBFBD>˺<EFBFBD><CBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><C4B2>ʲ<EFBFBD><CAB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܲ<EFBFBD><DCB2>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĺ<EFBFBD><C4B9><EFBFBD>
|
|
|
|
|
GPtr<MaterialInstance> aMat = 0;
|
|
|
|
|
IndexT index = m_graphicMaterialMap.FindIndex(shaderID);
|
|
|
|
|
if (InvalidIndex != index)
|
|
|
|
|
{
|
|
|
|
|
GPtr<Graphic::Material>& mat = m_graphicMaterialMap.ValueAtIndex(index);
|
|
|
|
|
// add ref cnt
|
|
|
|
|
//mat->SetHaveMaterialInstanceCnt(mat->GetHaveMaterialInstanceCnt() + 1);
|
|
|
|
|
|
|
|
|
|
aMat = MaterialInstance::Create();
|
|
|
|
|
_InitMaterialInstance(aMat,shaderID,mat);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
GPtr<Graphic::Material> mat = GenesisMaterialMaker::MakeFromShader(shaderID);
|
|
|
|
|
m_graphicMaterialMap.Add(shaderID,mat);
|
|
|
|
|
|
|
|
|
|
aMat = MaterialInstance::Create();
|
|
|
|
|
_InitMaterialInstance(aMat,shaderID,mat);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return aMat;
|
|
|
|
|
}
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
void MaterialInstanceManager::_InitMaterialInstance(GPtr<Graphic::MaterialInstance>& matIns, const Resources::ResourceId& shaderID,const GPtr<Graphic::Material>& mat)
|
|
|
|
|
{
|
|
|
|
|
matIns->Clone(mat);
|
|
|
|
|
matIns->_SetShaderID(shaderID);
|
|
|
|
|
matIns->_AssignDefaultToInstance();
|
|
|
|
|
}
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
bool
|
|
|
|
|
MaterialInstanceManager::HaveMaterialInstance(const MaterialId& matID)
|
|
|
|
|
{
|
|
|
|
|
IndexT index = m_graphicMaterialInstanceMap.FindIndex(matID);
|
|
|
|
|
return (InvalidIndex != index );
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
const GPtr<Graphic::MaterialInstance>&
|
|
|
|
|
MaterialInstanceManager::GetMaterialInstance(const MaterialId& matID)
|
|
|
|
|
{
|
|
|
|
|
IndexT index = m_graphicMaterialInstanceMap.FindIndex(matID);
|
|
|
|
|
if(InvalidIndex != index )
|
|
|
|
|
{
|
|
|
|
|
return m_graphicMaterialInstanceMap.ValueAtIndex(index);
|
|
|
|
|
}
|
|
|
|
|
return MaterialInstance::NullMaterial;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
GPtr<Graphic::MaterialInstance>
|
|
|
|
|
MaterialInstanceManager::NewMaterialInstanceCopyByMatID(const MaterialId& matID)
|
|
|
|
|
{// <20>иò<D0B8><C3B2><EFBFBD><EFBFBD><EFBFBD><F2B4B4BD>ò<EFBFBD><C3B2>ʵ<EFBFBD>copy<70><79>
|
|
|
|
|
|
|
|
|
|
GPtr<MaterialInstance> aMat = 0;
|
|
|
|
|
IndexT index = m_graphicMaterialInstanceMap.FindIndex(matID);
|
|
|
|
|
if(InvalidIndex == index )
|
|
|
|
|
{
|
|
|
|
|
n_assert(0);
|
|
|
|
|
return aMat;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
aMat = m_graphicMaterialInstanceMap.ValueAtIndex(index);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>id <20><><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD>ɵ<EFBFBD>
|
|
|
|
|
GPtr<MaterialInstance> aMatRet = _CreateMaterialInstance(aMat->GetShaderID());
|
|
|
|
|
aMatRet->CopyFrom(aMat); //copyFrom need to be continue...
|
|
|
|
|
return aMatRet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
void
|
|
|
|
|
MaterialInstanceManager::RemoveMaterialInstance(const MaterialId& matID)
|
|
|
|
|
{
|
|
|
|
|
IndexT index = m_graphicMaterialInstanceMap.FindIndex(matID);
|
|
|
|
|
if(InvalidIndex != index )
|
|
|
|
|
{
|
|
|
|
|
m_graphicMaterialInstanceMap.Erase(matID);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
/*
|
|
|
|
|
* <EFBFBD>IJ<EFBFBD><EFBFBD>ʲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿڼ<EFBFBD>
|
|
|
|
|
*/
|
|
|
|
|
GPtr<Graphic::MaterialInstance>
|
|
|
|
|
MaterialInstanceManager::ModifyMaterialInstance(const MaterialId& matID,const Resources::ResourceId& newShaderID)
|
|
|
|
|
{
|
|
|
|
|
GPtr<MaterialInstance> aMat = 0;
|
|
|
|
|
IndexT index = m_graphicMaterialInstanceMap.FindIndex(matID);
|
|
|
|
|
if(InvalidIndex == index )
|
|
|
|
|
{
|
2014-06-19 16:21:15 +08:00
|
|
|
|
IndexT nMissing = m_graphicMaterialInstanceMap.FindIndex("sys:Missing_Material.material");
|
|
|
|
|
if (nMissing != InvalidIndex)
|
|
|
|
|
{
|
|
|
|
|
aMat = m_graphicMaterialInstanceMap.ValueAtIndex(nMissing);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
aMat = _CreateNewMaterialInstance("sys:Missing_Material.material");
|
|
|
|
|
aMat->SetMaterialID(aMat->GetMaterialID());
|
|
|
|
|
m_graphicMaterialInstanceMap.Add("sys:Missing_Material.material",aMat);
|
|
|
|
|
n_warning("Material Missing, use default material instead!");
|
|
|
|
|
}
|
2014-05-05 14:50:33 +08:00
|
|
|
|
return aMat;
|
|
|
|
|
}
|
|
|
|
|
aMat = m_graphicMaterialInstanceMap.ValueAtIndex(index);
|
|
|
|
|
GPtr<MaterialInstance> newMat = _CreateNewMaterialInstance(newShaderID);
|
|
|
|
|
newMat->SetMaterialID(aMat->GetMaterialID());
|
|
|
|
|
aMat->CopyFrom(newMat);
|
|
|
|
|
return aMat;
|
|
|
|
|
}
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
void MaterialInstanceManager::ModifyMaterialInstanceID(const MaterialId& matID,const MaterialId& newMatID)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
IndexT index = m_graphicMaterialInstanceMap.FindIndex(matID);
|
|
|
|
|
if(InvalidIndex == index )
|
|
|
|
|
{
|
|
|
|
|
n_assert(0);
|
|
|
|
|
return ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GPtr<MaterialInstance> aMat = 0;
|
|
|
|
|
aMat = m_graphicMaterialInstanceMap.ValueAtIndex(index);
|
|
|
|
|
m_graphicMaterialInstanceMap.EraseAtIndex(index);
|
|
|
|
|
|
|
|
|
|
aMat->SetMaterialID(newMatID);
|
|
|
|
|
m_graphicMaterialInstanceMap.Add(newMatID,aMat);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
GPtr<Graphic::MaterialInstance>
|
|
|
|
|
MaterialInstanceManager::LoadMaterialInstance(const MaterialId& matID,const Resources::ResourceId& shaderID )
|
|
|
|
|
{// <20>˺<EFBFBD><CBBA><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬһ<CDAC><D2BB><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>2<EFBFBD><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD>load<61><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD>ɵģ<C9B5><C4A3>ٴӴ<D9B4><D3B4>̼<EFBFBD><CCBC><EFBFBD>һ<EFBFBD>顣<EFBFBD><E9A1A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̣<EFBFBD>
|
|
|
|
|
GPtr<MaterialInstance> aMat = 0;
|
|
|
|
|
IndexT index = m_graphicMaterialInstanceMap.FindIndex(matID);
|
|
|
|
|
if(InvalidIndex != index )
|
|
|
|
|
{
|
|
|
|
|
n_warning("LoadMaterialInstance load same material %s",matID.Value());
|
|
|
|
|
m_graphicMaterialInstanceMap.EraseAtIndex(index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
aMat = _CreateNewMaterialInstance(shaderID);
|
|
|
|
|
aMat->SetMaterialID(matID);
|
|
|
|
|
m_graphicMaterialInstanceMap.Add(aMat->GetMaterialID(),aMat);
|
|
|
|
|
return aMat;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
void
|
|
|
|
|
MaterialInstanceManager::SaveMaterial()
|
|
|
|
|
{
|
|
|
|
|
//_SaveMaterialMngFile();
|
|
|
|
|
//_SaveAllMaterialInstance();
|
|
|
|
|
Resources::ResourceManager::Instance()->SaveMaterials();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
void MaterialInstanceManager::SaveOneMaterialInstance(const Resources::ResourceId& matID)
|
|
|
|
|
{
|
|
|
|
|
Resources::ResourceManager::Instance()->SaveMaterial(matID);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
Util::String MaterialInstanceManager::GetInitParamValue(const Resources::ResourceId& matID,int paramIndex)
|
|
|
|
|
{
|
|
|
|
|
int index = m_graphicMaterialMap.FindIndex(matID);
|
|
|
|
|
if(index == -1)
|
|
|
|
|
return "";
|
|
|
|
|
GPtr<Graphic::Material>& mat = m_graphicMaterialMap.ValueAtIndex(index);
|
|
|
|
|
const MaterialParamList& paramList = mat->GetParamList();
|
|
|
|
|
if(paramIndex >= paramList.Size())
|
|
|
|
|
return "";
|
|
|
|
|
return paramList[paramIndex]->GetStringValue();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|