OpenGL鼠標拖拽


前序

前段時間學習3D MAX,一對比就發現差距是相當大。我也做了一個三維展示的小軟件,但是拖拽操作非常不友好,如果場景的尺寸特別大,會導致拖不動,尺寸過小會導致輕輕拖一下,模型就不知道飛哪去了。我是每次鼠標移動都是讓模型移動相同的距離,所以就出現了這種情況。下面就簡單說一下,怎么做到模型跟隨鼠標移動,就像鼠標抓着模型到處甩的效果。

方法


我們在設置OpenGL的投影矩陣的時候,需要設置近平面和遠平面,這里,BP和DQ分別表示近平面和遠平面。除此外,我們還需要設置攝像機的位置,這里我們用A點代表攝像機,攝像機的角度為2θ,假設觀察的物體位於CF平面上,我們的屏幕分辨率是X * Y,OpenGL的視口長寬設置為屏幕大小,那么,我們可以很容易的算出物體所在表面的高度CF = tanθ * AC。如果鼠標在縱向拖動的像素距離為ybits,那么相應的物體需要在Y軸方向移動的距離ydistance = ybits / Y * CF = ybits / Y * AC * tanθ。現在只要能取到AC的長度就能算出物體需要移動的距離。

深度緩沖

在OpenGL中我們可以通過獲取鼠標所在點的深度值,然后通過gluUnProject函數就能得到這個點所在的z軸坐標。

int winX, winY;     //winX和winY分別是窗口的xy坐標
double x, y, z;     //鼠標所在點在OpenGL坐標系中的坐標
float depth;        //鼠標點所在的深度值
int viewport[4];    //視口數據
double mvMatrix[16], projectMatrix[16];     //當前的modelview矩陣和projection矩陣

glGetIntegerv(GL_VIEWPORT, viewport);                       //獲取當前視口
glGetDoublev(GL_MODELVIEW_MATRIX, mvMatrix);                //獲取當前的modelview矩陣
glGetDoublev(GL_PROJECTTION_MATRIX, projectMatrix);         //獲取當前的projection矩陣

//鼠標當前的坐標為mouseX, mouseY, 均為int類型
winX = mouseX;
winY = viewport[3] - mouseY;            //Windows上的點坐標遠點位於屏幕左上角
glReadPixels(winX, winY, 1, 1, GL_DEPTH_COMPONENT, &depth);     //獲取深度,保存於depth
//gluUnProject(x坐標,y坐標,深度,modelview矩陣,projection矩陣,OpenGL的x坐標,OpenGL的y坐標,OpenGL的z坐標)
gluUnProject((GLdouble)winX, (GLdouble)winY, (GLdouble)depth, mvMatrix, projectMatrix, &x, &y, &z);

最后的計算

知道了鼠標點在OpenGL坐標系的具體坐標后,可以通過攝像機的坐標與點坐標之間運算,得到一個大概的移動距離(通過屏幕坐標反算OpenGL坐標會有誤差)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM