Difference between revisions of "Vertex Formats"

From OpenGL Wiki
Jump to navigation Jump to search
 
 
Line 1: Line 1:
 
It's possible that you have a complex scene with different objects having different formats. Perhaps we should call it layout instead of format since this topic is not about using float or int or unsigned int.<br>
 
It's possible that you have a complex scene with different objects having different formats. Perhaps we should call it layout instead of format since this topic is not about using float or int or unsigned int.<br>
 
<br>
 
<br>
Some object might just need vertices and texcoords.<br>
+
Some objects might just need vertices and texcoords.<br>
 
Padding is added to make the vertex structure a multiple of 32 bytes since some GPUs prefer it that way, such as ATI/AMD.<br>
 
Padding is added to make the vertex structure a multiple of 32 bytes since some GPUs prefer it that way, such as ATI/AMD.<br>
  
Line 11: Line 11:
 
   };
 
   };
  
Some vertices might need normals as well
+
Some objects might need vertex, normals, texcoords. This struct is already multiple of 32 bytes.
  
 
   struct Vertex_VNT
 
   struct Vertex_VNT
Line 28: Line 28:
 
   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
   glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex_VT), zzz);
 
   glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex_VT), zzz);
   //Notice that would must disable normals
+
   //Notice that we must disable normals
 
   glDisableClientState(GL_NORMAL_ARRAY);
 
   glDisableClientState(GL_NORMAL_ARRAY);
 
   }
 
   }
   else (object_needs == VNT)
+
   else if(object_needs == VNT)
 
   {
 
   {
 
   glEnableClientState(GL_VERTEX_ARRAY);
 
   glEnableClientState(GL_VERTEX_ARRAY);
Line 52: Line 52:
 
   glDisableClientState(GL_NORMAL_ARRAY);
 
   glDisableClientState(GL_NORMAL_ARRAY);
 
   }
 
   }
   else (object_needs == VNT)
+
   else if(object_needs == VNT)
 
   {
 
   {
 
   //glEnableClientState(GL_VERTEX_ARRAY);  //already enabled
 
   //glEnableClientState(GL_VERTEX_ARRAY);  //already enabled
Line 61: Line 61:
 
   glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex_VNT), zzz);
 
   glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex_VNT), zzz);
 
   }
 
   }
 +
 +
 +
To further reduce the number of calls to make
 +
 +
  if(object_needs != presentVertexFormat)
 +
  {
 +
  presentVertexFormat=object_needs;
 +
  if(object_needs == VT)
 +
  {
 +
    glDisableClientState(GL_NORMAL_ARRAY);
 +
    glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VT), xxx);
 +
    glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex_VT), zzz);
 +
  }
 +
  else
 +
  {
 +
    glEnableClientState(GL_NORMAL_ARRAY);
 +
    glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VNT), xxx);
 +
    glNormalPointer(2, GL_FLOAT, sizeof(Vertex_VNT), yyy);
 +
    glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex_VNT), zzz);
 +
  }
 +
  }
 +
  else if(object_needs == presentVertexFormat)
 +
  {
 +
  if (object_needs == VT)
 +
  {
 +
  glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VT), xxx);
 +
  glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex_VT), zzz);
 +
  }
 +
  else if(object_needs == VNT)
 +
  {
 +
  glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VNT), xxx);
 +
  glNormalPointer(2, GL_FLOAT, sizeof(Vertex_VNT), yyy);
 +
  glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex_VNT), zzz);
 +
  }
 +
  }
 +
 +
 +
So now we have introduced the concept of vertex formats in our application and we keep track of the current format with <b>presentVertexFormat</b>.

Latest revision as of 18:09, 27 December 2008

It's possible that you have a complex scene with different objects having different formats. Perhaps we should call it layout instead of format since this topic is not about using float or int or unsigned int.

Some objects might just need vertices and texcoords.
Padding is added to make the vertex structure a multiple of 32 bytes since some GPUs prefer it that way, such as ATI/AMD.

 struct Vertex_VT
 {
  float x, y, z;
  float s0, t0;
  float padding[3];
 };

Some objects might need vertex, normals, texcoords. This struct is already multiple of 32 bytes.

 struct Vertex_VNT
 {
  float x, y, z;
  float nx, ny, nz;
  float s0, t0;
 };

What you could do is

 if(object_needs == VT)
 {
  glEnableClientState(GL_VERTEX_ARRAY);
  glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VT), xxx);
  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex_VT), zzz);
  //Notice that we must disable normals
  glDisableClientState(GL_NORMAL_ARRAY);
 }
 else if(object_needs == VNT)
 {
  glEnableClientState(GL_VERTEX_ARRAY);
  glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VNT), xxx);
  glEnableClientState(GL_NORMAL_ARRAY);
  glNormalPointer(2, GL_FLOAT, sizeof(Vertex_VNT), yyy);
  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex_VT), zzz);
 }

or to reduce further the number of calls to make

 if(object_needs == VT)
 {
  //glEnableClientState(GL_VERTEX_ARRAY);  //already enabled
  glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VT), xxx);
  //glEnableClientState(GL_TEXTURE_COORD_ARRAY);   //already enabled
  glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex_VT), zzz);
  //Notice that would must disable normals
  glDisableClientState(GL_NORMAL_ARRAY);
 }
 else if(object_needs == VNT)
 {
  //glEnableClientState(GL_VERTEX_ARRAY);  //already enabled
  glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VNT), xxx);
  glEnableClientState(GL_NORMAL_ARRAY);
  glNormalPointer(2, GL_FLOAT, sizeof(Vertex_VNT), yyy);
  //glEnableClientState(GL_TEXTURE_COORD_ARRAY);   //already enabled
  glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex_VNT), zzz);
 }


To further reduce the number of calls to make

 if(object_needs != presentVertexFormat)
 {
  presentVertexFormat=object_needs;
  if(object_needs == VT)
  {
    glDisableClientState(GL_NORMAL_ARRAY);
    glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VT), xxx);
    glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex_VT), zzz);
  }
  else
  {
    glEnableClientState(GL_NORMAL_ARRAY);
    glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VNT), xxx);
    glNormalPointer(2, GL_FLOAT, sizeof(Vertex_VNT), yyy);
    glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex_VNT), zzz);
  }
 }
 else if(object_needs == presentVertexFormat)
 {
 if (object_needs == VT)
 {
  glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VT), xxx);
  glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex_VT), zzz);
 }
 else if(object_needs == VNT)
 {
  glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VNT), xxx);
  glNormalPointer(2, GL_FLOAT, sizeof(Vertex_VNT), yyy);
  glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex_VNT), zzz);
 }
 }


So now we have introduced the concept of vertex formats in our application and we keep track of the current format with presentVertexFormat.