Looking for help with glDrawArrays

I have a continuos level of detail terrain engine that I have written and it works really well. I have hit a stumbling block, though, trying to optimize it. In the unoptimized version, I am sending triangle fans individually (via glBegin(GL_TRIANGLE_FAN) then sending the vertices) down the pipeline. To speed things up, I am attempting to send arrays of quads (for low level of detail areas) and triangles (for hight level of detail areas). The problem that I am having is that nothing gets rendered with the batch method.

Below is a pseudo-codish example of what I am trying to do only showing the vertices for clarity (no color or texture).

struct VERT
{
  float fX, fY, fZ;
};

Then in my terrain class definition I have:

VERT *m_pVerticePool;
int m_iIndex; 

I am calling it m_pVerticePool because the number of vertices is dynamic dependent upon the camera’s location and orientation.

When I initialize the terrain:

m_pVerticePool = new VERT[iTerrainSize * iTerrainSize];  // iTerrainSize is the length of the square terrain patch in pixels

iTerrainSize is potentially different for each terrain patch I instantiate.

Later on, I populate m_pVerticePool:

void UpdateVerts(float x, float y, float z, int index)
{
   m_pVerticePool[index].fX = x;
   m_pVerticePool[index].fY = y;
   m_pVerticePool[index].fZ = Z;
   m_iIndex++;
}  

Once I have updated all of the vertices, it is time to render:

// omitting the matrix mode and other setup stuff that works with the brute force method
glEnableClientState(GL_VERTEX_ARRAY);
// I intentionally have left of color and texture here.

glVertexPointer(3, GL_FLOAT, 0, m_pVerticePool);

glDrawArrays(GL_QUADS, 0, m_iIndex);  // Quads for the low level of detail areas.....

glDisableClientState(GL_VERTEX_ARRAY);
m_iIndex = 0;

Then I continue to loop. It doesn’t crash, but I don’t see quads displayed.
What I am doing incorrectly? The order of the vertices are the same as with the brute force glBegin method. Could it be the unused portions of the pVerticePool array (but I was thinking that m_iIndex in the glDrawArrays call would prevent that stuff from being read)?

Thank you.

m_index is just a total.

You actually fill in the data with an [index] offset but it’s not clear if this is done correctly or sequentially.

If you really are using indices then try glDrawElements to specify the index base pointer, if you don’t then make sure that when you’re building your data that the variable index in your code starts at zero and increments by one to give you valid data.

You don’t specify a color array either you will inherit whatever color is lying around in the pipeline.

Ah, thank you for the quick response. I have the color and texture values, I just omitted them for some clarity.

Yes, the indicies are sequential.

void CalcVerts()
{
   m_iIndex = 0;
   for z loop
   {
      for x loop
      {
          y = getY(x, z);
          UpdateVerts(x, y, z, m_iIndex);
      }
   }
}  

Thanks again!

Edit, never mind, looks like m_iIndex is global, that’s a kinda nasty way of doing this.

You call by value and use global scope to increment. It should work but I don’t see the point of doing this.

P.S. earlier you said m_iIndex was in your terrain claa, but these don’t look like class methods as you’ve declared them. I assume they are and that m_iIndex is properly scoped for each terrain patch…?

No, not global, and yes, those are methods. I think I failed in my attempt to make the code ‘clear’ :wink: . But, in retrospect, I think that the passed parameter is indeed superfluous.

Even as a class member it’s still superfluous. Moreover you’re adjusting the same class member variable that you also have passes as a call by value.

Makes me wonder if you have a compiler bug (unlikely). All the same just use the member OR use a call by ref, it’s better code.