輸入如何處理
若是開發一個交互型的應用(如游戲),通常需要子類化 GLSurfaceView,由此可以獲取輸入事件。下面有個例子:
java代碼:
- package eoe.ClearTest;
- import javax.microedition.khronos.egl.EGLConfig;
- import javax.microedition.khronos.opengles.GL10;
- import android.app.Activity;
- import android.content.Context;
- import android.opengl.GLSurfaceView;
- import android.os.Bundle;
- import android.view.MotionEvent;
- public class ClearActivity extends Activity
- {
- @Override
- protected void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- mGLView = new ClearGLSurfaceView(this);
- setContentView(mGLView);
- }
- @Override
- protected void onPause()
- {
- super.onPause();
- mGLView.onPause();
- }
- @Override
- protected void onResume()
- {
- super.onResume();
- mGLView.onResume();
- }
- private GLSurfaceView mGLView;
- }
- class ClearGLSurfaceView extends GLSurfaceView
- {
- public ClearGLSurfaceView(Context context)
- {
- super(context);
- mRenderer = new ClearRenderer();
- setRenderer(mRenderer);
- }
- public boolean onTouchEvent(final MotionEvent event)
- {
- queueEvent(new Runnable(){ public void run()
- { mRenderer.setColor(event.getX() / getWidth(), event.getY() / getHeight()1.0f); }}); return true; } ClearRenderer mRenderer; }
- class ClearRenderer implements GLSurfaceView.Renderer
- {
- public void onSurfaceCreated(GL10 gl, EGLConfig config)
- { // Do nothing special. }
- public void onSurfaceChanged(GL10 gl, int w, int h)
- { gl.glViewport(0, 0, w, h); }
- public void onDrawFrame(GL10 gl)
- { gl.glClearColor(mRed, mGreen, mBlue, 1.0f);
- gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
- }
- public void setColor(float r, float g, float b)
- {
- mRed = r; mGreen = g; mBlue = b; }
- private float mRed;
- private float mGreen;
- private float mBlue;
- }
這個應用在每一幀中清空屏幕。當 tap 屏幕時,改變屏幕的顏色。這里在 ClearGLSurfaceView.onTouchEvent() 中使用了 queueEvent()。queueEvent() 方法用於在 UI 線程和渲染線程間通信。也可以用起它的 Java 線程通信技術,如 synchronized 方法,但 queueEvent 最簡單的線程通信方法。
其他的GLSurfaceView例子
在Android SDK的API Demo例子程序中還有很多例子:
GLSurfaceView
Kube
Translucent GLSurfaceView:透明背景
Textured Triangle:紋理貼圖
Sprite Text:在 texture 上寫文本並顯示在 3D 場景中
Touch Rotate:旋轉 3D 對象
選擇一個Surface
GLSurfaceView 提供了接口可選擇 surface 的類型。默認情況下, GLSurfaceView 會使用一個 16 位 RGB frame buffer,帶 16 位深度。你也可以根據自己的需要進行選擇,比如在 Translucent GLSurfaceView 例子里,需要一個 Alpha 通道來實現透明。GLSurfaceView 提供了 setEGLSurfaceChooser()方法來選擇 surface。
選擇一個 RGB (565)的16位 framebuffer,接口如下:
setEGLConfigChooser(boolean needDepth)若要定制 red, green, blue, alpha 和 depth,則用如下接口:
setEGLConfigChooser(int redSize, int greenSize,int blueSize, int alphaSize,int depthSize, int stencilSize)使用自己實現的 EGLConfigChooser,用如下的接口:
setEGLConfigChooser(EGLConfigChooser configChooser)持續型渲染模式 & 通知型渲染模式
大多數 3D 應用,如游戲、模擬等都是持續型渲染的動畫,還有些 3D 應用是反應式的(reactive),它們往往先被動等待,當用戶有了動作再做出反應。對於這種應用,持續渲染屏幕是浪費時間。若開發反應式的應用,可以調用下面的方法
GLSurfaceView.setRenderMode(RENDERMODE_WHEN_DIRTY);停止持續渲染。當調用
GLSurfaceView.requestRender()時,程序再渲染屏幕。
調試
GLSurfaceView.setDebugFlags() 方法可以激活log或者錯誤檢測,它們可以幫助調試 OpenGL ES 調用。具體使用時,在 GLSurfaceView 的構造函數中,調用 setRender() 之前調用 GLSurfaceView.setDebugFlags()就可以了。下面是個例子:
java代碼:
- public ClearGLSurfaceView(Context context)
- {
- super(context);
- // Turn on error-checking and logging setDebugFlags(DEBUG_CHECK_GL_ERROR |DEBUG_LOG_GL_CALLS);
- mRenderer = new ClearRenderer(); setRenderer(mRenderer);
系列之Android GLSurfaceView用法詳解(一)的帖子鏈接http://www.eoeandroid.com/thread-96857-1-1.html