PDA

View Full Version : Multiple buffers for a single vertex



Ostsol
06-24-2003, 08:39 AM
I asked about this a while back. . . but I'm still having problems. To recap: I'm trying to make my memory usage more efficient in my terrain rendering by using only a single set of (x, y) positions, stored in a vertex array via VBO, that is used for all terrain segments. Unfortunately, what I currently have is not working properly.

Here's the two structures I use:



struct TerrainGridVertex
{
float coords[3];
};

struct TerrainVertex
{
float height;
float colour[3];
};
The first is for the reusable coordinates and the second is used for each individual terrain segment. The first has three coordinates when it really only needs two, but that's just there for debugging purposes.

Here's my code for filling the buffers:


aGrid = new TerrainGridVertex[nSize * nSize];
aTerrainVertices = new TerrainVertex[nSize * nSize];

for (y = 0; y < nSize; y++)
for (UINT x = 0; x < nSize; x++)
{
aGrid[x + y * nSize].coords[0] = (float) x;
aGrid[x + y * nSize].coords[1] = (float) y;
aGrid[x + y * nSize].coords[2] = afTotal[x + y * nSize] * 0.5f;
aTerrainVertices[x + y * nSize].height = afTotal[x + y * nSize] * 0.5f;

float fColour;
fColour = afTotal[x + y * nSize] / 255.0f;

aTerrainVertices[x + y * nSize].colour[0] = fColour;
aTerrainVertices[x + y * nSize].colour[1] = fColour;
aTerrainVertices[x + y * nSize].colour[2] = fColour;
}

UINT nGridSize = nSize * nSize * sizeof (TerrainGridVertex);
UINT nTerrainSize = nSize * nSize * sizeof (TerrainVertex);

glGenBuffersARB (nMeshes, &amp;gluiVertexArray);

glGenBuffersARB (1, &amp;gluiTerrainGrid);

glBindBufferARB (GL_ARRAY_BUFFER_ARB, gluiTerrainGrid);
glBufferDataARB (GL_ARRAY_BUFFER_ARB, nGridSize, aGrid, GL_STATIC_DRAW_ARB);

glBindBufferARB (GL_ARRAY_BUFFER_ARB, gluiVertexArray);
glBufferDataARB (GL_ARRAY_BUFFER_ARB, nTerrainSize, aTerrainVertices, GL_STATIC_DRAW_ARB);

GLenum eError = glGetError ();

switch (eError)
{
case GL_OUT_OF_MEMORY:
return false;

default:
break;
}
Again, the reusable array has 3-element coordinates for debugging purposes. In the vertex program I can simple tell it to use the third coordinate to render "normally", without combining with another array.

Here's my draw code:


glEnable (GL_VERTEX_PROGRAM_ARB);
glBindProgramARB (GL_VERTEX_PROGRAM_ARB, nVertexProgram);

glEnableClientState (GL_VERTEX_ARRAY);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
glEnableClientState (GL_COLOR_ARRAY);

glBindBufferARB (GL_ARRAY_BUFFER_ARB, gluiTerrainGrid);
glVertexPointer (3, GL_FLOAT, sizeof (TerrainGridVertex), 0);

glBindBufferARB (GL_ARRAY_BUFFER_ARB, gluiVertexArray);

glTexCoordPointer (1, GL_FLOAT, sizeof (TerrainGridVertex), 0);
glColorPointer (3, GL_FLOAT, sizeof (TerrainGridVertex), BUFFER_OFFSET (sizeof (float) * 1));

glDrawElements (GL_QUADS, (nSize - 1) * (nSize - 1) * 4, GL_UNSIGNED_INT, anIndices);

glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0);

glDisable (GL_VERTEX_PROGRAM_ARB);
glDisableClientState (GL_VERTEX_ARRAY);
glDisableClientState (GL_TEXTURE_COORD_ARRAY);
glDisableClientState (GL_COLOR_ARRAY);

Lastly is my vertex program:


!!ARBvp1.0

PARAM mvp[4] = {state.matrix.mvp};
PARAM one = {1.0, 1.0, 1.0, 1.0};

TEMP vertcoords;

MOV result.color, vertex.color;

MOV vertcoords.x, vertex.position.x;
MOV vertcoords.y, vertex.position.y;
MOV vertcoords.z, vertex.texcoord.x;
MOV vertcoords.w, one.w;

DP4 result.position.x, mvp[0], vertcoords;
DP4 result.position.y, mvp[1], vertcoords;
DP4 result.position.z, mvp[2], vertcoords;
DP4 result.position.w, mvp[3], vertcoords;

END

Is there anything you can see wrong with what I've done?

Csiki
06-24-2003, 08:57 AM
Originally posted by Ostsol:

glGenBuffersARB (nMeshes, &gluiVertexArray);

I hope nMeshes==1. http://www.opengl.org/discussion_boards/ubb/smile.gif



glBindBufferARB (GL_ARRAY_BUFFER_ARB, gluiTerrainGrid);
glVertexPointer (3, GL_FLOAT, sizeof (TerrainGridVertex), 0);
glBindBufferARB (GL_ARRAY_BUFFER_ARB, gluiVertexArray);
glTexCoordPointer (1, GL_FLOAT, sizeof (TerrainGridVertex), 0);
glColorPointer (3, GL_FLOAT, sizeof (TerrainGridVertex), BUFFER_OFFSET (sizeof (float) * 1));

If you bind gluiVertexArray, then why sizeof(TerrainGridVertex)? Not TerrainVertex?

Korval
06-24-2003, 09:24 AM
Also, why does "TerrainGridVertex" have 3 floats? Shouldn't it just be 2 (the x and y)? Granted, Csiki's point is likely the actual cause of the problem.

Ostsol
06-24-2003, 10:57 AM
*sighs* I can't believe I didn't catch that. . . Copy-paste is the bane of my existance. Thanks, guys!

TerrainGridVertex has three components only temporarily. It's like that so I could test other parts of my vertex shader without worrying about combining the vertex positions. It certainly is totally pointless overall, though, and can be taken out. http://www.opengl.org/discussion_boards/ubb/smile.gif

Anyways, it finaly works, so thanks, again.