2014-09-25 75 views
1

我想讓我的對象旋轉取決於哪個軸是想要的(通過按x,y,z),然後用同一個鍵開始/停止rotaion。這裏是我的代碼:使用鍵盤旋轉 - 過剩/ OpenGL

#include <glut.h> 
#include <stdio.h> 

static GLfloat spin = 0.0; 

void init(void){ 
glClearColor(0.0, 0.0, 0.0, 0.0); 
glShadeModel(GL_SMOOTH); 
} 

void action(void) 
{ 

} 


void display(void) 
{ 
glClear(GL_COLOR_BUFFER_BIT); 
glPushMatrix(); 


glBegin(GL_LINE_LOOP); 
glColor3f(1.00, 0.00, 0.00); 
glVertex3f(0.00, 0.00, 0.00); 
glVertex3f(0.00, 0.00, -1.00); 
glVertex3f(0.50, 0.00, -1.00); 
glVertex3f(0.75, 0.0, -0.75); 
glVertex3f(0.25, 0.25, -1.0); 
glVertex3f(0.50, 0.50, -0.50); 

glColor3f(0.00, 1.00, 0.00); 
glVertex3f(0.00, 0.00, 0.00); 
glVertex3f(0.00, 0.00, 1.00); 
glVertex3f(0.50, 0.00, 1.00); 
glVertex3f(0.75, 0.0, 0.75); 
glVertex3f(0.25, 0.25, 1.0); 
glVertex3f(0.50, 0.50, 0.50); 

glEnd(); 

glPopMatrix(); 
glutSwapBuffers(); 
glFlush(); 
} 

//spin function 
void spinDisplay(void){ 
spin = spin + 0.02; 
if (spin > 360.0) 
    spin = spin - 360.0; 
glutPostRedisplay(); 
} 


void reshape(int w, int h) 
{ 
glViewport(0, 0, (GLsizei)w, (GLsizei)h); 
glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
glFrustum(-1.0, 1.0, -1.0, 1.0, 0.5, 15.0); 
glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 
gluLookAt(1.5, 1.5, 1.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); 

} 


//keyboard event handler 
void keyboard(unsigned char key, int x, int y) 
{ 
switch (key) 
{ 
case 27: // Escape key 
    exit(0); 
    break; 
case 'x': 
    glRotatef(spin, 1.0, 0.0, 0.0); 
    break; 
case 'y': 
    glRotatef(spin, 0.0, 1.0, 0.0); 
    break; 
case 'z': 
    glRotatef(spin, 0.0, 0.0, 1.0); 
    break; 
case 'r': 
    glutIdleFunc(action); 
    break; 
} 
glutPostRedisplay(); 
} 


void mouse(int button, int state, int x, int y){ 
switch (button){ 
case GLUT_LEFT_BUTTON: 
    if (state == GLUT_DOWN) 
     glutIdleFunc(spinDisplay); 
    break; 
case GLUT_RIGHT_BUTTON: 
    if (state == GLUT_DOWN) 
     glutIdleFunc(NULL); 
    break; 
default: 
    break; 
} 
} 

int main(int argc, char** argv) 
{ 
glutInit(&argc, argv); 
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); 
glutInitWindowSize(500, 500); 
glutInitWindowPosition(100, 100); 
glutCreateWindow(argv[0]); 
init(); 
glutReshapeFunc(reshape); 
glutDisplayFunc(display); 
glutMouseFunc(mouse); 
glutKeyboardFunc(keyboard); 
glutIdleFunc(action); 
glutMainLoop(); 
return 0; 
} 

我在鍵盤功能,我想,但我想知道glRotatef每個鍵 - 也就是說,它是否屬於那裏。我創建了函數操作,我打算使用它來調用glutIdleFunc(),但我不確定如何將旋轉合併到它中。即使我可以對如何/爲什麼我的鍵盤調用不正確做出澄清,那也是非常棒的!

+1

我會建議看看[this](http://www.lighthouse3d.com/tutorials/glut-tutorial/animation/)和[this](http://www.lighthouse3d.com/tutorials/glut-教程/鍵盤/)教程。實際上,該頁面上的所有教程都非常有用。 – vesan 2014-09-26 01:28:41

+0

或這些教程:http://ogldev.atspace.co.uk/ – StarShine 2014-09-26 09:46:16

回答

4

保持狀態

您想要將當前的旋轉狀態寫入某個變量。所以當你想畫你的場景時,它會被知道。

struct rot_state { 
    bool rotating; // animation/movement happening 
    float x,y,z;  // current rotation values 
    int current_axis; // 0 for x, 1 for y, 2 for z 
} 

該狀態保持當前的旋轉狀態,程序可以在該狀態下工作。

動畫

glutIdleFunc做了所有在這個例子中,通過增加(動畫)正確的軸app_state.x += increment; 轉運蛋白調用是在每次開機時無關和處理循環的工作時間。所以它被用作動畫邏輯的門,然後強制重畫框架。

儘管它可以做得更好,但我並不想掩蓋原始代碼。

顯示

當顯示幀你可以使用你已經擁有並應用旋轉的infromation。

glRotatef(app_state.x, 1, 0, 0); 
glRotatef(app_state.y, 0, 1, 0); 
glRotatef(app_state.z, 0, 0, 1); 

代碼

#include <glut.h> 
#include <stdio.h> 

struct rot_state { 
    bool rotating; // animation/movement happening 
    float x,y,z;  // current rotation values 
    int current_axis; // 0 for x, 1 for y, 2 for z 
} app_state; 

void init(void){ 
    // Setting up initial app state 
    app_state.rotating = false; 
    app_state.x = app_state.y = app_state.z = 0.0f; 
    app_state.current_axis = 0; 

    glClearColor(0.0, 0.0, 0.0, 0.0); 
    glShadeModel(GL_SMOOTH); 
} 

void action(void) 
{ 
    // Animate the rotation 
    float increment = 1.0f; 
    switch (app_state.current_axis) 
    { 
    case 0: 
     app_state.x += increment; 
     break; 
    case 1: 
     app_state.y += increment; 
     break; 
    case 2: 
     app_state.z += increment; 
     break; 
    default: 
     break; 
    } 

    glutPostRedisplay(); 
} 


void display(void) 
{ 
    glClear(GL_COLOR_BUFFER_BIT); 
    glPushMatrix(); 

    // Apply the rotations 
    glRotatef(app_state.x, 1, 0, 0); 
    glRotatef(app_state.y, 0, 1, 0); 
    glRotatef(app_state.z, 0, 0, 1); 

    glBegin(GL_LINE_LOOP); 
    glColor3f(1.00, 0.00, 0.00); 
    glVertex3f(0.00, 0.00, 0.00); 
    glVertex3f(0.00, 0.00, -1.00); 
    glVertex3f(0.50, 0.00, -1.00); 
    glVertex3f(0.75, 0.0, -0.75); 
    glVertex3f(0.25, 0.25, -1.0); 
    glVertex3f(0.50, 0.50, -0.50); 

    glColor3f(0.00, 1.00, 0.00); 
    glVertex3f(0.00, 0.00, 0.00); 
    glVertex3f(0.00, 0.00, 1.00); 
    glVertex3f(0.50, 0.00, 1.00); 
    glVertex3f(0.75, 0.0, 0.75); 
    glVertex3f(0.25, 0.25, 1.0); 
    glVertex3f(0.50, 0.50, 0.50); 

    glEnd(); 

    glPopMatrix(); 
    glutSwapBuffers(); 
    glFlush(); 
} 

void reshape(int w, int h) 
{ 
    glViewport(0, 0, (GLsizei)w, (GLsizei)h); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glFrustum(-1.0, 1.0, -1.0, 1.0, 0.5, 15.0); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    gluLookAt(1.5, 1.5, 1.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); 

} 

//keyboard event handler 
void keyboard(unsigned char key, int x, int y) 
{ 
    switch (key) 
    { 
    case 27: // Escape key 
     exit(0); 
     break; 
    case 'x': 
     app_state.current_axis = 0; 
     break; 
    case 'y': 
     app_state.current_axis = 1; 
     break; 
    case 'z': 
     app_state.current_axis = 2; 
     break; 
    case 'r': 
     app_state.rotating ^= 1; 
     glutIdleFunc(app_state.rotating ? action : NULL); 
     break; 
    } 
    glutPostRedisplay(); 
} 


int main(int argc, char** argv) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); 
    glutInitWindowSize(500, 500); 
    glutInitWindowPosition(100, 100); 
    glutCreateWindow(argv[0]); 
    init(); 
    glutReshapeFunc(reshape); 
    glutDisplayFunc(display); 
    glutKeyboardFunc(keyboard); 
    glutIdleFunc(action); 
    glutMainLoop(); 
    return 0; 
} 

這應該讓你開始。

考慮

請記住,這迫使那些本地的對象特定軸的旋轉。如果你想對旋轉有更多的控制,你會想看看一些四元數 - >矩陣旋轉。這裏有一篇關於Wiki的文章,還有更多關於互聯網的文章。

此外,動畫方案被放入閒置功能,並且您不能直接控制動畫的速度。它完全取決於應用程序的幀率。還有大量關於如何實現主循環的精彩文章,以便您的邏輯/時間可以精確處理。

+0

很好的回答,希望這不會結束與您的代碼只是複製粘貼,這裏有很多有用的信息。 – vesan 2014-09-26 12:04:06