在將窗口中的圖形信息送到視區去輸出之前,必須進行坐標變換,即將用戶坐標系的坐標值轉化為設備坐標系的坐標值,即窗口-視區變換。
從窗口到視口的映射世界窗口用其左、上、右和下邊界描述,分別是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是使用矩陣的形式來表示的,所以,上面所列舉的全部內容均需要轉換為矩陣形式,之後轉換為相應的代碼即可。上面就是視窗變換的全部,如果要理解其中的原理,則需要對計算機圖形學比較的熟悉。