Libgdx New 3D API 教程之 -- Libgdx 3D 基础

时间:2022-08-17 20:39:50

This blog is a chinese version of xoppa's Libgdx new 3D api tutorial. For English version, please refer to >>LINK<<

翻译至: Libgdx的作者之一Xoppa的博文:http://blog.xoppa.com/basic-3d-using-libgdx-2/


本教程将指导您使用LibGDX 3D API提供的基础功能。我假设你已经熟悉LibGDX,让我们建立一个新的项目,并调用它Basic3DTest。我们将要实现ApplicationListener接口,所以让我们从这里开始:

public class Basic3DTest implements ApplicationListener {
@Override
public void create () {
}

@Override
public void render () {
}

@Override
public void dispose () {
}

@Override
public void resume () {
}

@Override
public void resize (int width, int height) {
}

@Override
public void pause () {
}
}

现在我们来加点内容。

首先,我们要添加一下相机,这样,才3D的场景中才有相应的效果:

public class Basic3DTest implements ApplicationListener {
public PerspectiveCamera cam;

@Override
public void create () {
cam = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
cam.position.set(10f, 10f, 10f);
cam.lookAt(0,0,0);
cam.near = 0.1f;
cam.far = 300f;
cam.update();
}
...
}
我们创建了一个PerectiveCamera,设置他的可视角度为67度(这也是一个常用设置),同时,也按照长宽比设置了当前的宽度和高度。然后,指定了camera的位置是基于原点的,右移10个单位,上移10个单位,后退10个单位。Z轴是指向观察者的,所以,对于观察者来说,正的Z值就是观察者向后移。相机正对着0,0,0这一点,因为那里会放我们的3D对象。设置near和far的值,确保我们总是可以看到我们物体。最后,我们将camera做一次更新,以便刷新相机的参数。

现在,我们要添加一些可见的物体。当然可以使用一些建模软件来得到一些模型(迟点讨论),现在,我们只在代码里实现一个盒子:

public class Basic3DTest implements ApplicationListener {
public PerspectiveCamera cam;
public Model model;
public ModelInstance instance;

@Override
public void create () {
cam = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
...
cam.update();

ModelBuilder modelBuilder = new ModelBuilder();
model = modelBuilder.createBox(5f, 5f, 5f,
new Material(ColorAttribute.createDiffuse(Color.GREEN)),
Usage.Position | Usage.Normal);
instance = new ModelInstance(model);
}

@Override
public void dispose () {
model.dispose();
}
...
}

在这里,我们实例化一个ModelBuilder,用于通过代码来创建模型。然后我们创建一个简单的盒子,尺寸为5x5x5。我们还指定了这个盒子的材质为:绿色漫反射颜色的材料,位置,正常的组件模型。我们创建了一个模型,至少Usage.Position是必需的。Usage.Normal是为盒子指定一些普通的性质,如正常的照明。Usage是VertexAttributes的子类。


一个模型包含一切渲染对象和资源信息。它不包含如模型的位置这样的信息。为此我们需要创建ModelInstance,它包含了要渲染模型的位置,旋转和缩放。默认情况下,位置是在(0,0,0),所以我们创建一个ModelInstance后,它将在(0,0,0)这里被渲染。


模型在不用时需要disposed,所以在Dispose()中加了一行。


现在,让我们的渲染模型实例。

public class Basic3DTest implements ApplicationListener {
public PerspectiveCamera cam;
public ModelBatch modelBatch;
public Model model;
public ModelInstance instance;

@Override
public void create () {
modelBatch = new ModelBatch();

cam = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
...
cam.update();

ModelBuilder modelBuilder = new ModelBuilder();
model = modelBuilder.createBox(5f, 5f, 5f,
new Material(ColorAttribute.createDiffuse(Color.GREEN)),
Usage.Position | Usage.Normal);
instance = new ModelInstance(model);
}

@Override
public void render () {
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

modelBatch.begin(cam);
modelBatch.render(instance);
modelBatch.end();
}

@Override
public void dispose () {
modelBatch.dispose();
model.dispose();
}
...
}

在这里,我们添加用于沉浸模型的ModelBatch,在create方法初始化它。在render方法中,我们先清除屏幕,然后调用modelBatch.begin(cam)方法,渲染我们的ModelInstance,然后调用modelBatch.end(),完成渲染。最后,我们还要销毁一下modelBatch,以确保所有的资源都得到正确的释放。

Libgdx New 3D API 教程之 -- Libgdx 3D 基础

看起来还不错,只是加点灯光可能会更好点,所以:

public class Basic3DTest implements ApplicationListener {
public Lights lights;
...

@Override
public void create () {
lights = new Lights();
lights.ambientLight.set(0.4f, 0.4f, 0.4f, 1f);
lights.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.2f));
...
}

@Override
public void render () {
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

modelBatch.begin(cam);
modelBatch.render(instance, lights);
modelBatch.end();
}
...
}

添加了一个Lights的实例,构建后设置环境光为(0.4, 0.4, 0.4), 这里注意透明值alpha被忽略了。接着添加一个DirectionLight,设置其颜色为0.8, 0.8, 0.8, 方向为 -1.0, -0.8f, 0.2,我假设你对这些光什么的都了解了(译者汗啊)。最后,我们把这灯光传给modelBatch, 以便让他在渲染model instance时使用.

Libgdx New 3D API 教程之 -- Libgdx 3D 基础


看起来好多了,现在,我们给相机加一些控制方法,这样,我们就可以从不同的角度,来观察物体了:

public class Basic3DTest implements ApplicationListener {
...
public CameraInputController camController;
...

@Override
public void create () {
...
camController = new CameraInputController(cam);
Gdx.input.setInputProcessor(camController);
}

@Override
public void render () {
camController.update();
...
}
...
}

我们在这里添加了一个CameraInputController, 把我们的相机传进去当然参数。我们还将这个CameraInputController,设定为当前的输入处理器,并在render方法中调用camController.update()。这就是一个基本相机处理器的完整添加方法了。你可以用鼠标来试试。


完整代码在Libgdx test里。