使用OpenGL的几何变换
一. OpenGl几何变换的介绍
几何变换是指三维场景中的物体运动的变化,包括物体的平移、旋转、和缩放。
在OpenGL中,可以使用下面三个函数便捷地实现简单图形平移、旋转、缩放变换的功能:
glTranslatef(Type x, Type y, Type z);
glRotatef(Type angle, Type x, Type y, Type z);
glScalef(Type x,Type y,Type z);
虽然直接使用OpenGL中的矩阵操作函数也可以实现几何变换,但是使用变换函数变换的速度要快很多。
二. 平移变换
glTranslatef(Type x, Type y, Type z);
作用:使坐标系沿着 X, Y 和 Z 轴移动。
参数说明:x、y、z分别指定平移向量的x、y、z方向的坐标量。
注意在glTranslatef(x, y, z)中,当您移动的时候,您并不是相对屏幕中心移动,而是相对与当前所在的屏幕位置,将你绘点坐标的原点在当前原点的基础上平移一个(x,y,z)向量。
三. 旋转变换
glRotatef(Type angle, Type x, Type y, Type z);
作用:将坐标系绕向量(x,y,z)产生一个angle角度的旋转,满足右手定则。
如矩阵模式是GL_MODELVIEW或GL_PROJECTION时,函数glRotate()调用后所有绘制的对象将被旋转。如果(x,y,z)朝向用户方向,旋转将按逆时针方向进行。
函数glRotate()旋转的是坐标系而不是物体,如果参数angle为零,则该函数不产生任何效果。
四. 缩放变换
glScalef(Type x,Type y,Type z);
作用:将坐标系进行相应倍数的缩放。
参数:x,y,z分别为模型在x,y,z轴方向的缩放比。参数也可取负数,也可以理解为先关于某轴翻转180°,再缩放。
注意:一个为0的缩放因子将把所有对象的坐标值变为零,因此在使用时一定要小心。
五. 另外介绍一个很实用的函数:
glLoadIdentity()
将当前的用户坐标系的原点移到了屏幕中心:类似于一个复位操作。
六. 实例:键盘控制三角形的变换
说明:通过键盘操作,完成一个三角形的平移和缩放。
比如左键是向左平移,右键向右平移;上键变大,下键缩小。
R是绕着屏幕中心旋转。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<gl/glut.h> 2 3 void triangle(void) 4 { 5 glClear(GL_COLOR_BUFFER_BIT); 6 glBegin(GL_TRIANGLES); 7 glColor3f(1.0,0.0,0.0); 8 glVertex2f(0.0,0.2); 9 glVertex2f(0.1732,-0.1); 10 glVertex2f(-0.1732,-0.1); 11 glVertex2f(0.0,0.2); 12 glEnd(); 13 glFlush(); 14 } 15 16 void keyboard(unsigned int key,int x,int y) 17 { 18 switch(key){ 19 case GLUT_KEY_LEFT: 20 glMatrixMode (GL_MODELVIEW); 21 glTranslatef (-0.1, 0.0, 0.0); 22 glutPostRedisplay(); 23 break; 24 case GLUT_KEY_RIGHT: 25 glMatrixMode (GL_MODELVIEW); 26 glTranslatef (0.1, 0.0, 0.0); 27 glutPostRedisplay(); 28 break; 29 case GLUT_KEY_UP: 30 glMatrixMode (GL_MODELVIEW); 31 glScalef (1.2, 1.2, 1.0); 32 glutPostRedisplay(); 33 break; 34 case GLUT_KEY_DOWN: 35 glMatrixMode (GL_MODELVIEW); 36 glScalef (0.8, 0.8, 1.0); 37 glutPostRedisplay(); 38 break; 39 } 40 } 41 42 void keyboardR(unsigned char key,int x,int y) 43 { 44 switch(key) 45 { 46 case 'r': 47 glMatrixMode (GL_MODELVIEW); 48 glRotatef (45, 0, 0, -1); 49 glutPostRedisplay(); 50 break; 51 } 52 } 53 54 55 int main(int argc,char *argv[]) 56 { 57 glutInit(&argc,argv); 58 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB ); 59 glutInitWindowSize(600, 600); 60 glutCreateWindow("键盘控制三角形变换"); 61 glutDisplayFunc(&triangle); 62 glutKeyboardFunc(keyboardR); 63 glutSpecialFunc(keyboard); 64 glutMainLoop(); 65 return 0; 66 }
七. 实例:太阳地球月亮
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <gl/glut.h> // OpenGL toolkit 2 #include <math.h> 3 4 // Lighting values 5 GLfloat whiteLight[] = { 0.2f, 0.2f, 0.2f, 1.0f }; 6 GLfloat sourceLight[] = { 0.8f, 0.8f, 0.8f, 1.0f }; 7 GLfloat lightPos[] = { 0.0f, 0.0f, 0.0f, 1.0f }; 8 9 // Called to draw scene 10 void RenderScene(void) 11 { 12 // Earth and Moon angle of revolution 13 static float fMoonRot = 0.0f; 14 static float fEarthRot = 0.0f; 15 16 // Clear the window with current clearing color 17 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 18 19 // Save the matrix state and do the rotations 20 glMatrixMode(GL_MODELVIEW); 21 glPushMatrix(); 22 23 // Translate the whole scene out and into view 24 glTranslatef(0.0f, 0.0f, -300.0f); 25 26 // Set material color, Red 27 // Sun 28 glDisable(GL_LIGHTING); 29 glColor3ub(255, 255, 0); 30 glutSolidSphere(15.0f, 30, 17); 31 glEnable(GL_LIGHTING); 32 33 // Move the light after we draw the sun! 34 glLightfv(GL_LIGHT0,GL_POSITION,lightPos); 35 36 // Rotate coordinate system 37 glRotatef(fEarthRot, 0.0f, 1.0f, 0.0f); 38 39 // Draw the Earth 40 glColor3ub(0,0,255); 41 glTranslatef(105.0f,0.0f,0.0f); 42 glutSolidSphere(15.0f, 30, 17); 43 44 // Rotate from Earth based coordinates and draw Moon 45 glColor3ub(200,200,200); 46 glRotatef(fMoonRot,0.0f, 1.0f, 0.0f); 47 glTranslatef(30.0f, 0.0f, 0.0f); 48 fMoonRot+= 15.0f; 49 if(fMoonRot > 360.0f) 50 fMoonRot = 0.0f; 51 glutSolidSphere(6.0f, 30, 17); 52 53 // Restore the matrix state 54 glPopMatrix(); // Modelview matrix 55 // Step earth orbit 5 degrees 56 fEarthRot += 5.0f; 57 if(fEarthRot > 360.0f) 58 fEarthRot = 0.0f; 59 // Show the image 60 glutSwapBuffers(); 61 } 62 63 // This function does any needed initialization on the rendering 64 // context. 65 void SetupRC() 66 { 67 // Light values and coordinates 68 glEnable(GL_DEPTH_TEST); // Hidden surface removal 69 glFrontFace(GL_CCW); // Counter clock-wise polygons face out 70 glEnable(GL_CULL_FACE); // Do not calculate inside of jet 71 72 // Enable lighting 73 glEnable(GL_LIGHTING); 74 75 // Setup and enable light 0 76 glLightModelfv(GL_LIGHT_MODEL_AMBIENT,whiteLight); 77 glLightfv(GL_LIGHT0,GL_DIFFUSE,sourceLight); 78 glLightfv(GL_LIGHT0,GL_POSITION,lightPos); 79 glEnable(GL_LIGHT0); 80 81 // Enable color tracking 82 glEnable(GL_COLOR_MATERIAL); 83 84 // Set Material properties to follow glColor values 85 glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); 86 87 // Black blue background 88 glClearColor(0.0f, 0.0f, 0.0f, 1.0f ); 89 } 90 91 void TimerFunc(int value) 92 { 93 glutPostRedisplay(); 94 glutTimerFunc(100, TimerFunc, 1); 95 } 96 97 void ChangeSize(int w, int h) 98 { 99 GLfloat fAspect; 100 // Prevent a divide by zero 101 if(h == 0) 102 h = 1; 103 // Set Viewport to window dimensions 104 glViewport(0, 0, w, h); 105 106 // Calculate aspect ratio of the window 107 fAspect = (GLfloat)w/(GLfloat)h; 108 109 // Set the perspective coordinate system 110 glMatrixMode(GL_PROJECTION); 111 glLoadIdentity(); 112 113 // field of view of 45 degrees, near and far planes 1.0 and 425 114 gluPerspective(45.0f, fAspect, 1.0, 425.0); 115 116 // Modelview matrix reset 117 glMatrixMode(GL_MODELVIEW); 118 glLoadIdentity(); 119 } 120 121 int main(int argc, char* argv[]) 122 { 123 glutInit(&argc, argv); 124 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); 125 glutInitWindowSize(800, 600); 126 glutCreateWindow("Earth/Moon/Sun System"); 127 glutReshapeFunc(ChangeSize); 128 glutDisplayFunc(RenderScene); 129 glutTimerFunc(250, TimerFunc, 1); 130 SetupRC(); 131 glutMainLoop(); 132 return 0; 133 }
运行结果: