I have this program:
#include <GL/freeglut.h>
#include <SFML/Window.hpp>
static GLfloat year = 0, day = 0, moon = 0;
bool m,M,y,Y,d,D;
void init()
{
glClearColor(0,0,0,0);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
}
///////////////////
///Display the sun, earth, and moon
///////////////////
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1,1,1);
glColor3f(1,1,0);
glPushMatrix();
glutSolidSphere(1, 20, 16);//the sun
//here is where we transform matrices to get to the planet's position
glColor3f(0,0,1);
glRotatef((GLfloat)year , 0, 1, 0);
glTranslatef(2,0,0);
glPushMatrix(); //remember the planets position
glRotatef((GLfloat)day, 0, 1, 0); //rotate the planet, but do not remember its rotation
glutSolidSphere(0.2, 10, 8); // planet
glColor3f(0.3,0.3,0.3);
glPopMatrix(); //go back to the position at which the earth was drawn (before rotation)
glRotatef(moon, 0, 1.5, 0);
glTranslatef(0.5,0,0);
glutSolidSphere(0.05,10,8); //and then draw the moon, transformed properly
glPopMatrix();
glPopMatrix();
//glutSwapBuffers();
//glutPostRedisplay();
}
////////////////////////////
///Set all the viewport and perspective stuff when the window is resized
////////////////////////////
void reshape(int w, int h)
{
glViewport(0,0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, (GLfloat)w / (GLfloat)h, 1, 200);
gluLookAt(0,2, 5, 0,0,0, 0, 1, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void update(const sf::Input &input)
{
const GLfloat rotationSpeed = 0.05f;
//if M is pressed, move the moon forwards or backwards in rotation
if(input.IsKeyDown(sf::Key::M) && !input.IsKeyDown(sf::Key::LShift))
moon = (moon + 2 * rotationSpeed);
else if(input.IsKeyDown(sf::Key::M))
moon = (moon - 2 * rotationSpeed);
//if Y is pressed move the earth in orbit
if(input.IsKeyDown(sf::Key::Y) && !input.IsKeyDown(sf::Key::LShift))
year = (year + rotationSpeed);
else if(input.IsKeyDown(sf::Key::Y))
year = (year - rotationSpeed);
//if D is pressed rotate earth, simulating days
if(input.IsKeyDown(sf::Key::D) && !input.IsKeyDown(sf::Key::LShift))
day = (day + rotationSpeed);
else if(input.IsKeyDown(sf::Key::D))
day = (day - rotationSpeed);
}
////////////////////////////////////////////////
/// /param: Event: The event
/// /param: capitalValue: The value of the capital lettered bools
/// /param: lowerCaseValue: The value of the lowercase bools
////////////////////////////////////////////////
void keyboard(sf::Event theEvent, bool value)
{
switch(theEvent.Key.Code)
{
case sf::Key::Y:
if(theEvent.Key.Shift)
Y = value;
else
y = value;
break;
}
}
int main(int argc, char** argv)
{
init();
glutInit(&argc, argv); //so glutSolidSphere can be used
sf::Window *app = new sf::Window(sf::VideoMode(800,600), "SFML",
sf::Style::Close);
reshape(app->GetWidth(), app->GetHeight()); //set the proper window and viewport stuff
while(app->IsOpened())
{
sf::Event theEvent;
while(app->GetEvent(theEvent))
{
switch(theEvent.Type)
{
case sf::Event::KeyPressed:
keyboard(theEvent, true);
break;
case sf::Event::KeyReleased:
keyboard(theEvent, false);
break;
case sf::Event::Resized:
reshape(app->GetWidth(), app->GetHeight());
break;
case sf::Event::Closed:
app->Close();
break;
}
}
update(app->GetInput()); //update the planets based on current keyboard status
display(); //display the planets
app->Display(); //show the window
}
}
The earth rotates around the sun, and the moon rotates around the earth, but no matter what happens, the earth is ALWAYS drawn in front of the sun (even when its rotated behind), and the moon is ALWAYS drawn in front of the Earth (and in front of the sun, naturally). I don't really know why.