gt: 			sun = new Light ( world );
context: 
  package com.cube.GLCube.GL;
  
  import java.util.Collections;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  
  import javax.microedition.khronos.egl.EGLConfig;
  import javax.microedition.khronos.opengles.GL10;
  
  import android.graphics.Bitmap;
  import android.opengl.GLSurfaceView;
  import android.os.Bundle;
  import android.os.Parcelable;
  import android.util.Log;
  
  import com.cube.GLCube.UIConnect.ConnectToUI;
  import com.cube.GLCube.UIConnect.ConnectToUI.FutureLayout;
  import com.cube.GLCube.UIConnect.CubeSide;
  import com.cube.GLCube.UIConnect.Run;
  import com.cube.GLCube.UIConnect.Run.RunnableListener;
  import com.cube.GLCube.UIConnect.XMLLoad;
  import com.cube.UI.MainActivity;
  import com.cube.UI.TouchEventListener;
  import com.threed.jpct.Camera;
  import com.threed.jpct.FrameBuffer;
  import com.threed.jpct.Light;
  import com.threed.jpct.RGBColor;
  import com.threed.jpct.SimpleVector;
  import com.threed.jpct.World;
  import com.threed.jpct.util.MemoryHelper;
  
  public class GLRenderer extends Render
  {
  	private FrameBuffer fb;
  	private World world;
  	private Light sun;
  	private Map < String, CubeSide > layouts;
  	private List < FutureLayout < Bitmap >> textureInit;
  	private List < String > sides;
  	private RGBColor backgroundColor;
  	private Background back;
  	private Cube cube;
  	
  	private float[] cubeMatrixInit = null;
  	
  	MainActivity activity;
  
  	public GLRenderer ( MainActivity activity, GLSurfaceView parent )
  	{
  		super ( activity, parent );
  		this.activity = activity;
  		backgroundColor = new RGBColor ( 26, 130, 247 );
  		back = new Background ( );
  	}
  	
  	void onRestoreInstanceState(Parcelable state){
  		if (!(state instanceof Bundle)) {
  			return;
  		}
  		Bundle bundle = (Bundle) state;
  		cubeMatrixInit = bundle.getFloatArray("cubeRotation");
  		super.onResume();
  	}
  	
  	Parcelable onSaveInstanceState(){
  		Bundle bundle = new Bundle();
  		if( cube != null )
  			bundle.putFloatArray("cubeRotation", cube.getRotationMatrix().getDump());
  		else
  			bundle.putFloatArray("cubeRotation", cubeMatrixInit);
  		return bundle;
  	}
  	public boolean onInitializating ( GL10 gl )
  	{
  		//Log.d("CubeGL","Initing");
  		if ( world == null )
  		{
  			return true;
  		}
  		sides = XMLLoad.getSides ( activity );
  		
  		final Run < HashMap < String, CubeSide > > layoutInit = ConnectToUI.createLayouts ( sides,
  				Math.min ( fb.getWidth ( ), fb.getHeight ( ) ), activity );
  		
  		textureInit = ConnectToUI.loadTexture ( sides );
  		layoutInit.addListener ( new RunnableListener < HashMap < String, CubeSide > > ( ) {
  			
  			@Override
  			public void onResultComputed ( Run < HashMap < String, CubeSide >> runnable,
  					HashMap < String, CubeSide > result )
  			{
  				layouts = Collections.unmodifiableMap ( result );
  				for ( FutureLayout < Bitmap > futureTask : textureInit )
  				{
  					String side = futureTask.getLayoutName ( );
  					futureTask.setLayout ( layouts.get ( side ) );
  				}
  			}
  			
  		} );
  		
  		wait ( layoutInit );
  		for ( FutureLayout < Bitmap > futureTask : textureInit )
  		{
  			wait ( futureTask );
  		}
  		return false;
  	}
  	
  	public boolean onInitialized ( GL10 gl )
  	{
  		//Log.d("CubeGL","Inited");
  		cube = new Cube ( this, layouts );
  		cube.setTextures ( textureInit );
  		if ( cubeMatrixInit != null )
  		{
  			cube.getRotationMatrix().setDump(cubeMatrixInit);
  			cube.rotateX(0.0001f);
  		}
  		else
  		{
  			//cube.fold ( 2000 );
  		}
  		return false;
  	}
  	
  	public void onDrawing ( GL10 gl )
  	{
  		//Log.d("CubeGL","onDraw");
  		if ( TouchEventListener.scaleSpan > 0 )
  		{
  			String side = cube.getInZoomSide ( );
  			if ( side != null )
  			{
  				CubeSide cs = cube.getCubeSide ( side );
  				cs.onCubeRotateWhileZoom ( TouchEventListener.scaleSpan );
  			}
  		}
  		if ( TouchEventListener.displacementX != 0 )
  		{
  			cube.rotateY ( TouchEventListener.displacementX );
  		}
  		
  		if ( TouchEventListener.displacementY != 0 )
  		{
  			cube.rotateX ( TouchEventListener.displacementY );
  		}
  		
  		if ( TouchEventListener.velocityX != 0 || TouchEventListener.velocityY != 0 )
  		{
  			cube.animateRotation ( TouchEventListener.velocityY / 2.5f,
  					TouchEventListener.velocityX / 2.5f, 60f );
  		}
  		
  		if ( TouchEventListener.rotationZ != 0 )
  		{
  			cube.rotateZ ( TouchEventListener.rotationZ/10f );
  		}
  		
  		TouchEventListener.resetTouchInfo ( );
  		fb.clear ( backgroundColor );
  		back.draw ( gl );
  		cube.draw ( );
  		world.renderScene ( fb );
  		world.draw ( fb );
  		fb.display ( );
  	}
  	
  	@Override
  	public void onSurfaceChanged ( GL10 gl, final int w, final int h )
  	{
  		if ( fb != null )
  		{
  			fb.dispose ( );
  		}
  		fb = new FrameBuffer ( gl, w, h );
  		
  		// If orientation changed but it's not an initialization
  		if ( layouts != null )
  		{
  			Runnable r = new Runnable ( ) {
  				@Override
  				public void run ( )
  				{
  					for ( CubeSide cs : layouts.values ( ) )
  					{
  						cs.onLayoutChanged ( );
  					}
  				}
  			};
  			activity.runOnUiThread ( r );
  			textureInit = ConnectToUI.loadTexture ( sides );
  			for ( FutureLayout < Bitmap > futureTask : textureInit )
  			{
  				final String side = futureTask.getLayoutName ( );
  				futureTask.setLayout ( layouts.get ( side ) );
  				futureTask.addListener ( new RunnableListener < Bitmap > ( ) {
  					
  					@Override
  					public void onResultComputed ( Run < Bitmap > runnable, Bitmap result )
  					{
  						//Log.d("CubeGL","side:"+side+" result:"+result+" cube:" + cube );
  						cube.setTexture ( result, side );
  					}
  				} );
  				wait ( futureTask );
  			}
  		}
  		if ( world == null )
  		{
  			world = new World ( );
  			world.setAmbientLight ( 100, 100, 100 );
  			
  