display vertices?

Dear opengl friends,
a beginner needs you :).

I want to create a simple .OBJ viewer in opengl. I made some code to read .OBJ and display it, rotate with mouse… that works ok so far.

I want to enhance it so it displays the vertices as small squares which one can select with the mouse.

I want to draw the model first, somehow finding out which polys were drawn and which not, so I do not display vertices for polys that are not visible. Maybe using the buffers somehow.

Then I thought to maybe use colored Quads positioned at each vertex and draw these over the model, but I am unsure of how to position them so that they are always normal to the camera.

Maybe I am also on the wrong track, would be very kind if someone could give a hint.

Thanks, col

There are presently three ways to handle this:

  1. Use a display list for a quad and transform input points onto the screen as offsets for the quad instances (slow).

  2. Use the point sprites (GL_ARB_point_sprite) extension.

  3. Use a geometry shader (if the extension is supported) to produce quads (two triangles) for input points.

If your geometry is static, you could use an octree-based CPU-bound algorithm to determine the visibility for sets of points, however the testing cost involved may not be worth the potential speedup (minus the test).

As far as orienting the quads at the screen: I would recommend exploring the point sprites extension. This will have the desired effect if #3 is not an option.

Note that some drivers/hardware render points as square blocks of pixels (the size adjustable via. glPointSize), but this is obviously platform-dependent (some render points as circles).

Lastly, for the hit testing, the painter’s method is effective as long as you don’t need to determine all of the points within a subset of the viewport larger than 1 pixel, provided also that you would only be interested in the point(s) closest to the view plane.

It seems that bill-boards would solve the problems you describe relating to view-oriented quads. You will find plenty of reference material for this technique. There is even an OpenGL-extension called “point-sprites” that would be useful to you, I think.

In terms of knowing which polys were drawn the answer is simple: you probably don’t. Assuming that you are using depth testing, you submit all your polys to OpenGL and the front-most ones get drawn on screen. Here front-most is obviously related to your camera position/orientation.

One simple solution you could try is to draw a bill-board/point-sprite for each vertex in a second pass, as you suggest. Depth-testing will ensure that vertices on hidden surfaces don’t get drawn. Possibly there would be some leaking around the model silhouette.

So you draw the bill-boards on screen to show the user where to click in order to manipulate the vertices. Now, you also render the bill-boards into a separate selection buffer. The selection buffer is probably some color buffer, where you mangle the vertex index into a color. Here, the vertex bill-boards obviously have different colors. When the user clicks on the screen you check the selection buffer to see if a vertex was clicked. If the color of the clicked pixel in the selection buffer corresponds to a vertex index you know which vertex was clicked, and you can start dragging it.

I hope this helps and puts you on the right track.

T

If your geometry is static, you could use an octree-based CPU-bound algorithm to determine the visibility for sets of points, however the testing cost involved may not be worth the potential speedup (minus the test).

Using depth buffering is probably faster in the case of large models. A CPU algorithm that in the worst-case scenario tests every vertex runs into problems for large models.

Note that some drivers/hardware render points as square blocks of pixels (the size adjustable via. glPointSize), but this is obviously platform-dependent (some render points as circles).

What you describe depends if point smoothing is used or not. Unsmoothed points are rendered as quads, smooth points are rendered as circles.

Using depth buffering is probably faster in the case of large models. A CPU algorithm that in the worst-case scenario tests every vertex runs into problems for large models.

That is what I was suggesting – though I don’t know what depth buffering has to do with the visibility testing of points w.r.t. a viewport, I believe you might be referring to using hardware clipping for a dataset that has been loaded into device memory (which is definitely faster).

What you describe depends if point smoothing is used or not. Unsmoothed points are rendered as quads, smooth points are rendered as circles.

I’ve been using OpenGL since 2005 and forgot point smoothing existed (for shame). Though the documentation suggests “proper filtering”… whatever that means.

I still stand by my suggestion to use GL_ARB_point_sprite, however, as this is the simplest way to ensure that you will get square points (or whatever shape you would like them to be).

That is what I was suggesting – though I don’t know what depth buffering has to do with the visibility testing of points w.r.t. a viewport, I believe you might be referring to using hardware clipping for a dataset that has been loaded into device memory (which is definitely faster).

There seems to be some confusion here. I would call the removal of points outside the view frustom clipping (this would also handle cases where a primitive has vertices both inside and outside the frustum). I meant that if a depth buffer is used, vertices for triangles that are occluded (by line-of-sight, assuming no transparency) will also be occluded. Thus, there is no need to do occlusion queries on the CPU, since it will be handled by the depth-testing anyway. That is all, very simple really, and perhaps too obvious to point out. There is, however, the small problem with vertices on the silhouette, but a prototype implementation can quite possibly ignore this.

Using display lists/VBO’s is definately faster, but that is not really specific to the question here, in my opinion.

I agree that GL_ARB_point_sprite is a good call here. Really, it is just bill-boarding done in hardware. The nice thing is that one is only passing a single point to the GPU per quad.

One more point: you must ensure that there is no anti-aliasing enabled when rendering the vertex IDs into a color buffer for picking. In other words, disable multisampling and point smoothing. Also, you need to disable blending, or else set alpha to 1.0, or something of the kind. Otherwise you will corrupt the vertex IDs that get stored.