Difference between revisions of "Hello World for Android"

From JPCT
Jump to: navigation, search

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 861

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 862

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 587

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 608

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 608

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 608

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 608

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 608

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 608

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 608

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 608

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 608

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 608

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 608

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 587

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 608

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 608

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 608

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 608

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 608

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 608

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 608

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 608

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 608

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 608

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 608

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 241

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 242

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 241

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 242

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954

Deprecated: assert(): Calling assert() with a string argument is deprecated in /usr/home/ws10522/public_html/wiki/includes/diff/DairikiDiff.php on line 954
Line 247: Line 247:
 
====Comments on the source code====
 
====Comments on the source code====
  
=====onCreate=====
+
=====onCreate(Bundle savedInstanceState)=====
  
 
This is the basic setup for an Activity that uses OpenGL ES 1.x. It can be found in many Android examples except for two small parts:
 
This is the basic setup for an Activity that uses OpenGL ES 1.x. It can be found in many Android examples except for two small parts:
Line 281: Line 281:
 
mGLView.setRenderer(renderer);
 
mGLView.setRenderer(renderer);
 
setContentView(mGLView);
 
setContentView(mGLView);
 +
}
 +
</pre>
 +
 +
=====copy(Object src)=====
 +
 +
Again, this is my way to implement pause/resume/destroy/create of the Activity. It's pretty hacky. The basic idea is to keep a copy of the first instance of the Activity in a static field and copy all other fields to the new one. Again, i don't claim that this is a good solution. But it works for me and i never bothered to find another one.
 +
 +
<pre>
 +
private void copy(Object src) {
 +
try {
 +
Logger.log("Copying data from master Activity!");
 +
Field[] fs = src.getClass().getDeclaredFields();
 +
for (Field f : fs) {
 +
f.setAccessible(true);
 +
f.set(this, f.get(src));
 +
}
 +
} catch (Exception e) {
 +
throw new RuntimeException(e);
 +
}
 
}
 
}
 
</pre>
 
</pre>
  
 
[[Category:jPCT-AE]]
 
[[Category:jPCT-AE]]

Revision as of 23:14, 2 February 2013

A very simple HelloWorld for jPCT-AE

This code should help to get you started. It displays a simple, lit cube that you can rotate by using the touch screen. It includes basic pause/resume handling. I'll post the complete source code and comment on some important parts later on the page.

The source cde

package com.threed.jpct.example;

import java.lang.reflect.Field;

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

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.MotionEvent;

import com.threed.jpct.Camera;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.Light;
import com.threed.jpct.Logger;
import com.threed.jpct.Object3D;
import com.threed.jpct.Primitives;
import com.threed.jpct.RGBColor;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.Texture;
import com.threed.jpct.TextureManager;
import com.threed.jpct.World;
import com.threed.jpct.util.BitmapHelper;
import com.threed.jpct.util.MemoryHelper;

/**
 * A simple demo. This shows more how to use jPCT-AE than it shows how to write
 * a proper application for Android. It includes basic activity management to
 * handle pause and resume...
 * 
 * @author EgonOlsen
 * 
 */
public class HelloWorld extends Activity {

	// Used to handle pause and resume...
	private static HelloWorld master = null;

	private GLSurfaceView mGLView;
	private MyRenderer renderer = null;
	private FrameBuffer fb = null;
	private World world = null;
	private RGBColor back = new RGBColor(50, 50, 100);

	private float touchTurn = 0;
	private float touchTurnUp = 0;

	private float xpos = -1;
	private float ypos = -1;

	private Object3D cube = null;
	private int fps = 0;

	private Light sun = null;

	protected void onCreate(Bundle savedInstanceState) {

		Logger.log("onCreate");

		if (master != null) {
			copy(master);
		}

		super.onCreate(savedInstanceState);
		mGLView = new GLSurfaceView(getApplication());

		mGLView.setEGLConfigChooser(new GLSurfaceView.EGLConfigChooser() {
			public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
				// Ensure that we get a 16bit framebuffer. Otherwise, we'll fall
				// back to Pixelflinger on some device (read: Samsung I7500)
				int[] attributes = new int[] { EGL10.EGL_DEPTH_SIZE, 16, EGL10.EGL_NONE };
				EGLConfig[] configs = new EGLConfig[1];
				int[] result = new int[1];
				egl.eglChooseConfig(display, attributes, configs, 1, result);
				return configs[0];
			}
		});

		renderer = new MyRenderer();
		mGLView.setRenderer(renderer);
		setContentView(mGLView);
	}

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

	@Override
	protected void onResume() {
		super.onResume();
		mGLView.onResume();
	}

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

	private void copy(Object src) {
		try {
			Logger.log("Copying data from master Activity!");
			Field[] fs = src.getClass().getDeclaredFields();
			for (Field f : fs) {
				f.setAccessible(true);
				f.set(this, f.get(src));
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public boolean onTouchEvent(MotionEvent me) {

		if (me.getAction() == MotionEvent.ACTION_DOWN) {
			xpos = me.getX();
			ypos = me.getY();
			return true;
		}

		if (me.getAction() == MotionEvent.ACTION_UP) {
			xpos = -1;
			ypos = -1;
			touchTurn = 0;
			touchTurnUp = 0;
			return true;
		}

		if (me.getAction() == MotionEvent.ACTION_MOVE) {
			float xd = me.getX() - xpos;
			float yd = me.getY() - ypos;

			xpos = me.getX();
			ypos = me.getY();

			touchTurn = xd / -100f;
			touchTurnUp = yd / -100f;
			return true;
		}

		try {
			Thread.sleep(15);
		} catch (Exception e) {
			// No need for this...
		}

		return super.onTouchEvent(me);
	}

	protected boolean isFullscreenOpaque() {
		return true;
	}

	class MyRenderer implements GLSurfaceView.Renderer {

		private long time = System.currentTimeMillis();

		public MyRenderer() {
		}

		public void onSurfaceChanged(GL10 gl, int w, int h) {
			if (fb != null) {
				fb.dispose();
			}
			fb = new FrameBuffer(gl, w, h);

			if (master == null) {

				world = new World();
				world.setAmbientLight(20, 20, 20);

				sun = new Light(world);
				sun.setIntensity(250, 250, 250);

				// Create a texture out of the icon...:-)
				Texture texture = new Texture(BitmapHelper.rescale(BitmapHelper.convert(getResources().getDrawable(R.drawable.icon)), 64, 64));
				TextureManager.getInstance().addTexture("texture", texture);

				cube = Primitives.getCube(10);
				cube.calcTextureWrapSpherical();
				cube.setTexture("texture");
				cube.strip();
				cube.build();

				world.addObject(cube);

				Camera cam = world.getCamera();
				cam.moveCamera(Camera.CAMERA_MOVEOUT, 50);
				cam.lookAt(cube.getTransformedCenter());

				SimpleVector sv = new SimpleVector();
				sv.set(cube.getTransformedCenter());
				sv.y -= 100;
				sv.z -= 100;
				sun.setPosition(sv);
				MemoryHelper.compact();

				if (master == null) {
					Logger.log("Saving master Activity!");
					master = HelloWorld.this;
				}
			}
		}

		public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		}

		public void onDrawFrame(GL10 gl) {
			if (touchTurn != 0) {
				cube.rotateY(touchTurn);
				touchTurn = 0;
			}

			if (touchTurnUp != 0) {
				cube.rotateX(touchTurnUp);
				touchTurnUp = 0;
			}

			fb.clear(back);
			world.renderScene(fb);
			world.draw(fb);
			fb.display();

			if (System.currentTimeMillis() - time >= 1000) {
				Logger.log(fps + "fps");
				fps = 0;
				time = System.currentTimeMillis();
			}
			fps++;
		}
	}
}

Comments on the source code

onCreate(Bundle savedInstanceState)

This is the basic setup for an Activity that uses OpenGL ES 1.x. It can be found in many Android examples except for two small parts:

  • The master/copy-lines: With these, i'm doing very basic pause/resume handling. I'm sure that there are better ways but this is the first thing that i came up with, i never had a problem with it and it works fine for me even in complex applications. Feel free to use anything you like instead.
  • The creation of a dedicated EGLConfigChooser: This serves one single purpose, which is to make 3D acceleration on my old Samsung Galaxy. I never came across any other device that required this and i most likely never will. But it doesn't hurt either, so i'm using it in all my OpenGL ES 1.x Activities. If you aren't targetting a real old device running on Android 1.5, you should be save to omit this part. If you are using OpenGL ES 2.0, it's not an issue anyway.
protected void onCreate(Bundle savedInstanceState) {

	Logger.log("onCreate");

	if (master != null) {
		copy(master);
	}

	super.onCreate(savedInstanceState);
	mGLView = new GLSurfaceView(getApplication());

	mGLView.setEGLConfigChooser(new GLSurfaceView.EGLConfigChooser() {
		public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
			// Ensure that we get a 16bit framebuffer. Otherwise, we'll fall
			// back to Pixelflinger on some device (read: Samsung I7500)
			int[] attributes = new int[] { EGL10.EGL_DEPTH_SIZE, 16, EGL10.EGL_NONE };
			EGLConfig[] configs = new EGLConfig[1];
			int[] result = new int[1];
			egl.eglChooseConfig(display, attributes, configs, 1, result);
			return configs[0];
		}
	});

	renderer = new MyRenderer();
	mGLView.setRenderer(renderer);
	setContentView(mGLView);
}
copy(Object src)

Again, this is my way to implement pause/resume/destroy/create of the Activity. It's pretty hacky. The basic idea is to keep a copy of the first instance of the Activity in a static field and copy all other fields to the new one. Again, i don't claim that this is a good solution. But it works for me and i never bothered to find another one.

private void copy(Object src) {
	try {
		Logger.log("Copying data from master Activity!");
		Field[] fs = src.getClass().getDeclaredFields();
		for (Field f : fs) {
			f.setAccessible(true);
			f.set(this, f.get(src));
		}
	} catch (Exception e) {
		throw new RuntimeException(e);
	}
}