void mrShaderButtonHandler::OnCommand() {

	DbgAssert(m_dialogHWnd != NULL);

	// Add the filter
	IMtlBrowserFilter_Manager* filterManager = Get_IMtlBrowserFilter_Manager();
	if(filterManager != NULL) {
		filterManager->AddFilter(m_shaderFilter);
	}

	// Browse for a texmap
	BOOL newMat;
	BOOL cancel;
	MtlBase* mtlBase = GetCOREInterface()->DoMaterialBrowseDlg(m_dialogHWnd, (BROWSE_MAPSONLY | BROWSE_INCNONE), newMat, cancel);
	if(!cancel) {
		DbgAssert((mtlBase == NULL) || ((mtlBase->SuperClassID() == TEXMAP_CLASS_ID)));

		Texmap* texmap = static_cast<Texmap*>(mtlBase);
		SetShader(texmap);
	
		Update();
	}

	if(filterManager != NULL) {
		filterManager->RemoveFilter(m_shaderFilter);
	}
}
void CMaxMaterialCollection::OnScratchLibChanged()
{
#ifdef PERSIST_SCRATCH

	//figure out which materials were added or deleted and fire appropriate events.
	//this is currently pretty inefficient since we hav to walk the entire list of materials to 
	//figure out which ones to add or remove. Could improve this by adding better messagin from 
	//mpSceneLib

	if(s_PreventRecursion)
		return;
	s_PreventRecursion = true;

	int numLibMtls = mpScratchMtlLib->Count();
	//int numMtlsWrapped = mMtlMap.size();

	//adding material
	if(numLibMtls > mLastScratchMtlLibSize )
	{

		for(int i=0; i< numLibMtls; i++)
		{
			//get the max material to be wrapped
			MtlBase *pMtl = mpScratchMtlLib->operator[](i);
			assert(pMtl); //can this be empty?
			if(pMtl == NULL || pMtl->SuperClassID() != MATERIAL_CLASS_ID)
				continue;

			DWORD_PTR key = (DWORD_PTR) pMtl;

			if(mMtlMap.find(key)!= mMtlMap.end())
				continue;//found

			//Create the wrapper
			CComObject<CMaxMaterial> *pWrapperObject;
			HRESULT hr = CComObject<CMaxMaterial>::CreateInstance(&pWrapperObject);
			assert(SUCCEEDED(hr));
			if(!SUCCEEDED(hr))
			{
				s_PreventRecursion = false;
				return;
			}

			//Initalize the new wrapper
			pWrapperObject->setCollection(this);
			//TODO validate the downcast
			pWrapperObject->setMtl((Mtl *)pMtl);

		}
	}
	s_PreventRecursion = false;
	mLastScratchMtlLibSize = numLibMtls;
#endif
}
Exemple #3
0
bool mrShaderFilter::Include(MtlBase& mtlBase, DWORD flags) {

	// Validate using the class ID
	ClassDesc* classDesc = GetCOREInterface()->GetDllDir().ClassDir().FindClass(mtlBase.SuperClassID(), mtlBase.ClassID());
	DbgAssert(classDesc != NULL);
	if(classDesc != NULL) {
		return Include(*classDesc, flags);
	}
	else {
		return true;
	}
}
//stop gap method
//if the material editor becomes visible and teh material in it is not
//already wrapped we better add it. 
void CMaxMaterialCollection::OnMeditVisible()
{
	if(!m_suspendCount)
	{
		MtlBase *m = GetMtlEditInterface()->GetCurMtl();
		if(m->SuperClassID()!=MATERIAL_CLASS_ID)
			return;
		CComPtr<IMaxMaterial> pWrapper;
		FindItemKey((DWORD_PTR)(m), &pWrapper.p);
		if(!pWrapper)
		{
			MakeWrapperObject((Mtl*)m);
			FindItemKey((DWORD_PTR)(m), &pWrapper.p);
			if(pWrapper)
				AddPersistence(pWrapper);
		}
	}
}
void CMaxMaterialCollection::OnSceneLibChanged()
{
	//figure out which materials were added or deleted and fire appropriate events.
	//this is currently pretty inefficient since we hav to walk the entire list of materials to 
	//figure out which ones to add or remove. Could improve this by adding better messagin from 
	//mpSceneLib

	if(s_PreventRecursion)
		return;
	s_PreventRecursion = true;

	int numLibMtls = mpSceneMtlLib->Count();
	//int numMtlsWrapped = mMtlMap.size();

	//adding material
	if(numLibMtls > mLastSceneMtlLibSize )
	{

		for(int i=0; i< numLibMtls; i++)
		{
			//get the max material to be wrapped
			MtlBase *pMtl = mpSceneMtlLib->operator[](i);
			//assert(pMtl); //can this be empty?
			//the assertion is no good because a makerefrestore may be setting the ref from
			//lib to material to null. The lib notifies us.
			if(pMtl == NULL || pMtl->SuperClassID() != MATERIAL_CLASS_ID)
				continue;

			//TODO validate the downcast
			HRESULT hr = MakeWrapperObject(static_cast<Mtl*>(pMtl));
			assert(SUCCEEDED(hr));
			if (!SUCCEEDED(hr))
			{
				s_PreventRecursion = false;
				return;
			}

		}
	}
	//removing material
	/*
	We no longer track removals other than to update our record of the new size (mLastSceneMtlLibSize)
	The idea is that we keep all of our wrappers alive unless explicitly destroyed. 
	We assume that all new materials will pass through the scenematerials lib via OkMtlForScene or some equivalent method.

	else if(numLibMtls < mLastSceneMtlLibSize )
	{
		ifxClxnType::iterator it=mMtlMap.begin();
		while(it!=mMtlMap.end())
		{
			Mtl *pMtlToCheck = (Mtl *) (*it).first;
			if(mpSceneMtlLib->FindMtl(pMtlToCheck) == -1)//no longer in scene
			{
				pMtlWrapper.Attach((*it).second);
#ifdef XXXRECYCLE_MATS
			//add the wrapper to our data structure
				mRecycledMtlMap.insert(*it);
				pMtlWrapper.p->AddRef();
#endif
				Fire_OnMaterialRemoved(this, pMtlWrapper);
				it = mMtlMap.erase(it);
				pMtlWrapper.Release();
			}
			else
				it++;
		}
	}
	*/
	//update our record of the size of sceneMtlLib
	mLastSceneMtlLibSize = numLibMtls;
	s_PreventRecursion = false;
/* TO DO implement an integrity checker
#ifndef NDEBUG
	else
		CheckIntegrity();
#endif
		*/
}