PDA

View Full Version : gluSphere distorting when I move it to the corners of the screen!



Roach
01-02-2003, 04:57 AM
Hi gang,
I'm having a little problem with a gluSphere (actually a globe) distorting when positioned in the corners of the screen. All I am really doing is preforming a glTranslatef call to move the globe from the center of the screen, shrink it, and then move it to the new x, y position. I set the viewport with glViewport(0, 0,
static_cast(globeFormWidth_),
static_cast(globeFormHeight_));

Any ideas? Here is some code:





/////////////////////////////////////////////////////////////
// Method: draw_i
//
// Purpose: the real draw
//
// Notes: caller holds application and OpenGL lock
//
void
DcGui_Impl::Globe3d::draw_i()
{
// clear the buffer and the depth buffer. This will paint the
// screen clear. We want this even if we aren't going to paint
// anything else.
//
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
if (!attributes_.isHidden_) {

// first determine the density and set hi/low
determineDensity();

// now do the globe work. First push the matrix on the stack
//
glPushMatrix();

// move it to where it should be
glTranslatef(attributes_.currentPos_.x_,
attributes_.currentPos_.y_,
attributes_.zoomDist_);

// 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);

glPushMatrix();

// 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);

// enable the texture
glEnable(GL_TEXTURE_2D);

// call the display list that contains the earth
glCallList(attributes_.globeDisplayList_);
//nothing else should have a texture
//
glDisable(GL_TEXTURE_2D);
glPopMatrix();

// now have all the overlays draw
for (int i = 0; i < DcGui_Impl::GLOBE_OVERLAY_TOTAL; i++) {
glPushMatrix();

//repeat the rotates. Popping the
// matrix before removed all the rotates and other translations
//
glRotatef(attributes_.yRotation_.measuredIn(degree ), 1.0, 0.0, 0.0);
glRotatef(attributes_.xRotation_.measuredIn(degree ), 0.0, 1.0, 0.0);

// now draw the overlay. Each overlay determines if it should draw
// and does the right thing
//
attributes_.overlays_[i]->draw();

// pop the matrix so previous colors/rotations/translations/etc
// do not affect the next overlay
//
glPopMatrix();
}

// this matrix pop is for the general "move the earth to the right place"
// matrix push
//
glPopMatrix();

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

// make sure this is done drawing before leaving
glXWaitGL();

// check and report for any errors
GlobeError::OpenGLError(ARCH_LOCATION);

}

/////////////////////////////////////////////////////////
// Method: createGlobeDisplayList
//
// Purpose: Create the display list that contains the globe
// and the textures. This should only happen at startup
// and when the globe's radius is changed (set to "out of
// the way" position")
//
// Notes: caller holds application and (if not in initialization) openGL
// locks
//
void
DcGui_Impl::Globe3d::createGlobeDisplayList()
{
// first delete the existing list
//
if (attributes_.globeDisplayList_ != 0) {
glDeleteLists(attributes_.globeDisplayList_, 1);
}

// now generate a new one
attributes_.globeDisplayList_ = glGenLists(1);

// as long as we were able to create the list, populate it with
// the globe data
if (attributes_.globeDisplayList_ != 0) {
glNewList(attributes_.globeDisplayList_, GL_COMPILE);
glPushMatrix();
// want texture on while creating the globe
glEnable(GL_TEXTURE_2D);

// to ensure that the correct texture will be mapped
// onto the globe
glBindTexture(GL_TEXTURE_2D, texName_);

// set the color to white so the texture mapping will show up
glColor3dv(GLOBE_WHITE_COLOR);

// orient the earth with the north pole up! This is only for the
// earth so pop
glRotatef(-90.0, 1.0, 0.0, 0.0);

// make it one less than the radius so that the lat-long grid
// is a good fit on top.
//
gluSphere(globe_, attributes_.globeRadius_-1, 48, 48);

// turn off the texture since we don't want other objects
// to draw with texturing.
glDisable(GL_TEXTURE_2D);

glPopMatrix();
glEndList();
}
}

//////////////////////////////////////////////////////
// Method: setPosition_i
//
// Purpose: set the position (left, right, up, down, default, or out of the
// way) of the globe on the screen
//
// Notes: 1) one of two overloaded functions
// 2) caller holds application and OpenGL locks
//
//
void
DcGui_Impl::Globe3d::setPosition_i(GlobePositionOp tion pos)
{
// we want the zoom to start here so that the whole world in properly in
// view. It is here rather than being a constant because this is
// the only time it is set.
//
attributes_.zoomDist_ = -280.0;

// determine the radius of the globe
// the diameter is 1/3 the window width (for everything but
// out of the way) so the radius is half of that
//
attributes_.globeRadius_ = globeFormWidth_/6.0;

// check if the radius is going to change. If so, will need to
// do set radius
bool radiusChanged = false;
if ( (pos != GLOBE_OUT_OF_THE_WAY &amp;&amp;
attributes_.posOption_ == GLOBE_OUT_OF_THE_WAY) &amp;#0124; &amp;#0124;
(pos == GLOBE_OUT_OF_THE_WAY &amp;&amp;
attributes_.posOption_ != GLOBE_OUT_OF_THE_WAY)) {
radiusChanged = true;
}

attributes_.posOption_ = pos;

// always at the center of the screen
attributes_.currentPos_.z_ = 0.0;

if (pos == GLOBE_DEFAULT) {
// right in the center
attributes_.currentPos_.x_ = 0.0;
attributes_.currentPos_.y_ = 0.0;
}
// all the rest move it out of the way but also
// account for the radius of the earth
else if (pos == GLOBE_UPPER_RIGHT) {
// move it over a quarter of the screen both x, y
attributes_.currentPos_.x_ = globeFormWidth_/4.0;
attributes_.currentPos_.y_ = globeFormHeight_/4.0;
}
else if (pos == DcGui_Impl::GLOBE_UPPER_LEFT) {
// move it over a quarter of the screen left x and up y
attributes_.currentPos_.x_ = (0-(globeFormWidth_/4.0));
attributes_.currentPos_.y_ = (globeFormHeight_/4.0);
}
else if (pos == DcGui_Impl::GLOBE_LOWER_LEFT) {
// move it over a quarter of the screen left x and down y
attributes_.currentPos_.x_ =
(0 - (globeFormWidth_/4.0));
attributes_.currentPos_.y_ =
(0 - (globeFormHeight_/4.0));
}
else if (pos == DcGui_Impl::GLOBE_LOWER_RIGHT) {
// move it over a quarter of the screen right x and down y
attributes_.currentPos_.x_ =
(globeFormWidth_/4.0);
attributes_.currentPos_.y_ =
(0 - (globeFormHeight_/4.0));
}
else if (pos == DcGui_Impl::GLOBE_OUT_OF_THE_WAY) {
// this needs to be 60% of the current size
attributes_.globeRadius_ = (attributes_.globeRadius_/10) * 6;

// move it into the right quadrant
attributes_.currentPos_.x_ =
(globeFormWidth_/4.0);
attributes_.currentPos_.y_ =
(globeFormHeight_/4.0);
}

if (radiusChanged) {
// a change in the earth's radius means that we need to
// reset the globe display list
createGlobeDisplayList();

// it also means that the overlays need to readjust their values
// use attributes_.overlays_.size() in case the
// overlays have not been set up yet (this is called in
// the constructor)
//
for (int i = 0; i < attributes_.overlays_.size(); i++) {
attributes_.overlays_[i]->updateEarthRadius(attributes_.globeRadius_);
}
}

}



Any ideas??


[This message has been edited by Roach (edited 01-02-2003).]