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 }

 

posted @ 2016-07-06 16:15  追寻1024的程序猿  阅读(38101)  评论(0编辑  收藏  举报