Creating layer elements for materials and textures
 
 
 

For each cube, CubeCreator allows the user to apply one material and one texture to each of the faces. This section of code does all the necessary low-level setup so that CreateCubeDetailed() can apply the material and texture in a few lines of code.

Here we create an array of polygon vertex numbers that we’ll use below.

// Array of polygon vertices.
int lPolygonVertices[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,12, 13,
    14, 15, 16, 17, 18, 19, 20, 21, 22, 23 };

CubeCreator uses only one texture, but we still need to use a DirectArray to store the pointer to that texture. The DirectArray will need only one element, i.e., element 0, for that texture.

FBX SDK supports various texture channels, including diffuse, specular, ambient, and shininess. We’re going to use the diffuse channel: that allows us to set the color of each face of the cube.

Here, we create the DirectArray for textures:

// Set texture mapping for diffuse channel.
KFbxLayerElementTexture* lTextureDiffuseLayer=
    KFbxLayerElementTexture::Create(pMesh, "Diffuse Texture");
lTextureDiffuseLayer->SetMappingMode(KFbxLayerElement::eBY_POLYGON);

This time, we are going to use the IndexArray as well as the DirectArray.

lTextureDiffuseLayer->SetReferenceMode(KFbxLayerElement::eINDEX_TO_DIRECT);

Here we point the mesh’s layer to the object that contains the DirectArray and IndexArray for textures:

if(pMesh->GetLayer(0))
    pMesh->Getlayer(0)->SetDiffuseTextures(lTextureDiffuseLayer);
else
    return;

To correctly map the texture onto the mesh, we need the UV coordinates on the same channel (i.e., diffuse texture). FBX SDK will pair the texture data with the UV coordinates of the same given channel.

// Create UV for Diffuse channel.
KFbxLayerElementUV* lUVDiffuseLayer=
    KFbxLayerElementUV::Create(lMesh, "DiffuseUV");
lUVDiffuseLayer->SetMappingMode(KFbxLayerElement::eBY_POLYGON_VERTEX);

We are going to use IndexArray to store index numbers for DirectArray:

lUVDiffuseLayer->SetReferenceMode(KFbxLayerElement::eINDEX_TO_DIRECT);
lLayer->SetUVs(lUVDiffuseLayer, KFbxLayerElement::eDIFFUSE_TEXTURES);

Since we may apply a material to the faces, we also need a layer element for materials:

// Set material mapping.
KFbxLayerElementMaterial* lMaterialLayer=KFbxLayerElementMaterial::Create(pMesh, "");
lMaterialLayer->SetMappingMode(KFbxLayerElement::eBY_POLYGON);
lMaterialLayer->SetReferenceMode(KFbxLayerElement::eINDEX_TO_DIRECT);
if(pMesh->GetLayer(0))
    pMesh->Getlayer(0)->SetMaterials(lMaterialLayer);
else
    return;

These four vectors define UV coordinates for mapping the the texture onto the face of a cube. UV coordinates are normalized to range from 0.0 to 1.0: the vectors below will map the texture so that it covers the entire surface of the face.

KFbxVector2 lVectors0(0, 0);
KFbxVector2 lVectors1(1, 0);
KFbxVector2 lVectors2(1, 1);
KFbxVector2 lVectors3(0, 1);

Our DirectArray for diffuse UV coordinates has four elements, one for each coordinate:

lUVDiffuseLayer->GetDirectArray().Add(lVectors0);
lUVDiffuseLayer->GetDirectArray().Add(lVectors1);
lUVDiffuseLayer->GetDirectArray().Add(lVectors2);
lUVDiffuseLayer->GetDirectArray().Add(lVectors3);

This IndexArray has 24 elements, one for each of the six vertices of the four faces of the cube. We use it to index the DirectArray of four UV coordinates.

// Now we have set the UVs as eINDEX_TO_DIRECT reference
// and in eBY_POLYGON_VERTEX mapping mode.
// We must update the size of the index array.
 lUVDiffuseLayer->GetIndexArray().SetCount(24);

This IndexArray has has six elements, one for each face of a cube. We use it to index the DirectArray of textures defined in lTextureDiffuseLayer.

//We are in eBY_POLYGON, so there’s only need for 6 index (a cube has 6 polygons).
lTextureDiffuseLayer->GetIndexArray().SetCount(6);

For each of the six faces of the cube:

// Create polygons. Assign texture and texture UV indices.
for(i = 0; i < 6; i++)
{
// all faces of the cube have the same texture
lMesh->BeginPolygon(-1, -1, -1, false);) 
for(j = 0; j < 4; j++)
{
// Control point index
lMesh->AddPolygon(lPolygonVertices[i*4 + j]);
 // update the index array of the UVs that map the texture to the face
 lUVDiffuseLayer->GetIndexArray().SetAt(i*4+j, j);
 }
 lMesh->EndPolygon ();
 }

Now we have finished creating the KFbxMesh object.