網頁

2010年11月26日星期五

Android OpenGl 初始化設定

OPENGL 劃一個三角形 首先需要設定 OPENGL的參數,因為我們使用3D 所以於設定的時候啟動深度緩衝,因為3D繪圖會遇到一個問題,那一個三角形要先畫哪個後畫,你會想說很簡單由遠的地方開始畫,然後再畫近的,這個想法不錯,但是如果這兩個三角形是有切面的時候這樣的遠近算法就會失效,解決這個方法最快最簡的方法就是深度緩衝,深度緩衝就是建立一塊和畫面相同大小的記憶體(Depth buffer),當三角形要畫上每一像素的時候就去檢查這個像素的深度是否比較靠近鏡頭,如果比較近就可以畫上該像素,這就是深度緩衝的原理。
不過原理不太需要了解要畫3D記得打開他。

OPEN GL 是一個有限狀態機,所謂有限狀態機就是當你設定之後他就不會變動,除非你下指令把它取消,所以下了指指令
gl.glEnable(GL10.GL_DEPTH_TEST); //啟動深度測試
表示已經啟動了深度緩衝。



//視窗改變大小
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// TODO Auto-generated method stub
float ratio = (float) width / height;

gl.glViewport(0, 0, width, height); //設定opengl 繪圖視窗,全螢幕的話就是如左寫法
gl.glMatrixMode(GL10.GL_PROJECTION); //以下將設定opengl的 投射 參數(攝影機參數)
gl.glLoadIdentity(); //清除 投射矩陣
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); //設定可視座標也是重新定義座標,畫面座標 左邊 右邊 上邊 下邊 深度開始 深度結束

gl.glMatrixMode(GL10.GL_MODELVIEW); //表示任何的轉變將會影響到模型觀點的矩陣.
gl.glLoadIdentity(); //清除模型矩陣

}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);//設定最棒的顏色修正
gl.glClearColor(0.0f, 0, 0, 0); //清除背景顏色RGBA
gl.glShadeModel(GL10.GL_SMOOTH);//啟用平滑陰影

gl.glClearDepthf(1.0f); //清除深度緩衝
gl.glEnable(GL10.GL_DEPTH_TEST); //啟動深度測試
gl.glDepthFunc(GL10.GL_LEQUAL); //深度測試類型
}




Android OPENGL 程式架構



Android 要撰寫OPENGL
於CLASS 中要 implements Renderer
implements Renderer之後Eclipse 要求須要
import android.opengl.GLSurfaceView.Renderer;

然後必須建立三個事件,通常Eclipse會幫忙完成這件事情,
或是直接Copy 如下程式碼貼上使用


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

import android.opengl.GLSurfaceView.Renderer;

public class OpenglRendererClass implements Renderer{

@Override
public void onDrawFrame(GL10 arg0) {
// TODO Auto-generated method stub

}

@Override
public void onSurfaceChanged(GL10 arg0, int arg1, int arg2) {
// TODO Auto-generated method stub

}

@Override
public void onSurfaceCreated(GL10 arg0, EGLConfig arg1) {
// TODO Auto-generated method stub

}
}

這樣就建立起了Android 使用 Open gl 的基本架構
onDrawFrame 這個方法會一直被呼叫,呼叫的速度我猜測大概是每畫完一次畫面,就立刻再度被呼叫,所以他可以看成更新畫面的迴圈。
所有畫圖的指令都在寫在這個方法裡面。

onSurfaceChanged這個我解釋成,當畫面大小變動的時候,例如第一次執行,畫面大小調整成全螢幕,當畫面大小改變的時候須要改變OPENGL畫面設定參數

onSurfaceCreatedy字面上的意義比較簡單,當OPENGL被建立的時候,這個方法裡拿來做一些OPENGL初始化設定的動作。


有了這個基本的CLASS之後,我們怎麼讓ACTIVE 顯示我們的OPENG呢



import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.os.Bundle;

public class Opengl1 extends Activity {
/** Called when the activity is first created. */
Renderer render = new OpenglRendererClass();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

GLSurfaceView glView = new GLSurfaceView(this);
glView.setRenderer(render);
setContentView(glView);
}
}


什麼都沒有 黑黑的一片。 但是沒有出錯就是好的開始。

2010年10月30日星期六

關於圖片隨著dpi改變

關於圖片隨著dpi改變
http://blog.k-res.net/?p=642 中有介紹
细分了很多文件夹处理以支持不同设备的分辨率加载对应的图片,如drawable-hdpi,drawable-ldpi,drawable-mdpi 等,如果没有注意这个问题而将贴图图片随意安置的话,在decode的时候系统会默认根据设备dpi的不同对目标图片格式解码的同时进行大小调整,也就是 说有可能破坏原本已经是2^n大小的贴图图片,导致原本在模拟器上正确的绘图在真机上变成大白板!
解决这个问题的方法可以将图片放到不受dpi影响的drawable-nodpi中

2010年10月27日星期三

宅男要看,設計師更要知道

兩矩形快速偵測碰撞

兩矩形快速偵測碰撞公式
If (B.X1 > A.X2 Or B.Y1 > A.Y2 Or B.X2 < A.X1 Or B.Y2 < A.Y1) Then
碰撞
Else
沒碰撞
End If

2010年10月25日星期一

Android 貼圖速度

以下由模擬器測試結果

一次的getPixel 是 0.06ms
一次的DrawRect(0,0,100,100) 一次大約是0.12ms (565的環境下)
一次的DrawRect(0,0,100,100) 一次大約是0.17ms (ARGB 4444 8888的環境下)

一次的DrawRect(10,10,210,210) 一次大約是0.25ms (565的環境下)

一次的drawBitmap(Plant, 0, 0, paint); 大約是0.38ms (RGB565的環境下) Png 200 *200 無透明
一次的drawBitmap(Plant, 0, 0, paint); 大約是0.39ms (RGB565的環境下) JPG 200 *200 無透明

一次的drawBitmap(Plant, 0, 0, paint); 大約是0.18ms (RGB565的環境下) JPG 100 * 100 無透明

一次的drawBitmap(Plant, 0, 0, paint); 大約是0.54ms (RGB565的環境下) PNG 100 * 100 有透明
一次的drawBitmap(Plant, 0, 0, paint); 大約是0.52ms (ARGB8888的環境下) PNG 100 * 100 有透明

一次的drawBitmap(Plant, 0, 0, paint); 大約是2ms (RGB565的環境下) PNG 200 *200 有透明
一次的drawBitmap(Plant, 0, 0, paint); 大約是1.5ms (ARGB8888的環境下) PNG 200 *200 有透明

一次的drawCircle(50, 50, 50, paint); 一次大約是0.37ms (RGB565的環境下)
一次的DrawText 大約是0.11ms (565的環境下)
一次的DrawText 大約是0.12ms (ARGB 4444 8888的環境下)