Libgdx:用于“战争迷雾”的帧缓冲 - 效果

时间:2016-03-18 08:13:53

标签: android opengl-es libgdx framebuffer blending

我正在为Android编写RTS游戏,我希望玩家单位的“战争迷雾”效果。此效果意味着每个单元周围只有一个“圆圈”显示背景地图,而在没有播放器单元的地方,屏幕应为黑色。我不想使用着色器。

我的第一个版本正常运行。我正在做的是将地图渲染到默认的帧缓冲区,然后我有一个完全黑色的第二个帧缓冲区(类似于光技术)。在玩家单位的情况下,我然后批量绘制一个完全透明的纹理,并在其中间有一个边缘模糊的白色圆圈。 最后,我使用Gdx.gl.glBlendFunc(GL20.GL_DST_COLOR,GL20.GL_ZERO)在第一个上绘制第二个(浅色)FrameBuffer的colorTexture;

现在的视觉效果确实是整个地图都是黑色的,我的单位周围的圆圈是可见的 - 但是添加了很多白色。 原因非常清楚,因为我为这些单位绘制了光纹理:

lightBuffer.begin();
        Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE);

        Gdx.gl.glEnable(GL20.GL_BLEND);

        Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1f);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        batch.setProjectionMatrix(camera.combined);
        batch.begin();

        batch.setColor(1f, 1f, 1f, 1f);
        for (RTSTroopAction i : unitList) {
                batch.draw(lightSprite, i.getX() + (i.getWidth() / 2) - 230, i.getY() + (i.getHeight() / 2) - 230, 460, 460); //, 0, 0, lightSprite.getWidth(), lightSprite.getHeight(), false, true);

        }

        batch.end();
        lightBuffer.end();

但是,我不希望原始纹理上的“白色东西”,我只是希望原始背景闪耀。我怎样才能做到这一点?

我认为它正在使用blendFuncs,但我无法确定使用哪些值。

1 个答案:

答案 0 :(得分:0)

感谢Tenfour04指向了正确的方向,我找到了解决方案。首先,问题不在batch.end();中。问题是,精灵批处理确实维护了自己的blendFunc设置。这些在flush()时应用;叫做。 (end()也调用它)。 但是,当它绘制一个TextureRegion时,它也会调用flush,该TextureRegion被绑定到与前一个draw()调用中使用的纹理不同的纹理。

所以在我的原始代码中:当我调用batch.draw(lightBuffer,...)时,我设置的任何blendFunc总是被覆盖。解决方案是使用spritebatch的blendFunc而不是Gdx.gl.blendFunc。

总工作代码最终如下所示:

null

//现在我们将lightBuffer渲染到默认的"帧缓冲区" //正确混合!

lightBuffer.begin();
        Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
        Gdx.gl.glEnable(GL20.GL_BLEND);          
// start rendering to the lightBuffer
// set the ambient color values, this is the "global" light of your scene
        Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1f);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
// start rendering the lights 
        batch.setProjectionMatrix(camera.combined);
        batch.begin();
// set the color of your light (red,green,blue,alpha values)
        batch.setColor(1f, 1f, 1f, 1f);
        for (RTSTroopAction i : unitList) {
            if (i.getOwnerId() == game.getCallback().getPlayerId()) {
                batch.draw(lightSprite, i.getX() + (i.getWidth() / 2) - 230, i.getY() + (i.getHeight() / 2) - 230, 460, 460); //, 0, 0, lightSprite.getWidth(), lightSprite.getHeight(), false, true);
            }
        }
        batch.end();
        lightBuffer.end();