窗口與顯示主要與三個量有關:世界座標,窗口大小和視口大小。圍繞這些量共有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設爲原來的一半,則視口變爲原來大小的一半,會使圖像適配窗口的一半,可得:(瘦高三角、空餘部分、未顯示部分和我截圖時畫的紅線,紅線在窗口中央)
因爲圖像要拉伸適配視口,所以會產生形變。
注意:紅線左右都有黑色的部分,但是意義不同。左側的黑色部分是在世界座標系中截取的空餘部分;而右側的黑色部分則是未顯示任何圖像的結果。
即,若截取圖像的比例和視口比例了不同,則會產生形變。
即使視口大小與窗口大小不同,只要比例相同就不會形變,只是“未顯示任何圖像”的區域就多了。