Android OpenGL ES 簡明開發教程 04

來源:互聯網
上載者:User

本篇介紹3D 座標系下的座標變換transformations。

Coordinate System座標系

OpenGL使用了右手座標系統,右手座標系判斷方法:在空間直角座標系中,讓右手拇指指向x軸的正方向,食指指向y軸的正方向,如果中指能指向z軸的正方向,則稱這個座標係為右手直角座標系。

Translate平移變換

方法public abstract void glTranslatef (float
x, float y, float z) 用於座標平移變換。

在上個例子中我們把需要顯示的正方形後移了4個單位,就是使用的座標的平移變換,可以進行多次平移變換,其結果為多個平移矩陣的累計結果,矩陣的順序不重要,可以互換。

Rotate旋轉

方法public abstract void glRotatef(float
angle, float x, float y, float z)用來實現選擇座標變換,單位為角度。 (x,y,z)定義旋轉的參照向量方向。多次旋轉的順序非常重要。

比如你選擇一個骰子,首先按下列順序選擇3次:

gl.glRotatef(90f, 1.0f, 0.0f, 0.0f);gl.glRotatef(90f, 0.0f, 1.0f, 0.0f);gl.glRotatef(90f, 0.0f, 0.0f, 1.0f);

然後打算逆向旋轉回原先的初始狀態,需要有如下旋轉:

gl.glRotatef(90f, -1.0f, 0.0f, 0.0f);gl.glRotatef(90f, 0.0f, -1.0f, 0.0f);gl.glRotatef(90f, 0.0f, 0.0f, -1.0f);

或者如下旋轉:

gl.glRotatef(90f, 0.0f, 0.0f, -1.0f);gl.glRotatef(90f, 0.0f, -1.0f, 0.0f);gl.glRotatef(90f, -1.0f, 0.0f, 0.0f);

旋轉變換glRotatef(angle, -x, -y, -z) 和glRotatef(-angle, x, y, z)是等價的,但選擇變換的順序直接影響最終座標變換的結果。 角度為正時表示逆時針方向。

Translate & Rotate (平移和旋轉組合變換)

在對Mesh(網格,構成三維形體的基本單位)同時進行平移和選擇變換時,座標變換的順序也直接影響最終的結果。

比如:先平移後旋轉, 旋轉的中心為平移後的座標。

先選擇後平移:
平移在則相對於旋轉後的座標系:

一個基本原則是,座標變換都是相對於變換的Mesh本身的座標系而進行的。

Scale(縮放)

方法public abstract void glScalef (float
x, float y, float z)用於縮放變換。

為使用gl.glScalef(2f, 2f, 2f) 變換後的基本,相當於把每個座標值都乘以2.

Translate
& Scale(平移和縮放組合變換)

同樣當需要平移和縮放時,變換的順序也會影響最終結果。

比如先平移後縮放:

gl.glTranslatef(2, 0, 0);gl.glScalef(0.5f, 0.5f, 0.5f);

如果調換一下順序:

gl.glScalef(0.5f, 0.5f, 0.5f);gl.glTranslatef(2, 0, 0);

結果就有所不同:

矩陣操作,單位矩陣

在進行平移,旋轉,縮放變換時,所有的變換都是針對當前的矩陣(與當前矩陣相乘),如果需要將當前矩陣回複最初的無變換的矩陣,可以使用單位矩陣(無平移,縮放,旋轉)。

public abstract void glLoadIdentity()。

在棧中儲存當前矩陣和從棧中恢複所存矩陣,可以使用

public abstract void glPushMatrix()

public abstract void glPopMatrix()。

在進行座標變換的一個好習慣是在變換前使用glPushMatrix儲存當前矩陣,完成座標變換操作後,再調用glPopMatrix恢複原先的矩陣設定。

最後利用上面介紹的座標變換知識,來繪製3個正方形A,B,C。進行縮放變換,使的B比A小50%,C比B小50%。 然後以螢幕中心逆時針旋轉A,B以A為中心順時針旋轉,C以B為中心順時針旋轉同時以自己中心高速逆時針旋轉。

修改 onDrawFrame 代碼如下:

public void onDrawFrame(GL10 gl) { // Clears the screen and depth buffer. gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); // Replace the current matrix with the identity matrix gl.glLoadIdentity(); // Translates 10 units into the screen. gl.glTranslatef(0, 0, -10); // SQUARE A // Save the current matrix. gl.glPushMatrix(); // Rotate square A counter-clockwise. gl.glRotatef(angle, 0, 0, 1); // Draw square A. square.draw(gl); // Restore the last matrix. gl.glPopMatrix(); // SQUARE B // Save the current matrix gl.glPushMatrix(); // Rotate square B before moving it, //making it rotate around A. gl.glRotatef(-angle, 0, 0, 1); // Move square B. gl.glTranslatef(2, 0, 0); // Scale it to 50% of square A gl.glScalef(.5f, .5f, .5f); // Draw square B. square.draw(gl); // SQUARE C // Save the current matrix gl.glPushMatrix(); // Make the rotation around B gl.glRotatef(-angle, 0, 0, 1); gl.glTranslatef(2, 0, 0); // Scale it to 50% of square B gl.glScalef(.5f, .5f, .5f); // Rotate around it's own center. gl.glRotatef(angle*10, 0, 0, 1); // Draw square C. square.draw(gl); // Restore to the matrix as it was before C. gl.glPopMatrix(); // Restore to the matrix as it was before B. gl.glPopMatrix(); // Increse the angle. angle++; }

本例代碼下載

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.