当我按下一个键时,如何让这个球体围绕另一个球体旋转?

时间:2015-11-19 10:42:42

标签: c opengl

我是OpenGL的新手,我正试图模仿行星系统。我有一个地球和太阳。当我按R时,我希望地球在轴上旋转,当我按T时,我希望围绕太阳旋转。我试过以下但没有成功。这是迄今为止的代码:

#include <GL/glut.h>

int angle=1;
int x,y,z=0;
int axis=0;

void init(void){
 glClearColor(0.0,0.0,0.0,0.0);
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 }
void drawEarth(void){
  glutWireSphere(0.5,30,30);
 }

void idleFunc(){
 angle++;
 glutPostRedisplay();
 }

 void key(unsigned char key, int x, int y){
if (key=='R'){
 idleFunc(); // How can I make this function run ONLY when I press R?
 //Or how can I make my earth continuosly rotating when I press R? 
 glutPostRedisplay();          
 } else 
 if(key=='T'){
 //How can I make it revolve around the sun when I press key T?
 //I have tried glTranslate(x,y,z); with no success
 glutPostRedisplay();
 }

 }
void display(void){
 glClearColor(0.05,0.05,0.5,0.0);
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 ///////////////////////
 glColor3f(0.03,0.05,0.09);
 glPushMatrix();
 glMatrixMode(GL_MODELVIEW);
 glRotatef(angle, 1.0,1.0,1.0); //Is this making it rotate about its axis?
 drawEarth(); //Draw Earth
 glPopMatrix();
 /////////////////////////////////////
 glPushMatrix();
 glTranslatef(.7,.7,.7);
 glColor3f(1.0,1.0,1.0);
 glutWireSphere(0.2,50,50); //Sun
 glPopMatrix();

 glFlush();

 }
int main(int argc, char **argv){
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_SINGLE);
  glutInitWindowPosition(10,10);
  glutInitWindowSize(400,400);
  init();
  glutCreateWindow("Planets");
  glutDisplayFunc(display);
  glutKeyboardFunc(key);
  glutIdleFunc(idleFunc);

  glFlush();
  glutMainLoop();

  }

问题:

我怎样才能让地球围绕太阳旋转?感谢。

PS:我在代码中添加了一些注释,让我感到困惑。

1 个答案:

答案 0 :(得分:0)

设置定时器/空闲回调,使其始终运行,但只有在设置了相应的标志(键盘回调切换)时才更新太阳/轴角:

#include <GL/glut.h>

bool animateAxis = false;
bool animateSun = false;
void key(unsigned char key, int x, int y)
{
    if( key == 'r' )    animateAxis = !animateAxis;
    if( key == 't' )    animateSun = !animateSun;
}

int angleAxis = 0;
int angleSun = 0;
void update()
{
    if( animateAxis )   angleAxis += 3;
    if( animateSun )    angleSun += 1;
    angleAxis = angleAxis % 360;
    angleSun = angleSun % 360;
}

void display(void)
{
    glClearColor(0.05,0.05,0.2,0.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    const double w = glutGet( GLUT_WINDOW_WIDTH );
    const double h = glutGet( GLUT_WINDOW_HEIGHT );
    gluPerspective( 60.0, w / h, 0.1, 100.0 );

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    gluLookAt
        (
        30, 30, 30,
        0, 0, 0,
        0, 0, 1
        );

    // sun
    glColor3ub( 255, 255, 0 );
    glutWireSphere( 5, 8, 8 );

    // earth
    glPushMatrix();

    // rotate around sun
    glRotatef( angleSun, 0, 0, 1 );

    glTranslatef( 20, 0, 0 );

    // rotate around axis
    glRotatef( angleAxis, 0, 0, 1 );

    glColor3ub( 31, 117, 254 );
    glutWireSphere( 2, 8, 8 );
    glPopMatrix();

    glutSwapBuffers();
}

void timer( int value )
{
    update();
    glutPostRedisplay();
    glutTimerFunc( 16, timer, 0 );
}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE);
    glutCreateWindow("Planets");
    glutDisplayFunc(display);
    glutKeyboardFunc(key);
    glutTimerFunc( 0, timer, 0 );
    glutMainLoop();
}