Hello World for Android

From JPCT
Revision as of 19:26, 15 October 2010 by Admin (Talk | contribs)

Jump to: navigation, search

A very simply HelloWorld for jPCT-AE

This code should help to get you started. Currently, it lacks inline documentation...i'll add this later. It also lacks proper handling of stop and especially pause events. If you can improve this, i would be very grateful. For now, it's better than nothing. It displays a simple, lit cube that you can rotate by using the touch screen.

package com.threed.jpct.example;

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;

/**
 * A simple demo. This shows more how to use jPCT-AE than it shows how to write
 * a proper application for Android, because i have no idea how to do this. This
 * thing is more or less a hack to get you started...
 * It lacks proper handling of pause and stop for example...
 * 
 * @author EgonOlsen
 * 
 */
public class HelloWorld extends Activity {

	private GLSurfaceView mGLView;
	private MyRenderer renderer = null;
	private FrameBuffer fb = null;
	private World world = null;
	private boolean paused = false;
	private RGBColor back = new RGBColor(50, 50, 100);
	
	private float touchTurn = 0;
	private float touchTurnUp = 0;

	private float xpos = -1;
	private float ypos = -1;
	
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Logger.log("onCreate");
		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() {
		paused = true;
		super.onPause();
		mGLView.onPause();
	}

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

	protected void onStop() {
		renderer.stop();
		super.onStop();
	}

	public boolean onTouchEvent(MotionEvent me) {

		try {
			Thread.sleep(15);
		} catch(Exception e) {
			// No need for this...
		}
		
		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;
		}
		return super.onTouchEvent(me);
	}


	protected boolean isFullscreenOpaque() {
		return true;
	}

	class MyRenderer implements GLSurfaceView.Renderer {

		private Object3D cube = null;

		private int fps = 0;

		private long time = System.currentTimeMillis();

		private Light sun = null;

		private boolean stop = false;

		public MyRenderer() {
		}

		public void stop() {
			stop = true;
			if (fb != null) {
				fb.dispose();
				fb = null;
			}
		}

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

		public void onSurfaceCreated(GL10 gl, EGLConfig config) {
			TextureManager.getInstance().flush();
			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);
		}

		public void onDrawFrame(GL10 gl) {

			try {
				if (!stop) {
					if (paused) {
						Thread.sleep(500);
					} else {
						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++;
					}
				} else {
					if (fb != null) {
						fb.dispose();
						fb = null;
					}
				}
			} catch (Exception e) {
				Logger.log("Drawing thread terminated!", Logger.MESSAGE);
			}
		}
	}
}