[Closed] SDK Standard Materials Question…
you don’t need to include stdmat2.h from the samples just the correct sdk include stdmat.h
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