2012年11月13日 星期二

Android:OpenGL 座標變換

*注意要領*

  1. 注意glPushMatrix以及glPopMatrix的交互使用配合以建構出設想的模式
  2. glTranslatef (float x, float y, float z) 平移座標軸
  3. glRotatef(float angle, float x, float y, float z) 旋轉座標軸
  4. glScalef (float x, float y, float z) 縮大或放小
  5. 可以透過不斷的改變角度或其他參數來達到動態的效果
OpenGLRenderer

package com.example.opengltest2;

import ...

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();
 
 gl.glTranslatef(0, 0, -10);//Z軸轉置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);
 // 以自己為中心旋轉,12倍目的是為了自轉比較快的效果
 gl.glRotatef(angle * 12, 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);
 //float ratio=(float)width/height;//比例大小
//gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);//設定投影模式
 // 選擇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);

}

}






5 則留言:

  1. 請問我有可能跟您要這個程式嗎?
    想要實作但沒成功,個人研究用。

    回覆刪除
  2. https://www.box.com/s/c4lbiikgo1mvq5ddmjfx

    看看

    回覆刪除
  3. 你好,我已經收到您的程式,非常感謝。
    另外我想請教,如果我要將四方型旋轉方式藉由方向感測器接收的值來運行,這樣是否可行?
    站主若知道任何資源可否分享給我知道一下,在此非常感謝。

    回覆刪除
  4. 應該是可以的,還看過蠻多類似應用
    不過我想首先應該要先了解Sensor的API怎麼用...

    有一本書http://www.books.com.tw/exep/prod/booksfile.php?item=0010527598
    如果想學全面一些OpenGL ES 1.0 for Android,這本書還不錯
    它裡面Chapter12就是專門講這個,還附一個現成範例
    給你參考~

    回覆刪除