OpenGL的glScalef缩放变换函数详解

glScalef是openGL中的模型缩放函数,就是把当前矩阵与一个表示延各个轴对物体进行拉伸、压缩、反射的矩阵相乘。这个物体的每个点的x,y,z坐标与对应的xyz参数相乘。

先看函数定义
void glScalef(GLfloat x,
         GLfloat y,
         GLfloat z);

参数x,y,z分别为模型在x,y,z轴方向的缩放比。

例如:
如glScalef(2.0f,3.0f,4.0f);将模型按x,y,z方向分别拉伸了2,3,4倍。
参数也可取负数,也可以理解为先关于某轴翻转180°,再缩放;
如glScalef(1.0f,1.0f,-1.0f);将模型关于z轴翻转了180°(即关于xy轴所在平面对称);
如glScalef(1.0f,1.0f,-2.0f);将模型关于-z轴拉伸2倍。

 

附上代码例子:

  1 #include <stdio.h>
  2 #include <Windows.h>
  3 #include <gl/glut.h>
  4 
  5 /*
  6  功能描述:使用OpenGL简单画一个虚心水壶
  7  缩放变换函数glScalef
  8  */
  9 
 10 //输出模式,0-单缓存模式;非0双缓存模式
 11 #define OUTPUT_MODE 1
 12 
 13 float scale = 0.0;
 14 bool add = true;
 15 
 16 unsigned char axle = 'x';
 17 
 18 void init(void)
 19 {
 20     //glClearColor函数设置好清除颜色,glClear利用glClearColor函数设置好的当前清除颜色设置窗口颜色
 21     glClearColor(1.0, 1.0, 0.8, 1.0);
 22 }
 23 
 24 void display(void)
 25 {
 26     printf("scale=%f, axle=%c\n", scale, axle);
 27     glClear(GL_COLOR_BUFFER_BIT);
 28 
 29     //配置缩放比例大小scale
 30     scale = (add ? scale + 0.1 : scale - 0.1);
 31     if (scale >= 2.0)
 32     {
 33         add = false;
 34     } else if (scale <= 0.0) {
 35         add = true;
 36     }
 37     //开始绘画
 38     glPushMatrix();
 39     {
 40         if (axle == 'x') {
 41             glScalef(scale, 1, 1);
 42         } else if (axle == 'y') {
 43             glScalef(1, scale, 1);
 44         } else if (axle == 'z') {
 45             glScalef(1, 1, scale);
 46         } else {            
 47             glScalef(scale, scale, scale);
 48         }
 49         glColor3f (1.0, 0.0, 1.0); //画笔梅红色
 50         glBegin(GL_POLYGON);
 51         glVertex2f(-0.2, -0.2);
 52         glVertex2f(-0.2, 0.2);
 53         glVertex2f(0.2, 0.2);
 54         glVertex2f(0.2, -0.2);
 55         glEnd();
 56     }
 57     glPopMatrix();
 58     
 59     glLoadIdentity();  //加载单位矩阵
 60     glColor3f (0.0, 0.0, 1.0); //画笔蓝色
 61     //--------画直线START--------
 62     //画直线
 63     glBegin(GL_LINES);
 64     glVertex2f(-0.5, 0);
 65     glVertex2f(0.5, 0);
 66     glVertex2f(0, 0.5);
 67     glVertex2f(0, -0.5);
 68     glEnd();
 69     //--------画直线E N D--------
 70         
 71     if (OUTPUT_MODE == 0) {
 72         glFlush();//单缓存GLUT_SINGLE时使用
 73     } else {
 74         glutSwapBuffers();//因为使用的是双缓存GLUT_DOUBLE,所以这里必须要交换缓存才会显示
 75     }
 76 
 77     Sleep(50);
 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 void keyboard(unsigned char key, int x, int y)
100 {
101     switch (key) {
102         case 'x':
103         case 'X':
104             axle = 'x';
105             glutPostRedisplay();
106             break;
107         case 'y':
108         case 'Y':
109             axle = 'y';
110             glutPostRedisplay();
111             break;
112         case 'z':
113         case 'Z':
114             axle = 'z';
115             glutPostRedisplay();
116             break;
117         case 'a':
118         case 'A':
119             axle = 'a';
120             glutPostRedisplay();
121             break;
122         default:
123             break;
124     }
125     printf("按键%c\n", key);
126 }
127 
128 int main(int argc, char *argv[])
129 {
130     printf("可通过按键xyza控制图形按哪一轴缩放\n");
131     glutInit(&argc, argv);
132     
133     glutInitDisplayMode(GLUT_RGB | (OUTPUT_MODE == 0 ? GLUT_SINGLE : GLUT_DOUBLE));
134     glutInitWindowPosition(100, 100);
135     glutInitWindowSize(400, 400);
136     glutCreateWindow("第一个 OpenGL 程序");
137 
138     init();
139     glutDisplayFunc(&display);
140     glutIdleFunc(display);  //设置不断调用显示函数
141     glutReshapeFunc(reshape);
142     glutKeyboardFunc(keyboard);
143     glutMainLoop();
144     return 0;
145 }

按x轴缩放:

 

按y轴缩放:

 

按z轴缩放:

 

按xyz轴缩放:

 

posted @ 2016-07-07 14:57  追寻1024的程序猿  阅读(16539)  评论(0编辑  收藏  举报