青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 132  文章 - 51  trackbacks - 0
<2025年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

常用鏈接

留言簿(7)

隨筆分類

隨筆檔案

文章分類

文章檔案

cocos2d-x

OGRE

OPenGL

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

使用OpenGL實現三維坐標的鼠標揀選
Implementation of RIP(Ray-Intersection-Penetration)
3D Coordinates Mouse Selection Using OpenGL
顧 露 (武漢理工大學 計算機系 中科院智能設計與智能制造研究所 湖北武漢 430070)
摘要(Abstract):
本文提出并實現一種用于三維坐標揀選的RIP(Ray-Intersection-Penetration)方法。介紹了如何在已經渲染至窗口的三維場景
中,使用鼠標或者相關設備揀選特定三維對象的方法。此方法對于正交投影或透視投影均有效,相對于OpenGL自帶的選擇與反饋機制,本方法無論是揀選精度
還是算法實現效率均高出許多,是一種比較通用的解決方案。關鍵詞(Keywords) 正交投影(Ortho-Projection)、透視投影(Perspective-Projection)
世界坐標系、屏幕坐標系、三維揀選、OpenGL
一、簡介(Introduction)
OpenGL是一種比較“純粹”的3D圖形API,一般僅用于三維圖形的渲染,對于特定領域的開發者(如游戲開發者)而言,如果選擇使用
OpenGL進行開發,類似碰撞檢測的機制就都需要自行編寫了。但是由于鼠標在圖形程序中的應用非常非常之廣泛(例如現在已經很少有PC游戲能完全地脫離
鼠標),OpenGL在圖形庫的基礎上添加了選擇與反饋機制(Select &
Feedback)來滿足用戶使用鼠標實時操作三維圖形的需要。但由于種種原因,我們需要更為特殊的選擇機制以滿足特定需求,在這里我們提出了一種簡單迅
速的RIP(Ray-Intersection-Penetration)方法,可以滿足絕大多數典型應用的需要。
二、相關研究(Related Work) 用過OpenGL選擇與反饋機制的開發者,或多或少可能都會覺得它難以令人滿意。大致表現在下面幾個方面:
一、 編寫程序比較繁瑣。
想要使用選擇反饋機制就需要切換渲染模式,操作命名堆棧,計算揀選矩陣,檢查選中記錄,這些繁瑣的步驟很容易出錯,而且非常不便于調試,只會降低工作效率和熱情。二、 只能做基于圖元的選定。

下圖(1 – a),使用GL_TRIANGLES繪制了一個三角形,三個頂點分別為
P1、P2和P3。若使用該機制,你將只能判斷是否在三維場景中選中了這個三角形(用戶點擊處是否在P1、P2和P3的范圍內),而無法判斷用戶是點擊了
這個三角形哪一部分(是左邊的m區域內還是右邊的n區域內),因為所繪制的P1、P2和P3本身構成的三角形就是一個基本圖元,對于揀選機制而言是不可分
的。當然,把這個三角形拆成兩個三角形再分別進行測試也是一個可行的方案,可是看看圖(1 – b),這可怎么拆呢?還有圖(1 –
c)呢?另外,如果n和m兩個平面不共面呢?對于使用者而言,OpenGL提供的揀選機制功能的確有限。

三、降低了渲染效率。
OpenGL
中的選擇和反饋是與普通渲染方式不同的一種特殊的渲染方式。我們使用時一般是先在幀緩存中渲染普通場景,然后進入選擇模式重繪場景,此時幀緩存的內容并無
變化。也就是說,為了選擇某些物體,我們需要在一幀中使用不同的渲染方式將其渲染兩遍。我們知道對對象進行渲染是比較耗時的操作,當場景中需要選擇的對象
多而雜的時候,采用這個機制是非常影響速度的。
另外在OpenGL紅寶書中介紹了一種簡便易行的辦法:在后緩沖中使用不同的顏色重繪所有對象,每個對象用一個單色來標示其顏色,這樣畫好之后我們讀取鼠
標所在點的顏色,就能夠確定我們揀選了哪個物體。這種方法有一個缺陷,當場景中需要選擇的對象的數目超出一定限度時,可能會出現標識數的溢出。對于這個問
題,紅寶書給出的解決辦法就是多次掃描。實踐證明這種方法的確簡便易行,但仍有不少局限性,而且做起來并不比第一種機制方便多少。限于篇幅,不再贅述。三、具體描述(Related Work) 看過了上面兩種方法,我們會發現這兩種方法都不是十分的方便,而且使用者不能對其進行完全的控制,不能精確地判定鼠標定位與實際的世界空間中三維坐標的關系。那么有什么更好的辦法能夠更簡單更精確地對其加以控制呢? 實際上此處給出的解決方案十分簡單,就是一個很普通也很有用的 GLU 函數 gluUnProject()。
此函數的具體用途是將一個OpenGL視區內的二維點轉換為與其對應的場景中的三維坐標。
轉換過程如下圖所示(由點P在窗口中的XY坐標得到其在三維空間中的世界坐標):

這個函數在glu.h中的原型定義如下:int APIENTRY gluUnProject (
GLdouble winx,
GLdouble winy,
GLdouble winz,
const GLdouble modelMatrix[16],
const GLdouble projMatrix[16],
const GLint viewport[4],
GLdouble *objx,
GLdouble *objy,
GLdouble *objz);  其中前三個值表示窗口坐標,中間三個分別為模型視圖矩陣(Model/View Matrix),投影矩陣(Projection Matrix)和視區(ViewPort),最后三個為輸出的世界坐標值。  可能你會問:窗口坐標不是只有X軸和Y軸兩個值么,怎么這里還有Z值?這就要從二維空間與三維空間的關系說起了。 
 眾所周知,我們通過一個放置在三維世界中的攝像機,來觀察當前場景中的對象。通過使用諸如gluPerspective()
這樣的OpenGL函數,我們可以設置這個攝像機所能看到的視野的大小范圍。這個視野的邊界所圍成的幾何體是一個標準的平截頭體(Frustum),可以
看做是金字塔狀的幾何體削去金字塔的上半部分后形成的一個臺狀物,如果還原成金字塔狀,就得到了通常我們所說的視錐(View
Frustum)這個視錐的錐頂就是視點(View Point)也就是攝像機所在的位置。平截頭體,視錐以及視點之間的關系,如下圖所示:

在上面的圖中,遠裁剪面ABCD和近裁剪面A’B’C’D’構成了平截頭體,加上虛線部分就是視錐,頂點O就是攝像機所在的視點。我們在窗口中所能看到的東東,全部都在此平截頭體內。這跟前面的窗口坐標Z值有什么關系呢?看下圖


此圖所示,點P和點P’分別在遠裁剪面ABCD和近裁剪面A’B’C’D’上。我們點擊屏幕上的點P,反映到視錐中,就是選中了所有的從點P到點P’的
點。舉個形象的例子,這就像是我們挽弓放箭,如果射出去的箭近乎筆直地飛出(假設力量非常之大近乎無窮),從挽弓的地點直至擊中目標,在這條直線的軌跡上
任何物體都將被一穿而過。對應這里的情況,用戶單擊鼠標獲得屏幕上的某一點,即是指定了從視點指向屏幕深處的某一方向,也就確定了屏幕上某條從O點出發的
射線(在圖中即為OP)。在這里,我們稱呼其為揀選射線。
因此,從窗口的XY坐標,我們僅僅只能獲得一條出發自O點的揀選射線,并不能得到用戶想要的點在這條射線上的確切位置。
這時候窗口坐標的Z值就能派上用場了。我們通過Z值,來指定我們想要的點在射線上的位置。假如用戶點擊了屏幕上的點(100,100)得到了這條射線OP,那么我們傳入值1.0f就表示近裁剪面上的P點,而值0.0f則對應遠裁剪面上的P’點。

樣,我們通過引入一個窗口坐標的Z值,就能指定視錐內任意點的三維坐標。與此同時,我們還解決了前面紅寶書給出的方法中存在的缺陷——同一位置上重疊物體
的選擇問題。解決辦法是:從屏幕坐標得到射線之后,分別讓重疊的物體與該射線求交,得到的交點,然后根據這些與視點的遠近確定選擇的對象。如此我們就不必
受“僅僅只能選取屏幕中離觀察者最近的物體”的限制了。這樣一來,如果需要的話,我們甚至可以用代碼來作一定的限定,通過判斷交點與視點的距離,使得與該
揀選射線相交的物體中,離視點遠的對象才能被選取,這樣就能夠對那些暫時被其他對象遮住的物體進行選取。
至于如何求揀選射線與對象的交點,在各種圖形學的書中的數學部分均有講述,在此不再贅述。
四、例程(Sample Code Fragment)

前面講述了RIP方法,現在我們來看如何編寫代碼以實現之,以及一些需要注意的問題。
由于揀選射線以線段形式存儲更加便于后面的計算,況且我們可以直接得到縱跨整個平截頭體的線段(即前面圖中的線段PP’),故我們直接計算出這條連接遠近裁剪面的線段。我們將揀選射線的線段形式稱之為揀選線段。
在下面的代碼前方聲明有兩個類Point3f和LineSegment這分別表示由三個浮點數構成的三維空間中的點,以及由兩個點構成的空間中的一條線段。
應注意代碼中用到了類Point3f的一個需要三個浮點參數的構造函數,以及類LineSegment的一個需要兩個點參數的構造函數。
獲取揀選射線的例程如下所示(使用C++語言編寫):class Point3f;
class LineSegment;
LineSegment GetSelectionRay(int mouse_x, int mouse_y) {
// 獲取 Model-View、Projection 矩陣 & 獲取Viewport視區
GLdouble modelview[16];
GLdouble projection[16];
GLint viewport[4];
glGetDoublev (GL_MODELVIEW_MATRIX, modelview);
glGetDoublev (GL_PROJECTION_MATRIX, projection);
glGetIntegerv (GL_VIEWPORT, viewport); GLdouble world_x, world_y, world_z; // 獲取近裁剪面上的交點
gluUnProject( (GLdouble) mouse_x, (GLdouble) mouse_y, 0.0,
modelview, projection, viewport,
&world_x, &world_y, &world_z);
Point3f near_point(world_x, world_y, world_z); // 獲取遠裁剪面上的交點
gluUnProject( (GLdouble) mouse_x, (GLdouble) mouse_y, 1.0,
modelview, projection, viewport,
&world_x, &world_y, &world_z);
Point3f far_point(world_x, world_y, world_z); return LineSegment(near_point, far_point);
}

如果你是使用Win32平臺進行開發,那么應當注意傳入正確的參數。因為無論是使用Win32 API 還是DirectInput
來獲取鼠標坐標,得到的Y值都應取反后再傳入。因為OpenGL默認的原點在視區的左下角,Y軸從左下角指向左上角,而Windows默認的原點在窗口的
左上角,而Y軸方向與OpenGL相反,從左上角指向左下角。如下圖所示:

我們可以看到代碼被注釋分為了三個部分:獲取當前矩陣及視區,獲取近裁剪面的交點,獲取遠裁剪面的交點。
我們通過OpenGL提供的查詢函數輕松得到當前的ModelView和Projection矩陣,以及當前的Viewport(視區,也就是窗口的客戶端區域,如果整個窗口區域用于OpenGL渲染的話)。
獲得兩個裁剪面上的交點的代碼基本上是一樣的,唯一的不同點是我們前面曾經詳細地討論過的窗口的Z坐標。不錯,這個坐標表示的就是“深淺”的概念。它的值從點P’到點P的變化是從0.0f逐漸增至1.0f。此處類似于OpenGL的深度測試機制。
在得到兩個交點之后,我們使用它們通過返回語句直接構建一條線段。在這里僅僅作為實例代碼,故簡捷清晰地直接返回線段對象,而沒有通過引用參數來提高效率。

時用戶可以使用這個函數來判斷所選擇的對象了。只需在需要的地方判斷對象是否與此線段相交即可判斷對象是否被選中,還可以通過進一步計算其交點位置來得到
詳細的交點信息。這些計算均是常見的計算機圖形學與三維數學計算,比如線段與三角形求交,線段與面求交,線段與球體求交,線段與柱體或錐體求交,等等。請
參考所列出的計算機圖形學書籍。
五、結論(Conclusion)

在本文中,我們介紹了一種行之有效的三維坐標拾取方法,主要使用GLU庫中的實用工具實現。這種方法速度快,效率高,能在不必重新繪制對象的前提下完成揀選工作。對比OpenGL自帶的揀選機制來看,RIP的確在各種方面均有一定的優勢。
六、參考文獻(Reference) 【1】《OpenGL Programming Guide》
OpenGL ARB Mason Woo, Jackie Heider, Tom Davis, Dave Shreiner
【2】《OpenGL Reference Manual》
OpenGL ARB
【3】《Computer Graphics》
Donald Heam, M. Pauline Baker
【4】《Computer Graphics using OpenGL 2nd Edition》
F.S. Hill, JR.
posted on 2010-06-05 18:45 風輕云淡 閱讀(3091) 評論(0)  編輯 收藏 引用 所屬分類: OpenGL
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲国产人成综合网站| 99国产一区| 欧美一区午夜精品| 中文一区二区| 亚洲精品免费一区二区三区| 欧美aⅴ一区二区三区视频| 久久免费视频在线观看| 久久久久国色av免费看影院| 久久香蕉国产线看观看网| 麻豆精品精华液| 亚洲国产精品一区制服丝袜| 91久久午夜| 亚洲欧美国产高清| 久久福利一区| 久久天天躁夜夜躁狠狠躁2022 | 一区二区三区久久精品| 亚洲视频在线观看网站| 久久精品在线免费观看| 亚洲福利视频网站| 亚洲午夜精品久久久久久app| 欧美亚洲一区二区三区| 欧美电影免费观看| 久久精品国产第一区二区三区| 亚洲一级二级在线| 国产一区二区三区在线观看视频| 男女视频一区二区| 亚洲激情成人| 午夜精品一区二区三区电影天堂| 久久久久久尹人网香蕉| 欧美日韩精品免费观看视频| 国产欧美日韩伦理| 在线观看亚洲视频| 亚洲线精品一区二区三区八戒| 免费成人毛片| 国产欧美日韩亚洲一区二区三区| 1769国产精品| 久久国产黑丝| 99re在线精品| 久久免费国产精品| 国产精品视频成人| 99re国产精品| 免费在线日韩av| 亚洲欧美区自拍先锋| 欧美日本精品| 亚洲国产另类久久精品| 久久成人这里只有精品| 亚洲人永久免费| 久久久国际精品| 国产精品五月天| aaa亚洲精品一二三区| 久久综合亚洲社区| 欧美亚洲自偷自偷| 国产精品国产三级国产专播品爱网| 在线观看欧美成人| 久久久亚洲高清| 午夜在线a亚洲v天堂网2018| 欧美午夜宅男影院| 99视频在线观看一区三区| 欧美福利电影网| 久久九九精品| 久久网站热最新地址| 极品日韩久久| 久久天天狠狠| 欧美中文字幕不卡| 韩国av一区二区三区| 久久精品毛片| 欧美一区二区三区在线看 | 欧美成人官网二区| 亚洲高清在线| 欧美黄色一区| 欧美精品激情在线观看| 亚洲国产欧美一区二区三区久久| 久久久在线视频| 久久久久久穴| 亚洲国产日韩欧美在线动漫| 欧美成人xxx| 蜜桃av噜噜一区| 亚洲国产老妈| 日韩视频免费看| 国产精品免费在线| 久久精品国产精品| 久久免费偷拍视频| 亚洲精选大片| 亚洲一区二区三区在线| 国模一区二区三区| 亚洲国产女人aaa毛片在线| 欧美三级特黄| 另类天堂视频在线观看| 欧美激情视频一区二区三区免费| 在线午夜精品自拍| 午夜在线不卡| 在线一区观看| 久久国产精彩视频| 欧美超级免费视 在线| 亚洲精品在线视频| 亚洲性感美女99在线| 雨宫琴音一区二区在线| 亚洲欧洲免费视频| 国产精品激情偷乱一区二区∴| 久久久噜噜噜久噜久久| 欧美高清视频在线播放| 午夜在线一区| 久久精品夜色噜噜亚洲a∨| 亚洲国产美女久久久久| 一区二区三区 在线观看视| 在线观看国产成人av片| 亚洲一区日本| 亚洲日韩欧美视频| 亚洲影院色无极综合| 亚洲国产欧美不卡在线观看| 亚洲日本成人女熟在线观看| 国产欧美日韩一区二区三区在线观看 | 美女黄毛**国产精品啪啪| 亚洲图片欧洲图片日韩av| 久久av资源网| 亚洲一区免费观看| 蜜桃av一区二区三区| 欧美在线啊v一区| 欧美日韩精品免费观看视一区二区| 久久久亚洲影院你懂的| 国产精品www| 免费亚洲电影在线| 国产精品乱码人人做人人爱| 欧美高清不卡| 好看的日韩av电影| 亚洲欧美精品在线观看| 亚洲性感激情| 欧美日韩精品久久久| 亚洲精品1234| 亚洲区国产区| 老色鬼精品视频在线观看播放| 午夜欧美理论片| 国产精品v一区二区三区| 亚洲人www| 亚洲毛片在线观看.| 欧美国产精品v| 欧美国产第二页| 亚洲国产成人精品女人久久久 | 日韩视频一区二区在线观看| 亚洲精品网址在线观看| 男女视频一区二区| 亚洲第一福利在线观看| 亚洲国产高清aⅴ视频| 久久野战av| 蜜臀av性久久久久蜜臀aⅴ四虎 | 激情综合亚洲| 久热国产精品视频| 欧美成人精品不卡视频在线观看| 免费成人黄色| 亚洲电影免费观看高清完整版在线| 激情久久久久久久久久久久久久久久| 午夜宅男欧美| 久久久久高清| 精品51国产黑色丝袜高跟鞋| 久久国产视频网| 欧美成人免费观看| 亚洲精品视频在线| 欧美日韩免费看| 亚洲素人一区二区| 欧美专区日韩视频| 一区在线电影| 欧美精品大片| 亚洲一区二区三区激情| 久久精品天堂| 最新亚洲电影| 国产精品久久九九| 欧美一区免费视频| 亚洲视频碰碰| 国内成+人亚洲| 欧美激情在线观看| 亚洲欧美久久久久一区二区三区| 久久九九全国免费精品观看| 亚洲国产二区| 国产精品一区久久| 久久久久国产精品一区三寸| 亚洲人体偷拍| 麻豆精品精品国产自在97香蕉| 亚洲日本va在线观看| 欧美亚州一区二区三区| 久久精品青青大伊人av| 欧美激情第五页| 香蕉乱码成人久久天堂爱免费| 国内自拍亚洲| 欧美日韩国产美| 久久久99免费视频| 日韩午夜三级在线| 久久综合一区二区三区| 亚洲一区二区三区免费视频| 国内精品模特av私拍在线观看| 欧美精品福利| 久久久久久穴| 欧美亚洲视频| 99爱精品视频| 欧美大片免费观看| 欧美在线一级视频| 99精品免费网| 亚洲国产1区| 在线播放一区| 一区二区亚洲欧洲国产日韩| 国产精品美女久久久免费|