OpenGL的glRotatef旋转变换函数详解
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 }