The sample code in this topic is also presented in the ExportScene03/main.cxx
sample program.
The FbxSurfaceMaterial
class is the base class for Lambertian (FbxSurfaceLambert
) and Phong (FbxSurfacePhong
) materials. In the following code sample, we create five materials and add them to the FbxNode
of a FbxMesh
via FbxNode::AddMaterial()
. Once materials are bound to a node, they can be mapped to the polygons of a mesh.
// Create materials for pyramid.
void CreateMaterials(FbxScene* pScene, FbxMesh* pMesh)
{
int i;
for (i = 0; i < 5; i++ )
{
FbxString lMaterialName = "material";
FbxString lShadingName = "Phong";
lMaterialName += i;
FbxDouble3 lBlack(0.0, 0.0, 0.0);
FbxDouble3 lRed(1.0, 0.0, 0.0);
FbxDouble3 lColor;
FbxSurfacePhong *lMaterial = FbxSurfacePhong::Create(pScene, lMaterialName.Buffer());
// Generate primary and secondary colors.
lMaterial->Emissive.Set(lBlack);
lMaterial->Ambient.Set(lRed);
lColor = FbxDouble3(i > 2 ? 1.0 : 0.0,
i > 0 && i < 4 ? 1.0 : 0.0,
i % 2 ? 0.0 : 1.0);
lMaterial->Diffuse.Set(lColor);
lMaterial->TransparencyFactor.Set(0.0);
lMaterial->ShadingModel.Set(lShadingName);
lMaterial->Shininess.Set(0.5);
//get the node of mesh, add material for it.
FbxNode* lNode = pMesh->GetNode();
if(lNode)
lNode->AddMaterial(lMaterial);
}
}
The following code sample uses the CreateMaterials()
function defined above to bind five materials to the five faces of a square pyramid. We first begin by defining the control points and the normals of the pyramid.
// Create a pyramid with materials.
FbxNode* CreatePyramidWithMaterials(FbxScene* pScene, char* pName)
{
int i, j;
FbxMesh* lMesh = FbxMesh::Create(pScene, pName);
FbxVector4 vertex0(-50, 0, 50);
FbxVector4 vertex1(50, 0, 50);
FbxVector4 vertex2(50, 0, -50);
FbxVector4 vertex3(-50, 0, -50);
FbxVector4 vertex4(0, 100, 0);
FbxVector4 lNormalP0(0, 1, 0);
FbxVector4 lNormalP1(0, 0.447, 0.894);
FbxVector4 lNormalP2(0.894, 0.447, 0);
FbxVector4 lNormalP3(0, 0.447, -0.894);
FbxVector4 lNormalP4(-0.894, 0.447, 0);
// Create control points.
lMesh->InitControlPoints(16);
FbxVector4* lControlPoints = lMesh->GetControlPoints();
lControlPoints[0] = vertex0;
lControlPoints[1] = vertex1;
lControlPoints[2] = vertex2;
lControlPoints[3] = vertex3;
lControlPoints[4] = vertex0;
lControlPoints[5] = vertex1;
lControlPoints[6] = vertex4;
lControlPoints[7] = vertex1;
lControlPoints[8] = vertex2;
lControlPoints[9] = vertex4;
lControlPoints[10] = vertex2;
lControlPoints[11] = vertex3;
lControlPoints[12] = vertex4;
lControlPoints[13] = vertex3;
lControlPoints[14] = vertex0;
lControlPoints[15] = vertex4;
// specify normals per control point.
FbxGeometryElementNormal* lNormalElement= lMesh->CreateElementNormal();
lNormalElement->SetMappingMode(FbxGeometryElement::eByControlPoint);
lNormalElement->SetReferenceMode(FbxGeometryElement::eDirect);
lNormalElement->GetDirectArray().Add(lNormalP0);
lNormalElement->GetDirectArray().Add(lNormalP0);
lNormalElement->GetDirectArray().Add(lNormalP0);
lNormalElement->GetDirectArray().Add(lNormalP0);
lNormalElement->GetDirectArray().Add(lNormalP1);
lNormalElement->GetDirectArray().Add(lNormalP1);
lNormalElement->GetDirectArray().Add(lNormalP1);
lNormalElement->GetDirectArray().Add(lNormalP2);
lNormalElement->GetDirectArray().Add(lNormalP2);
lNormalElement->GetDirectArray().Add(lNormalP2);
lNormalElement->GetDirectArray().Add(lNormalP3);
lNormalElement->GetDirectArray().Add(lNormalP3);
lNormalElement->GetDirectArray().Add(lNormalP3);
lNormalElement->GetDirectArray().Add(lNormalP4);
lNormalElement->GetDirectArray().Add(lNormalP4);
lNormalElement->GetDirectArray().Add(lNormalP4);
We then create a new material layer element (FbxGeometryElementMaterial
) within the mesh to specify that the materials are bound to the control points of the polygons in the mesh. The function FbxMesh::BeginPolygon()
uses an index to determine which material will be bound to the new polygon. This index refers to the position of the material stored in the FbxNode
.
// Array of polygon vertices.
int lPolygonVertices[] = { 0, 3, 2, 1,
4, 5, 6,
7, 8, 9,
10, 11, 12,
13, 14, 15 };
// Set material mapping.
FbxGeometryElementMaterial* lMaterialElement = lMesh->CreateElementMaterial();
lMaterialElement->SetMappingMode(FbxGeometryElement::eByPolygon);
lMaterialElement->SetReferenceMode(FbxGeometryElement::eIndexToDirect);
// Create polygons. Assign material indices.
// Pyramid base.
lMesh->BeginPolygon(0); // Material index.
for(j = 0; j < 4; j++)
{
lMesh->AddPolygon(lPolygonVertices[j]); // Control point index.
}
lMesh->EndPolygon ();
// Pyramid sides.
for(i = 1; i < 5; i++)
{
lMesh->BeginPolygon(i); // Material index.
for(j = 0; j < 3; j++)
{
lMesh->AddPolygon(lPolygonVertices[4 + 3*(i - 1) + j]); // Control point index.
}
lMesh->EndPolygon ();
}
FbxNode* lNode = FbxNode::Create(pScene,pName);
lNode->SetNodeAttribute(lMesh);
CreateMaterials(pScene, lMesh);
return lNode;
}