Hi all,
I’m drawing graphics to an Image using ShapeRenderer and FrameBuffer and after I create the Image I dispose the ShapeRenderer and the FrameBuffer, but when I dispose the FrameBuffer the Image doesn’t display. It seems like the Image is referencing the Texture located inside the FrameBuffer, so is a way to make a copy of the FrameBuffer’s Texture? Then I should be able to dispose the FrameBuffer without affecting the Image.
The Texture constructor doesn’t take another Texture, but it does take a TextureData object, so I thought I could use the getTextureData() method to create new Texture, but I just got an error (see code below). I also tried making a copy of the TextureRegion, but that did nothing as I think the new TextureRegion is also referencing the same Texture.
Here is a short example code that draws a filled rectangle. I also left in my code trying to generate a new Texture with the getTextureData() method and the error I got from it.
package com.tekker.test;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
public class Test extends ApplicationAdapter {
Stage stage;
Table tableMain;
TestBackground background;
@Override
public void create () {
stage = new Stage();
Gdx.input.setInputProcessor(stage);
tableMain = new Table();
tableMain.setFillParent(true);
stage.addActor(tableMain);
background = new TestBackground(Gdx.graphics.getWidth(), 200);
tableMain.add(background).size(background.getWidth(), background.getHeight());
}
@Override
public void render () {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.draw();
}
@Override
public void dispose(){
stage.dispose();
}
}
package com.tekker.test;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.glutils.FrameBuffer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
public class TestBackground extends Table {
Color backgroundColor = new Color(0.5f, 0.5f, 0.5f, 1.0f);
Image backgroundImage;
public TestBackground(float width, float height){
setSize(width, height);
createBackground();
}
private void createBackground(){
FrameBuffer buffer = new FrameBuffer(Format.RGBA8888, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false);
ShapeRenderer shapeRenderer = new ShapeRenderer();
buffer.begin();
Gdx.gl.glBlendFuncSeparate(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA, GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.graphics.getGL20().glEnable(GL20.GL_BLEND);
shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
shapeRenderer.rect(0f, 0f, getWidth(), getHeight(), backgroundColor, backgroundColor, backgroundColor, backgroundColor);
shapeRenderer.end();
buffer.end();
Texture bufferTexture = buffer.getColorBufferTexture();
Texture newTexture = new Texture(bufferTexture.getTextureData()); // <<< ERROR >>>
TextureRegion region = new TextureRegion(newTexture);
region.flip(false, true);
backgroundImage = new Image(region);
shapeRenderer.dispose();
buffer.dispose();
}
@Override
public void draw (Batch batch, float parentAlpha) {
applyTransform(batch, computeTransform());
backgroundImage.draw(batch, parentAlpha);
resetTransform(batch);
super.draw(batch, parentAlpha);
}
}
ERROR MESSAGE:
Exception in thread "LWJGL Application" com.badlogic.gdx.utils.GdxRuntimeException: Pixmap already disposed
at com.badlogic.gdx.graphics.Pixmap.getPixels(Pixmap.java:356)
at com.badlogic.gdx.graphics.GLTexture.uploadImageData(GLTexture.java:248)
at com.badlogic.gdx.graphics.GLTexture.uploadImageData(GLTexture.java:212)
at com.badlogic.gdx.graphics.Texture.load(Texture.java:133)
at com.badlogic.gdx.graphics.Texture.<init>(Texture.java:121)
at com.tekker.test.TestBackground.createBackground(TestBackground.java:39)
at com.tekker.test.TestBackground.<init>(TestBackground.java:21)
at com.tekker.test.Test.create(Test.java:34)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:136)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:114)