在上一个教程中,我们已经了解了如何使用LibGDX转换、加载和显示模型。现在我们来看看如何加载一个完整的3D场景。
这里我们继续使用上一篇的代码。我们有一个ModelInstance实例数组,我们将使用它来定义场景。我们已经学习了如何加载飞船模型,接下来让我们再添加几个模型。你可以点击这里下载这本篇教程使用的模型。它包含4个模型(obj文件):
之前我们使用fbx-conv转换模型。我们也将对这些模型进行转换,但现在我们只使用obj文件。如下为加载这些模型的代码:
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.graphics.g3d.Environment;
import com.badlogic.gdx.graphics.g3d.Model;
import com.badlogic.gdx.graphics.g3d.ModelBatch;
import com.badlogic.gdx.graphics.g3d.ModelInstance;
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
import com.badlogic.gdx.graphics.g3d.environment.DirectionalLight;
import com.badlogic.gdx.graphics.g3d.utils.CameraInputController;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Array;
public class MainGame extends ApplicationAdapter{
public PerspectiveCamera cam;
private CameraInputController camCtrol;
private ModelBatch modelBatch;
private AssetManager assets;
private Array<ModelInstance> instances = new Array<>();
private Environment env;
private boolean loading;
private Array<ModelInstance> blocks = new Array<>();
private Array<ModelInstance> invaders = new Array<>();
private ModelInstance ship;
private ModelInstance space;
@Override
public void create() {
modelBatch = new ModelBatch();
env = new Environment();
env.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 0.4f, 0.4f, 1f));
env.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(7f, 7f, 7f);
cam.lookAt(0,0,0);
cam.near = 1f;
cam.far = 300f;
cam.update();
camCtrol = new CameraInputController(cam);
Gdx.input.setInputProcessor(camCtrol);
assets = new AssetManager();
assets.load("model/scene/ship.obj", Model.class);
assets.load("model/scene/block.obj", Model.class);
assets.load("model/scene/invader.obj", Model.class);
assets.load("model/scene/spacesphere.obj", Model.class);
loading = true;
}
private void doneLoading() {
ship = new ModelInstance(assets.get("model/scene/ship.obj", Model.class));
ship.transform.setToRotation(Vector3.Y, 180).trn(0, 0, 6f);
instances.add(ship);
Model blockModel = assets.get("model/scene/block.obj", Model.class);
for (float x = -5f; x <= 5f; x += 2f) {
ModelInstance block = new ModelInstance(blockModel);
block.transform.setToTranslation(x, 0, 3f);
instances.add(block);
blocks.add(block);
}
Model invaderModel = assets.get("model/scene/invader.obj", Model.class);
// invaderModel.animations.i
for (float x = -5f; x <= 5f; x += 2f) {
for (float z = -8f; z <= 0f; z += 2f) {
ModelInstance invader = new ModelInstance(invaderModel);
invader.transform.setToTranslation(x, 0, z);
instances.add(invader);
invaders.add(invader);
}
}
space = new ModelInstance(assets.get("model/scene/spacesphere.obj", Model.class));
loading = false;
}
@Override
public void resize (int width, int height) {
}
@Override
public void render () {
if (loading && assets.update())
doneLoading();
camCtrol.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, env);
if (space != null)
modelBatch.render(space);
modelBatch.end();
}
@Override
public void pause () {
}
@Override
public void resume () {
}
@Override
public void dispose () {
modelBatch.dispose();
instances.clear();
assets.dispose();
}
}
这里测试我用的是obj文件,如上一篇所述,应该使用fbx-conv将其转换才会使性能更好点。运行效果如下: