我想将自己的LibGDX游戏的一个实体渲染为PNG。因此,我做了一个小的工具,它是一个LibGDX应用程序,用于显示该实体,并在F5上截屏。该应用程序的目标只是生成PNG。
camera.update();
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
batch.begin();
animation.update(Gdx.graphics.getDeltaTime() * 1000);
animation.draw(batch);
batch.end();
if(exporting)
// export...
从该wiki page中我了解了如何制作屏幕截图,并且通过删除了for循环,我能够获得一个屏幕截图,该屏幕截图无法用黑色像素代替透明像素。
byte[] pixels = ScreenUtils.getFrameBufferPixels(0, 0, Gdx.graphics.getBackBufferWidth(), Gdx.graphics.getBackBufferHeight(), true);
Pixmap pixmap = new Pixmap(Gdx.graphics.getBackBufferWidth(), Gdx.graphics.getBackBufferHeight(), Pixmap.Format.RGBA8888);
BufferUtils.copy(pixels, 0, pixmap.getPixels(), pixels.length);
PixmapIO.writePNG(Gdx.files.external("mypixmap.png"), pixmap);
pixmap.dispose();
它适用于实体的边缘,但不适用于内部的多个部分。
边缘:(完美)
内部:(不应透明)
所以我开始玩混合游戏来解决这个问题。 使用
batch.enableBlending();
batch.setBlendFunction(
exporting ? GL20.GL_ONE : GL20.GL_SRC_ALPHA, // exporting is set to true on the frame where the screenshot is taken
GL20.GL_ONE_MINUS_SRC_ALPHA);
这对它有所改进:
但是对于像眼镜这样的图像来说,它们应该是透明的,所以它是不透明的:
代替:
我应该怎么做才能解决这个问题?我想要的是非常标准的,透明的背景,上面有半透明的图像。我希望它的行为就像普通的图像软件那样具有分层(如GIMP)。
答案 0 :(得分:1)
您的问题是因为书写的颜色和alpha均由相同的功能SRC_ALPHA和ONE_MINUS_SRC_ALPHA调制。
您需要使用glBlendFuncSeparate实现此目的。就您而言:
batch.begin();
// first disable batch blending changes (see javadoc)
batch.setBlendFunction(-1, -1);
// then use special blending.
Gdx.gl.glBlendFuncSeparate(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA,GL20.GL_SRC_ALPHA, GL20.GL_DST_ALPHA);
... your drawings ...
batch.end();
通过这种方式,颜色通道仍然像往常一样进行混合,但是添加了alpha通道(源和目标)。
请注意,对于libgdx 1.9.7+,不再需要批量混合技巧,而可能是:
batch.begin();
batch.setBlendFunctionSeparate(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA,GL20.GL_SRC_ALPHA, GL20.GL_DST_ALPHA);
... your drawings ...
batch.end();