libGDX 3D 的基本使用

本教程将学习使用 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,并确保在渲染调用中更新它。这就是添加基本相机控制器的全部内容。现在可以拖动以使相机旋转。

猜你喜欢

转载自blog.csdn.net/u012970287/article/details/127782162
今日推荐