如何在Libgdx Actor中渲染3D对象?

时间:2017-03-21 19:04:45

标签: android 3d libgdx

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

我尝试将背景图片添加到Stage,然后添加到StageActor,以便在其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);
    }
}

我想要的是什么:

What I would like

我所拥有的是:

What I have instead

我已经尝试直接在ApplicationAdapter render()方法中渲染模型批处理并且它工作正常,因此问题必须位于Stage的某处,但我无法找到。

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题,但我只需要渲染一次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中使用它。