// your point struct might look something like this
struct drawpoint
{
float position[3];
unsigned char color[4];
};
// to do - experiment with different sizes and tune for best perf
#define MAX_POINTS 65536
// let's not have code stretching 4 miles across the screen
#define BUFFER_MAP_BITS (GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT)
// using a vector here; just change it to whatever container type you prefer
std::vector<drawpoint> myWonderfulPoints;
GLuint pointsvbo = 0;
// call this once only at startup
void CreateMeABuffer (void)
{
glGenBuffers (1, &pointsvbo);
glBindBuffer (GL_ARRAY_BUFFER, pointsvbo);
glBufferData (GL_ARRAY_BUFFER, MAX_POINTS * sizeof (drawpoint), NULL, GL_STREAM_DRAW);
glBindBuffer (GL_ARRAY_BUFFER, 0);
}
// call this every frame to draw stuff!
void DrawMeSomePoints (void)
{
drawpoint *bufpoints = NULL;
int pointcount = 0;
glBindBuffer (GL_ARRAY_BUFFER, pointsvbo);
glEnableClientState (GL_VERTEX_ARRAY);
glEnableClientState (GL_COLOR_ARRAY);
// because bufpoints points to NULL here, this will work (yes, I did test it)
glVertexPointer (3, GL_FLOAT, sizeof (drawpoint), bufpoints->position);
glColorPointer (4, GL_UNSIGNED_BYTE, sizeof (drawpoint), bufpoints->color);
if ((bufpoints = (drawpoint *) glMapBufferRange (GL_ARRAY_BUFFER, 0, MAX_POINTS * sizeof (drawpoint), BUFFER_MAP_BITS)) == NULL)
{
// error handling here - suggest falling back to immediate mode? don't forget to call glBindBuffer (GL_ARRAY_BUFFER, 0) and glDisableClientState!
return;
}
// you may prefer to use a proper iterator here
for (int i = 0; i < myWonderfulPoints.size (); i++)
{
// adds current point to buffer
memcpy (&bufpoints[pointcount], &myWonderfulPoints[i], sizeof (drawpoint));
// go to next slot in buffer
pointcount++;
// check for potential overflow
if (pointcount == MAX_POINTS)
{
// draw what we got so far
glDrawArrays (GL_POINTS, 0, pointcount);
// re-init buffer and counter
if ((bufpoints = (drawpoint *) glMapBufferRange (GL_ARRAY_BUFFER, 0, MAX_POINTS * sizeof (drawpoint), BUFFER_MAP_BITS)) == NULL)
{
// error handling here - if this fails we've got bigger problems on our hands than not being able to get a usable pointer!
}
pointcount = 0;
}
}
// draw anything left over
if (pointcount) glDrawArrays (GL_POINTS, 0, pointcount);
glDisableClientState (GL_VERTEX_ARRAY);
glDisableClientState (GL_COLOR_ARRAY);
glBindBuffer (GL_ARRAY_BUFFER, 0);
}