首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >libgdx嵌套FrameBuffer

libgdx嵌套FrameBuffer
EN

Stack Overflow用户
提问于 2014-08-24 12:32:40
回答 2查看 766关注 0票数 4

在我的LevelScreen渲染方法中,我使用FBO渲染多道模糊着色器。我想要实现的是做一个MenuScreen,在背景上渲染LevelScreen,在上面应用另一个模糊效果。

这是伪代码

代码语言:javascript
复制
    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();
    }

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

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-08-24 13:31:17

您可以手动处理事务,可以使用自定义类来处理FrameBuffers (可能由堆栈支持),使用startRender(FrameBuffer)endRender()等方法正确地管理事物,比如关闭旧的FrameBuffer,然后打开新的FrameBuffer等等。

此外,尽量避免在呈现方法中创建新对象。

代码语言:javascript
复制
Sprite background = new Sprite(fbo.getColorBufferTexture());

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

编辑:

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

代码语言:javascript
复制
FrameBuffer fb1 = ..., fb2 = ...;
fb1.begin();
// draw something on fb1
fb2.begin();
// draw something on fb2
fb2.end();
// draw something on fb1 again
fb1.end();

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

代码语言:javascript
复制
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();
        }
    }
}

然后你就这样用它:

代码语言:javascript
复制
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();

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

票数 8
EN

Stack Overflow用户

发布于 2014-08-28 19:51:18

一个简单的解决方案,但这可能是您所需要的:

将LevelScreen分解为不同的方法:

代码语言:javascript
复制
protected void render(float delta){
    update(delta);
    drawFBOs(delta);
    drawMain(delta);
}

并分别实现了上述三种方法。然后还创建这个方法,MenuScreen可以用它自己的FBO引用调用这个方法。

代码语言:javascript
复制
protected void renderToFBO(float delta, FrameBuffer target){
    update(delta); //if necessary
    drawFBOs(delta);
    target.begin();
    drawMain(delta);
    target.end();
}

如果需要设置某些参数,可以向drawMain方法构造函数添加一个布尔值,以确定它是直接绘制到屏幕上,还是直接绘制到框架缓冲区中。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25471727

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档