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

来源:互联网 发布:掌上阅读软件下载 编辑:程序博客网 时间:2024/06/05 01:58

         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和onResumepublic 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;@Overrideprotected 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() {@Overridepublic EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {// TODO Auto-generated method stubint[] 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);}@Overrideprotected void onPause() {// TODO Auto-generated method stubsuper.onPause();mGLView.onPause();}@Overrideprotected void onResume() {// TODO Auto-generated method stubsuper.onResume();mGLView.onResume();}@Overrideprotected void onStop() {// TODO Auto-generated method stubsuper.onStop();}//实现手势触摸移动@Overridepublic 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);}//实现上下左右键@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {// TODO Auto-generated method stubif(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);}@Overridepublic boolean onKeyUp(int keyCode, KeyEvent event) {// TODO Auto-generated method stubif (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);}@Overridepublic void onDrawFrame(GL10 gl) {// TODO Auto-generated method stubtry {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);}}@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) {// TODO Auto-generated method stubif(fb!=null)fb.dispose();//清理缓冲器fb=new FrameBuffer(gl,width,height);}@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) {// TODO Auto-generated method stubif(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;}}}}}

原创粉丝点击