I'm having a problem understanding how to render the vertex data in fbx model into directx. This is my two functions and I've already triangulated all the mesh nodes.
bool FBXLoader::CopyVertexData(Mesh* mesh)
{
FbxVector4 pos, nor;
FbxNode* rootNode = mScene->GetRootNode();
if (rootNode)
{
int iChildNodeCount = rootNode->GetChildCount();
for (int i = 0; i < iChildNodeCount; i++)
{
// Child Node -> Object
FbxNode* fbxChildNode = rootNode->GetChild(i);
FbxMesh* fbxMesh = fbxChildNode->GetMesh();
if (!fbxMesh)
continue;
int iVertexCount = fbxMesh->GetControlPointsCount();
if (iVertexCount > 0)
{
SubMesh subMesh;
int iPolyCount = fbxMesh->GetPolygonCount();
for (int j = 0; j < iPolyCount; j++)
{
// The poly size should be 3 since it's a triangle
int iPolySize = fbxMesh->GetPolygonSize(j);
// Get 3 vertices for the triangle
for (int k = 0; k < iPolySize; k++)
{
// Get index
int index = fbxMesh->GetPolygonVertex(j, k);
subMesh.indices.push_back(index);
// Get position
pos = fbxMesh->GetControlPointAt(index);
// Get normal
fbxMesh->GetPolygonVertexNormal(j, k, nor);
// Insert pos and nor data
Vertex vertex;
vertex.fPos = DirectX::XMFLOAT3((float)pos.mData[0], (float)pos.mData[1], (float)pos.mData[2]);
vertex.fNor = DirectX::XMFLOAT3((float)nor.mData[0], (float)nor.mData[1], (float)nor.mData[2]);
vertex.fTex = DirectX::XMFLOAT2(0.5f, 1.0f);
subMesh.vertices.push_back(vertex);
}
}
mesh->subMeshes.push_back(subMesh);
}
}
}
else
{
MessageBox(NULL, "Unable to create FBX Root Node object", "Error", MB_ICONERROR | MB_OK | MB_TASKMODAL);
return false;
}
return true;
}
bool FBXLoader::CopyVertexDataTest(Mesh* mesh)
{
FbxNode* rootNode = mScene->GetRootNode();
if (rootNode)
{
int iChildNodeCount = rootNode->GetChildCount();
for (int i = 0; i < iChildNodeCount; i++)
{
// Child Node -> Object
FbxNode* fbxChildNode = rootNode->GetChild(i);
FbxMesh* fbxMesh = fbxChildNode->GetMesh();
if (!fbxMesh)
continue;
int iVertexCount = fbxMesh->GetControlPointsCount();
if (iVertexCount > 0)
{
SubMesh subMesh;
FbxVector4* pVertices = fbxMesh->GetControlPoints();
for (int j = 0; j < iVertexCount; j++)
{
Vertex vertex;
vertex.fPos = DirectX::XMFLOAT3((float)pVertices[j].mData[0], (float)pVertices[j].mData[1], (float)pVertices[j].mData[2]);
vertex.fNor = DirectX::XMFLOAT3(0.3f, 0.6f, 0.9f);
vertex.fTex = DirectX::XMFLOAT2(0.5f, 1.0f);
subMesh.vertices.push_back(vertex);
}
int iIndexCount = fbxMesh->GetPolygonVertexCount();
//int* indices = new int[iIndexCount];
int* indices = fbxMesh->GetPolygonVertices();
for (int j = 0; j < iIndexCount; j++)
{
subMesh.indices.push_back(indices[j]);
}
mesh->subMeshes.push_back(subMesh);
}
}
}
else
{
MessageBox(NULL, "Unable to create FBX Root Node object", "Error", MB_ICONERROR | MB_OK | MB_TASKMODAL);
return false;
}
return true;
}
Here's the result using between those 2 functions. All images are the output of shader
CopyVertexData
CopyVertexDataTest
I exported the same model into .obj format for data checking between fbxMesh->GetControlPointAt(index) and fbxMesh->GetControlPoints(). So... my first question is why is it that GetControlPoints() gave me the same exact vertices data as the .obj data while GetControlPointsAt(...) gave different values?
Here's my second question. Let's use a cube model as an example case. A cube have 6 faces and each face have 6 vertices(2 triangles) which means a cube will have 12 triangles and 36 vertices. Assume that the cube have 6 polygon faces.
I load the cube fbx model and then I triangulate the mesh. I assumed that when I use GetPolygonCount(), I will get 12 triangulated polygons and each polygons will give 3 vertices. Is it wrong?
My solution
bool FBXLoader::CopyVertexData(Mesh* mesh)
{
FbxVector4 pos, nor;
FbxNode* rootNode = mScene->GetRootNode();
if (rootNode)
{
int iChildNodeCount = rootNode->GetChildCount();
for (int i = 0; i < iChildNodeCount; i++)
{
// Child Node -> Object
FbxNode* fbxChildNode = rootNode->GetChild(i);
FbxMesh* fbxMesh = fbxChildNode->GetMesh();
if (!fbxMesh)
continue;
int iVertexCount = fbxMesh->GetControlPointsCount();
if (iVertexCount > 0)
{
int indicesIndex = 0;
SubMesh subMesh;
// Get all positions
FbxVector4* pVertices = fbxMesh->GetControlPoints();
int iPolyCount = fbxMesh->GetPolygonCount();
for (int j = 0; j < iPolyCount; j++)
{
// The poly size should be 3 since it's a triangle
int iPolySize = fbxMesh->GetPolygonSize(j);
// Get 3 vertices of the triangle
for (int k = 0; k < iPolySize; k++)
{
// Get index
int index = fbxMesh->GetPolygonVertex(j, k);
subMesh.indices.push_back(indicesIndex++);
// Get normal
fbxMesh->GetPolygonVertexNormal(j, k, nor);
// Insert pos and nor data
Vertex vertex = Vertex();
vertex.fPos = DirectX::XMFLOAT3(static_cast<float>(pVertices[index].mData[0]), static_cast<float>(pVertices[index].mData[1]), static_cast<float>(pVertices[index].mData[2]));
vertex.fNor = DirectX::XMFLOAT3(static_cast<float>(nor.mData[0]), static_cast<float>(nor.mData[1]), static_cast<float>(nor.mData[2]));
vertex.fTex = DirectX::XMFLOAT2(0.0f, 0.0f);
subMesh.vertices.push_back(vertex);
}
}
mesh->subMeshes.push_back(subMesh);
}
}
}
else
{
MessageBox(NULL, "Unable to create FBX Root Node object", "Error", MB_ICONERROR | MB_OK | MB_TASKMODAL);
return false;
}
return true;
}
Result