- I'm not sure the text labels are being done in the best way;
they are sometimes, but not always, occluded by spheres that
pass in front of them.
+
+ GENERAL OPENGL NAIVETY:
+
+ I don't understand the *right* way to place text in front of the
+ atoms. What I'm doing now is close, but has glitches. I think I
+ understand glPolygonOffset(), but I think it doesn't help me.
+
+ Here's how I'd phrase the problem I'm trying to solve:
+
+ - I have a bunch of spherical objects of various sizes
+ - I want a piece of text in the scene, between each object
+ and the observer
+ - the position of this text should be apparently tangential
+ to the surface of the sphere, so that:
+ - it is never inside the sphere;
+ - but can be occluded by other objects in the scene.
+
+ So I was trying to use glPolygonOffset() to say "pretend all
+ polygons are N units deeper than they actually are" where N was
+ somewhere around the maximal radius of the objects. Which wasn't a
+ perfect solution, but was close. But it turns out that can't work,
+ because the second arg to glPolygonOffset() is multiplied by some
+ minimal depth quantum which is not revealed, so I can't pass it an
+ offset in scene units -- only in multiples of the quantum. So I
+ don't know how many quanta in radius my spheres are.
+
+ I think I need to position and render the text with glRasterPos3f()
+ so that the text is influenced by the depth buffer. If I used 2f,
+ or an explicit constant Z value, then the text would always be in
+ front of each sphere, and text would be visible for spheres that
+ were fully occluded, which isn't what I want.
+
+ So my only guess at this point is that I need to position the text
+ exactly where I want it, tangential to the spheres -- but that
+ means I need to be able to compute that XYZ position, which is
+ dependent on the position of the observer! Which means two things:
+ first, while generating my scene, I need to take into account the
+ position of the observer, and I don't have a clue how to do that;
+ and second, it means I can't put my whole molecule in a display
+ list, because the XYZ position of the text in the scene changes at
+ every frame, as the molecule rotates.
+
+ This just *can't* be as hard as it seems!
*/
#include <X11/Intrinsic.h>
y -= line_height;
- glPushAttrib (GL_LIGHTING | GL_DEPTH_TEST);
+ glPushAttrib (GL_TRANSFORM_BIT | /* for matrix contents */
+ GL_ENABLE_BIT); /* for various glDisable calls */
glDisable (GL_LIGHTING);
glDisable (GL_DEPTH_TEST);
{
glEnable(GL_CULL_FACE);
}
+#if 0
if (do_labels && !wire)
{
/* This is so all polygons are drawn slightly farther back in the depth
{
glDisable (GL_POLYGON_OFFSET_FILL);
}
+#endif
if (!wire)
set_atom_color (mi, 0, False);
molecule_atom *a = &m->atoms[i];
int j;
- glPushAttrib (GL_LIGHTING | GL_DEPTH_TEST);
- glDisable (GL_LIGHTING);
-/* glDisable (GL_DEPTH_TEST);*/
+ if (!wire)
+ {
+ glDisable (GL_LIGHTING);
+#if 1
+ glDisable (GL_DEPTH_TEST);
+#endif
+ }
if (!wire)
set_atom_color (mi, a, True);
glRasterPos3f (a->x, a->y, a->z);
- /* Before drawing the string, shift the origin to center
+ /* Before drawing the string, shift the origin to center
the text over the origin of the sphere. */
glBitmap (0, 0, 0, 0,
-string_width (mc->xfont1, a->label) / 2,
for (j = 0; j < strlen(a->label); j++)
glCallList (mc->font1_dlist + (int)(a->label[j]));
- glPopAttrib();
+ /* More efficient to always call glEnable() with correct values
+ than to call glPushAttrib()/glPopAttrib(), since reading
+ attributes from GL does a round-trip and stalls the pipeline.
+ */
+ if (!wire)
+ {
+ glEnable(GL_LIGHTING);
+#if 1
+ glEnable(GL_DEPTH_TEST);
+#endif
+ }
}
if (do_bbox)
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
- gluPerspective( 30.0, 1/h, 1.0, 100.0 );
+ gluPerspective( 30.0, 1/h, 20.0, 40.0 );
gluLookAt( 0.0, 0.0, 15.0,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);