我正在为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,但我无法确定使用哪些值。
答案 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();