Vertex Arrays (glInterleavedArrays) - Help!

Hi all.

I’m currently playing with Vertex arrays and I’ve come accross a problem. I’m using the glInterleavedArrays function so I can stuff all my data in one array and access it with a struct. (Code to follow) I think I’m doing this ok but none of the geometry gets drawn and I get a crash when I exit the app.

// This is the headder file for the class
typedef struct tagVertex
{
float fRed;
float fGreen;
float fBlue;
float fAlpha;

float fXNorm;
float fZNorm;
float fYNorm;

float fXPos;
float fYPos;
float fZPos;

} Vertex;

class CLandscape
{
public:
CLandscape();
virtual ~CLandscape();
void Generate(vec3_t vOffset, long lXSize, long lYSize, float fHeightVar);
bool Load(string strFilename, float fHeightVar, vec3_t vOffset);
long Draw(float fParam);
void ProcessLights(LightsCol vLights, vec3_t vCam);
void GenerateNormals(bool fAveraged = true);
private:
VertexCol m_vVert;
Vertex * m_pVert;
TriangleCol m_vTris;
long m_lXSize;
long m_lYSize;
};

And this is my generate and draw functions.

#define ZERO(x) memset((void*)(&(x)),0,sizeof((x)))
#define COPY(x,y) memcpy((void*)(y), (void*)(&(x)),sizeof(x))

#define SAFE_ARRAY_DELETE(x) if((x)) delete [] (x);
#define SAFE_DELETE(x) if((x)) delete (x);

#define ELEMENTS_IN(x) (sizeof(x) / sizeof((x)[0]))

CLandscape::CLandscape()
{
// nullify the vertex array
m_pVert = NULL;
}

CLandscape::~CLandscape()
{
// delete the array
SAFE_ARRAY_DELETE(m_pVert);
}

void CLandscape::Generate(vec3_t vOffset, long lXSize, long lYSize, float fHeightVar)
{
// build the grid
m_vVert.resize(lYSize * lXSize);
m_lXSize = lXSize;
m_lYSize = lYSize;

// delete the array if it has been allocated
SAFE_ARRAY_DELETE(m_pVert);

m_pVert = new Vertex[lYSize * lXSize];

for(long ix = 0; ix < lXSize; ix++)
{
for(long iy = 0; iy < lYSize; iy++)
{
//theta = -PI / 2 + dtheta; theta < PI / 2 - dtheta + 0.1; theta += dtheta)
long lIndex = (ix * lXSize) + iy;
Vertex v;

  	// zero our vertex
  	ZERO(v);

  	v.fRed = 1.0f;
  	v.fGreen = 1.0f;
  	v.fBlue = 1.0f;

  	v.fXPos = vOffset[x] + ix;
  	v.fYPos = vOffset[z] + iy;
  	v.fZPos = vOffset[y] + PerlinNoise_2D(ix,iy,2);

  	// copy the vertex to the array at its current position
  	COPY(v, m_pVert);
  	m_pVert++; //advance the pointer to the next struct!
  }

}

// We are using Interleaved Arrays!
glInterleavedArrays(GL_C4F_N3F_V3F,0,(GLvoid*)m_pVert);

return;

}

long CLandscape: raw(float fParam)
{
glDrawArrays(GL_POINTS,0,ELEMENTS_IN(((float*)m_pVert)));
return 0;
}

So, does this seem sensible? What about my technique for filling the array with geometry? Could this be a data alignment problem, it shouldn’t be becasue the data in the struct does stop on a 32 bit boundary (I think!)…

As I said, when Draw is called, nothing appears on the screen, even though the non VA version draws a nice random surface.

Thanks, Pete…

Hi all.

I’ve subsequently changed the generate code to the following…

void CLandscape::Generate(vec3_t vOffset, long lXSize, long lYSize, float fHeightVar)
{
m_lXSize = lXSize;
m_lYSize = lYSize;

// delete the array if it has been allocated
if(m_pVert)
{
delete [] m_pVert;
m_pVert = NULL;
}

m_pVert = new Vertex[lYSize * lXSize];
long lCount = 0;
for(long ix = 0; ix < lXSize; ix++)
{
for(long iy = 0; iy < lYSize; iy++)
{
//theta = -PI / 2 + dtheta; theta < PI / 2 - dtheta + 0.1; theta += dtheta)
//long lIndex = (ix * lXSize) + iy;
//Vertex v;

  	// zero our vertex
  	ZERO(m_pVert[0]);

  	m_pVert[0].fRed = 1.0f;
  	m_pVert[0].fGreen = 1.0f;
  	m_pVert[0].fBlue = 1.0f;

  	m_pVert[0].fXPos = vOffset[x] + ix;
  	m_pVert[0].fYPos = vOffset[y] + iy;
  	m_pVert[0].fZPos = vOffset[z];// + PerlinNoise_2D(ix,iy,2);

  	// copy the vertex to the array at its current position
  	//COPY(v, m_pVert);
  	m_pVert++; //advance the pointer to the next struct!
  	lCount++;
  }

}

    // We are using Interleaved Arrays!

glInterleavedArrays(GL_C4F_N3F_V3F,0,(GLvoid*)m_pVert);

return;
}

long CLandscape: raw(float fParam)
{
glDrawArrays(GL_POINTS,0, m_lXSize * m_lYSize);
return 0;
}

However, now I get a access violation on the glDrawArrays line. ?!>"***^^^% Get my drift, man?

Anybody got some ideas? Are there any nice tutorials on using glInterleavedArrays out there that dummies like me can make use of? I’ll write on is there isn’t and also if I get this thing working!

Thanks

Pete

this dont look right

_pVert[0].fRed = 1.0f; m_pVert[0].fGreen = 1.0f; m_pVert[0].fBlue = 1.0f; m_pVert[0].fXPos = vOffset[x] + ix; m_pVert[0].fYPos = vOffset[y] + iy; m_pVert[0].fZPos = vOffset[z];// + PerlinNoise_2D(ix,iy,2); // copy the vertex to the array at its current position //COPY(v, m_pVert); m_pVert++; //advance the pointer to the next struct! lCount++;

try someit like m_pVert[lCount]…
and forget about m_pVert++; //advance the pointer to the next struct!

OH MY GOD!

You’re completely correct! I dont even need to check the code, what a novice error! I should have made a copy of the pointer if I wanted to use the ++ operator on it.

For those who haven’t seen the BLATANT error here we go.

I go through my vertex loop creating geometry and appending it to my Vertex array at the current pointer position. I then increment the pointer.

I use this pointer in my call to glInterleavedArrays. BUT THE POINTER POINTS TO JUST PAST THE LAST ELEMENT! I could (should kick myself.)

Thanks alot zed

Yeah. Just coded it in.

Its all hunky dory now…

(Sigh)

Pete