2015-11-19 2 views
0

Я новичок в 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: Я добавил несколько комментариев в код, где я запутался.

ответ

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(); 
} 
Смежные вопросы