OpenGL是近幾年發展起來的一個性能卓越的三維圖形標準, 由于其開放性和獨立于操作系統, 目前已成為業界應用最廣泛的三維圖形應用程序接口 (API) [1]。
OpenGL的優良性能使其成為三維人機交互程序開發的首選平臺。然而, 在眾多的介紹OpenGL程序開發的書籍中, 對如何使用鼠標選取程序中的三維實體并進行人機交互的方法介紹得很少。對三維實體的選取在很多交互式OpenGL程序中都是非常重要的人機交互手段, 本文將針對這一技術進行分析, 提出具體的實現方法。
1 三維實體的特殊性
現在的交互式OpenGL程序大多數都允許用戶使用鼠標選擇屏幕上的物體, 以便進行修改、移動、刪除或其它的操作。然而對三維實體的選擇因為其特殊性, 在實現上存在一定難度, 下面對平面和三維情況下選擇物體的方式進行對比。
有過平面圖形編程經驗的人都知道, 一般情況下, 對平面區域的選擇是比較簡單的。當用戶點擊鼠標時, 程序根據事先定義的平面區域的坐標區間與鼠標點擊時所處的坐標相比較, 立即可以判斷出鼠標是否在平面區域內被點擊, 從而確定平面區域是否被選中。
相比之下, 用鼠標選取三維實體就困難得多。這是因為, 最終顯示在屏幕上的三維圖像實際上只是三維實體的二維表示, 或者可以說是三維實體的投影。通常投影有兩種方式, 即正交投影和透視投影。正交投影的特點是不受距離的影響, 投影的大小總是等于對象的實際大小, 這種投影方式多用于工程制圖中。透視投影的特點是它受到距離的影響, 對象距離投影面越遠, 其投影就越小, 這與真實世界是相符的。不論采用哪一種投影方式, 用鼠標選擇物體時, 實際上點擊的是物體的投影。而當物體經歷多次旋轉和平移變換時, 通常其投影的位置、大小和形狀都將發生改變, 所以無法使用選擇平面區域的方法去用鼠標選擇三維實體。
2 OpenGL實用庫 (GLU) 函數選取三維實體
通過使用OpenGL實用庫函數[2], 我們可以比較容易地進行選擇。其主要步驟是:
(1) 分配一個數組作為存放被選擇實體信息的緩沖區, 使用glSelectBuffer () 函數選擇這個數組。
(2) glRenderMode () 函數, 參數設為G L_S E L E C T, 使程序進入選擇模式 (selection mode) 。
(3) glInitNames () 和glPushName () 函數, 初始化名字堆棧 (name stack) 。
(4) glu Pick Matrix () 和glu Perspective () 函數, 進行視圖變換, 在此之前需要調用glPushMatrix () 函數保存變換狀態。
(5) 繪制場景中的各個實體。
(6) gluPopMatrix () 恢復原來的變換狀態, g l R e n d e r M o d e () 函數參數設為GL_RENDER, 使程序進入正常渲染模式, 同時得到被選中的實體數量。
(7) 如果被選中的實體數量多于1個, 則對其進行排序, 保證距離屏幕最近的實體被選擇。
這些步驟中關鍵的在于第2步和第5步。OpenGL的選擇模式是一種特殊的光柵化模式, 在這種模式下, 并不會在屏幕上畫出任何東西, 而是將各個實體的信息存入緩沖區, 在這種模式中, 顏色、深度、模板和累積緩存的內容不受影響。由于選擇模式的這個特點, 我們可以把各個實體的繪制單獨編寫成一個函數DrawObjects () , 這個函數既可以在普通模式下繪制屏幕上看得見的實體, 又可以在選擇模式下繪制實體。
3 使用設備無關位圖 (DIB) 和顏色查詢表來選取三維實體
這種方法的思路是以下幾點。
(1) 捕捉鼠標點擊發生的位置 (x, y) 。
(2) 建立一個顏色查詢表, 為場景中的每一個實體分配一種特定的顏色。
(3) 使用顏色查詢表中指定的顏色在內存中畫出所有實體, 結果并不顯示在屏幕上。
(4) 找到點 (x, y) 位置對應的顏色, 根據這種顏色在顏色查詢表中找到相對應的三維實體。
(5) 重新以各實體本來的顏色和紋理進行繪制, 并將結果輸出至屏幕。
這種方法的實現要借助于DIB。在上述步驟的第 (3) 步中, 我們需要向內存中的DIB繪制專門用來選擇實體的臨時畫面, 只有這樣, 使用者才不會察覺到屏幕畫面的變化;而在第 (5) 步中, 最終顯示在屏幕上的畫面也是事先繪制在D I B中, 然后通過BitBlt函數輸出到屏幕。
4 結語
本文介紹的兩種在OpenGL程序中選取三維實體的技術各有特點。從原理上來說, 第一種方法較難于理解, 第二種方法則淺顯易懂;從實現上來說, 第一種方法的代碼較少, 第二種方法的代碼較多, 但如果將所需的設備無關位圖及其相關操作封裝成一個可重用的類, 則可以大大提高編程效率;從運行效率來看, 第二種方法因為需要在內存中預先繪制場景, 所以效率比第一種方法要低, 但在計算機硬件速度不斷提升的當今, 這種差別并不明顯。
本文所介紹的兩種方法具有通用性, 可廣泛適用于各類交互式OpenGL程序, 使用時可以根據需要選擇其一。
摘要:本文分析了OpenGL程序中實現對三維實體實現選取的意義和難點, 提出了選取三維實體的兩種具體方法, 并對這兩種方法進行了比較。
關鍵詞:OpenGL,三維實體,選取技術
參考文獻
[1] Mason Woo, 等[著], 吳斌, 等[譯].OpenGL權威編程指南[M].北京:中國電力出版社, 2001.
[2] Microsoft Corp.MSDN Library 6.0[CP/CD].Microsoft Corp, 1998.