转载:http://blog.csdn.net/haohan_meng/article/details/23154511
每当窗口的大小改变时,视口和裁剪区域必须重新定义,以适应新的窗口大小。只有这样,才能够使窗口中显示的图像保持原来的形状,而不发生扭曲。
1、 定义视口(窗口内部的渲染区域)
void glViewport(GLint x, GLint y, GLsizei width, GLsizeiheight);
其中,x,y参数指定了窗口内部视口的左下角位置,width和height参数指定了视口的大小(以屏幕像素为单位)。
2、 定义裁剪区域
对裁剪区域进行重新定义,使纵横比保持不变,窗口仍然维持在原来的形状。也就是根据新窗口大小的纵横比(像素之比,使用屏幕坐标系统),重新定义裁剪区域的纵横比(逻辑单位之比,使用笛卡尔坐标系统),使裁剪区域与视口的纵横比保持一致,这就是保持图像形状不变的关键所在。
我们在裁剪区域中使用了正投影:
void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far);
注:纵横比指的是垂直方向上一个单位长度内的像素数量与水平方向上一个单位长度内的像素数量之比。
/* 程序清单 2-2
*
*/
#include <glut.h>
// 绘制场景(显示回调函数)
void RenderScene()
{
// OpenGL命令,清除颜色缓冲区(使用当前设置的颜色)
glClear(GL_COLOR_BUFFER_BIT);
// 把当前绘图颜色设置为红色
glColor3f(1.0f, 0.0f, 0.0f);
// OpenGL命令,用当前的绘图颜色绘制一个填充矩形
glRectf(-25.0f, 25.0f, 25.0f, -25.0f);
// 刷新绘图命令,此时所有未执行的OpenGL命令被执行
glFlush();
}
// 设置渲染状态
void SetupRC()
{
// 设置用于清除窗口的颜色
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
}
// 当窗口大小改变时由GLUT函数库调用
void ChangeSize(GLsizeiw, GLsizei h)
{
//
GLfloat aspectRatio;
// 防止被0所除
if (0 == h){
h = 1;
}
// 设置视口为窗口的大小
glViewport(0, 0, w, h);
// 选择投影矩阵,并重置坐标系统
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// 计算窗口的纵横比(像素比)
aspectRatio = (GLfloat) w / (GLfloat) h;
// 定义裁剪区域(根据窗口的纵横比,并使用正投影)
if (w <=h) {// 宽 < 高
glOrtho(-100.0, 100.0, -100 /aspectRatio, 100 / aspectRatio, 1.0, -1.0);
} else {// 宽 > 高
glOrtho(-100.0 * aspectRatio, 100.0 *aspectRatio, -100.0, 100.0, 1.0, -1.0);
}
// 选择模型视图矩阵,并重置坐标系统
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char *argv[])
{
// 传递命令行参数,并对GLUT函数库进行初始化
glutInit(&argc, argv);
// 设置创建窗口时的显示模式(单缓冲区、RGBA颜色模式)
glutInitDisplayMode(GLUT_SINGLE |GLUT_RGBA);
// 创建窗口
glutCreateWindow("GLRect");
// 设置显示回调函数
glutDisplayFunc(RenderScene);
// 设置当窗口的大小发生变化时的回调函数
glutReshapeFunc(ChangeSize);
// 设置渲染状态
SetupRC();
// 启动GLUT框架的运行,一经调用便不再返回,直到程序终止
glutMainLoop();
return 0;
}
程序运行的结果如图所示:
窗口大小1
窗口大小2