javalibgdxpixmap

What is the sufficient way of updating a pixmap dynamically?


Objectives

Currently I am using libgdx Pixmap to create an health bar, but when I change the drawLine parameters to new value then suddenly still there's no changes. In the bellow code is my current working code, I'm not sure if this is the sufficient way of drawing Pixmap dynamically.

// This code is working when written all in update method

Pixmap frame = new Pixmap(32, 3, Pixmap.Format.RGBA8888);
frame.drawRectangle(...);
frame.drawLine(...);

Texture texture = new Texture(frame);
frame.dispose();

batch.begin();
batch.draw(texture ...);
batch.end();

Sample healthbar

enter image description here


Solution

  • You shouldn't be using Pixmap for that (as general rule of thumb: if you think you need to use Pixmap for something then you are likely wrong). A Pixmap is used to load, store or manipulate the image data in CPU memory: RAM. Manipulating image data in CPU memory is relatively slow and the resulting data can't be used to render on the screen with e.g. SpriteBatch.

    For that you need to upload (copy) the data from CPU memory to GPU memory: VRAM. A Texture is used to represent the image data in VRAM. So, indeed, you could do that by creating a Texture out of it. Alternatively you could reuse an existing texture by calling the texture.load(pixmap) method. However, uploading image data from RAM to VRAM is also relatively slow.

    So, instead of manipulating the image data on CPU and then copying it to GPU, you're better of to use the GPU directly to achieve what you want. You didn't provide enough information about what you actually want to achieve, but here are a few options that could help you get started.

    1. Draw only a portion of the full bar. Let's say you have an image in your atlas that represents the full health bar and you want to render only a portion of it, representing the actual health: batch.draw(region.getTexture(), x, y, width * health, height, region.getU(), region.getV(), region.getU() + health * (region.getU2() - region.getU()), region.getV2()); (here x, y, width and height are the location and size of bar in your world coordinates and health is the normalized health ranging from 0 to 1).
    2. Scale a TextureRegion to the size of the bar. Let's say your health bar is fully opaque or only with an outerline, then you can use a single pixel TextureRegion and scale it to be the size you want: barch.draw(region, x, y, width * health, height);
    3. Use a nine-patch.
    4. Use ShapeRenderer, which provides practically the same and more drawing functionality as Pixmap does, but instead does it directly using the GPU.