OpenGL 真实感日地月系统

2018-10-12  本文已影响0人  善法
#include <windows.h>
#include <GL/glut.h>

GLdouble speed=0.1,day,month,year,solarcycle;
//月亮、地球、太阳的半径
GLfloat mr=0.15,er=0.3,sr=0.4;
//月亮、地球的公转半径
GLfloat mrr=0.6,err=2;

void init()
{
    glClearColor(0,0,0.1,1);
    glEnable(GL_POINT_SMOOTH|GL_LINE_SMOOTH|GL_POLYGON_SMOOTH);
}

void keyboard(GLubyte key,GLint x,GLint y)
{
    if(key==27) exit(0);
}

void timer(GLint millis)
{
    day+=speed*360/0.997;
    month+=speed*360/29.5;
    year+=speed*360/365.2475;
    solarcycle+=speed*360/27.5;
    glutPostRedisplay();
    glutTimerFunc(millis,timer,millis);
}

void reshape(GLint w,GLint h)
{
    glViewport(0,0,w,h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(30,(GLfloat)w/h,1,1000);
    glTranslatef(0,0,-8);
    glRotatef(30,1,0,0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void light(GLfloat r)
{
    GLfloat pos[][4]=
    {
        {r,0,0,1},{-r,0,0,1},{0,r,0,1},
        {0,-r,0,1},{0,0,r,1},{0,0,-r,1}
    };
    GLfloat params[]={0.9,0.9,0.9,1};
    for(int i=0;i<6;i++)
    {
        glLightfv(GL_LIGHT0+i,GL_POSITION,pos[i]);
        glLightfv(GL_LIGHT0+i,GL_DIFFUSE,params);
        glEnable(GL_LIGHT0+i);
    }
}

void material(GLfloat r,GLfloat g,GLfloat b)
{
    GLfloat params[]={r,g,b,1};
    glEnable(GL_LIGHTING);
    glMaterialfv(GL_FRONT,GL_DIFFUSE,params);
}

void color(GLfloat r,GLfloat g,GLfloat b)
{
    glDisable(GL_LIGHTING);
    glColor3f(r,g,b);
}

// 经纬线
void wire(GLfloat r)
{
    color(0.5,0.5,0.5);
    glutWireSphere(1.005*r,24,12);
}

// 自转轴
void axle(GLfloat r)
{
    color(0,0,0);
    glBegin(GL_LINE);
    glVertex3f(0,0,-r*1.2);
    glVertex3f(0,0,r*1.2);
    glEnd();
}

void sun(GLfloat r)
{
    glPushMatrix();
    glRotatef(90,-1,0,0);
    color(0.9,0.1,0.1);
    glutSolidSphere(r,24,12);
    wire(r);
    glPopMatrix();
}

void earth(GLfloat r)
{
    glPushMatrix();
    glRotatef(90,-1,0,0);
    material(0.1,0.1,0.9);
    glutSolidSphere(r,24,12);
    wire(r);
    glPopMatrix();
}

void moon(GLfloat r)
{
    glPushMatrix();
    glRotatef(90,-1,0,0);
    material(0.75,0.75,0.1);
    glutSolidSphere(r,24,12);
    wire(r);
    glPopMatrix();
}

void display()
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    // 太阳光照、太阳自转
    light(sr);
    glPushMatrix();
    glRotatef(solarcycle,0,1,0);
    sun(sr);
    glPopMatrix();

    // 地球公转
    glRotatef(year,0,1,0);
    glTranslatef(err,0,0);
    glRotatef(-year,0,1,0);
    glRotatef(-23.5,0,0,1);

    // 地球自转
    glPushMatrix();
    glRotatef(day,0,1,0);
    earth(er);
    glPopMatrix();

    // 月球公转
    glRotatef(month,0,1,0);
    glTranslatef(mrr,0,0);
    moon(mr);
    glutSwapBuffers();
}

int main()
{
    glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE);
    glutCreateWindow("Galaxy");
    glutFullScreen();
    glutKeyboardFunc(keyboard);
    init();
    glutTimerFunc(25,timer,25);
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    glEnable(GL_DEPTH_TEST);
    glutMainLoop();
    return 0;
}


上一篇下一篇

猜你喜欢

热点阅读