libgdx嵌套了FrameBuffer

Ale*_*DET 2 framebuffer glsl game-engine libgdx

我在我的LevelScreen渲染方法中使用FBO渲染多遍模糊着色器.我想要实现的是制作一个MenuScreen,在背景上渲染LevelScreen,在其上应用另一个模糊效果.

这是伪代码

    protected void render(float delta) {
        // render the scene to the FBO
        fbo.begin();
        levelScreen.render(delta);
        fbo.end();

        // retrieve texture and flip Y
        Sprite background = new Sprite(fbo.getColorBufferTexture());
        background.flip(false, true);

        // apply the blurX shader and
        // render the sprite
        batch.setShader(blurH);
        batch.begin();
        background.draw(batch);
        batch.end();
    }
Run Code Online (Sandbox Code Playgroud)

问题是该levelScreen.render()函数已经包含a fbo.begin() fbo.end()并且场景直接在屏幕上呈现.

有没有办法处理正确嵌套的fbo?

kaj*_*acx 5

你可以手工处理的事情,使用自定义的类来处理帧缓冲区,可能通过支持堆叠,以类似的方法startRender(FrameBuffer)endRender()界河会妥善管理的东西,喜欢接近老帧缓冲,并打开新的话,等

另外,尽量避免在render方法中创建新对象.

Sprite background = new Sprite(fbo.getColorBufferTexture());
Run Code Online (Sandbox Code Playgroud)

如果这是一个字段,这应该工作得很好.

编辑:

如果我理解正确,您当前的问题如下所示:

FrameBuffer fb1 = ..., fb2 = ...;
fb1.begin();
// draw something on fb1
fb2.begin();
// draw something on fb2
fb2.end();
// draw something on fb1 again
fb1.end();
Run Code Online (Sandbox Code Playgroud)

但是你不能同时打开多个FrameBuffers,对吧?因此,创建一个基于堆栈的类来为您管理FrameBuffers,简单的事情可以做:

class FrameBufferManager {
    private Stack<FrameBuffer> stack = new Stack<FrameBuffer>();

    public void begin(FrameBuffer buffer) {
        if (!stack.isEmpty()) {
            stack.peek().end();
        }
        stack.push(buffer).begin();
    }

    public void end() {
        stack.pop().end();
        if (!stack.isEmpty()) {
            stack.peek().begin();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你像这样使用它:

FrameBuffer fb1 = ..., fb2 = ...;
FrameBufferManager manager = ...;

manager.begin(fb1);
// draw something on fb1
manager.begin(fb2);
// draw something on fb2
manager.end();
// draw something on fb1 again
manager.end();
Run Code Online (Sandbox Code Playgroud)

但是,无论有没有经理,我都没有尝试过,但它应该解决你的问题.我不确定每次更改FrameBuffer时我是否需要重新打开渲染器和批处理(我通常这样做).