The program described in this section draws a simple solar system with a planet and a sun, both using the same sphere-drawing routine. To write this program, you need to use glRotate*() for the revolution of the planet around the sun and for the rotation of the planet around its own axis. You also need glTranslate*() to move the planet out to its orbit, away from the origin of the solar system. Remember that you can specify the desired size of the two spheres by supplying the appropriate arguments for the auxSphere() routine.
To draw the solar system, you first want to set up a projection and a viewing transformation. For this example, gluPerspective() and gluLookAt() are used.
Drawing the sun is straightforward, since it should be located at the origin of the grand, fixed coordinate system, which is where the sphere routine places it. Thus, drawing the sun doesn't require translation; you can use glRotate*() to make the sun rotate about an arbitrary axis. To draw a planet rotating around the sun, as shown in Figure 3-21 , requires several modeling transformations. The planet needs to rotate about its own axis once a day. And once a year, the planet completes one revolution around the sun.
![[IMAGE]](figures/fig3-21.gif)
Figure 3-21 : Planet and Sun
To determine the order of modeling transformations, visualize what happens to the local coordinate system. An initial glRotate*() rotates the local coordinate system that initially coincides with the grand coordinate system. Next, glTranslate*() moves the local coordinate system to a position on the planet's orbit; the distance moved should equal the radius of the orbit. Thus, the initial glRotate*() actually determines where along the orbit the planet is (or what time of year it is).
A second glRotate*() rotates the local coordinate system around the local axes, thus determining the time of day for the planet. Once you've issued all these transformation commands, the planet can be drawn.
In summary, these are the OpenGL commands to draw the sun and planet; the full program is shown in Example 3-6 .
glPushMatrix();
auxWireSphere(1.0); /* draw sun */
glRotatef ((GLfloat) year, 0.0, 1.0, 0.0);
glTranslatef (2.0, 0.0, 0.0);
glRotatef ((GLfloat) day, 0.0, 1.0, 0.0);
auxWireSphere(0.2); /* draw smaller planet */
glPopMatrix();
Example 3-6 : A Planetary System: planet.c
#include <GL/gl.h>
#include <GL/glu.h>
#include "aux.h"
static int year = 0, day = 0;
void dayAdd (void)
{
day = (day + 10) % 360;
}
void daySubtract (void)
{
day = (day - 10) % 360;
}
void yearAdd (void)
{
year = (year + 5) % 360;
}
void yearSubtract (void)
{
year = (year - 5) % 360;
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 1.0, 1.0);
glPushMatrix();
auxWireSphere(1.0); /* draw sun */
glRotatef((GLfloat) year, 0.0, 1.0, 0.0);
glTranslatef (2.0, 0.0, 0.0);
glRotatef((GLfloat) day, 0.0, 1.0, 0.0);
auxWireSphere(0.2); /* draw smaller planet */
glPopMatrix();
glFlush();
}
void myinit(void)
{
glShadeModel(GL_FLAT);
}
void myReshape(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef (0.0, 0.0, -5.0);
}
int main(int argc, char** argv)
{
auxInitDisplayMode(AUX_SINGLE | AUX_RGBA);
auxInitPosition(0, 0, 500, 500);
auxInitWindow(argv[0]);
myinit();
auxKeyFunc(AUX_LEFT, yearSubtract);
auxKeyFunc(AUX_RIGHT, yearAdd);
auxKeyFunc(AUX_UP, dayAdd);
auxKeyFunc(AUX_DOWN, daySubtract);
auxReshapeFunc(myReshape);
auxMainLoop(display);
}
Try This
Try adding a moon to the planet. Or try several moons and additional planets. Hint: Use glPushMatrix() and glPopMatrix() to save and restore the position and orientation of the coordinate system at appropriate moments. If you're going to draw several moons around a planet, you need to save the coordinate system prior to positioning each moon and restore the coordinate system after each moon is drawn.
Try tilting the planet's axis.
OpenGL Programming Guide