本教程将学习使用 libGDX 提供的3D API 的基础知识。本教程假设您已经熟悉 libGDX 的基本使用,libGDX的环境搭建可以点击这里查看。 我们创建如下代码:
- public class MainGame 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 MainGame 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 = 1f;
- cam.far = 300f;
- cam.update();
- }
- ...
- }
上面代码中,我们创建了一个 PerspectiveCamera 摄像机,其视野为67度(这是常用的),并将纵横比设置为当前的宽度和高度。cam.position.set 将摄像机位置设置在坐标为(x=10, y=10, z=10)的位置(10个单位)。Z轴朝向玩家,也即是垂直屏幕。lookAt 将相机设置为朝(0, 0, 0)看,因为这是我们放置3D对象的位置。near 和 far 设置相机的最近和最远的值,以确保始终能看到我们的对象。最后,调用 update 更新相机,使我们所做的所有更改都能被相机反映出来。
现在,让我们往场景添加一些模型。这里我们简单的通过代码来创建一个简单的立方体模型,后面的教程我们在通过 3D 建模软件导出模型来使用。
- public class MainGame 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.Position是必要的。将Usage.Normal法线添加到长方体中,因此例如,照明可以正常工作。Usage是VertexAttribute的一个子类。
模型包含关于渲染内容的所有内容,并跟踪资源。它不包含渲染模型的位置等信息。因此,我们需要创建一个ModelInstance。ModelInstance包含模型应渲染的位置、旋转和缩放。默认情况下,这是在(0,0,0),所以我们只需创建一个ModelInstance,它应该在(0,0,0)处呈现。
接下来,我们来渲染创建的立方体模型:
- public class MainGame 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(GL20.GL_COLOR_BUFFER_BIT | GL20.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,以确保所有资源(如它使用的着色器)都已正确处理。

我们的立方体模型渲染效果出来了,但是看起来怪怪的,我们在渲染模型的时候可以加一个环境灯光:
- public class MainGame implements ApplicationListener {
- public Environment environment;
- ...
-
- @Override
- public void create () {
- 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));
- ...
- }
-
- @Override
- public void render () {
- 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(instance, environment);
- modelBatch.end();
- }
- ...
- }
我们添加一个 Environmen t环境实例。我们构造它并设置环境光为(0.4,0.4,0.4),注意alpha值被忽略。然后我们添加一个方向光,颜色为(0.8,0.8,0.8),方向为(-1.0,-0.8f,0.2)。最后,我们在渲染模型时将环境传递给modelbatch。效果如下:

看起来好多了。libGDX 中我们可以使用自带的一个摄像机控制处理 CameraInputController 来控制我们的摄像机,以便我们可以从其他角度查看模型。
- public class MainGame implements ApplicationListener {
- ...
- public CameraInputController camController;
- ...
-
- @Override
- public void create () {
- ...
- camController = new CameraInputController(cam);
- Gdx.input.setInputProcessor(camController);
- }
-
- @Override
- public void render () {
- camController.update();
- ...
- }
- ...
- }
在这里,我们添加了一个CameraInputController,它是我们用cam作为参数创建的。我们还设置了 Gdx.input.setInputProcessor 为此camController,并确保在渲染调用中更新它。这就是添加基本相机控制器的全部内容。现在可以拖动以使相机旋转。