2011.03.23 15:17 Android/OpenGL



enGLTest.java - 메인 액티비티
package pe.berabue.opengl;

import android.app.*;
import android.os.*;
import android.view.*;

public class OpenGLTest extends Activity {
    /** Called when the activity is first created. */
	
	public static GLGameSurfaceView mGLView;
	public static GLGameRenderer mGLRenderer;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 조명 항상켜기
         getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 
        
        mGLRenderer = new GLGameRenderer(this);
        mGLView = new GLGameSurfaceView(this);
        setContentView(mGLView);
    }
    
	@Override
	public void onPause() {
		mGLView.mGameThread.pauseThread();
		super.onPause();
	}

	@Override
	public void onResume() {
		mGLView.mGameThread.resumeThread();
		super.onResume();
	}
}


GLGameSurfaceView.java - 쓰레드가 있는 부분 
package pe.berabue.opengl;

import android.content.*;
import android.opengl.*;
import android.util.*;
import android.view.*;

public class GLGameSurfaceView extends GLSurfaceView{
	
	public static GameThread mGameThread;

	public static boolean isRun;
	public static boolean isWait;
	
	public GLGameSurfaceView(Context context) {
		super(context);
		setRenderer(OpenGLTest.mGLRenderer);
		setRenderMode(RENDERMODE_WHEN_DIRTY); // 한번만 그려줌
		setFocusableInTouchMode(true);
		
		mGameThread = new GameThread(context);
		mGameThread.start();
	}
	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		Log.v(null,"onKeyDown");
		return super.onKeyDown(keyCode, event);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		Log.v(null,"onTouchEvent");
		return super.onTouchEvent(event);
	}
	
	// Thread
	public class GameThread extends Thread {

		public GameThread(Context context) {
			isRun = true;
			isWait = false;
		}

		public void run() {
			while(isRun) {
				try {
					OpenGLTest.mGLView.requestRender(); // onDrawFrame
					mGameThread.sleep(10);
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
				synchronized (this) {
					if (isWait) {
						try { wait(); } catch (Exception e) {
							// 에러 무시
						}
	                }
				}//syn
			}
		}
		
		/* Thread pause */
		public void pauseThread() {
			isWait = true;
			synchronized (this) {
				this.notify();
			}
		}

		/* Thread Resume */
		public void resumeThread() {
			isWait = false;
	        synchronized (this) {
	             this.notify();
	        }
	    }
	}
}
setRenderMode(RENDERMODE_WHEN_DIRTY); 
GLGameRenderer의 그려주는 부분에서 1회만 그려준다. 파라메터를 RENDERMODE_CONTINUOUSLY로 바꿀 경우 계속 그리기.
1회만 그리는 이유는 멀티쓰레드를 사용하여 원활한 키 입력이나 터치를 받기 위해서 라는데.. 동기화는 다음에 생각하기로...

OpenGLTest.mGLView.requestRender();
requestRender();는 onDrawFrame();을 호출한다. GLGameRenderer의 onDrawFrame();호출.


GLGameRenderer.java - 실제로 그려지는 부분
package pe.berabue.opengl;

import javax.microedition.khronos.egl.*;
import javax.microedition.khronos.opengles.*;

import android.content.*;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.*;

public class GLGameRenderer implements Renderer {

	public GLGameRenderer(Context context) {
		
	}
	
	@Override
	public void onDrawFrame(GL10 gl) {
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
		// 실제 그려지는 부분..
	}

	@Override
	public void onSurfaceChanged(GL10 gl, int width, int height) {
		
	}

	@Override
	public void onSurfaceCreated(GL10 gl, EGLConfig arg1) {
		gl.glClearColor(0, 1, 0, 0.5f);	// RGBA 배경화면  0-> 1 점점밝아짐
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);	// ??
	}

}

Renderer을 구현(implemets)하게되면 기본적으로 위 3개의 메서드를 추가해야 된다.
onDrawFrame(); 실제로 그려지는 부분. 이 부분을 주기적으로 호출해 그림을 그려준다.
onSurfaceChanged(); 화면이 바뀔때 실행되는 부분.(실행시, orientation이 변경될때 등)
onSurfaceCreated(); 처음 실행 후 만들어질때 실행된다. (홈키를 누르거나 전화를 받고 다시 화면이 나올때도 실행)


GLGameRenderer에 조금 더 추가하면 기본적인 틀이 완성. 오늘은 여기까지.


실행화면

 

 



posted by 베라뷰