Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Model loading Algorithm with MS C++ and opengl

Status
Not open for further replies.

ashstampede

Programmer
Aug 30, 2004
104
0
0
GB
I could really really use some help on making my model loader faster, it is loading .obj file format. There area where it is slow is converting the mesh data to opengl VBO data. so it looks for duplicate vertex,normal and uv data and creates indices as appropriatly.

a model with 570 faces loads in like 2 seconds, but i have a model with 25000+ faces, I waited maybe 20mins with it not showing on the screen, yet i kept hitting a break point and it was still processing.

I am using stl vectors as my containers
I think this is the main problem area, the compare section

Code:
for(unsigned int h = 0; h < ActualVertexArraySize; h++)//we will already set 0 so move to next element for the IB
{
	//because we start from the beginning each time need to ensure we dont count the current data 
   if(iterVT != endVT)
   {
		//check the vertices
	   //use the temp data to compare with the rest of the vertex
		if(FLOATCOMPARE(pVT.x,iterVT->x)&&
		  FLOATCOMPARE(pVT.y,iterVT->y)&&
		  FLOATCOMPARE(pVT.z,iterVT->z) )
	   {
	     if(hasNormal)
		 {
		  if(iterNT != endNT)
		  {
		   if(FLOATCOMPARE(pNT.x,iterNT->x)&&
			  FLOATCOMPARE(pNT.y,iterNT->y)&&
			  FLOATCOMPARE(pNT.z,iterNT->z) )
		   {
			if(hasUV)
			{
			  if(FLOATCOMPARE(pUV.u,iterUV->u)&&
				 FLOATCOMPARE(pUV.v,iterUV->v) )
			  {
				//it is a old index, so reuse it, then increment the new index place
	   			currentMesh.triangleIndexBuffer[index]= h;
				reuse = true;
				break;
			  }//end compare UV
			}
			else
			{
		     //it is a old index, so reuse it, then increment the new index place
	   	     currentMesh.triangleIndexBuffer[index]= h;
			 reuse = true;
			 break;
			}
		   }//end compare normals
		  }//check if normal iterator in range
		 }//end if hasNormal
		 else if(hasUV)
		 {
		  if(iterUV != endUV)
		  {
		   if(FLOATCOMPARE(pUV.u,iterUV->u)&&
			  FLOATCOMPARE(pUV.v,iterUV->v) )
		   {
		   	 //it is a old index, so reuse it, then increment the new index place
	   	     currentMesh.triangleIndexBuffer[index]= h;
			 reuse = true;
			 break;
		   }//end comapre UV
		  }//check if uv iterator in range
		 }//end else if hasUV
		 //it is a old index, so reuse it, then increment the new index place
	   	 currentMesh.triangleIndexBuffer[index]= h;
		 reuse = true;
		 break;
	   }//end vert compare
   }
   if(iterVT != endVT)
		iterVT++;
   if(iterNT != endNT && hasNormal)
	 iterNT++;
   if(iterUV != endUV && hasUV)
	  iterUV++;
}//end for actual vertex size
//the element was unique so add it as a new vertexsize, jump and increment the index buffer.
if(!reuse)
{
	currentMesh.triangleIndexBuffer[index]= ActualVertexArraySize++;
	vtBuffer.push_back(pVT);
	endVT = vtBuffer.end();
	if(hasNormal)
	{
		ntBuffer.push_back(pNT);
		endNT = ntBuffer.end();
	}
	if(hasUV)
	{
		uvBuffer.push_back(pUV);
		endUV = uvBuffer.end();
	}
}
  
//reset the iterators
iterVT = vtBuffer.begin();
iterNT = ntBuffer.begin();
iterUV = uvBuffer.begin();

and the model sorting in its entirity
Code:
for(unsigned int currentFace= 0; currentFace < currentMesh.meshData->numFaces; currentFace++)
{
  bool hasNormal =false; bool hasUV = false;
  bool reuse = false;
  //short hand reference
  pf  = currentMesh.meshData->faceList[currentFace];

  //did we count normals and uv's when reading the mesh data
  if(currentMesh.meshData->numNormals > 0)
  {
    hasNormal = true; 
    pNT = currentMesh.meshData->normalList[pf.normalIndices[0]];
  }
  if(currentMesh.meshData->numUV > 0)
 	hasUV = true;
		
  //check for duplicate vertices,normals and uv
  /*Here we use K to represent 3 points of a triangle
  We use index to move along the currentFace and reference the actual data of a uv,normal,or vertex*/
  for(int k = 0; k < 3; k++, index++)
  {
    pVT = currentMesh.meshData->vertexList[pf.vertIndices[k]];
    if(hasNormal && currentMesh.meshData->numNormals > 1 )
    {
     pNT = currentMesh.meshData->normalList[pf.normalIndices[k]];
    }
    if(hasUV)
    {
	pUV = currentMesh.meshData->uvList[pf.uvIndices[k]];
    }
    //go through all the list list of normals, UV and vertices to check if they are in the VBO
   //assign Indices based on, 
   for(unsigned int h = 0; h < ActualVertexArraySize; h++)
   {
    //because we start from the beginning each time need to ensure we dont count the current data 
     if(iterVT != endVT)
     {
	//check the vertices
	//use the temp data to compare with the rest of the vertex
	if(FLOATCOMPARE(pVT.x,iterVT->x)&&
	   FLOATCOMPARE(pVT.y,iterVT->y)&&
	   FLOATCOMPARE(pVT.z,iterVT->z) )
	 {
	    if(hasNormal)
	    {
	     if(iterNT != endNT)
	     {
		if(FLOATCOMPARE(pNT.x,iterNT->x)&&
		   FLOATCOMPARE(pNT.y,iterNT->y)&&
		   FLOATCOMPARE(pNT.z,iterNT->z) )
	       {
		 if(hasUV)
		 {
		   if(FLOATCOMPARE(pUV.u,iterUV->u)&&
		      FLOATCOMPARE(pUV.v,iterUV->v) )
		   {
		   //it is a old index, so reuse it, then increment the new index place
		   currentMesh.triangleIndexBuffer[index]= h;
		   reuse = true;
		   break;
		  }//end compare UV
		}
		else
		{
		   //it is a old index, so reuse it, then increment the new index place
		  currentMesh.triangleIndexBuffer[index]= h;
		  reuse = true;
		  break;
		}
	     }//end compare normals
	   }//check if normal iterator in range
       }//end if hasNormal
       else if(hasUV)
       {
	 if(iterUV != endUV)
	 {
	  if(FLOATCOMPARE(pUV.u,iterUV->u)&&
	     FLOATCOMPARE(pUV.v,iterUV->v) )
          {
           //it is a old index, so reuse it, then increment the new index place
	    currentMesh.triangleIndexBuffer[index]= h;
	    reuse = true;
	    break;
	  }//end comapre UV
	 }//check if uv iterator in range
	}//end else if hasUV
      //it is a old index, so reuse it, then increment the new index place
      currentMesh.triangleIndexBuffer[index]= h;
      reuse = true;
      break;
   }//end vert compare
  }
  if(iterVT != endVT)
    iterVT++;
  if(iterNT != endNT && hasNormal)
    iterNT++;
  if(iterUV != endUV && hasUV)
    iterUV++;
 }//end for actual vertex size
//the element was unique so add it as a new vertexsize, jump and increment the index buffer.
if(!reuse)
{
 currentMesh.triangleIndexBuffer[index]= ActualVertexArraySize++;
 vtBuffer.push_back(pVT);
 if(hasNormal)
 {
  ntBuffer.push_back(pNT);
 }
 if(hasUV)
 {
  uvBuffer.push_back(pUV);
 }
}
 
//reset the iterators
iterVT = vtBuffer.begin();
iterNT = ntBuffer.begin();
iterUV = uvBuffer.begin();
endVT = vtBuffer.end();
endNT = ntBuffer.end();
endUV = uvBuffer.end();
reuse = false;
}//end loop per trangle
if(currentIterVT != currentMesh.meshData->vertexList.end())
 currentIterVT++;
if(currentIterUV != currentMesh.meshData->uvList.end() && hasUV)
  currentIterUV++;
if(currentIterNT != currentMesh.meshData->normalList.end() && hasNormal)
	currentIterNT++;
}//for current face
 
you could just make it two separate steps. make your converter its own project. where you find all the duplicates and save out the optimized file, and your actual loader loads only the optimized file. I dont know if that will help any, or even work for how you have things set up, but its an idea. have you checked out:

most of the tutorials on this site are pretty good. gives you pretty much an entire run down of 3d programming.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top