前言
這是我第一次在簡書上發表一些個人的筆記或經驗,可能沒什么人看,我也盡量寫清楚一些。(個人的語言表達有些差,當作鍛煉鍛煉,不喜勿噴)
這個標題我自己都感覺有些啰嗦,大概意思就是:使用C++和開源庫 freeglut 在 Visuai Studio 2015 上編寫的一個可以 通過鼠標操作圖形的縮放,移動等功能的小demo。我這片文章不會詳細介紹OpenGL的一些函數說明,需要大家自行搜索。
當然在最后,我會提供代碼的下載地址。
正文
1.效果實現的核心思想.
就是為了維護一個矩形的四個數值(left,right,bottom,top)。矩陣左下角為(left,bottom),右上角角為(right,top)。看到這里我想到大家都猜到是“glOrtho”這個函數了,核心就是為了維護這個函數的一個在freeglut的一個封裝”gluOrtho2D“。
在我的理解中,gluOrtho2D這個函數通常是和”glViewPort“一起使用。
gluOrtho2D:叫做正射投影,或者叫做平行投影。形象的說就是生成我們了解的正視圖,俯視圖,側視圖類似的圖像。但是它不是將圖形的”正視圖“給畫出來,而是只畫出局部的”正視圖“,這個局部的范圍就是由上面那四個數字確定。
glViewPort:設置我們的窗口尺寸大小。這個函數和”gluOrtho2D“可以這樣聯系起來:我們有一個能夠拍攝平行投影的數碼相機,我們可以通過”gluOrtho2D“來選取我們要拍攝風景的哪個局部,通過”glViewPort“設置我們通過這個相機獲取照片保存的像素尺寸大小。
現在,我們就是通過維護這四個數值來達到我們demo的希望的效果。
2.實現平移
首先我們先聲明一個函數:
void move (int x0 ,int y0 ,int x1 ,int y1)
注意:我們默認顯示窗口的像素尺寸為( width,height ),且之后的代碼里面出現,定義與此一樣。還有窗口坐標和我們的opengl默認坐標系不一樣。OpenGL默認的是左下角為(0,0),x軸水平向右增加,y軸豎子向上增加。而窗口坐標系 是以左上角為(0,0),x軸水平向右增加,y軸豎子向下增加。
函數定義說明:坐標(x0,y0)是鼠標拖動時的初始的窗口坐標,坐標(x1,y1)是鼠標拖動后,希望移動到的窗口坐標。
double _x = -(x1 - x0);
double _y = +(y1 - y0);
double c_x = (right - left) / double(width);
double c_y = (top - bottom) / double(height);
_x *= c_x;
_y *= c_y;
right+=_x;
left+=_x;
top+=_y;
bottom+=_y;
/*...更新opengl的一些設置包括 gluOrtho2D 和 glViewPort */
第1,2行是求在窗口坐標中的差值。
第3,4行是求窗口尺寸和正射投影的尺寸的比例關系
第5,6行是講窗口坐標平移尺寸映射到正射投影的世界坐標系中。
第7-10行是更新這四個數值,改變它們達到圖像跟隨鼠標移動的效果
第11,行,看注釋說明,我們也了解是重新設置OpenGL的一些參數,具體可以看最后的代碼。
3.實現縮放
同樣,我需要先定義下我們的函數
void scale(int x, int y, double s_x, double s_y)
對函數的中參數定義如下:
(x,y)是窗口坐標系的坐標,是我們的縮放的中心。
(s_x,s_y) 是縮放的比例,小于1.0是縮小,大于1.0是放大,等于1.0 沒有什么變化。
下面是實現代碼:
auto p = this->getWorldPoint(x, y);
left = p.x-(p.x - left) / s_x;
bottom = p.y-(p.y - bottom) / s_y;
right = p.x+(right - p.x) / s_x;
top = p.y+(top - p.y) / s_y;
先通過”getWorldPoint“求出( x,y)在正射投影的世界的對應坐標 p 。接下來為了保證 p 在新的投影矩陣中的相對位置不變。對這四個值進行了單獨更新。后四行代碼,自己可以通過簡單例子推算的。
有關地方值得注意,我們的這后四行代碼都是除以它們對應的縮放倍數。原因和我們的使用放大鏡類似,假設我們的放大鏡的鏡片面積不變。我改變放大鏡的放大倍數后,我們通過放大鏡看到的真實場景的面積是是變小的,反正依然。所以當我們要放大時,我們就要減小這個正視投影的矩陣大小,反正則增加。
雜項 (未補齊)
1.getWorldPoint(得到窗口坐標對應的世界坐標)
2.代碼下載地址
日志
- 于2016年11月05日第一次編寫,添加主要內容。計劃于下次補充一些圖片,和編寫 ”雜項“