libgdx3D第二讲-加载模型

在libgdx中加载模型

Loading models using LibGDX

  • 资源准备:
一件模型(你也可以使用你自己的模型):
ship.zip(来自LibGDX gdx-invaders)

将其解压到android project 的 assets folder 中(包括三个文件,要放在同一目录)
  • ship.obj: 将要加载的模型文件
  • ship.mtl:材质
  • ship.png: 纹理图片
注意:此模型为OBJ格式,仅仅是为了本次教程。OBJ格式不被完全支持,应当小心使用。之后将讲解如何将其转换的更适用。如果你是用自己的OBJ模型,你会发现它可能不能被正确渲染,这将在一会儿解决。

网页云笔记地址:http://note.youdao.com/share/?id=293374f0be5eee11ce1badd0f7458203&type=note        用到的资源我都粘贴在这里了
  • 教程开始:
  • 1.现在我们来改变Basic3DTest中使用的模型

public   class   LoadModelsTest  implements   ApplicationListener {
...
     @Override
     public   void   create () {
         modelBatch =  new   ModelBatch();
         environment =  new   Environment();
         environment.set( new   ColorAttribute(ColorAttribute.AmbientLight,  0 .4f,  0 .4f,  0 .4f, 1f));
         environment.add( new   DirectionalLight().set( 0 .8f,  0 .8f,  0 .8f, -1f, - 0 .8f, - 0 .2f));
         
         cam =  new   PerspectiveCamera( 67 , Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
         cam.position.set(1f, 1f, 1f);
         cam.lookAt( 0 , 0 , 0 );
         cam.near = 1f;
         cam.far = 300f;
         cam.update();
 
         ModelLoader loader =  new   ObjLoader();
         model = loader.loadModel(Gdx.files.internal( "data/ship.obj" ));
         instance =  new   ModelInstance(model);
 
         camController =  new   CameraInputController(cam);
         Gdx.input.setInputProcessor(camController);
     }
...
}
camera被拉近距离因为模型更小了;
ModelBuilder 被 ModelLoader 代替;

2.但在更大的应用程序,你可能想使用AssetManager来管理模型。所以,让我们添加AssetManager :
public   class   LoadModelsTest  implements   ApplicationListener {
     public   PerspectiveCamera cam;
     public   CameraInputController camController;
     public   ModelBatch modelBatch;
     public   AssetManager assets;
     public   Array<ModelInstance> instances =  new   Array<ModelInstance>();
     public   Environment environment;
     public   boolean   loading;
     
     @Override
     public   void   create () {
         modelBatch =  new   ModelBatch();
         environment =  new   Environment();
         environment.set( new   ColorAttribute(ColorAttribute.AmbientLight,  0 .4f,  0 .4f,  0 .4f, 1f));
         environment.add( new   DirectionalLight().set( 0 .8f,  0 .8f,  0 .8f, -1f, - 0 .8f, - 0 .2f));
         
         cam =  new   PerspectiveCamera( 67 , Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
         cam.position.set(1f, 1f, 1f);
         cam.lookAt( 0 , 0 , 0 );
         cam.near = 1f;
         cam.far = 300f;
         cam.update();
 
         camController =  new   CameraInputController(cam);
         Gdx.input.setInputProcessor(camController);
         
         assets =  new   AssetManager();
         assets.load( "data/ship.obj" , Model. class );
         loading =  true ;
     }
 
     private   void   doneLoading() {
         Model ship = assets.get( "data/ship.obj" , Model. class );
         ModelInstance shipInstance =  new   ModelInstance(ship);
         instances.add(shipInstance);
         loading =  false ;
     }
     
     @Override
     public   void   render () {
         if   (loading && assets.update())
             doneLoading();
         camController.update();
         
         Gdx.gl.glViewport( 0 0 , Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
         Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
 
         modelBatch.begin(cam);
         modelBatch.render(instances, environment);
         modelBatch.end();
     }
     
     @Override
     public   void   dispose () {
         modelBatch.dispose();
         instances.clear();
         assets.dispose();
     }
 
     public   void   resume () {
     }
 
     public   void   resize ( int   width,  int   height) {
     }
 
     public   void   pause () {
     }
}
Model被 AssetManager 代替;
ModelInstance 实例从一个变为多个;
增加了flag标志:是否在加载中;
在create()方法中创建 AssetManager并让其加载模型,之后设置flag来判断是否更新 AssetManager;
在render()方法中检查flag以及是否调用assets.update() 如果assets.update()返回true可知完成加载,我们调用新方法doneLoading(),当然在render()方法中我们渲染所有的 ModelInstance ;
 doneLoading()方法得到模型后,建立shipInstance 并将其加入 array中,进行渲染;
最后我们看到 loading flag 变为 false,assets.update() 不再被调用;
如果你在此时运行,你会看到输出的是和以前一样。虽然你可能会看到黑色屏幕在飞船之前弹出来,这是因为异步加载导致的。

3.现在再增加些东西
public   class   LoadModelsTest  implements   ApplicationListener {
...
     @Override
     public   void   create () {
         ...
         cam.position.set(7f, 7f, 7f);
         ...
     }
 
     private   void   doneLoading() {
         Model ship = assets.get( "data/ship.obj" , Model. class );
         for   ( float   x = -5f; x <= 5f; x += 2f) {
             for   ( float   z = -5f; z <= 5f; z += 2f) {
                 ModelInstance shipInstance =  new   ModelInstance(ship);
                 shipInstance.transform.setToTranslation(x, 0 , z);
                 instances.add(shipInstance);
             }
         }
         loading =  false ;
     }
...
}
我们移动相机远离原点,所以我们可以看到所有的飞船。您也可以滚动鼠标来放大或缩小。在doneLoading()方法中,我们现在了多个实例,它们排列在XZ平面上的网格位置上。


OBJ文件用来测试很好,但是在真实应用中不适合,因为文件缺失完整的渲染信息。LibGDX的ObjLoader功能仅用于测试且没有实现你可能要用到的所有功能。幸运的是有 fbx-conv来代替。FBX- CONV适用于转换多种文件格式(包括OBJ ),而FBX是首选的文件格式,因为几乎所有的建模应用程序支持该格式。有两种文件格式LibGDX支持, g3dj (这是JSON文本,便于调试)和g3db(二进制格式)
fbx-conv.zip
因此,让我们来转换我们的船模。下载FBX- CONV和输入命令:fbx-conv ship.obj   命令也可能是fbx-conv-win32所以请你尝试使用,我相信你会使用命令行(CLI),拖拽fbx文件到fbx-conv在大部分情况下是不行的。之后你会得到ship.g3db。

4.然后使用如下:
public   class   LoadModelsTest  implements   ApplicationListener {
...
     @Override
     public   void   create () {
         ...
         assets.load( "data/ship.g3db" , Model. class );
         ...
     }
 
     private   void   doneLoading() {
         Model ship = assets.get( "data/ship.g3db" , Model. class );
         ...
     }
...
}










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值