Notifications
Clear all

[Closed] SDK Standard Materials Question…

you don’t need to include stdmat2.h from the samples just the correct sdk include stdmat.h

1 Reply
(@archangel35757)
Joined: 1 year ago

Posts: 0

Thanks for the clarification… I’ve added the enums, removed the extraneous headers and everything compiles perfectly.

One more question… Where do I find the list of shader names to use with the “std2_shader_by_name” enum?

Cheers!

Here’s my snippet for setting the shader type:

	switch ( l_XSIShadeModel )
 	{
 		case 0: //Constant
 			l_iShadingModel = SHADE_CONST;
 			stdMtl->SetShading( l_iShadingModel );
 			break;
 		case 1: //Lambert-- closest match is Oren-Nayar-Blinn
 			if ( stdMtl->GetParamBlock(std2_shader) != NULL )
 				stdMtl->GetParamBlock(std2_shader)->SetValue(std2_shader_type,0,4);
 			break;
 		case 2: //Phong
 			l_iShadingModel = SHADE_PHONG;
 			stdMtl->SetShading( l_iShadingModel );
 			break;
 		case 3: //Blinn
 			l_iShadingModel = SHADE_BLINN;
 			stdMtl->SetShading( l_iShadingModel );
 			break;
 		default:
 			l_iShadingModel = SHADE_BLINN;
 			stdMtl->SetShading( l_iShadingModel );
 			break;
 	}

Thanks again for your help.

you have to look at the source code in stdmat2.cpp, the ShaderPBAccessor class handles object updates when we change the parameter block values

class ShaderPBAccessor : public PBAccessor
 {
 public:
 	void Set(PB2Value& v, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t)	// set from v
 	{
 		StdMtl2* m = (StdMtl2*)owner;
 		switch (id)
 		{
 			// use item data to unscramble sorted lists
 		case std2_shader_type: {
 			ClassDesc* pCD = StdMtl2::GetShaderCD(v.i);
 			if (pCD && m->GetShaderIndx() != NO_UPDATE )
 			{
 				m->SwitchShader(pCD); 
 				m->shaderId = v.i; 
 			}
 							   } break;
 		case std2_shader_by_name: {
 			if( v.s!=NULL ) {
 				for (int i = 0; i < StdMtl2::NumShaders(); i++)
 				{
 					ClassDesc* pCD = StdMtl2::GetShaderCD(i);
 					if (_tcsicmp(pCD->ClassName(), v.s) == 0)
 					{
 						m->pb_shader->SetValue(std2_shader_type, 0, i);
 						break;
 					}
 				}
 			}
 								  } break;
 		case std2_wire:
 			m->SetFlag(STDMTL_WIRE, v.i); break;		
 		case std2_two_sided:
 			m->SetFlag(STDMTL_2SIDE, v.i); break;		
 		case std2_face_map:
 			m->SetFlag(STDMTL_FACEMAP, v.i); break;
 		case std2_faceted:
 			m->SetFlag(STDMTL_FACETED, v.i); break;
 		}
 	}
 
 	void Get(PB2Value& v, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t, Interval& valid)	// get into v
 	{
 		StdMtl2* m = (StdMtl2*)owner;
 		switch (id)
 		{
 		case std2_shader_by_name: {
 			ClassDesc* pCD = StdMtl2::GetShaderCD(m->shaderId);
 			if (pCD)
 				v.s = (TCHAR*)pCD->ClassName();
 								  } break;
 		}
 	}
 };

so it uses the shader ClassDesc::ClassName()

i cobbled this mxs extension function from bits and pieces in stdmat2.cpp to return the array of class names

static int classDescListCompare(const void *elem1, const void *elem2) 
 {
 	ClassDesc* s1 = *(ClassDesc**)elem1;
 	ClassDesc* s2 = *(ClassDesc**)elem2;
 	TSTR sn1 = s1->ClassName();  // need to snap name string, since both use GetString()
 	TSTR sn2 = s2->ClassName();
 	return _tcscmp(sn1.data(), sn2.data());
 }
 
 def_visible_primitive(getStdMtlShaders, "getStdMtlShaders");
 
 Value* getStdMtlShaders_cf(Value** arg_list, int count)
 {
 	check_arg_count(getStdMtlShaders, 0, count);
 
 	Tab<ClassDesc*> shaderList;
 
 	shaderList.ZeroCount();
 	SubClassList* scList = GetCOREInterface()->GetDllDir().ClassDir().GetClassList(SHADER_CLASS_ID);
 	for (long i = 0, j = 0; i < scList->Count(ACC_ALL); ++i) 
 	{
 		if( (*scList)[i].IsPublic() ) 
 		{
 			ClassDesc* pClassD = (*scList)[i].CD();
 			shaderList.Append(1, &pClassD);
 		}
 	}
 	shaderList.Sort(&classDescListCompare);
 
 	int numshaders = shaderList.Count();
 
 	one_typed_value_local(Array* result);
 	vl.result = new Array(numshaders);
 	vl.result->size = numshaders;
 	for (int i = 0; i < numshaders; ++i)
 		vl.result->data[i] = new String(shaderList[i]->ClassName())	;
 	return_value(vl.result);
 }

and it returns this


 #("Anisotropic", "Blinn", "Metal", "Multi-Layer", "Oren-Nayar-Blinn", "Phong", "Strauss", "Translucent Shader")
 

so you should be able to use the following

StdMat2* mat = NewDefaultStdMat();
 mat->GetParamBlock(std2_shader)->SetValue(std2_shader_by_name,0,"Oren-Nayar-Blinn");

oops fixed it

Page 2 / 2