Android 3D jpct-ae 一个场景小例子

         jpct-ae 一个场景小例子,加载了一些3ds模型,并且实现了手指触摸移动,实现了上下左右键。但是,此处有两个3ds模型在最终的画面里面没有显示,程序也没有报错,不知道是为什么,这一点让我很纳闷。

源代码和3ds模型,材质图片下载地址:http://download.csdn.net/detail/itde1/4283530,模型图片在res/raw文件夹里面。

注意:1,Loader.load3DS返回的是Object3D[],是一个数组,一般选择数组的第一项。

    2,jpct-ae 里面rotate()默认的是逆时针方向旋转,若要顺时针方向旋转,则rotate(负数);

代码:

package com.je;
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 com.threed.jpct.Camera;
import com.threed.jpct.Config;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.Light;
import com.threed.jpct.Loader;
import com.threed.jpct.Logger;
import com.threed.jpct.Object3D;
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.MemoryHelper;

import android.app.Activity;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.Window;
import android.view.WindowManager;
  
public class JpctExampleActivity extends Activity {
	//JpctAdvancedExampleActivity对象用来处理activity的onPause和onResume
	public static JpctExampleActivity master=null;
	
	private GLSurfaceView mGLView;
	private MRenderer mRenderer=null;

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

	private float xpos = -1;
	private float ypos = -1;
	
	private int move=0;
	private float turn=0;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		// 如果本类对象不为NULL,将从Object中所有属性装入该类
		if(master!=null)
			copy(master);
		super.onCreate(savedInstanceState);
		mGLView=new GLSurfaceView(getApplication());
		// 使用自己实现的 EGLConfigChooser,该实现必须在setRenderer(renderer)之前
		// 如果没有setEGLConfigChooser方法被调用,则默认情况下,
		//   视图将选择一个与当前android.view.Surface兼容至少16位深度缓冲深度EGLConfig。
		mGLView.setEGLConfigChooser(new GLSurfaceView.EGLConfigChooser() {
			
			@Override
			public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
				// TODO Auto-generated method stub
				int[] att=new int[]{EGL10.EGL_DEPTH_SIZE,16,EGL10.EGL_NONE};
				EGLConfig[] config=new EGLConfig[1];
				int[] result = new int[1];
				egl.eglChooseConfig(display, att, config, 1, result);
				return config[0];
			}
		});
	
		mRenderer=new MRenderer();
		mGLView.setRenderer(mRenderer);
		setContentView(mGLView);
	}

	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
		mGLView.onPause();
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		mGLView.onResume();
	}

	@Override
	protected void onStop() {
		// TODO Auto-generated method stub
		super.onStop();
	}
	
	
	//实现手势触摸移动
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		//按下手指
		if(event.getAction()==MotionEvent.ACTION_DOWN){
			xpos=event.getX();
			ypos=event.getY();
			return true;
		}
		//抬起手指
		if (event.getAction() == MotionEvent.ACTION_UP) {
			xpos = -1;
			ypos = -1;
			touchTurn = 0;
			touchTurnUp = 0;
			return true;
		}
		//移动
		if (event.getAction() == MotionEvent.ACTION_MOVE) {
			float xd = event.getX() - xpos;
			float yd = event.getY() - ypos;

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

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

		try {
			Thread.sleep(15);
		} catch (Exception e) {
			
		}

		return super.onTouchEvent(event);
	}
	
	//实现上下左右键
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		// TODO Auto-generated method stub
		if(keyCode==KeyEvent.KEYCODE_DPAD_UP){
			move=2;
			return  true;
		}

		if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
			move = -2;
			return true;
		}

		if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
			turn = 0.05f;
			return true;
		}

		if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
			turn = -0.05f;
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}

	@Override
	public boolean onKeyUp(int keyCode, KeyEvent event) {
		// TODO Auto-generated method stub
		if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
			move = 0;
			return true;
		}

		if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
			move = 0;
			return true;
		}

		if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
			turn = 0;
			return true;
		}

		if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
			turn = 0;
			return true;
		}
		return super.onKeyUp(keyCode, event);
	}

	private void copy(Object src) {
	        try {
	            // 打印日志
	            Logger.log("Copying data from master Activity!");
	            // 返回一个数组,其中包含目前这个类的的所有字段的Filed对象
	            Field[] fs = src.getClass().getDeclaredFields();
	            // 遍历fs数组
	            for (Field f : fs) {
	                // 尝试设置无障碍标志的值。标志设置为false将使访问检查,设置为true,将其禁用。
	                f.setAccessible(true);
	                // 将取到的值全部装入当前类中
	                f.set(this, f.get(src));
	            }
	        } catch (Exception e) {
	            // 抛出运行时异常
	            throw new RuntimeException(e);
	        }
	    }
	

	class MRenderer implements GLSurfaceView.Renderer {
		
		private FrameBuffer fb=null;
		private World world=null;
		private RGBColor back=new RGBColor(100,100,100);
		private Object3D plane=null;//平面
		private Object3D tree1=null;//树
		private Object3D tree2=null;
		private Object3D rock=null;//石头
		private Object3D grass=null;//草
		private Object3D cube=null;//长方体
		private Object3D house=null;//房子
		private Object3D head=null;//一个骷髅头
		private Light light=null;
		
		private long time=System.currentTimeMillis();//返回的是以毫秒为单位的当前时间
		private SimpleVector lightRot=new SimpleVector(-100,-100f,100);
		
		public MRenderer(){
			//此代码在下一个例子中会解释
			Config.maxPolysVisible = 500;
			Config.farPlane = 1500;
			Config.glTransparencyMul = 0.1f;
			Config.glTransparencyOffset = 0.1f;
			Texture.defaultToMipmapping(true);
			Texture.defaultTo4bpp(true);
		}
		
		@Override
		public void onDrawFrame(GL10 gl) {
			// TODO Auto-generated method stub
			try {
				if (true) {
					Camera cam = world.getCamera();
					if (turn != 0) {
						world.getCamera().rotateY(-turn);
					}

					if (touchTurn != 0) {
						world.getCamera().rotateY(touchTurn);
						touchTurn = 0;
					}

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

					if (move != 0) {
						world.getCamera().moveCamera(cam.getDirection(), move);
					}

					fb.clear(back);
					world.renderScene(fb);//转换灯光和所有的多边形
					world.draw(fb);
					fb.display();//显示

					if (light != null) {
						light.rotate(lightRot, plane.getTransformedCenter());
					}
				} else {
					if (fb != null) {
						fb.dispose();
						fb = null;
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
				Logger.log("Drawing thread terminated!", Logger.MESSAGE);
			}
		}

		@Override
		public void onSurfaceChanged(GL10 gl, int width, int height) {
			// TODO Auto-generated method stub
			if(fb!=null)
				fb.dispose();//清理缓冲器
			fb=new FrameBuffer(gl,width,height);
			
		}

		@Override
		public void onSurfaceCreated(GL10 gl, EGLConfig config) {
			// TODO Auto-generated method stub
			if(JpctExampleActivity.master==null){
				world=new World();
				Resources res = getResources();
				//取得材质管理器
				TextureManager tm=TextureManager.getInstance();
				//取得纹理
				Texture grass2 = new Texture(res.openRawResource(R.raw.grassy));
				Texture leaves = new Texture(res.openRawResource(R.raw.tree2y));
				Texture leaves2 = new Texture(res.openRawResource(R.raw.tree3y));
				Texture rocky = new Texture(res.openRawResource(R.raw.rocky));
				Texture planetex = new Texture(res.openRawResource(R.raw.planetex));	
				Texture housey2 = new Texture(res.openRawResource(R.raw.photo));
				Texture heady=new Texture(res.openRawResource(R.raw.photo));
				//将纹理添加到材质管理器里面
				tm.addTexture("grass2", grass2);
				tm.addTexture("leaves", leaves);
				tm.addTexture("leaves2", leaves2);
				tm.addTexture("rock", rocky);
				tm.addTexture("grassy", planetex);
				tm.addTexture("housey2",housey2);
				tm.addTexture("heady",heady);
				//构造平面,该出用的是经过处理的数据
				plane = Loader.loadSerializedObject(res.openRawResource(R.raw.serplane));
				//加载岩石,树,草,房子,骷髅头的3ds模型
				//查看API文档可知,Loader.load3DS返回的是Object3D[],是一个数组,这里选择数组的第一项
				//数组第一项就是我们需要的模型,所以写为Loader.load3DS(  )[0];
				rock=Loader.load3DS(res.openRawResource(R.raw.rock), 30f)[0];
				tree1=Loader.load3DS(res.openRawResource(R.raw.tree2), 5f)[0];
				tree2=Loader.load3DS(res.openRawResource(R.raw.tree3), 5f)[0];
				grass=Loader.load3DS(res.openRawResource(R.raw.grass), 2f)[0];
				cube=Loader.load3DS(res.openRawResource(R.raw.cube), 1f)[0];
				//?????????? 在这里有些问题,house和head这两个3ds模型加载不进去?????????
				house=Loader.load3DS(res.openRawResource(R.raw.house1), 1f)[0];
				head=Loader.load3DS(res.openRawResource(R.raw.head), 1f)[0];
				//上面的house和head两个模型在最终的画面里面看不到,没有出现,笔者也不知道是为什么??????????????
				
				grass.translate(-45, -17, -50);//平移
				grass.rotateZ((float) Math.PI);
				rock.translate(0, 0, -90);
				//绕X轴旋转90度,注意:rotateX()默认的是逆时针方向旋转
				rock.rotateX(-(float) Math.PI / 2);
				tree1.translate(-50, -100, -50);
				tree1.rotateZ((float) Math.PI);
				tree2.translate(60, -95, -10);
				tree2.rotateZ((float) Math.PI);
				plane.rotateX((float) Math.PI / 2f);
				cube.translate(-80, 0, -110);
				cube.rotateX((float)Math.PI/2f);
				head.translate(-45, -17, -50);
				head.rotateZ((float) Math.PI);
				house.translate(-70, 0, -110);
				house.rotateX((float)Math.PI/2f);
				//下面的可要可不要
				house.setName("house");
				plane.setName("plane");
				tree1.setName("tree1");
				tree2.setName("tree2");
				grass.setName("grass");
				rock.setName("rock");
				//设置纹理方式
				house.calcTextureWrapSpherical();
				head.calcTextureWrapSpherical();
				cube.calcTextureWrapSpherical();
				//设置纹理
				house.setTexture("housey2");
				head.setTexture("heady");
				cube.setTexture("housey2");
				tree1.setTexture("leaves");
				tree2.setTexture("leaves2");
				rock.setTexture("rock");
				grass.setTexture("grass2");
				
				//加入到world里面
				world.addObject(plane);
				world.addObject(tree1);
				world.addObject(tree2);
				world.addObject(grass);
				world.addObject(rock);
				world.addObject(house);
				world.addObject(head);
				world.addObject(cube);
				//释放内存
				plane.strip();
				tree1.strip();
				tree2.strip();
				grass.strip();
				rock.strip();
				house.strip();
				head.strip();
				cube.strip();
				
				world.setAmbientLight(250, 250, 250);//设置光环境光
				world.buildAllObjects();//Calls build() for every object in the world.
				
				light = new Light(world);//设置光照
				light.setIntensity(250, 250, 0);//设置光颜色

				Camera cam = world.getCamera();
				cam.moveCamera(Camera.CAMERA_MOVEOUT, 250);
				cam.moveCamera(Camera.CAMERA_MOVEUP, 100);
				//相机的在plane的中心
				cam.lookAt(plane.getTransformedCenter());

				SimpleVector sv = new SimpleVector();
				sv.set(plane.getTransformedCenter());
				Log.e("X:", plane.getTransformedCenter().toString());
				sv.y -= 500;
				sv.x -= 300;
				sv.z += 200;
				//设置光照的位置,此处的sv为plane的中心
				light.setPosition(sv);
				//释放内存
				MemoryHelper.compact();
				if (master == null) {
					Logger.log("Saving master Activity!");
					master = JpctExampleActivity.this;
				}
			}
		}
	}
}

你可能感兴趣的:(JPCT-AE游戏引擎学习)