How to handle resume for libGDX Image with Pixmap texture - libgdx

I have a com.badlogic.gdx.scenes.scene2d.ui.Image that is built from a Pixmap. The Pixmap is only one pixel because I'm using it to build an Image that functions as a background that can fade in and out.
Pixmap pmap = new Pixmap(1, 1, Pixmap.Format.RGBA8888);
pmap.setColor(1.0f, 1.0f, 1.0f, 1.0f);
pmap.drawPixel(0, 0);
bgImage = new Image(new Texture(pmap));
pmap.dispose();
bgImage.setSize(MyGame.VIRUAL_WIDTH, MyGame.VIRUAL_HEIGHT);
bgImage.getColor().a = 0.0f;
bgImage.addAction(Actions.sequence(Actions.fadeIn(1.0f),Actions.delay(3.0f),Actions.fadeOut(1.0f)));
stage.addActor(bgImage);
It works great but my concern is that the game might be paused while the actions are taking place. I assume the actions will continue upon resuming so I need to keep the same Image but the underlying Pixmap is not managed and therefore needs to be recreated upon resume. I'm having trouble figuring out how to reattach the Texture/Pixmap to the Image. Building the Pixmap itself is easy but getting an existing Image to use it is the problem.

My solution was as follows
Assume Pixmap pixmap = ...
TextureData texData = new PixmapTextureData(pixmap, Format.RGBA8888, false, false, true);
Texture texture = new Texture(texData);
Image image = new Image(texture);
The last flag in PixmapTextureData is "managed". It runs on mine.
You can check out the first portion of the following link to see what is managed and what is not. http://www.badlogicgames.com/wordpress/?p=1513

There is no setTexture method on an Image. Looking at the Image(Texture) constructor it wraps the texture in a drawable region:
this(new TextureRegionDrawable(new TextureRegion(texture)));
So you can do something similar and use the Image.setDrawable method to change the drawable object used. Something like this:
bgImage.setDrawable(new TextureRegionDrawable(new TextureRegion(new Texture(pmap))));
I think you can probably reuse the TextureRegion and all of its containers (so after generating a new pixmap, just wrap it in a Texture and push that into the saved TextureRegion from before the pause.

Related

LibGDX Generating a png from a model

The title pretty much say it all, I need to get a image from a Model is this posible? I searched for this and found nothing.
Solution thanks to #retodaredevil
FrameBuffer fbo = new FrameBuffer(Pixmap.Format.RGBA4444, screenWidth, screenHeight, true);
ModelBatch batch = new ModelBatch();
fbo.begin(); // make fbo the current buffer
Gdx.gl.glViewport(0, 0,screenWidth, screenHeight);
Gdx.gl.glClear(GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
batch.begin(camera);
batch.render(instance, environment);
batch.end();
try{
FileHandle fh = new FileHandle(output);
Pixmap pixmap = ScreenUtils.getFrameBufferPixmap(0,0,screenWidth,screenHeight);
PixmapIO.writePNG(fh, pixmap);
pixmap.dispose();
}catch (Exception e){
e.printStackTrace();
}
fbo.end(); // Now you can draw on the display again
batch.dispose();
fbo.dispose();
From what I understand, we'll have to use two different tutorials
https://github.com/mattdesl/lwjgl-basics/wiki/FrameBufferObjects
https://xoppa.github.io/blog/basic-3d-using-libgdx/ (You're probably already familiar with this)
FrameBuffer fbo = new FrameBuffer(Pixmap.Format.RGBA4444, width, height, hasDepth);
// I've never used a FrameBuffer before so you may have to play around with constructor parameters
ModelBatch batch = // your ModelBatch initialization here
fbo.begin(); // make fbo the current buffer
glClearColor(0f, 0f, 0f, 1f);
glClear(GL_COLOR_BUFFER_BIT);
batch.resize(fbo.getWidth(), fbo.getHeight());
batch.begin();
batch.render(modelInstance, environment);
batch.end();
fbo.end(); // Now you can draw on the display again
// If you want to, you can resize your batch and use it to draw on the display
batch.resize(Display.getWidth(), Display.getHeight());
Once you do whatever you need to do to your FrameBuffer, you can get the texture
fbo.getTexture();
EDIT: That method doesn't exist, look at OP's question for solution
EDIT 2: FrameBuffer does actually have a method called getColorBufferTexture()
For saving a texture, look at https://www.badlogicgames.com/forum/viewtopic.php?p=8358#p8358 or https://www.badlogicgames.com/forum/viewtopic.php?t=5686
I used this to get one of the links: Libgdx save SpriteBatch in a texture everything else I duckduckgoed
If something doesn't work let me know and I can try to look around more.

Libgdx Group Size Issue

To make my question clearer , I created a simple test class as below.
`public void create () {
stage = new Stage();
// GP
Texture texture1 = new Texture(Gdx.files.internal("data/badlogic.jpg"));
TextureRegion tr = new TextureRegion(texture1);
Image image = new Image(tr);
Group gp = new Group();
ImageButton ib = new ImageButton(new Image(tr).getDrawable());
ib.setSize(90, 256);
gp.addActor(ib);
gp.setPosition(0, 0);
stage.addActor(gp);
gp.debugAll();
}`
The size of badlogic logo is 256*256. I set it to 90*256 in the test.But the outcome looks like this http://imgsrc.baidu.com/forum/w%3D580/sign=fb0e4402d21373f0f53f6f97940e4b8b/0958c32397dda1448779b0cbb1b7d0a20df486e2.jpg
If i set the image size before sending it to imagebutton, then it will rendered as 256*256 ,the full original size. This function is so simple. I can not figure out where is going wrong.
First of all, last update of Libgdx project is 1.4.1: http://libgdx.badlogicgames.com/download.html
The problem is the Drawable object that you are sending to the ImageButton, if you want to change the size of the Image or Texture before adding it to the ImageButton (so you will solve the problem asked), you will just need to use the .setBounds() method
I write down a little example:
1. Initialize Image object with your image file:
`Image image = new Image( new Texture ( Gdx.Files.internal("yourPathFile.png") ) );`
2. .setBounds() javadoc: (x coordinate, y coordinate, width of the image, height of the image)
image.setBounds(0f, 0f, 50f, 60f)
then you can send the image to the ImageButton object as Drawable.
`ImageButton myButton = new ImageButton(image.getDrawable());'
That's all.
Here you have some constructors of ImageButton object from the Libgdx official javadoc.
See also:
Release versions: http://libgdx.badlogicgames.com/releases/
ImageButton javadoc: http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/ImageButton.html

LibGDX Android Game - displaying fixed text (ie Score) over a scrolling screen

I am beginning to write a game in LibGDX, only just beginning. I have got a basic tile map loaded, a player sprite and can move the character around and the screen (camera) scrolls around - perfect.
I have two overlayed textures in the bottom right of the screen, a left and right arrow, which are used as the joypad to control the character. I position these in relation to the players.x position, which is always fixed to the centre of the screen. Cool so far .... As below:
/////////////////////////////////////////////////////////////////
private void renderJoypad(float deltaTime)
{
batch.draw(Assets.leftJoypad, blockman.position.x-14, 1, 3, 3);
batch.draw(Assets.rightJoypad, blockman.position.x-9, 1, 3, 3);
}
I am now trying to put the player's score in the top left of the screen. The score is made of a Bitmap font, as below.
font = new BitmapFont(Gdx.files.internal("fonts/minecrafter.fnt"),Gdx.files.internal("fonts/minecrafter.png"),false);
font.setScale(0.02f);
In my render() method I cam calling some other methods to update, like the positions of the
leftJoypad etc, as in renderJoypad(). I am also calling my draw font method to update the position of the score, however, when I scroll it is all jerky, and sometimes it shows less characters than there should be.
public void drawScore(float deltaTime)
{
font.draw(batch, "00000", blockman.position.x, 10);
}
I believe that I need to place the score (and any other on screen texts, HUD etc) into a stage, but I cannot understand how to get it working with my existing code.
My show method is as follows:
public void show()
{
//load assets class to get images etc
Assets Assets = new Assets();
//start logging Framerate
Gdx.app.log( GameScreen.LOG, "Creating game" );
fpsLogger = new FPSLogger();
//set the stage - bazinga
Gdx.input.setInputProcessor(stage);
//stage.setCamera(camera);
//stage.setViewport(480, 360, false);
batch = new SpriteBatch();
//load the Joypad buttons
loadJoypad();
//background image
loadBackground();
//sounds
jumpSound = Gdx.audio.newSound(Gdx.files.internal("sounds/slime_jump.mp3"));
//LOAD block man here
// load the map, set the unit scale to 1/16 (1 unit == 16 pixels)
loadMap();
//draw the score
font = new BitmapFont(Gdx.files.internal("fonts/minecrafter.fnt"),Gdx.files.internal("fonts/minecrafter.png"),false);
font.setScale(0.02f);
// create an orthographic camera, shows us 30x20 units of the world
camera = new OrthographicCamera();
camera.setToOrtho(false, 30, 20);
camera.update();
// create the Blockman we want to move around the world
blockman = new Blockman();
blockman.position.set(25, 8);
}
and my render() method is as follows:
public void render(float delta)
{
// get the delta time
float deltaTime = Gdx.graphics.getDeltaTime();
stage.act(deltaTime);
stage.draw();
// clear the screen
Gdx.gl.glClearColor(0.3f, 0.3f, 0.3f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
renderBackground(deltaTime);
batch = renderer.getSpriteBatch();
//updateBlockman(deltaTime);
blockman.update(deltaTime);
// let the camera follow the blockMan, x-axis only
camera.position.x = blockman.position.x;
camera.update();
// set the tile map rendere view based on what the
// camera sees and render the map
renderer.setView(camera);
renderer.render();
//start the main sprite batch
batch.begin();
// render the blockMan
renderBlockman(deltaTime);
renderJoypad(deltaTime);
drawScore(deltaTime);
batch.end();
fpsLogger.log();
}
I have tried to change the way things work with relation to the Spritebatch etc and just cannot seem to get it working as I require.
Can anyone suggest how I may approach getting a stage and actors to work, or a second camera or something to help me achieve a fixed score display in the corner.
Do I need to use Scene 2D or something - aahhh! My head is exploding....
I look forward and thank you in advance.
Regards
James
I have a couple of suggestions:
Check to see if you have setUseIntegerPositions set to true
(the default) when you draw your font. If you do, and you're scaling
it, then it can cause some odd effects similar to those that you
describe. Set it to false and see if it fixes the problem.
Reset your spritebatch's matrices before drawing the text, that way you won't need to adjust it for the scrolling.
I'd even go as far as to recommend not scaling the font if you can help it, because fonts often look a little odd after being scaled.

ShapeRenderer doesn't render when using Skins

My shapes drawn by shape renderer does not show when I use skins. The shape is drawn inside the actor using an instance of ShapeRenderer. I think this is caused by the skin because I tried adding an empty table and the shapes show, but if I add an instance of a skin the shapes does not show.
This code is from the libgdx tests in github:
Skin skin = new Skin(Gdx.files.internal("data/uiskin.json"));
Label nameLabel = new Label("Name:", skin);
Table t1 = new Table();
t1.setFillParent(true);
t1.add(nameLabel);
stage.addActor(t1);
you need to .end() the SpriteBatch befor using the ShapeRender.begin() after the ShapeRender.end() you need to call SpriteBatch.begin() in your actor. Else you do have 2 concurenting batches.
actor.draw(SpriteBatch batch, float delta){
batch.end();
ShapeRender.begin(Some Typee);//start it with your shapetype
//drawing stuff with the shaperender
ShapeRender.end();//dont forget to end it
batch.begin(); //need to be started again for the next actors to be dawn
}
An empty table shouldnt be a problem.

how to draw a bitmap and call it back when u need it in actionscript 3?

I am using the bitmap data to save choices of the user in my game...but I came across a problem in it... I can ask the bitmap to draw an image...
circle_clk = new circle_big;
addChild(cicle_clk);
circle_clk.addEventListener(MouseEvent.CLICK, cir_bitmap);
function cir_bitmap (mEvent:MouseEvent) {
bmpdata= new BitmapData (300, 300);
bmp = new Bitmap (bmpdata);
addChild (bmp);
bmpdata.draw(circle_clk);
}
but now I need to ask it bring back this image at the end of the game... how would I do this? how can I draw a bitmap, temporarily remove it from the stage and bring it back when I need it..plus how can I know if it really took an image?..can somebody help me with it please?
Move this line to an outer context such as the class:
bmpdata= new BitmapData (300, 300);
Then using your code:
circle_clk = new circle_big;
addChild(cicle_clk);
circle_clk.addEventListener(MouseEvent.CLICK, cir_bitmap);
function cir_bitmap (mEvent:MouseEvent) {
bmp = new Bitmap (bmpdata);
addChild (bmp);
bmpdata.draw(circle_clk);
}
If you need to remove the bitmap and add it later, just move it off the stage (change the X coordinate for example) and then place it back where needed when you need the image back in view.