窗口与显示主要与三个量有关:世界坐标,窗口大小和视口大小。围绕这些量共有4个函数:
glutInitWindowPosition(int x, int y)//定义窗口位置
glViewport(int x, int y, GlLsizei w, Glsizei h)//定义视口大小
glutInitWindowSize(int width, int height)//定义窗口大小
gluOrtho2D(x_mix, x_max, y_mix, y_max)//截取图像大小
世界坐标:
固有坐标系,不可改变,没有偏差。时世界坐标系(世界坐标空间)的坐标。
gluOrtho2D(x_mix, x_max, y_mix, y_max)
用于截取世界坐标系相应区域。在世界坐标系中以从(x_mix, x_max)到(y_mix, y_max)的直线为对角线的矩形部分截取图像,该截图可以被用于显示。
窗口大小:
glutInitWindowSize(int width, int height)
width:宽、横;
height:高、竖;
部分电脑屏幕有1920*1080个像素(比如说我的),该语句用于创建一个width*height个像素的窗口
以上两个值之间无关。
视口大小:
截图不会适配窗口,不能在窗口中直接显示,而是需要在视口中拉伸并显示。视口则是截图在窗口中显示的区域,即,图像只在视口中显示。视口用于把截图和窗口联系起来。
glViewport(int x, int y, GlLsizei w, Glsizei h)
可以定义截取的图像在窗口的哪一部分显示。
(x, y)是视口左下角在窗口里位置的坐标;(0, 0)是窗口左下角;w、h是视口的宽和高。截图就在这一部分显示。
“视口”在有些地方也叫“视区”。
另外:
窗口在屏幕中的位置由
glutInitWindowPosition(int x, int y)
确定,
(x, y)是窗口左上角的位置。
以下是图例:
void display()
{
……
glBegin(GL_TRIANGLES);
glVertex2f(0, 0);
glVertex2f(0, 100);
glVertex2f(100, 50);
glEnd();
……
}//画出了一个三角形
这个三角形的坐标值很大,默认的窗口只能显示横轴、纵轴[-1, 1]区间的图形,所以根本显示不下,只能显示三角形的一部分。通过以下操作来让三角形显示出来。
void reshape(GLsizei w, GLsizei y)
{
……
gluOrtho2D(-50, 150, -50, 150);//设置截图大小
glViewport(0, 0, w, h);//设置视口大小
……
}
用gluOrtho2D截取出图形,参数不能太小,不用太大,要显示完整的三角形就必须要比三角形大,比三角形稍大些即可。这样就在世界坐标系中截出了一张200*200的图(区域),包含三角形和空白部分(或者说应该叫空黑部分?算了,叫做空余部分,也就是因为没有绘制图形而和清屏颜色一样的部分)。
glViewport中的w和h分别是窗口的宽和高。这样做的目的在于可以将视口设置为窗口大小,相当于图像直接适配窗口且用整个窗口显示图像。由此可得:(三角形和空余部分)
若将glViewport的w设为原来的一半,则视口变为原来大小的一半,会使图像适配窗口的一半,可得:(瘦高三角、空余部分、未显示部分和我截图时画的红线,红线在窗口中央)
因为图像要拉伸适配视口,所以会产生形变。
注意:红线左右都有黑色的部分,但是意义不同。左侧的黑色部分是在世界坐标系中截取的空余部分;而右侧的黑色部分则是未显示任何图像的结果。
即,若截取图像的比例和视口比例了不同,则会产生形变。
即使视口大小与窗口大小不同,只要比例相同就不会形变,只是“未显示任何图像”的区域就多了。