View Full Version : Problem with gluProject

04-22-2003, 04:25 AM
Hey gang,
Got a small problem here - and am looking for some advice on what to do (cause I am stumped). Here's the situation - I have a Globe made with a gluSphere and I need to put "overlays" on it, such as little dots and little circles (to define certain locations on the globe).

Anyways - to place these things on the globe, what I am doing is disabling the Depth Test and using gluProgect to get the window coordinates for both the globe and the circles or dots that I am trying to place on them. I am then comparing the Z window coordinate to see if the circle and/or dot is visible to the user or not (if it's behind the globe - don't draw it).

Now - I seem to be at a good starting point - because this works (well most of the time). But I do have a slight problem - it seems that gluProject is not accurate enough, (Or more likely I am doing something wrong) and some of the dots and circles draw when they should be behind the globe. (For example - you can see a circle in cape cod bay - but in all actuality - it's some place in central Europe, which at this time is on the other side of the visible globe.) If I keep rotating though - the circles then stop drawing (as they should). So it seems to me that I am off by a tiny factor in my calculations. . .

Here's some code!


// screen clear. We want this even if we aren't going
// to paint anything else.

if (!attributes_.isHidden_) {

// now do the globe work. First push the matrix on
//the stack

// move it to where it should be - note these values change

// set the pixel zoom where 1.0 is no zoom.
// This is for drawing text
double pixelZoom = attributes_.zoomDist_/280.0;
if (pixelZoom < 0) {
pixelZoom = pixelZoom * -1;
glPixelZoom(pixelZoom, pixelZoom);
glPolygonOffset(1.0, 1.0);

// because we are rotating the globe by 90, the x and y
// rotation need to be on the other axis
glRotatef(attributes_.yRotation_.measuredIn(degree ),
1.0, 0.0, 0.0);
glRotatef(attributes_.xRotation_.measuredIn(degree ),
0.0, 1.0, 0.0);

// if the globe needs to be created again
if (attributes_.createGlobeDisplayList_) {

// We are enabling Polygon Offsetting to help eliminate
// Z fighting of the overlays that come close to or are
// directly on top of the globe's surface.
glPolygonMode(GL_FRONT, GL_FILL);

// enable the texture

// call the display list that contains the earth

//nothing else should have a texture

// For gluProject - we need to get the current projection
// matrix, current viewport matrix, and current viewport.
// We will use glGet functions to query the graphics
// hardware on what these values are.
GLdouble modelMatrix[16];
GLdouble projectionMatrix[16];
GLint viewport[4];

// Use the glGet functions to query the graphics hardware
// for the current matrices and viewport.
glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
glGetDoublev(GL_PROJECTION_MATRIX, projectionMatrix);
glGetIntegerv(GL_VIEWPORT, viewport);

// check and report for any errors

// These will be the window coordinates for the Globe.
// In this case
// all we really need is the Z window coordinate,
// as we will compare
// the globeZ value with the winZ value.
GLdouble globeWinX;
GLdouble globeWinY;
GLdouble globeWinZ;

// Get the window coordiates for the globe.
// Note that we are using
// 0, 0, 0 as object coordinates for the globe because
// the globe's
// object coordinates are represented in the
// current matrices that
// we are passing in. We only actualy care about
// the Z window
// coordinates as we will be compareing the labelWinZ with the
// globeWinZ to see if we need to draw the current label.
gluProject(0, 0, 0, modelMatrix,
projectionMatrix, viewport, &amp;globeWinX,


// check and report for any errors

// now draw all of the overlays. They are to be drawn in a
// specific order which follows.
// We are passing in the matrixs and the
// globe window coordinates to the overlays so that
// they can compare
// their window coordinates with the
// globe's window coordinates and
// do depth testing manually. We manually do depth
// testing on the
// overlays that deal with labels that might
// curve into the earth
// (such as tracks and threat regions).
// The matrixs and viewport
// are also passed in so that the overlays can use
// the gluProject method.
// the gluProject method converts object coordinates to
// window coordinates. Because the calls to get
// the matrixs
// (using glGet) are expensive, we only want to do
// these once.

// first the tracks
drawTracks(modelMatrix, projectionMatrix, viewport, globeWinX, globeWinY, globeWinZ);

// this matrix pop is for the general "move the earth to the right place"
// matrix push

// While glXSwapBuffers will call a glFlush before it
// swaps the buffers, we want to make sure that all the
// openGL calls are finished before we swap the bufffers.

// this pushes all the information out of the
// back buffer onto the screen
glXSwapBuffers(display_, window_);

// make sure this is done drawing before leaving

// check and report for any errors


void drawTracks(GLdouble modelviewMatrix[16],
GLdouble projectionMatrix[16], GLint viewport[4],
GLdouble globeWinX, GLdouble globeWinY,
GLdouble globeWinZ)
// enable polygon offsetting for Lines.
glPolygonMode(GL_FRONT, GL_LINE);


// set line width of the launch platforms.

for (int i = 0; i < launchDisplay_.size(); ++i) {

// we will use a gluQuadric Disk to draw the
// circles for the Launch Platforms.
GLUquadricObj *launchPlatform = gluNewQuadric();

// check and report error status

// if the quadric did get created
if (launchPlatform != 0) {
gluQuadricDrawStyle(launchPlatform, GLU_LINE);

// should be based on range of probibility - TBD
int launchPlatformRadius = 1;

double vec[3];

// These will be the window coordinates for the
//launch platforms.
// The window coordinates are the "true" X, Y,
// and Z values (i.e. actual pixel values)
GLdouble platformWinX;
GLdouble platformWinY;
GLdouble platformWinZ;

// Get the window coordinates for the launch
// platforms. We use
// the object coordinates for the current launch
// platform to get
// the proper window coordinates. We only actually
//care about the Z window coordinates as we will be
// compareing the paltformWinZ with the globeWinZ
// to see if we need to draw the current label.
gluProject(vec[0], vec[1], vec[2], modelMatrix,
projectionMatrix, viewport, &amp;platformWinX,

// check and report for any errors

// Disable the depth testing for the labels

// Compare the platform Z values with the Globe Z
// values. The lower the Z value, the closer the
// object is to the eye. If the platform Z value is
// less than the Globe Z value, we then draw
// the launch platform. If not don't draw anything.
if (platformWinZ < globeWinZ)
// glPushMatrix/glPopMatrix is needed around
// this code
// because the translate affects the matrix.
glTranslated(vec[0], vec[1], vec[2]);

// make sure the inner and outer radius are
// the same.
gluDisk(launchPlatform, launchPlatformRadius,
launchPlatformRadius, 60, 2);



} // end of (if (launchPlatform != 0)

} // end of for


// check and report for any errors