2011年4月17日 星期日

[ Android OpenGL ES 教學(三)] 轉換相關方法

基礎閱讀:[ Android OpenGL ES 教學(二)] 建立多邊形 發表在http://cheng-min-i-taiwan.blogspot.com/2011/04/android-opengl-es_17.html
延伸閱讀:[ Android OpenGL ES 教學(四)] 添加顏色 發表在 http://cheng-min-i-taiwan.blogspot.com/2011/05/android-opengl-es.html
參考文章:OpenGL ES Tutorial for Android – Part III – Transformations 發表在 http://blog.jayway.com/2010/01/01/opengl-es-tutorial-for-android-–-part-iii-–-transformations/




(以下圖形摘自參考文章)
坐標系統


轉換或移動
可以利用下列函式
public abstract void glTranslatef (float x, float y, float z)



旋轉
可以利用下列函式
public abstract void glRotatef(float angle, float x, float y, float z)



縮小或放大
可以利用下列函式
public abstract void glScalef (float x, float y, float z)



其他常用函式
1. 以單位矩陣取代目前的矩陣
public abstract void glLoadIdentity()
2. 儲存目前陣列
public abstract void glPushMatrix()
3. 恢復以前儲存陣列
public abstract void glPopMatrix()

以列是OpenGLRenderer.java程式列表(新增的程式用藍色字表示)


package nkut.cce.smartliving.opengl;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;

public class OpenGLRenderer implements Renderer {
private Square square;
private float angle = 0;

public OpenGLRenderer() {
// 初始化
square = new Square();
}

@Override
public void onDrawFrame(GL10 gl) {
// TODO Auto-generated method stub
// 清除螢幕和深度緩衝區
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// 以單位矩陣取代目前的矩陣
gl.glLoadIdentity();

// Z軸轉置 10 單位
gl.glTranslatef(0, 0, -10);

// 第一個方形
// 存儲目前陣列
gl.glPushMatrix();
// 反時鐘旋轉
gl.glRotatef(angle, 0, 0, 1);
// 畫出第一個方形
square.draw(gl);
// 復原成最後的矩陣
gl.glPopMatrix();

// 第二個方形
// 存儲目前陣列
gl.glPushMatrix();
// 在移動前先旋轉, 讓第二個方形圍繞著第一個方形旋轉
gl.glRotatef(-angle, 0, 0, 1);
// 移動第二個方形
gl.glTranslatef(2, 0, 0);
// 調整其大小為第一個方形的一半
gl.glScalef(.5f, .5f, .5f);
// 畫出第二個方形
square.draw(gl);

// 第三個方形
// 存儲目前陣列
gl.glPushMatrix();
// 讓第三個方形圍繞著第二個方形旋轉
gl.glRotatef(-angle, 0, 0, 1);
// 移動第三個方形
gl.glTranslatef(2, 0, 0);
// 調整其大小為第二個方形的一半
gl.glScalef(.5f, .5f, .5f);
// 以自己為中心旋轉
gl.glRotatef(angle * 10, 0, 0, 1);
// 畫出第三個方形.
square.draw(gl);

// 復原成第三個方形前的矩陣
gl.glPopMatrix();
// 復原成第二個方形前的矩陣.
gl.glPopMatrix();

// 增加角度
angle++;

}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// TODO Auto-generated method stub
// 設定新視域視窗的大小
gl.glViewport(0, 0, width, height);
// 選擇投射的陣列模式
gl.glMatrixMode(GL10.GL_PROJECTION);
// 重設投射陣
gl.glLoadIdentity();
// 計算視窗的寬高比率
GLU.gluPerspective(gl, 45.0f, (float) width / (float) height, 0.1f,
100.0f);
// 選擇MODELVIEW陣列
gl.glMatrixMode(GL10.GL_MODELVIEW);
// 重設MODELVIEW陣列
gl.glLoadIdentity();
}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
// 設定背景顏色為黑色, 格式是RGBA
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
// 設定流暢的陰影模式
gl.glShadeModel(GL10.GL_SMOOTH);
// 深度緩區的設定
gl.glClearDepthf(1.0f);
// 啟動深度的測試
gl.glEnable(GL10.GL_DEPTH_TEST);
// GL_LEQUAL深度函式測試
gl.glDepthFunc(GL10.GL_LEQUAL);
// 設定很好的角度計算模式
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
}

}

沒有留言:

張貼留言