2012-03-20 44 views
1

我做了(平移,旋轉,平移),但它仍圍繞原點旋轉。我所做的只是當你按下r鍵時,這個技巧就開始了(翻譯,旋轉,翻譯)。其結果是,它仍然是圍繞原點OpenGL,圍繞一個點的旋轉在原點附近仍然不起作用

#include <gl/glut.h> 

void OnKeyPress(unsigned char key, int x, int y) 
{ 
    if (key == 27) 
     exit(0); 
    switch(key) 
    { 
    case 'r': 
    case 'R': 
     // trick start here ********************* 
     glTranslatef(-60,-20,0); 
     glRotatef(10, 0, 0, 1); 
     glTranslatef(60, 20, 0); 
     glutPostRedisplay(); 
     break; 
    }; 
} 

void OnDisplay() 
{ 
    glClear(GL_COLOR_BUFFER_BIT); 
    glColor3f(0.0f,0.5f,1.0f); 

    glBegin(GL_TRIANGLES); 
    glVertex2f(20, 20); 
    glVertex2f(60, 20); 
    glVertex2f(20, 100); 
    glEnd(); 
    glFlush(); 
} 

int main(int argc, char *argv[]) 
{ 
    glutInit(&argc, argv);  
    glutInitDisplayMode(GLUT_RGBA); 
    glutInitWindowPosition(100, 100); 
    glutInitWindowSize(800, 600); 
    glutCreateWindow("OpenGL Lab1"); 
    glutDisplayFunc(OnDisplay); 
    glutKeyboardFunc(OnKeyPress); 

    glClearColor(1.0, 1.0, 1.0, 0.0);  
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    gluOrtho2D(-100, 100, -100, 100); 

    glutMainLoop(); 

    return 0; 
} 
+0

有什麼結果呢?此外,作爲一個側面說明看看'gluLookAt'。 – jli 2012-03-20 22:03:54

+0

結果是,它仍在原點附近旋轉 – YoungSalafi 2012-03-20 22:09:37

+2

@YoungSalafi不要摧毀你的問題。我已經回滾了。你標記的答案是正確的。這應該足以說明問題。 – Bart 2012-03-21 17:37:38

回答

4

你需要切換您的glTranslate調用的順序,因爲做最後的改造是應用到頂點的第一個旋轉。看到,每個轉換都是一個矩陣,它的當前矩陣與其相乘。然後將得到的矩陣乘以頂點以確定其最終位置。

所以,如果您有:

glTranslatef(-60,-20,0); (T1) 
glRotatef(10, 0, 0, 1); (R) 
glTranslatef(60, 20, 0); (T2) 

,也有一箇舊的矩陣莫離前一幀存儲,你將有:

M = (((Mo * T1) * R) * T2) 
到底

,這個M由各自乘以頂點Vo確定其最終位置:

V = M * Vo 

矩陣乘法是不可交換的,但它們是相關聯的,因此,括號順序並不重要,所有這些轉換是數學上等價於:

V = Mo * T1 * R * (T2 * Vo) 

注意,(T2 * VO)是T2(你最後一次轉換)轉換的頂點。如果我們把它叫做V1,我們有:

V = Mo * T1 * (R * V1) 

看到,T2轉化V1,你原來的頂點,現在又由(R * V1)的旋轉R被轉化,導致另一個頂點,現在翻譯,然後旋轉。繼續解決從右到左的表達式問題,您將按照與OpenGL代碼中「調用」的順序相反的順序將所有變換應用到頂點。

我假設你知道爲什麼你必須翻譯 - 旋轉 - 非翻譯以便圍繞你想要的旋轉進行旋轉,但是當你說「東西」在你的原點周圍旋轉時你弄錯了碼。事實上,如果你注意,你會注意到它正在旋轉點(-60,-20)。最後,您並沒有使用模型視圖矩陣,而是使用透視矩陣進行所有轉換(順便說一句,因爲您沒有像每個框架那樣重新設置它,就像大多數應用程序一樣)。你不應該這樣做,而應該使用GL_MODELVIEW來進行這種轉換。嘗試完成你的初始化函數:

... 
    Set_Transformations(); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    glutMainLoop(); 
} 
+0

你所指的是已經在Set_Transformations()函數中 – YoungSalafi 2012-03-20 22:13:46

+0

在最初發布的版本中,Set_Transforms()只處理GL_PROJECTION,而不處理GL_MODELVIEW。 – lvella 2012-03-20 23:05:02

+0

啊..很酷的thx我的壞 – YoungSalafi 2012-03-21 02:39:28

1

翻轉的(-, rot, +)它周圍(+, rot, -)代替:

#include <gl/glut.h> 

int angle = 0; 
void OnKeyPress(unsigned char key, int x, int y) 
{ 
    if (key == 27) 
     exit(0); 
    switch(key) 
    { 
    case 'r': 
    case 'R': 
     angle += 10; 
     glutPostRedisplay(); 
     break; 
    }; 
} 

void OnDisplay() 
{ 
    glClear(GL_COLOR_BUFFER_BIT); 
    glColor3f(0.0f,0.5f,1.0f); 

    glClearColor(1.0, 1.0, 1.0, 0.0);  
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    gluOrtho2D(-100, 100, -100, 100); 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    // trick start here ********************* 
    glTranslatef(60, 20, 0); 
    glRotatef(angle, 0, 0, 1); 
    glTranslatef(-60,-20,0); 

    glBegin(GL_TRIANGLES); 
    glColor3ub(0,0,255); 
    glVertex2f(20, 20); 
    glColor3ub(255,0,0); 
    glVertex2f(60, 20); 
    glColor3ub(0,0,255); 
    glVertex2f(20, 100); 
    glEnd(); 

    glFlush(); 
} 

int main(int argc, char *argv[]) 
{ 
    glutInit(&argc, argv);  
    glutInitDisplayMode(GLUT_RGBA); 
    glutInitWindowPosition(100, 100); 
    glutInitWindowSize(800, 600); 
    glutCreateWindow("OpenGL Lab1"); 
    glutDisplayFunc(OnDisplay); 
    glutKeyboardFunc(OnKeyPress); 

    glutMainLoop(); 

    return 0; 
}