Trouble with texturing manual meshes

Problems building or running the engine, queries about how to use features etc.

Trouble with texturing manual meshes

Postby AmitMathew » Thu Sep 29, 2005 2:13 am

I'm trying to create a way to import FBX files into Ogre. This is my first time playing with the HardwareBuffers, so if I've done anything dumb, please let me off easy. So far the vertices look right (for most meshes at least), but my texture UVs are for some reason incorrect.

Here is a link to the picture of the problem if it is any help:

Any help would be appreciated.


Code: Select all
void DrawMesh(KFbxNode* pNode, 
           KTime& pTime,
           KFbxXMatrix& pGlobalPosition, KFbxPose* pPose
   KFbxMesh* lMesh = (KFbxMesh*) pNode->GetNodeAttribute();

   int lVertexCount = lMesh->GetControlPointsCount();
   int polygonCount = lMesh->GetPolygonCount();
   int texCoordCount = lMesh->GetTextureUVCount();

   KFbxVector4* lControlPoints = lMesh->GetControlPoints();
   KFbxVector4* lNormals = lMesh->GetNormals();
   KFbxVector2* lTexCoords = lMesh->GetTextureUV();

   Ogre::MeshPtr mesh = MeshManager::getSingleton().createManual("test", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
   SubMesh* sub = mesh->createSubMesh();

   mesh->sharedVertexData = new VertexData();
   VertexData* vertexData = mesh->sharedVertexData;
   vertexData->vertexCount = lVertexCount;

   VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
   // positions
   vertexDecl->addElement(0, 0, VET_FLOAT3, VES_POSITION);
   // normals
   vertexDecl->addElement(1, 0, VET_FLOAT3, VES_NORMAL);
   // UVs
   vertexDecl->addElement(2, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES);

   VertexBufferBinding* binding = vertexData->vertexBufferBinding;

   // allocate the vertex buffer
   HardwareVertexBufferSharedPtr vBuf =
      vertexDecl->getVertexSize(0), vertexData->vertexCount,
      HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
   binding->setBinding(0, vBuf);
   Real* pVertex = static_cast<Real*>(vBuf->lock(HardwareBuffer::HBL_DISCARD));

   // allocate the normal buffer
   HardwareVertexBufferSharedPtr nBuf =
      vertexDecl->getVertexSize(1), getMeshVertexCount(lMesh),
      HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
   binding->setBinding(1, nBuf);
   Real* nVertex = static_cast<Real*>(nBuf->lock(HardwareBuffer::HBL_DISCARD));

   // allocate the uv buffer
   HardwareVertexBufferSharedPtr tBuf =
      vertexDecl->getVertexSize(2), getMeshVertexCount(lMesh),
      HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
   binding->setBinding(2, tBuf);
   Real* tVertex = static_cast<Real*>(tBuf->lock(HardwareBuffer::HBL_DISCARD));

   // build the vertex list
   for (int i = 0; i < lVertexCount; ++i) {

      KFbxVector4 vec = lControlPoints[i];

      *pVertex++ = vec[0];
      *pVertex++ = vec[1];
      *pVertex++ = vec[2];


        // build normal list
   for (int i = 0; i < polygonCount; ++i) {

      for (int j = 0; j < lMesh->GetPolygonSize(i); ++j) {

         KFbxVector4 normal;
         lMesh->GetPolygonVertexNormal(i, j, normal);

         *nVertex++ = normal[0];
         *nVertex++ = normal[1];
         *nVertex++ = normal[2];



        // build uv list
   for (int i = 0; i < polygonCount; ++i) {

      KFbxVector2* uvVertices = lMesh->GetTextureUV();

      for (int j = 0; j < lMesh->GetPolygonSize(i); ++j) {

         KFbxVector2 uv = uvVertices[lMesh->GetTextureUVIndex(i, j)];

         *tVertex++ = uv[0];
         *tVertex++ = uv[1];



   // calculate index count
   int indexCount = getMeshVertexCount(lMesh);

   // allocate the index buffer
   sub->indexData->indexCount = indexCount;
   sub->indexData->indexBuffer =
      HardwareIndexBuffer::IT_16BIT, sub->indexData->indexCount,
      HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
   HardwareIndexBufferSharedPtr iBuf = sub->indexData->indexBuffer;
   unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(HardwareBuffer::HBL_DISCARD));

   // build the index list
   for (int i = 0; i < polygonCount; ++i) {

      int polygonSize = lMesh->GetPolygonSize(i);

      for (int j = 0; j < polygonSize; j++) {

         int controlPointIndex = lMesh->GetPolygonVertex(i, j);

         *pIndices++ = controlPointIndex;



   sub->useSharedVertices = true;
   Vector3 minVertex = getMinVertex(lControlPoints, lVertexCount);
   Vector3 maxVertex = getMaxVertex(lControlPoints, lVertexCount);
   mesh->_setBounds(AxisAlignedBox(minVertex, maxVertex), false);
   mesh->_setBoundingSphereRadius(getRadius(minVertex, maxVertex));

int getMeshVertexCount(KFbxMesh* mesh) {

   int polygonCount = mesh->GetPolygonCount();
   int vertexCount = 0;

   for (int i = 0; i < polygonCount; ++i) {

      vertexCount += mesh->GetPolygonSize(i);


   return vertexCount;

User avatar
Posts: 21
Kudos: 0
Joined: 21 Jul 2003
Location: Athens, GA, USA

Postby sinbad » Thu Sep 29, 2005 1:39 pm

You probably need to invert the 'v' coordinate, some systems use the opposite v direction.

BTW you should really create a combined buffer, using 3 separate buffers is sub-optimal.
User avatar
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19261
Kudos: 69
Joined: 06 Oct 2002
Location: Guernsey, Channel Islands

Postby AmitMathew » Wed Oct 05, 2005 10:58 pm

The inverted v was one problem, but I also had much bigger problems. I originally had everything in one buffer, but changed it to three because the number of vertices given by FBX didn't match the number of UVs or normals, since there was a set of UVs and normals for each polygon vertex. To get everything to work, I changed it back to one buffer, and used a vertex for each polygon vertex. Of course that means the index buffer just goes from 0 to the number of vertices, which doesn't seem right. Is there a standard way of handling this for exporters?

User avatar
Posts: 21
Kudos: 0
Joined: 21 Jul 2003
Location: Athens, GA, USA

Return to Help

Who is online

Users browsing this forum: No registered users and 5 guests