#include <GL/glaux.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.1415926535898
static GLfloat year=0,day=0,hour=0;
static GLfloat width,depth;
void DrawOrbit(GLfloat r,GLint circle_points)
{
glBegin(GL_LINE_LOOP);
for(int i=0;i<circle_points;i++)
glVertex3f(cos(2*PI*i/circle_points)*r,0,sin(2*PI*i/circle_points)*r);
glEnd();
}
void init(void)
{
glClearColor(0.0,0.0,0.0,0.0);
glShadeModel(GL_SMOOTH);
GLfloat light_position[] = {4.0,1.0,4.0,0.0};
GLfloat white_light[] = {1.0,1.0,1.0,1.0};
GLfloat spot_direction[]={-1.0,0.0,-1.0};
GLfloat lmodel_ambient[] = {0.1,0.1,0.1,1.0};
glLightfv(GL_LIGHT0, GL_POSITION, light_position); //指定光源
glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);
glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);
glLightf(GL_LIGHT0,GL_CONSTANT_ATTENUATION,1.5);//衰减因子
glLightf(GL_LIGHT0,GL_LINEAR_ATTENUATION,0.5);
glLightf(GL_LIGHT0,GL_QUADRATIC_ATTENUATION,1.2);
glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,30.0);
glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,spot_direction);
glLightf(GL_LIGHT0,GL_SPOT_EXPONENT,2.0);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
}
void display (void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (GLfloat) width/(GLfloat) depth, 1.0, 20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0,0.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0);
glPushMatrix();
glRotatef(10.0,1.0,0.0,0.0);
{
// GLfloat sun_mat_emission[] = {0.5f, 0.0f, 0.0f, 1.0f};
// glMaterialfv(GL_FRONT, GL_EMISSION, sun_mat_emission);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_EMISSION);
glColor3f(0.5,0.0,0.0);
glutSolidSphere(0.5,20,16); /*draw sun*/
}
glColor3f(0.5,0.5,0.5);
DrawOrbit(1.5,100);
glDisable(GL_COLOR_MATERIAL);
glRotatef((GLfloat) year, 0.0,1.0,0.0);
glTranslatef(1.5,0.0,0.0);
glPushMatrix();
glRotatef((GLfloat) day, 0.0,1.0,0.0);
{
// GLfloat earth_mat_emission[] = {0.0f, 0.6f, 0.0f, 1.0f};
// glMaterialfv(GL_FRONT, GL_EMISSION, earth_mat_emission);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_EMISSION);
glColor3f(0.0,0.6,0.0);
glutSolidSphere(0.2,10,8); /*draw earth*/
}
glColor3f(0.5,0.2,0.5);
glLineStipple(1,0x3F07);
glEnable(GL_LINE_STIPPLE);
DrawOrbit(0.5,100);
glDisable(GL_LINE_STIPPLE);
glDisable(GL_COLOR_MATERIAL);
glPopMatrix();
glRotatef((GLfloat) hour, 0.0,1.0,0.0);
glTranslatef(0.5,0.0,0.0);
{
GLfloat moon_mat_emission[] = {0.1f, 0.0f, 0.5f, 1.0f};
glMaterialfv(GL_FRONT, GL_EMISSION, moon_mat_emission);
glutSolidSphere(0.1,8,6); /*draw moon*/
}
glPopMatrix();
glutSwapBuffers();
}
void reshape(int w, int h)
{
width=w;
depth=h;
glViewport(0,0, (GLsizei) w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0,(GLfloat) w/(GLfloat) h,1.0,20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0,0.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0);
}
void myIdle(void)
{
year += 0.5;
if( year > 360.0 )
year -= 360.0;
day += 1.0;
if( day > 360.0 )
day -= 360.0;
hour += 2.0;
if( day > 360.0 )
day -= 360.0;
display();
}
/*void mouse(int button, int state, int x, int y)
{
switch (button)
{
case GLUT_LEFT_BUTTON:
if (state==GLUT_DOWN)
{
year += 0.5;
if( year >= 360.0 )
year -= 360.0;
day += 1.0;
if( day >= 360.0 )
day -= 360.0;
hour += 2.0;
if( hour >= 360.0 )
hour -= 360.0;
glutPostRedisplay();
}
break;
default:
break;
}
}*/
/*void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 'd':
day = (day+10)%360;
glutPostRedisplay();
break;
case 'D':
day=(day-10)%360;
glutPostRedisplay();
break;
case 'y':
year=(year+5)%360;
glutPostRedisplay();
break;
case 'Y':
year=(year-5)%360;
glutPostRedisplay();
break;
case 'h':
hour=(hour+20)%360;
glutPostRedisplay();
break;
case 'H':
hour=(hour-20)%360;
glutPostRedisplay();
break;
default:
break;
}
}*/
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500,500);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
// glutKeyboardFunc(keyboard);
// glutMouseFunc(mouse);
glutIdleFunc(&myIdle);
glutMainLoop();
return 0;
}