Question

I am trying to convert a Texture to a Pixmap in LibGDX so I can get all of the pixel data into a ByteBuffer for some experiments, and from what I can tell, I should be able to do this by doing the following :

Pixmap pixmap = textureName.getTexture().getTextureData().consumePixmap();
ByteBuffer data = pixmap.getPixels();

This does seem to return a properly sized Pixmap, and the ByteBuffer does seem to be created just fine, but it is filled entirely with zeros, resulting in a blank, transparent image. This, and a couple other tests, lead me to believe that the Pixmap itself is simply being created as a fully transparent image like that, but I cannot find what may be causing that to happen. Is there some sort of limitation preventing this from working, or am I simply missing something obvious?

Was it helpful?

Solution

I believe that API (consumePixmap()) is meant for the Texture class to extract data out of a Pixmap when pushing the Pixmap up to the GPU.
A Libgdx Texture object represents texture data on the GPU, so getting the underlying data to the CPU isn't generally trivial (its the "wrong" direction for a rendering API). See http://code.google.com/p/libgdx/wiki/GraphicsPixmap

Additionally, the documentation on consumePixmap() says it requires a prepare() call before it will work.

To extract pixel information from a texture, you build a FrameBuffer object, render the texture to it, and then extract the pixels (see ScreenUtils).

Its not clear what you're trying to accomplish, but going the other direction (byte array -> Pixmap -> Texture) and then modifying the byte array and re-doing the transformation might work.

OTHER TIPS

I ran into a similar issue when I wanted to create a PNG of a level made in my level editor. The level is made out of tiles placed by the creator, the entire level is then saved as a .png to be used in the game.

Solved it the way P.T. explains. I hope it is useful for others that run into the same problem.

And in your application configuration: cfg.useGL20 = true; GL20 is required to be able to build the FrameBuffer

        public boolean exportLevel(){   

            //width and height in pixels
            int width = (int)lba.getPrefWidth();
            int height = (int)lba.getPrefHeight();

            //Create a SpriteBatch to handle the drawing.
            SpriteBatch sb = new SpriteBatch();

            //Set the projection matrix for the SpriteBatch.
            Matrix4 projectionMatrix = new Matrix4();

            //because Pixmap has its origin on the topleft and everything else in LibGDX has the origin left bottom
            //we flip the projection matrix on y and move it -height. So it will end up side up in the .png
            projectionMatrix.setToOrtho2D(0, -height, width, height).scale(1,-1,1); 

            //Set the projection matrix on the SpriteBatch
            sb.setProjectionMatrix(projectionMatrix);

            //Create a frame buffer.
            FrameBuffer fb = new FrameBuffer(Pixmap.Format.RGBA8888, width, height, false);

            //Call begin(). So all next drawing will go to the new FrameBuffer.
            fb.begin();

            //Set up the SpriteBatch for drawing.
            sb.begin();

            //Draw all the tiles.
            BuildTileActor[][] btada = lba.getTiles();
            for(BuildTileActor[] btaa: btada){
                for(BuildTileActor bta: btaa){
                    bta.drawTileOnly(sb);
                }
            }

            //End drawing on the SpriteBatch. This will flush() any sprites remaining to be drawn as well.
            sb.end();

            //Then retrieve the Pixmap from the buffer.
            Pixmap pm = ScreenUtils.getFrameBufferPixmap(0, 0, width, height);

            //Close the FrameBuffer. Rendering will resume to the normal buffer.
            fb.end();

            //Save the pixmap as png to the disk.
            FileHandle levelTexture = Gdx.files.local("levelTexture.png");
            PixmapIO.writePNG(levelTexture, pm);

            //Dispose of the resources.
            fb.dispose();
            sb.dispose();

Note: I am new to LibGDX so this may not be the neatest way to do this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top