OpenCASCADE Coordinate Transforms
eryar@163.com
Abstract. The purpose of the OpenGL graphics processing pipeline is to convert 3D descriptions of objects into a 2D image that can be displayed. In many ways, this process is similar to using a camera to convert a real-world scene into a 2D print. To accomplish the transformation from 3D to 2D, OpenGL defines several coordinate spaces and transformations between those spaces. Each coordinate space has some properties that make it useful for some part of the rendering process. The transformations defined by OpenGL afford applications a great deal of flexiblity in defining 3D-to-2D mapping. So understanding the various transformations and coordinate spaces used by OpenGL is essential. The blog use GLUT to demenstrate the conversion between 3D and 2D point.
Key Words. OpenCASCADE, OpenGL, Coordinate Transform,
1. Introduction
交互式計(jì)算機(jī)圖形學(xué)的迅速發(fā)展令人興奮,其廣泛的應(yīng)用使科學(xué)、藝術(shù)、工程、商務(wù)、工業(yè)、醫(yī)藥、政府、娛樂、廣告、教學(xué)、培訓(xùn)和家庭等各方面均獲得巨大收益。與圖形交互的方式目前主要還是鍵盤和鼠標(biāo)或pad上的觸摸方式。交互的方式主要分為兩種,一是在二維的屏幕或窗口上對(duì)三維的模型進(jìn)行控制;一是對(duì)三維視圖進(jìn)行控制(在OpenSceneGraph中對(duì)應(yīng)拖拽器和漫游器)。這就需要對(duì)計(jì)算機(jī)圖形學(xué)中的坐標(biāo)變換的原理有所理解。
三維場(chǎng)景視圖的計(jì)算機(jī)生成步驟有點(diǎn)類似拍一張照片的過程,但與使用照相機(jī)相比,利用圖形軟件生成的場(chǎng)景視圖有更大靈活性和更多的選擇。我們可以選擇平行投影或透視投影,還可以有選擇地沿視線消除一些場(chǎng)景等。
通過從三維模型到二維屏幕窗口的實(shí)現(xiàn)過程理解,方便理解計(jì)算機(jī)中對(duì)場(chǎng)景觀察的實(shí)現(xiàn)。場(chǎng)景的觀察即注重一個(gè)從三維世界轉(zhuǎn)換到二維屏幕的過程。假設(shè)場(chǎng)景的觀察者使用一臺(tái)相機(jī)來全程記錄世界的變化,那么相機(jī)位置的移動(dòng)、角度偏轉(zhuǎn)、焦距變化及鏡頭類型的選用都會(huì)改變底片上呈現(xiàn)的內(nèi)容,也就是觀察這個(gè)世界的方式。
通過從二維屏幕到三維場(chǎng)景中實(shí)現(xiàn)的理解,方便用戶通過二維的屏幕窗口的程序界面來操縱三維世界中的模型,如三維中模型的選擇及對(duì)選擇中的模型進(jìn)行相關(guān)的變換,如移動(dòng)、旋轉(zhuǎn)等。
本文結(jié)合OpenCASCADE中的類Graphic3d_Camera及GLUT來說明這兩個(gè)過程,進(jìn)而對(duì)OpenCASCADE中可視化模塊的理解。通過對(duì)OpenGL中坐標(biāo)變換原理的理解,為OpenCASCADE中對(duì)視圖的操作及拓樸模型(點(diǎn)、線、面和體)選擇的實(shí)現(xiàn)的理解打下基礎(chǔ),良好的交互可以讓場(chǎng)景中的模型充滿生機(jī)。
2.From 3D to 2D
從三維的模型到二維屏幕,OpenGL的渲染管線分為以下幾個(gè)部分:
v 模型視點(diǎn)變換MODELVIEW TRANSFORMATION;
v 投影變換PROJECTION TRANSFORMATION;
v 視口變換VIEWPORT TRANSFORMATION;
Figure 2.1 OpenGL Vertex Transformation Pipeline
如上圖所示為從模型坐標(biāo)系到設(shè)備坐標(biāo)系變換的管線,即模型經(jīng)過這些變換后,最終才能顯示在設(shè)備屏幕上。
Figure 2.2 Stages of Vertex Transformation(OpenGL Programming Guide)
在OpenGL中每個(gè)變換都對(duì)應(yīng)了一個(gè)矩陣運(yùn)算,如對(duì)模型視點(diǎn)的變換對(duì)應(yīng)了模型視點(diǎn)矩陣,可以通過glMatrixMode(GL_MODELVIEW)來指定義當(dāng)前的矩陣模式,再通過glLoadMatrix來指定這個(gè)變換矩陣。同理,對(duì)應(yīng)投影變換的相關(guān)函數(shù)為glMatrixMode(GL_PROJECTION)。
Figure 2.3 The vertex transformation pipeline(OpenGL SuperBible)
2.1 模型視點(diǎn)變換Model-View Transformation
模型視點(diǎn)變換相當(dāng)于調(diào)整要拍攝的物體的位置、姿態(tài)及調(diào)整相機(jī)使其對(duì)準(zhǔn)景物的過程,前者稱為模型變換,后者稱為視點(diǎn)變換。在OpenGL中,模型變換和視點(diǎn)變換的結(jié)果被合并為模型視點(diǎn)變換矩陣(Model-View Matrix)。在繪制物體前可以使用glTranslate, glRotate等來實(shí)現(xiàn)模型的位置、姿態(tài)變換。與模型變換對(duì)應(yīng),我們還可以采用視點(diǎn)變換改變觀察點(diǎn)的位置和方向,即改變相機(jī)的位置和拍攝角度,從而改變最終拍攝的結(jié)果。可以將視點(diǎn)變換的行為視作模型變換的逆操作,如將相機(jī)在X方向移動(dòng)N米,就相當(dāng)于將整個(gè)場(chǎng)景在-X方向移動(dòng)了N米。
經(jīng)過模型視點(diǎn)變換后,即可認(rèn)為場(chǎng)景從世界坐標(biāo)系(World Coordinate System, WCS)轉(zhuǎn)換到了相機(jī)坐標(biāo)系(Viewing Coordinate System, VCS)。對(duì)于世界坐標(biāo)系中任意向量Vwcs將其變換到相機(jī)坐標(biāo)系的公式為:
在VCS坐標(biāo)系中,習(xí)慣用n,u,v三個(gè)分量來表示坐標(biāo)基向量,如下圖所示為從世界坐標(biāo)系變換到視點(diǎn)坐標(biāo)系的變換:
Figure 2.4 From World Cooridante System to Viewing Coordinate System
其中模型視點(diǎn)變換矩陣內(nèi)容如下所示:
2.2 投影變換Projection Transformation
投影變換相當(dāng)于拍照時(shí)通過選擇鏡頭和調(diào)整焦距,將景物投射到二維底片的過程。主要操作對(duì)象是一個(gè)立方體或棱臺(tái)形狀的視景體。在視景體之外的對(duì)象將被裁剪,因而不會(huì)投影到二維面上。
立方體的視景體稱為平行投影視景體,通過使用glOrtho()函數(shù)創(chuàng)建,其結(jié)果是生成一個(gè)正射投影矩陣,如下圖所示:
Figure 2.5 Orthographic Viewing Volume(OpenGL Programming Guide)
Figure 2.6 Orthogonal Projection View Volume to Normalized View Volume
由于屏幕坐標(biāo)系經(jīng)常指定為左手系,因此規(guī)范化觀察體也常指定為左手系統(tǒng)。正投影觀察體的規(guī)范化變換矩陣是:詳細(xì)推導(dǎo)請(qǐng)參考《Computer Graphics with OpenGL》。
棱臺(tái)形狀的視景體又稱為視錐體,主要用于完成透視投影的工作,這種投影更符合人們的心理習(xí)慣,即離視點(diǎn)近的物體較大,離視點(diǎn)遠(yuǎn)的物體較小。在OpenGL中由函數(shù)glFrustum和gluPerspective來實(shí)現(xiàn)。
Figure 2.7 Perspective Viewing Volume Specifiedc by glFrustum
一般的透視投影規(guī)范化變換矩陣如下所示:詳細(xì)推導(dǎo)請(qǐng)參考《Computer Graphics with OpenGL》。
相機(jī)坐標(biāo)系的向量Vvcs變換到投影坐標(biāo)系下(Clipping Coordinate System, CCS)的計(jì)算公式為:
2.3 視口變換 Viewport Transformation
這一步的意義是將投影變換得到的結(jié)果反映到指定的屏幕窗口上去,有點(diǎn)類似將底片沖洗到照片上。如果照片的大小與底片不相符,那么將可能產(chǎn)生成像的放大或縮小。OpenGL中函數(shù)glViewport()指定了視口變換的結(jié)果區(qū)域。這一變換的同時(shí)還意味著場(chǎng)景最終變換到窗口坐標(biāo)系(Device Coordinate System, DCS,又稱為設(shè)備坐標(biāo)系)。
Figure 2.8 Mapping the Viewing Volume to the Viewport
從規(guī)范化的視景體到屏幕坐標(biāo)系的變換矩陣是:
綜上所述,場(chǎng)景從三維世界坐標(biāo)系變換到屏幕窗口的所有變換過程進(jìn)行疊加,則得到如下的變換公式:
這三個(gè)矩陣可以合并為一個(gè),稱為MVPW矩陣,它決定了任意三維空間中的對(duì)象在二維屏幕上表達(dá)時(shí)的變換過程。
3.From 2D to 3D
在理解OpenGL的整個(gè)渲染管線后,再來理解將屏幕上一點(diǎn)轉(zhuǎn)換為世界坐標(biāo)就比較容易了。從圖形渲染管線的開始到結(jié)束,一個(gè)模型坐標(biāo)系中的坐標(biāo)被變換到了屏幕坐標(biāo),那么現(xiàn)在把整個(gè)過程倒過來的話,屏幕上一個(gè)二維點(diǎn)坐標(biāo)也可轉(zhuǎn)換到世界坐標(biāo)系中。即將MVPW矩陣求逆即可。如下圖所示為從屏幕坐標(biāo)到世界坐標(biāo)的變換過程:
Figure 3.1 Viewport cooridnate to World Coordinate(By Zhangci)
當(dāng)理解從屏幕坐標(biāo)變換到世界坐標(biāo)后,也就可以方便理解Picking技術(shù)的實(shí)現(xiàn)了。即可以通過在二維的屏幕窗口中來選擇拓樸形狀的點(diǎn)、線和面等模型了。可以通過鼠標(biāo)直接拾取模型后,就可以方便地對(duì)模型的位置角度等進(jìn)行編輯,如OpenSceneGraph中的Dragger:
Figure 3.2 OpenSceneGraph TranslateAxisDragger
如上圖所示,用鼠標(biāo)在任意一個(gè)軸上進(jìn)行拖拽即可以對(duì)三維模型的位置進(jìn)行編輯。
4.Code Example
結(jié)合OpenCASCADE的類Graphic3d_Camera和GLUT可以方便來驗(yàn)證OpenGL中的坐標(biāo)變換過程。其中類Graphic3d_Camera已經(jīng)實(shí)現(xiàn)從世界坐標(biāo)系到規(guī)范坐標(biāo)系的變換,但還需要從規(guī)范坐標(biāo)系到屏幕窗口變換的矩陣,根據(jù)計(jì)算公式實(shí)現(xiàn)如下代碼所示:
void BuildNorm2ViewportMatrix(GLsizei theWidth, GLsizei theHeight)
{
// row 0
theNorm2Viewport.ChangeValue(0, 0) = (theWidth - 0) / 2.0;
theNorm2Viewport.ChangeValue(0, 1) = 0.0;
theNorm2Viewport.ChangeValue(0, 2) = 0.0;
theNorm2Viewport.ChangeValue(0, 3) = (0 + theWidth) / 2.0;
// row 1
theNorm2Viewport.ChangeValue(1, 0) = 0.0;
theNorm2Viewport.ChangeValue(1, 1) = (0 - theHeight) / 2.0;
theNorm2Viewport.ChangeValue(1, 2) = 0.0;
theNorm2Viewport.ChangeValue(1, 3) = (theHeight + 0) / 2.0;
// row 2
theNorm2Viewport.ChangeValue(2, 0) = 0.0;
theNorm2Viewport.ChangeValue(2, 1) = 0.0;
theNorm2Viewport.ChangeValue(2, 2) = 0.5;
theNorm2Viewport.ChangeValue(2, 3) = 0.5;
// row 3
theNorm2Viewport.ChangeValue(3, 0) = 0.0;
theNorm2Viewport.ChangeValue(3, 1) = 0.0;
theNorm2Viewport.ChangeValue(3, 2) = 0.0;
theNorm2Viewport.ChangeValue(3, 3) = 1.0;
}
當(dāng)用鼠標(biāo)點(diǎn)擊直線的起點(diǎn)時(shí),可以得到相應(yīng)的屏幕坐標(biāo)及世界坐標(biāo),如下圖所示:
Figure 4.1 Test Coordinate Transformation
其中世界坐標(biāo)系中的坐標(biāo)為坐標(biāo)原點(diǎn)(0,0,0),轉(zhuǎn)換到屏幕坐標(biāo)為(150,150),與鼠標(biāo)拾取的點(diǎn)一致。再將鼠標(biāo)拾取的點(diǎn)轉(zhuǎn)換到三維世界坐標(biāo)也為原點(diǎn),只是深度值Z不同。
5.Conclusion
綜上所述,在OpenGL中世界坐標(biāo)系中的模型經(jīng)過模型視點(diǎn)變換、投影變換和視口變換最終得到了二維窗口中的顯示圖像。而這個(gè)逆過程即從屏幕坐標(biāo)到三維世界坐標(biāo)系的變換對(duì)交互更有意義,即拾取技術(shù)的實(shí)現(xiàn)。
結(jié)合OpenCASCADE中的類Graphic3d_Camera和GLUT來試驗(yàn)了這些變換過程,為理解拓樸形狀點(diǎn)、線和面等的選擇交互的實(shí)現(xiàn)打下基礎(chǔ),進(jìn)一步理解Visualization模塊。
6. References
1. Dave Shreiner. OpenGL Programming Guide(7th Edition). Addison-Wesley. 2010
2. Richard S. Wright Jr., Benjamin Lipchak. OpenGL SuperBible. Sams. 2004
3. Randi J. Rost. OpenGL Shading Language(2nd Edition). Addison-Wesley. 2006
4. Donald Hearn, M. Pauline Baker. Computer Graphics with OpenGL. 2004
5. Zhangci. OpenGL Rendering Pipeline&Coordinate Transformation.
http://blog.csdn.net/zhangci226/article/details/5314184
6. 王銳, 錢學(xué)雷. OpenSceneGraph三維渲染引擎設(shè)計(jì)與實(shí)踐. 清華大學(xué)出版社. 2009