在libgdx中加载模型
Loading models using LibGDX
- 资源准备:
一件模型(你也可以使用你自己的模型):
(来自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和输入命令: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
);
...
}
...
}