OpenGL的glRotatef旋轉變換函數詳解
先看一下函數定義:
void glRotatef(GLfloat angle,
GLfloat x,
GLfloat y,
GLfloat z)
angle:為旋轉的角度,單位為度。
x,y,z:為對應xyz軸的布爾值變量。
重點是x,y,z表達的是什么意思呢?應該如何取值?
如果說x,y,z表達的是一個坐標(x,y,z),那么這個函數就說明了當前幾何圖形圍着這個坐標點旋轉。
但往哪個方向旋轉呢?所以很明顯,x,y,z表達的意思並不是坐標點,而是要圍繞哪個坐標軸旋轉。
即其實這里的x,y,z值相當於一個布爾值,0.0表示假,而非零參數則表示真。
所以如果你想讓當前的幾何圖形圍繞着z軸旋轉,那么x和y都設為0,而z設為非零值即可。
如果這里的x,y,z的值都設置為0.0,那么將圍繞着x軸旋轉。
還有一點需要注意,如果設置的旋轉值(x,y,z的值)為正數,那么旋轉的方向是逆時針的,如果旋轉值是負數,那么旋轉的方向是順時針的。
假設:glRotatef(45,1,0,0)
物體如何旋轉?
想象:從坐標(0,0,0)即原點,引出一條線到(1,0,0),用右手握住這條線.
這時,你會問,如何握?
右手大拇指指向(0,0,0)至(1,0,0)的方向才握。
另外四個手指的彎曲指向即是物體旋轉方向。
為什么是右手握住,而不是左手呢?
因為OpenGL是右手原則。
最后附上代碼供參考:
1 #include <stdio.h> 2 #include <gl/glut.h> 3 4 /* 5 功能描述:使用OpenGL簡單畫一個旋轉的三角形 6 旋轉變換函數glRotatef 7 */ 8 9 //輸出模式,0-單緩存模式;非0雙緩存模式 10 #define OUTPUT_MODE 1 11 12 //角度 13 int angle = 0; 14 15 int xyz[3] = {0, 0, 0}; 16 17 void display(void) 18 { 19 //printf("xyz={%d, %d, %d\n}", xyz[0], xyz[1], xyz[2]); 20 21 glClear(GL_COLOR_BUFFER_BIT); 22 23 24 glLoadIdentity(); 25 glRotatef(angle, xyz[0], xyz[1], xyz[2]); 26 27 glBegin(GL_TRIANGLES); 28 { 29 glVertex3f(0.0f, 0.0f, 0.0f); 30 glVertex3f(0.5f, 0.0f, 0.0f); 31 glVertex3f(0.0f, 0.5f, 0.0f); 32 } 33 glEnd(); 34 35 angle += 1; 36 angle %= 360; 37 38 if (OUTPUT_MODE == 0) { 39 glFlush();//單緩存GLUT_SINGLE時使用 40 } else { 41 glutSwapBuffers();//因為使用的是雙緩存GLUT_DOUBLE,所以這里必須要交換緩存才會顯示 42 } 43 } 44 45 //按鍵 46 void keyboard(unsigned char key, int x, int y) 47 { 48 switch (key) 49 { 50 case 'x': 51 case 'X': 52 xyz[0] = 1; 53 xyz[1] = xyz[2] = 0; 54 break; 55 case 'y': 56 case 'Y': 57 xyz[1] = 1; 58 xyz[0] = xyz[2] = 0; 59 break; 60 case 'z': 61 case 'Z': 62 xyz[2] = 1; 63 xyz[0] = xyz[1] = 0; 64 break; 65 case 'a': 66 case 'A': 67 xyz[0] = xyz[1] = xyz[2] = 0; 68 break; 69 case 'b': 70 case 'B': 71 xyz[0] = xyz[1] = xyz[2] = 1; 72 break; 73 default: 74 break; 75 } 76 printf("當前繞%c軸旋轉\n", key); 77 glutPostRedisplay(); 78 } 79 80 void reshape(int w, int h) 81 { 82 int offset = 50; 83 int dis = (w > h ? h : w) - offset * 2; 84 85 //配置顯示物體屏幕的大小 86 glViewport(offset, offset, (GLsizei)dis, (GLsizei)dis); 87 printf("reshape: w=%d, h=%d, dis=%d\n", w, h, dis); 88 89 glMatrixMode(GL_PROJECTION); 90 glLoadIdentity(); 91 92 glOrtho(-1.5, 1.5, -1.5, 1.5, 0, 10); 93 //gluOrtho2D(-1.5, 1.5, -1.5, 1.5); 94 95 glMatrixMode(GL_MODELVIEW); 96 glLoadIdentity(); 97 } 98 99 int main(int argc, char *argv[]) 100 { 101 printf("可通過按鍵xyzab控制圖形旋轉原點/軸\n"); 102 glutInit(&argc, argv); 103 104 glutInitDisplayMode(GLUT_RGB | (OUTPUT_MODE == 0 ? GLUT_SINGLE : GLUT_DOUBLE)); 105 glutInitWindowPosition(100, 100); 106 glutInitWindowSize(400, 400); 107 108 glutCreateWindow("第一個 OpenGL 程序"); 109 110 glutDisplayFunc(&display); 111 glutIdleFunc(display); //設置不斷調用顯示函數 112 glutReshapeFunc(reshape); 113 glutKeyboardFunc(&keyboard); 114 glutMainLoop(); 115 return 0; 116 }