opengl ES

「opengl ES」の編集履歴(バックアップ)一覧に戻る

opengl ES - (2009/04/02 (木) 01:54:39) の編集履歴(バックアップ)


OpenGL ESの勉強を始める

ApiDemosのGLSurfaceViewを1クラスにまとめてみた。
public class Sample extends Activity {
	public static class MyView extends SurfaceView implements
			SurfaceHolder.Callback {

		public MyView(Context context) {
			super(context);
			SurfaceHolder mHolder = getHolder();
			mHolder.addCallback(this);
			mHolder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
		}

		@Override
		public void surfaceChanged(SurfaceHolder holder, int format, int width,
				int height) {
		}

		@Override
		public void surfaceCreated(SurfaceHolder holder) {
			EGL10 mEgl = (EGL10) EGLContext.getEGL();
			EGLDisplay mEglDisplay = mEgl
					.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
			int[] version = new int[2];
			mEgl.eglInitialize(mEglDisplay, version);
			EGLConfig[] configs = new EGLConfig[1];
			int[] num_config = new int[1];

			int[] configSpec = { EGL10.EGL_DEPTH_SIZE, 16, EGL10.EGL_NONE };

			mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1,
					num_config);
			EGLConfig mEglConfig = configs[0];

			/*
			 * Create an OpenGL ES context. This must be done only once, an
			 * OpenGL context is a somewhat heavy object.
			 */
			EGLContext mEglContext = mEgl.eglCreateContext(mEglDisplay,
					mEglConfig, EGL10.EGL_NO_CONTEXT, null);

			EGLSurface
			/*
			 * Create an EGL surface we can render into.
			 */
			mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, mEglConfig,
					holder, null);

			/*
			 * Before we can issue GL commands, we need to make sure the context
			 * is current and bound to a surface.
			 */
			mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
					mEglContext);

			GL10 gl = (GL10) mEglContext.getGL();

			gl.glViewport(0, 0, getWidth(), getHeight());

			/*
			 * Set our projection matrix. This doesn't have to be done each time
			 * we draw, but usually a new projection needs to be set when the
			 * viewport is resized.
			 */

			float ratio = (float) getWidth() / getHeight();
			gl.glMatrixMode(GL10.GL_PROJECTION);
			gl.glLoadIdentity();
			gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);

			/*
			 * Usually, the first thing one might want to do is to clear the
			 * screen. The most efficient way of doing this is to use glClear().
			 */

			gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

			/*
			 * Now we're ready to draw some 3D objects
			 */

			gl.glMatrixMode(GL10.GL_MODELVIEW);
			gl.glLoadIdentity();
			gl.glTranslatef(0, 0, -3.0f);

			gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
			gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

			// ---------
			int one = 0x10000;
			int vertices[] = { -one, -one, -one, one, -one, -one, one, one,
					-one, -one, one, -one, -one, -one, one, one, -one, one,
					one, one, one, -one, one, one, };

			int colors[] = { 0, 0, 0, one, one, 0, 0, one, one, one, 0, one, 0,
					one, 0, one, 0, 0, one, one, one, 0, one, one, one, one,
					one, one, 0, one, one, one, };

			byte indices[] = { 0, 4, 5, 0, 5, 1, 1, 5, 6, 1, 6, 2, 2, 6, 7, 2,
					7, 3, 3, 7, 4, 3, 4, 0, 4, 7, 6, 4, 6, 5, 3, 0, 1, 3, 1, 2 };

			IntBuffer mVertexBuffer;
			IntBuffer mColorBuffer;
			ByteBuffer mIndexBuffer;

			// Buffers to be passed to gl*Pointer() functions
			// must be direct, i.e., they must be placed on the
			// native heap where the garbage collector cannot
			// move them.
			//
			// Buffers with multi-byte datatypes (e.g., short, int, float)
			// must have their byte order set to native order

			ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
			vbb.order(ByteOrder.nativeOrder());
			mVertexBuffer = vbb.asIntBuffer();
			mVertexBuffer.put(vertices);
			mVertexBuffer.position(0);

			ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4);
			cbb.order(ByteOrder.nativeOrder());
			mColorBuffer = cbb.asIntBuffer();
			mColorBuffer.put(colors);
			mColorBuffer.position(0);

			mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
			mIndexBuffer.put(indices);
			mIndexBuffer.position(0);

			gl.glFrontFace(gl.GL_CW);
			gl.glVertexPointer(3, gl.GL_FIXED, 0, mVertexBuffer);
			gl.glColorPointer(4, gl.GL_FIXED, 0, mColorBuffer);
			gl.glDrawElements(gl.GL_TRIANGLES, 36, gl.GL_UNSIGNED_BYTE,
					mIndexBuffer);

			mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);

			if (mEglSurface != null) {
				mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE,
						EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
				mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
				mEglSurface = null;
			}
			if (mEglContext != null) {
				mEgl.eglDestroyContext(mEglDisplay, mEglContext);
				mEglContext = null;
			}
			if (mEglDisplay != null) {
				mEgl.eglTerminate(mEglDisplay);
				mEglDisplay = null;
			}

		}

		@Override
		public void surfaceDestroyed(SurfaceHolder holder) {

		}

	}

	private MyView mGLSurfaceView;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mGLSurfaceView = new MyView(this);
		setContentView(mGLSurfaceView);
	}

	@Override
	protected void onPause() {
		super.onPause();
	}

	@Override
	protected void onResume() {
		super.onResume();
	}
}
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。