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

来源:互联网 发布:linux和shell的关系 编辑:程序博客网 时间:2024/05/22 04:44

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 {@Overridepublic void create () {}@Overridepublic void render () {}@Overridepublic void dispose () {}@Overridepublic void resume () {}@Overridepublic void resize (int width, int height) {}@Overridepublic void pause () {}}

现在我们来加点内容。

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

public class Basic3DTest implements ApplicationListener {public PerspectiveCamera cam;@Overridepublic 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;@Overridepublic 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);}@Overridepublic 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;@Overridepublic 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);}@Overridepublic 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();}@Overridepublic void dispose () {modelBatch.dispose();model.dispose();}...}

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


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

public class Basic3DTest implements ApplicationListener {public Lights lights;...@Overridepublic 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));...}@Overridepublic 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时使用.



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

public class Basic3DTest implements ApplicationListener {...public CameraInputController camController;...@Overridepublic void create () {...camController = new CameraInputController(cam);Gdx.input.setInputProcessor(camController);}@Overridepublic void render () {camController.update();...}...}

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


完整代码在Libgdx test里。


原创粉丝点击