I have a problem with the FBX SDK. I read in the data for the vertex position and the UV coordinates. It works fine, but now I want to read for each polygon to which texture it belongs, so that I can have models with multiple textures. Can anyone tell me how I can get the texture file name for my polygon? My code to read in vertex position and uv coordinates is the following:

int i, j, lPolygonCount = pMesh->GetPolygonCount();
FbxVector4* lControlPoints = pMesh->GetControlPoints(); 

int vertexId = 0;
for (i = 0; i < lPolygonCount; i++)

    int lPolygonSize = pMesh->GetPolygonSize(i);

    for (j = 0; j < lPolygonSize; j++)
        int lControlPointIndex = pMesh->GetPolygonVertex(i, j);
        FbxVector4 pos = lControlPoints[lControlPointIndex];
        current_model[vertex_index].x = pos.mData[0] - pivot_offset[0];
        current_model[vertex_index].y = pos.mData[1] - pivot_offset[1];
        current_model[vertex_index].z = pos.mData[2]- pivot_offset[2];

        FbxVector4 vertex_normal;
        pMesh->GetPolygonVertexNormal(i,j, vertex_normal);  

        current_model[vertex_index].nx = vertex_normal.mData[0];
        current_model[vertex_index].ny = vertex_normal.mData[1];
        current_model[vertex_index].nz = vertex_normal.mData[2];

        //read in UV data
        FbxStringList lUVSetNameList;

        //get lUVSetIndex-th uv set
        const char* lUVSetName = lUVSetNameList.GetStringAt(0);
        const FbxGeometryElementUV* lUVElement = pMesh->GetElementUV(lUVSetName);


            // only support mapping mode eByPolygonVertex and eByControlPoint
        if( lUVElement->GetMappingMode() != FbxGeometryElement::eByPolygonVertex &&
            lUVElement->GetMappingMode() != FbxGeometryElement::eByControlPoint )

        //index array, where holds the index referenced to the uv data
        const bool lUseIndex 
            = lUVElement->GetReferenceMode() != FbxGeometryElement::eDirect;
        const int lIndexCount= (lUseIndex) ? lUVElement->GetIndexArray().GetCount() : 0;

        FbxVector2 lUVValue;

        //get the index of the current vertex in control points array
        int lPolyVertIndex = pMesh->GetPolygonVertex(i,j);

        //the UV index depends on the reference mode
        int lUVIndex = pMesh->GetTextureUVIndex(i, j);
        lUVValue = lUVElement->GetDirectArray().GetAt(lUVIndex);
        current_model[vertex_index].tu = (float)lUVValue.mData[0];
        current_model[vertex_index].tv = (float)lUVValue.mData[1];

        vertex_index ++;


    float v1[3], v2[3], v3[3];
    v1[0] = current_model[vertex_index - 3].x;
    v1[1] = current_model[vertex_index - 3].y;
    v1[2] = current_model[vertex_index - 3].z;

    v2[0] = current_model[vertex_index - 2].x;
    v2[1] = current_model[vertex_index - 2].y;
    v2[2] = current_model[vertex_index - 2].z;

    v3[0] = current_model[vertex_index - 1].x;
    v3[1] = current_model[vertex_index - 1].y;
    v3[2] = current_model[vertex_index - 1].z;


You can get the the texture information by following steps,

FbxNode -> FbxSurfaceMaterial -> FbxLayeredTexture or FbxTexture -> Texture name (and other properties)

The code looks like,

int mcount = node->GetSrcObjectCount<FbxSurfaceMaterial>();
for (int index=0; index<mcount; index++ )
   FbxSurfaceMaterial *material = (FbxSurfaceMaterial*)node->GetSrcObject<FbxSurfaceMaterial>(index);
   if (material)
      // This only gets the material of type sDiffuse, you probably need to traverse all Standard Material Property by its name to get all possible textures.
      FbxProperty prop = material->FindProperty(FbxSurfaceMaterial::sDiffuse);

      // Check if it's layeredtextures
      int layered_texture_count = prop.GetSrcObjectCount<FbxLayeredTexture>();
      if (layered_texture_count > 0)
         for (int j=0; j < layered_texture_count; j++)
            FbxLayeredTexture* layered_texture = FbxCast<FbxLayeredTexture>(prop.GetSrcObject<FbxLayeredTexture>(j));
            int lcount = layered_texture->GetSrcObjectCount<FbxTexture>();
            for (int k=0; k<lcount; k++)
               FbxTexture* texture = FbxCast<FbxTexture>(layered_texture->GetSrcObject<FbxTexture>(k));
               // Then, you can get all the properties of the texture, include its name
               const char* texture_name = texture->GetName();
         // Directly get textures
         int texture_count = prop.GetSrcObjectCount<FbxTexture>();
         for (int j=0; j<texture_count; j++)
            const FbxTexture* texture = FbxCast<FbxTexture>(prop.GetSrcObject<FbxTexture>(j));
            // Then, you can get all the properties of the texture, include its name
            const char* texture_name = texture->GetName();
|improve this answer|||||
  • \$\begingroup\$ What's lproperty? \$\endgroup\$ – Syntac_ Aug 17 '13 at 18:29
  • \$\begingroup\$ Sorry, a typo here, should be the variable prop, not lproperty. \$\endgroup\$ – Wayne Wang Aug 17 '13 at 18:33

Can't tell FBX SDK specification from what you linked but that's how this data is stored in your FBX file, for instance:

  • "Cube" - mesh object

  • "Logo.png" - texture

FBX contains section called "Connections" which looks like this:

; Object connections

Connections:  { 
    Connect: "OO", "Model::Cube", "Model::Scene"
    Connect: "OO", "Material::Material__Logo_png", "Model::Cube"
    Connect: "OO", "Texture::Logo_png", "Model::Cube"
    Connect: "OO", "Video::Logo_png", "Texture::Logo_png"

FBX files can either be binary or ASCII and either contain paths to textures or having textures packed inside. You can use FBX Converter 2013 by Autodek to switch and pack/unpack textures.

|improve this answer|||||
  • \$\begingroup\$ but I have more textures per model. \$\endgroup\$ – CmasterG Apr 19 '13 at 12:59
  • \$\begingroup\$ Then you will have multiple "connections" to one mesh object. \$\endgroup\$ – Lufi Apr 19 '13 at 17:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.