鍍金池/ 教程/ Android/ 三維坐標(biāo)系及坐標(biāo)變換初步
繪制線段 Line Segment
投影變換 Projection
繪制迷你太陽系
繪制一個(gè)球體
繪制三角形 Triangle
OpenGL 光照模型
三維坐標(biāo)系及坐標(biāo)變換初步
定義 3D 模型的前面和后面
繪制一個(gè) 20 面體
顏色 Color
Depth Buffer
材質(zhì)及光照示例
基本幾何圖形定義
關(guān)于EGL
導(dǎo)言
Viewing 和 Modeling(MODELVIEW) 變換
FrameBuffer
設(shè)置光照效果 Set Lighting
Viewport 變換
階段小結(jié)
繪制點(diǎn) Point
OpenGL ES API 命名習(xí)慣
通用的矩陣變換指令
關(guān)于 OpenGL ES
創(chuàng)建實(shí)例應(yīng)用 OpenGLDemos 程序框架
OpenGL ES 管道(Pipeline)
GLSurfaceView

三維坐標(biāo)系及坐標(biāo)變換初步

OpenGL ES 圖形庫最終的結(jié)果是在二維平面上顯示 3D 物體(常稱作模型 Model)這是因?yàn)槟壳暗拇虿糠诛@示器還只能顯示二維圖形。但我們在構(gòu)造 3D 模型時(shí)必須要有空間想象能力,所有對模型的描述還是使用三維坐標(biāo)。也就是使用 3D 建模,而有 OpenGL ES 庫來完成從 3D 模型到二維屏幕上的顯示。

這個(gè)過程可以分成三個(gè)部分:

  • 坐標(biāo)變換,坐標(biāo)變換通過使用變換矩陣來描述,因此學(xué)習(xí) 3D 繪圖需要了解一些空間幾何,矩陣運(yùn)算的知識(shí)。三維坐標(biāo)通常使用齊次坐標(biāo)來定義。變換矩陣操作可以分為視角(Viewing),模型(Modeling)和投影(Projection)操作,這些操作可以有選擇,平移,縮放,正側(cè)投影,透視投影等。
  • 由于最終的 3D 模型需要在一個(gè)矩形窗口中顯示,因此在這個(gè)窗口之外的部分需要裁剪掉以提高繪圖效率,對應(yīng)3D 圖形,裁剪是將處在剪切面之外的部分扔掉。
  • 在最終繪制到顯示器(2D 屏幕),需要建立起變換后的坐標(biāo)和屏幕像素之間的對應(yīng)關(guān)系,這通常稱為「視窗」坐標(biāo)變換(Viewport) transformation.

如果我們使用照相機(jī)拍照的過程做類比,可以更好的理解 3D 坐標(biāo)變換的過程。

http://wiki.jikexueyuan.com/project/opengl-es-guide/images/61.png" alt="" />

  1. 拍照時(shí)第一步是架起三角架並把相機(jī)的鏡頭指向需要拍攝的場景,對應(yīng)到 3D 變換為 viewing transformation (平移或是選擇 Camera )
  2. 然后攝影師可能需要調(diào)整被拍場景中某個(gè)物體的角度,位置,比如攝影師給架好三角架后給你拍照時(shí),可以要讓你調(diào)整站立姿勢或是位置。對應(yīng)到 3D 繪製就是 Modeling transformation (調(diào)整所繪模型的位置,角度或是縮放比例)。
  3. 之后攝影師可以需要調(diào)整鏡頭取景(拉近或是拍攝遠(yuǎn)景),相機(jī)取景框所能拍攝的場景會(huì)隨鏡頭的伸縮而變換,對應(yīng)到 3D 繪圖則為 Projection transformation(裁剪投影場景)。
  4. 按下快門後,對于數(shù)碼相機(jī)可以直接在屏幕上顯示當(dāng)前拍攝的照片,一般可以充滿整個(gè)屏幕(相當(dāng)于將坐標(biāo)做規(guī)範(fàn)化處理 NDC),此時(shí)你可以使用縮放放大功能顯示照片的部分。對應(yīng)到 3D 繪圖相當(dāng)于 viewport transformation (可以對最終的圖像縮放顯示等)

下圖為 Android OpenGL ES 坐標(biāo)變換的過程:

http://wiki.jikexueyuan.com/project/opengl-es-guide/images/62.png" alt="" />

  • Object Coordinate System: 也稱作Local coordinate System,用來定義一個(gè)模型本身的坐標(biāo)系。
  • World Coordinate System: 3d 虛擬世界中的絕對坐標(biāo)系,定義好這個(gè)坐標(biāo)系的原點(diǎn)就可以用來描述模型的實(shí)現(xiàn)的位置,Camera 的位置,光源的位置。
  • View Coordinate System: 一般使用用來計(jì)算光照效果。
  • Clip Coordinate System: 對 3D 場景使用投影機(jī)換裁剪視角。
  • Normalized device coordinate System (NDC): 規(guī)范后坐標(biāo)系。
  • Windows Coordinate System: 最后屏幕顯示的 2D 坐標(biāo)系統(tǒng),一般原點(diǎn)定義在屏幕左上角。

http://wiki.jikexueyuan.com/project/opengl-es-guide/images/63.png" alt="" />

對于 Viewing transformation (平移,選擇相機(jī))和 Modeling transformation(平移,選擇模型)可以合并起來看,只是應(yīng)為向左移動(dòng)相機(jī),和相機(jī)不同將模型右移的效果是等效的。

所以在 OpenGL ES 中,

  • 使用 GL10.GL_MODELVIEW 來同時(shí)指定 viewing matrix 和 modeling matrix.
  • 使用 GL10.GL_PROJECTION 指定投影變換,OpenGL 支持透視投影和正側(cè)投影(一般用于工程制圖)。
  • 使用 glViewport 指定 Viewport 變換。

此時(shí)再看看下面的代碼,就不是很難理解了,后面就逐步介紹各種坐標(biāo)變換。

public void onSurfaceChanged(GL10 gl, int width, int height) {
// Sets the current view port to the new size.
gl.glViewport(0, 0, width, height);
// Select the projection matrix
gl.glMatrixMode(GL10.GL_PROJECTION);
// Reset the projection matrix
gl.glLoadIdentity();
// Calculate the aspect ratio of the window
GLU.gluPerspective(gl, 45.0f, (float) width / (float) height, 0.1f, 100.0f);
// Select the modelview matrix
 gl.glMatrixMode(GL10.GL_MODELVIEW);
// Reset the modelview matrix
 gl.glLoadIdentity();
}