tags:

views:

246

answers:

2

So I would like to draw a 2D point in OpenGL, but not in immediate mode. It's been a while since I've programmed in OpenGL so I'm a bit rusty, and I can't find it in the Redbook.

All help is appreciated.

Thanks!

A: 

I'm not sure you can do that... as far as I know, the only way to draw a point is by specifying glBegin( GL_POINTS );

The only other way I can think of doing it is just drawing a series of quads or triangles in screen space...

why would you want to draw a point otherwise? What's the problem with immediate mode?

Andrew Gotow
I would prefer not to use immediate mode firstly out of habit, second because of the reason for that habit (immediate mode being slower).But is that necessarily true for just a point?
adam_0
hrm... what about glDraw*(GL_POINTS,...) ? the primitive type is an argument of all draw methods.
Bahbar
+1  A: 

If by "not in immediate mode" you mean uploading your geometry to the graphics card and making calls to render it then there are a couple of ways to do this. The simplest is to use a display list to precompile a list of OpenGL commands to execute

Gluint list = glGenLists(1);
// Release with glDeleteLists(list,1);
glNewList(list,GL_COMPILE);

// Drawing code here

glEndList();

Then render it with

glCallList(list);

A potentially more flexible and faster way is with the vertex buffer objects extension (to get access to extensions easily look up the GLEW library). You can preload your geometry into a VBO, then render it through calls to OpenGL:

float data[2] = {...};

GLuint buffer;
glGenBuffersARB(1,&buffer);
// Release with glDeleteBuffersARB(1,&buffer);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(data), data, GL_STATIC_DRAW_ARB);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);

then draw with something like

GLuint indices[] = {0};

glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer);
glVertexPointer(3, GL_FLOAT, sizeof(float)*2, ((GLubyte*)NULL)+0);
glEnableClientState(GL_VERTEX_ARRAY);
glDrawElements(GL_POINTS,sizeof(indices)/(sizeof(indices[0])),GL_UNSIGNED_INT,indices);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);    

You may also want to look up using index buffers to upload the indices as well (or alternative drawing routines). I'm afraid it's a little late for my brain to recall all the different ways of using vertex and index buffers.

I'd add if you're just drawing one point then most of this is unnecessary (you need to be drawing 10s or 100s of thousands of points for it to be slow) and will only serve to make the code harder to read, understand and maintain.

Adam Bowen
Given the question was specifically to avoid immediate mode, the VBO solution is the right way to go. A GL_POINTS primitive should be rendered just like any other.
gavinb
I think a (decent) OpenGL driver will probably compile and upload the display list to the graphics card(/server) so that it doesn't have to be transferred every time it is displayed, so a display list is just as much "retained" mode as a buffer object is. It's also a lot more convenient, which is why I included it in the answer. Which is better depends on the application I think.
Adam Bowen