窗口-视区变换
在将窗口中的图形信息送到视区去输出之前,必须进行坐标变换,即将用户坐标系的坐标值转化为设备坐标系的坐标值,即窗口-视区变换。
从窗口到视口的映射世界窗口用其左、上、右和下边界描述,分别是W.l,W.t,W.r和W.b。视口在屏幕窗口坐标系中描述,使用V.l,V.t,V.r,V.b,单位是像素。窗口到视口的映射是基于一个公式生成的,这个公式在世界窗口中对每个给定的点(x, y)都在窗口坐标系中生成一个点(sx, sy)。由于窗口映射到视口是“成比例”的,而“成比例”这样的要求迫使这种映射具有线性形式
sx = Ax + C
sy = By + D
其中A,B,C和D是常数。这四个常数中,A和B是用于缩放x和坐标,C和D则平移它们。根据几何学的知识,可以通过下面的公式来计算A,B,C和D四个常量
(sx - V.l)/(V.r - V.l) = (x - W.l)/(W.r - W.l)
得到
A = (V.r - V.l)/(W.r - W.l)
和
C = (V.l - A*W.l)
同样的,
B = (V.t - V.b)/(W.t - W.b), D = V.b - B*W.b
现在对窗口到视口变换做一下总结:
sx = Ax + C 和 sy = By + D
以及
A = (V.r - V.l)/(W.r - W.l), C = V.l - A*W.l
和
B = (V.t - V.b)/(W.t - W.b), D = V.b - B*W.b
进行程序设计的过程中,经过投影后得到的视角范围在每个维度上均从-1扩展到1之间的正方体,因此就有
W.t = 1, W.b = -1
而在OpenGL中,有关窗口-视区变换是通过glViewport()函数来实现的,
下面是glViewport的具体形式
void glViewport(Glint x, Glint y, Glint width, Glint height);
此函数定义视口,在OpenGL应用程序设计的过程中,当执行了这个函数,OpenGL会自动地进行窗口到视口的变换,而这个变换的过程是通过矩阵的相乘来实现的。有关矩阵的数值则是通过上面所介绍的窗口到视口的映射来计算求得的。
下面给出此变换矩阵的一般形式
A 0 0 0
0 B 0 0
C D 1 0
0 0 0 0
将A,B,C,D的计算公式带入得
(V.r - V.l)/(W.r - W.l) 0 0 0
0 (V.t - V.b)/(W.t - W.b) 0 0
V.l - (V.r - V.l)*W.l/(W.r - W.l) V.b - (V.t - V.b)*W.b/(W.t - W.b) 1 0
0 0 0 0
具体分析,我们可以得出(V.r - V.l)即为glViewport函数中width值,W.r - W.l = 2.
(V.t - V.b)/(W.t - W.b)即为glViewport函数中的height值,而
V.l - (V.r - V.l)*W.l/(W.r - W.l) = width/2 + V.l,
V.b - (V.t - V.b)*W.b/(W.t - W.b) = height/2 + V.b
由此一来,就可以将上面的矩阵简化为
width/2 0 0 0
0 height/2 0 0
width/2 + x height/2 + y 1 0
0 0 0 0
根据视窗变换矩阵可以得到
sx = width/2 * x + (width/2 + x)
sy = height/2 * y + (height/2 + y)
在计算机中,x和y是使用矩阵的形式来表示的,所以,上面所列举的全部内容均需要转换为矩阵形式,之后转换为相应的代码即可。上面就是视窗变换的全部,如果要理解其中的原理,则需要对计算机图形学比较的熟悉。
阅读(5841) | 评论(0) | 转发(0) |