X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fglx%2Fmolecule.c;h=cb2932eb7168c232dec3fe8cc102371f3c069191;hb=8eb2873d7054e705c4e83f22d18c40946a9e2529;hp=954b98101dc03014adca815b485e016d06499597;hpb=585e1a6717d1dd9b90fbb53acaaae82106354d33;p=xscreensaver diff --git a/hacks/glx/molecule.c b/hacks/glx/molecule.c index 954b9810..cb2932eb 100644 --- a/hacks/glx/molecule.c +++ b/hacks/glx/molecule.c @@ -22,6 +22,49 @@ - 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 @@ -186,7 +229,7 @@ static XrmOptionDescRec opts[] = { { "-molecule", ".molecule", XrmoptionSepArg, 0 }, { "-timeout",".timeout",XrmoptionSepArg, 0 }, { "-spin", ".spin", XrmoptionSepArg, 0 }, - { "+spin", ".spin", XrmoptionNoArg, "" }, + { "+spin", ".spin", XrmoptionNoArg, "False" }, { "-wander", ".wander", XrmoptionNoArg, "True" }, { "+wander", ".wander", XrmoptionNoArg, "False" }, { "-labels", ".labels", XrmoptionNoArg, "True" }, @@ -552,7 +595,8 @@ print_title_string (ModeInfo *mi, const char *string, 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); { @@ -622,6 +666,7 @@ build_molecule (ModeInfo *mi) glEnable(GL_CULL_FACE); } +#if 0 if (do_labels && !wire) { /* This is so all polygons are drawn slightly farther back in the depth @@ -634,6 +679,7 @@ build_molecule (ModeInfo *mi) { glDisable (GL_POLYGON_OFFSET_FILL); } +#endif if (!wire) set_atom_color (mi, 0, False); @@ -689,16 +735,20 @@ build_molecule (ModeInfo *mi) 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, @@ -708,7 +758,17 @@ build_molecule (ModeInfo *mi) 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) @@ -1098,7 +1158,7 @@ reshape_molecule (ModeInfo *mi, int width, int height) 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);