美文网首页
OpenGL 真实感日地月系统

OpenGL 真实感日地月系统

作者: 善法 | 来源:发表于2018-10-12 10:30 被阅读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;
    }
    
    
    

    相关文章

      网友评论

          本文标题:OpenGL 真实感日地月系统

          本文链接:https://www.haomeiwen.com/subject/armxgftx.html