• libGDX 3D 的基本使用


    本教程将学习使用 libGDX 提供的3D API 的基础知识。本教程假设您已经熟悉 libGDX 的基本使用,libGDX的环境搭建可以点击这里查看。 我们创建如下代码:

    1. public class MainGame implements ApplicationListener {
    2. @Override
    3. public void create () {
    4. }
    5. @Override
    6. public void render () {
    7. }
    8. @Override
    9. public void dispose () {
    10. }
    11. @Override
    12. public void resume () {
    13. }
    14. @Override
    15. public void resize (int width, int height) {
    16. }
    17. @Override
    18. public void pause () {
    19. }
    20. }

    首先,我们需要添加一个摄像机,摄像机可以从某个角度查看我们创建的3D场景。

    1. public class MainGame implements ApplicationListener {
    2. public PerspectiveCamera cam;
    3. @Override
    4. public void create () {
    5. cam = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    6. cam.position.set(10f, 10f, 10f);
    7. cam.lookAt(0,0,0);
    8. cam.near = 1f;
    9. cam.far = 300f;
    10. cam.update();
    11. }
    12. ...
    13. }

    上面代码中,我们创建了一个 PerspectiveCamera 摄像机,其视野为67度(这是常用的),并将纵横比设置为当前的宽度和高度。cam.position.set 将摄像机位置设置在坐标为(x=10, y=10, z=10)的位置(10个单位)。Z轴朝向玩家,也即是垂直屏幕。lookAt 将相机设置为朝(0, 0, 0)看,因为这是我们放置3D对象的位置。near 和 far 设置相机的最近和最远的值,以确保始终能看到我们的对象。最后,调用 update 更新相机,使我们所做的所有更改都能被相机反映出来。

    现在,让我们往场景添加一些模型。这里我们简单的通过代码来创建一个简单的立方体模型,后面的教程我们在通过 3D 建模软件导出模型来使用。

    1. public class MainGame implements ApplicationListener {
    2. public PerspectiveCamera cam;
    3. public Model model;
    4. public ModelInstance instance;
    5. @Override
    6. public void create () {
    7. cam = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    8. ...
    9. cam.update();
    10. ModelBuilder modelBuilder = new ModelBuilder();
    11. model = modelBuilder.createBox(5f, 5f, 5f,
    12. new Material(ColorAttribute.createDiffuse(Color.GREEN)),
    13. Usage.Position | Usage.Normal);
    14. instance = new ModelInstance(model);
    15. }
    16. @Override
    17. public void dispose () {
    18. model.dispose();
    19. }
    20. ...
    21. }

    这里我们实例化一个ModelBuilder,它可以用来在代码上创建模型。然后我们创建一个简单的立方体模型,大小为 5x5x5。我们还向其添加了一个带有绿色漫反射颜色的材质,并向模型添加了 Usage.Position 和 Usage.Normal 组件。在创建模型时,Usage.Position是必要的。将Usage.Normal法线添加到长方体中,因此例如,照明可以正常工作。Usage是VertexAttribute的一个子类。

    模型包含关于渲染内容的所有内容,并跟踪资源。它不包含渲染模型的位置等信息。因此,我们需要创建一个ModelInstance。ModelInstance包含模型应渲染的位置、旋转和缩放。默认情况下,这是在(0,0,0),所以我们只需创建一个ModelInstance,它应该在(0,0,0)处呈现。

    接下来,我们来渲染创建的立方体模型:

    1. public class MainGame implements ApplicationListener {
    2. public PerspectiveCamera cam;
    3. public ModelBatch modelBatch;
    4. public Model model;
    5. public ModelInstance instance;
    6. @Override
    7. public void create () {
    8. modelBatch = new ModelBatch();
    9. cam = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    10. ...
    11. cam.update();
    12. ModelBuilder modelBuilder = new ModelBuilder();
    13. model = modelBuilder.createBox(5f, 5f, 5f,
    14. new Material(ColorAttribute.createDiffuse(Color.GREEN)),
    15. Usage.Position | Usage.Normal);
    16. instance = new ModelInstance(model);
    17. }
    18. @Override
    19. public void render () {
    20. Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    21. Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
    22. modelBatch.begin(cam);
    23. modelBatch.render(instance);
    24. modelBatch.end();
    25. }
    26. @Override
    27. public void dispose () {
    28. modelBatch.dispose();
    29. model.dispose();
    30. }
    31. ...
    32. }

    这里我们添加了负责渲染的ModelBatch,并在create方法中对其进行初始化。在render方法中,我们清屏,调用 modelBatch.begin(cam),渲染我们的ModelInstance,然后调用modelBatch.end() 完成渲染。最后,我们需要处理modelBatch,以确保所有资源(如它使用的着色器)都已正确处理。

    我们的立方体模型渲染效果出来了,但是看起来怪怪的,我们在渲染模型的时候可以加一个环境灯光:

    1. public class MainGame implements ApplicationListener {
    2. public Environment environment;
    3. ...
    4. @Override
    5. public void create () {
    6. environment = new Environment();
    7. environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 0.4f, 0.4f, 1f));
    8. environment.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.2f));
    9. ...
    10. }
    11. @Override
    12. public void render () {
    13. Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    14. Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
    15. modelBatch.begin(cam);
    16. modelBatch.render(instance, environment);
    17. modelBatch.end();
    18. }
    19. ...
    20. }

    我们添加一个 Environmen t环境实例。我们构造它并设置环境光为(0.4,0.4,0.4),注意alpha值被忽略。然后我们添加一个方向光,颜色为(0.8,0.8,0.8),方向为(-1.0,-0.8f,0.2)。最后,我们在渲染模型时将环境传递给modelbatch。效果如下:

    看起来好多了。libGDX 中我们可以使用自带的一个摄像机控制处理 CameraInputController 来控制我们的摄像机,以便我们可以从其他角度查看模型。

    1. public class MainGame implements ApplicationListener {
    2. ...
    3. public CameraInputController camController;
    4. ...
    5. @Override
    6. public void create () {
    7. ...
    8. camController = new CameraInputController(cam);
    9. Gdx.input.setInputProcessor(camController);
    10. }
    11. @Override
    12. public void render () {
    13. camController.update();
    14. ...
    15. }
    16. ...
    17. }

    在这里,我们添加了一个CameraInputController,它是我们用cam作为参数创建的。我们还设置了 Gdx.input.setInputProcessor 为此camController,并确保在渲染调用中更新它。这就是添加基本相机控制器的全部内容。现在可以拖动以使相机旋转。

  • 相关阅读:
    影像信息提取DEM
    开源与闭源:数字化时代的辩论与未来走向
    使用Lua编写Wireshark解析ProtoBuf插件
    测试八股文-单元测试框架
    肖sir__自动化面试题
    人体呼吸存在传感器成品,毫米波雷达探测感知技术,引领智能家居新潮流
    基于4G/5G协同的高密重载场景网络规划方法
    基于PHP下的大学生校园交流论坛的设计与实现毕业设计源码101634
    Jmeter之接口测试
    【Java面向对象】继承的认识与实现(2) 关键字 this 与 super 区别
  • 原文地址:https://blog.csdn.net/u012970287/article/details/127782162