我为文字游戏创建了动态纹理,并保留在FrameBuffer上。然后,我使用该FrameBuffer支持的TextureRegions绘制到屏幕上。这段代码在Android上运行良好,但在iOS上却遇到问题。
您可以在下面的屏幕截图中看到,在左下方绘制了FrameBuffer内容-一切都很好。
但是,如果返回到iOS主屏幕,则会丢弃FrameBuffer,然后根据需要重新创建所有内容并将其重新绘制到FrameBuffer。然后,FrameBuffer的内容似乎是屏幕的部分翻转镜像。
我尝试在每个帧上放置并重新创建FrameBuffer,以查看会发生什么。同样,除非我返回iOS主屏幕,否则此方法非常有效,此后FrameBuffer的内容不正确。
然后,我尝试减小FrameBuffer的大小并绘制多个FrameBuffers。如果执行此操作,除非返回到iOS主屏幕,否则它仍然可以正常工作。但是,在这种情况下,只有创建的第一个FrameBuffer损坏,所有后续缓冲区都可以。
然后,我尝试始终先创建一个1x1px FrameBuffer,再也不要画任何东西,这解决了我的问题....但是为什么!看来我从iOS主屏幕返回后创建的第一个FrameBuffer不能按预期工作,但是此后的每个FrameBuffer都可以。似乎总是试图在我创建的第一个FrameBuffer上绘制屏幕。
FrameBuffer的创建和绘制代码如下:
private static FrameBuffer getFrameBuffer(boolean newRequired) {
if (newRequired || frameBuffers.size == 0) {
FrameBuffer frameBuffer;
try {
frameBuffer = new FrameBuffer(Pixmap.Format.RGBA8888, getFrameBufferSize(), getFrameBufferSize(), false);
} catch (Exception e) {
frameBuffer = new FrameBuffer(Format.RGBA4444, getFrameBufferSize(), getFrameBufferSize(), false);
}
frameBuffer.begin();
Gdx.gl20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT);
frameBuffer.end();
frameBuffers.add(frameBuffer);
// Set up the camera correctly for the frame buffer
OrthographicCamera camera = new OrthographicCamera(frameBuffer.getWidth(), frameBuffer.getHeight());
camera.position.set(frameBuffer.getWidth() * 0.5f, frameBuffer.getHeight() * 0.5f, 0);
camera.update();
spriteBatch.setProjectionMatrix(camera.combined);
}
return frameBuffers.get(frameBuffers.size - 1);
}
private static TextureRegion getTextureUsingGpu(String letter, Bubble.BubbleType bubbleType) {
if (!enabled)
return null;
TextureRegion tx = getBlockImage(letter, bubbleType);
int width = (int) (tx.getRegionWidth() * LayoutManager.getShortEdge() / 1080 * LayoutManager.getScaling());
int height = (int) (tx.getRegionHeight() * LayoutManager.getShortEdge() / 1080 * LayoutManager.getScaling());
if (nextTextureX + width + PADDING > getFrameBufferSize()) {
nextTextureX = PADDING;
nextTextureY = nextRowY + PADDING;
if (nextTextureY + height + PADDING > getFrameBufferSize()) {
getFrameBuffer(true);
nextRowY = PADDING;
nextTextureY = PADDING;
}
}
FrameBuffer fb = getFrameBuffer(false);
fb.begin();
spriteBatch.begin();
tx.flip(false, !tx.isFlipY());
spriteBatch.disableBlending();
spriteBatch.draw(tx, nextTextureX, nextTextureY, width, height);
spriteBatch.enableBlending();
// Drawing Code Removed
spriteBatch.end();
fb.end();
TextureRegion textureRegion = new TextureRegion(fb.getColorBufferTexture(), nextTextureX, nextTextureY, width, height);
textureRegion.getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
cacheTexture(letter, textureRegion);
nextTextureX += width;
nextRowY = Math.max(nextRowY, nextTextureY + height);
return textureRegion;
}
最佳答案
如果要从getFrameBuffer
或getTextureUsingGpu
方法调用resize
或resume
,那就是问题所在。在iOS上,不一定要在OpenGL准备恢复之前调用resize
和resume
,因此在该处执行与OpenGL直接相关的任何操作都是不安全的,例如创建ShaderPrograms,加载纹理或创建FrameBuffers。我在游戏中通过使用resume
设置成员布尔值来解决此问题,并使用该值将新帧缓冲区的创建推迟到render
方法。
关于ios - iOS上的LibGDX FrameBuffer怪癖,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30047801/