The KFbxSurfaceMaterial class is the base class for Lambertian (KFbxSurfaceLambert) and Phong (KFbxSurfacePhong) materials. In the following code sample, we create five materials and add them to the KFbxNode of a KFbxMesh via KFBxNode::AddMaterial(). Once materials are bound to a node, they can be mapped to the polygons of a mesh.
// Create materials for pyramid. void CreateMaterials(KFbxScene* pScene, KFbxMesh* pMesh) { int i; for (i = 0; i < 5; i++ ) { KString lMaterialName = "material"; KString lShadingName = "Phong"; lMaterialName += i; fbxDouble3 lBlack(0.0, 0.0, 0.0); fbxDouble3 lRed(1.0, 0.0, 0.0); fbxDouble3 lColor; KFbxSurfacePhong *lMaterial = KFbxSurfacePhong::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. KFbxNode* lNode = pMesh->GetNode(); if(lNode) lNode->AddMaterial(lMaterial); } }
Example: Creating a Square Pyramid with Materials
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. KFbxNode* CreatePyramidWithMaterials(KFbxScene* pScene, char* pName) { int i, j; KFbxMesh* lMesh = KFbxMesh::Create(pScene, pName); KFbxVector4 lControlPoint0(-50, 0, 50); KFbxVector4 lControlPoint1(50, 0, 50); KFbxVector4 lControlPoint2(50, 0, -50); KFbxVector4 lControlPoint3(-50, 0, -50); KFbxVector4 lControlPoint4(0, 100, 0); KFbxVector4 lNormalP0(0, 1, 0); KFbxVector4 lNormalP1(0, 0.447, 0.894); KFbxVector4 lNormalP2(0.894, 0.447, 0); KFbxVector4 lNormalP3(0, 0.447, -0.894); KFbxVector4 lNormalP4(-0.894, 0.447, 0); // Create control points. lMesh->InitControlPoints(16); KFbxVector4* lControlPoints = lMesh->GetControlPoints(); lControlPoints[0] = lControlPoint0; lControlPoints[1] = lControlPoint1; lControlPoints[2] = lControlPoint2; lControlPoints[3] = lControlPoint3; lControlPoints[4] = lControlPoint0; lControlPoints[5] = lControlPoint1; lControlPoints[6] = lControlPoint4; lControlPoints[7] = lControlPoint1; lControlPoints[8] = lControlPoint2; lControlPoints[9] = lControlPoint4; lControlPoints[10] = lControlPoint2; lControlPoints[11] = lControlPoint3; lControlPoints[12] = lControlPoint4; lControlPoints[13] = lControlPoint3; lControlPoints[14] = lControlPoint0; lControlPoints[15] = lControlPoint4; // specify normals per control point. KFbxGeometryElementNormal* lNormalElement= lMesh->CreateElementNormal(); lNormalElement->SetMappingMode(KFbxGeometryElement::eBY_CONTROL_POINT); lNormalElement->SetReferenceMode(KFbxGeometryElement::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 (KFbxGeometryElementMaterial) within the mesh to specify that the materials are bound to the control points of the polygons in the mesh. The function KFbxMesh::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 KFbxNode.
// 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. KFbxGeometryElementMaterial* lMaterialElement = lMesh->CreateElementMaterial(); lMaterialElement->SetMappingMode(KFbxGeometryElement::eBY_POLYGON); lMaterialElement->SetReferenceMode(KFbxGeometryElement::eINDEX_TO_DIRECT); // 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 (); } KFbxNode* lNode = KFbxNode::Create(pScene,pName); lNode->SetNodeAttribute(lMesh); CreateMaterials(pScene, lMesh); return lNode; }