【问题标题】:How to render 3D object within a Libgdx Actor?如何在 Libgdx Actor 中渲染 3D 对象?
【发布时间】:2017-03-21 19:04:44
【问题描述】:

我发现的大多数 Libgdx 教程都展示了如何在 3D 世界中添加 2D 元素,但我想知道如何相反,在 2D 舞台中添加 3D 元素。

我尝试向Stage 添加背景图像,然后向Stage 添加Actor,在其draw() 方法中渲染模型批次和3D 实例。

但是,图像并未绘制,部分 3D 对象被隐藏。

SimpleGame 类

public class SimpleGame extends ApplicationAdapter {

    Stage stage;

    @Override
    public void create () {
        stage = new Stage();

        InputMultiplexer im = new InputMultiplexer(stage);
        Gdx.input.setInputProcessor( im );

        Image background = new Image(new Texture("badlogic.jpg"));
        background.setSize(stage.getWidth(), stage.getHeight());
        stage.addActor(background);

        setup();
    }

    private void setup() {
        SimpleActor3D group = new SimpleActor3D();
        group.setSize(stage.getWidth(), stage.getHeight());
        group.setPosition(0, 0);
        stage.addActor(group);
    }

    @Override
    public void render () {
        stage.act();

        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        Gdx.gl.glClear( GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT );

        stage.draw();
    }
}

SimpleActor3D 类

public class SimpleActor3D extends Actor {

    public Environment environment;
    public PerspectiveCamera camera;

    public ModelBatch modelBatch;
    public ModelInstance boxInstance;

    public SimpleActor3D() {
        environment = SimpleUtils.createEnvironment();
        camera = SimpleUtils.createCamera();
        boxInstance = SimpleUtils.createModelInstance(Color.GREEN);

        modelBatch = new ModelBatch();
    }

    @Override
    public void draw(Batch batch, float parentAlpha) {
        Gdx.gl.glViewport((int)getX(), (int)getY(), (int)getWidth(), (int)getHeight());

        modelBatch.begin(camera);
        modelBatch.render( boxInstance, environment );
        modelBatch.end();

        super.draw(batch, parentAlpha);
    }
}

SimpleUtils 类

public class SimpleUtils {

    public static Environment createEnvironment() {
        Environment environment = new Environment();
        environment.set( new ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 0.4f, 0.4f, 1f) );

        DirectionalLight dLight = new DirectionalLight();
        Color lightColor = new Color(0.75f, 0.75f, 0.75f, 1);
        Vector3 lightVector = new Vector3(-1.0f, -0.75f, -0.25f);
        dLight.set( lightColor, lightVector );
        environment.add( dLight ) ;

        return environment;
    }

    public static PerspectiveCamera createCamera() {
        PerspectiveCamera camera = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        camera.position.set(10f, 10f, 10f);
        camera.lookAt(0,0,0);
        camera.near = 1f;
        camera.far  = 300f;
        camera.update();

        return camera;
    }

    public static ModelInstance createModelInstance(Color color) {
        ModelBuilder modelBuilder = new ModelBuilder();

        Material boxMaterial = new Material();
        boxMaterial.set( ColorAttribute.createDiffuse(color) );

        int usageCode = VertexAttributes.Usage.Position + VertexAttributes.Usage.ColorPacked + VertexAttributes.Usage.Normal;

        Model boxModel = modelBuilder.createBox( 5f, 5f, 5f, boxMaterial, usageCode );

        return new ModelInstance(boxModel);
    }
}

我想要什么:

我有什么:

我曾尝试直接在 ApplicationAdapter render() 方法中渲染模型批次,并且效果很好,所以问题一定出在 Stage 的某个地方,但我找不到方法。

【问题讨论】:

  • 在Actor的draw方法中,在super调用前将batch.end()放在开头,batch.begin()放在结尾。但是如果你有很多这样的 3d 演员,性能会很差,因为在批次类型之间来回切换。
  • 谢谢你的工作!我不认为我必须结束这批,因为我没有用它来绘制任何东西。

标签: android 3d libgdx


【解决方案1】:

我遇到了同样的问题,但我只需要渲染一次 3d 对象,所以我想到了将 3d 模型渲染为 Sprite 的想法。为了做到这一点,我通过 modelBatch 将我的模型渲染到帧缓冲区对象而不是默认屏幕缓冲区,然后从 FBO 颜色缓冲区创建一个精灵。

示例代码如下:

FrameBuffer frameBuffer = new FrameBuffer(Pixmap.Format.RGBA8888, Gdx.graphics.getBackBufferWidth(), Gdx.graphics.getBackBufferHeight(), true);

Sprite renderModel(ModelInstance modelInstance) {
    frameBuffer.begin(); //Capture rendering to frame buffer.

    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT | (Gdx.graphics.getBufferFormat().coverageSampling ? GL20.GL_COVERAGE_BUFFER_BIT_NV : 0))
    modelBatch.begin(camera);
    modelBatch.render(modelInstance);
    modelBatch.end();

    frameBuffer.end();

    return new Sprite(frameBuffer.getColorBufferTexture());
}

您始终可以使用sprite.setTexture(); 方法在渲染循环中更新您的精灵纹理。您还可以从纹理创建图像 -> new Image(frameBuffer.getColorBufferTexture()); 并在 Scene2d 中使用它。

【讨论】:

    猜你喜欢
    • 2013-08-20
    • 2018-06-29
    • 1970-01-01
    • 1970-01-01
    • 2015-07-20
    • 2014-01-22
    • 1970-01-01
    • 1970-01-01
    • 2019-01-14
    相关资源
    最近更新 更多