3

I've gone through the nice tutorial that creates a simple libgdx game catching raindrops in a bucket. I want to learn more about using images, so I tried replacing the raindrop with a baby.

Cute Baby!

When I try loading baby.png, I get the following error:

com.badlogic.gdx.utils.GdxRuntimeException: Texture width and height must be 
powers of two: 60x83

How can I load an image of whatever size I want?

Don Kirkby
  • 53,582
  • 27
  • 205
  • 286

3 Answers3

5

before loading the image write..

Texture.setEnforcePotImages(false); 

you may do this in create function of application listner this is the easiest way if you don't want to create a texture atlas

Vikalp Jain
  • 1,419
  • 1
  • 11
  • 20
  • That's a nice short cut to know, thanks. Of course, there are performance benefits to using a texture atlas. – Don Kirkby Aug 30 '13 at 05:40
  • 1
    @DonKirkby ya there are many benefits of texture atlas but many a times this comes handy... instead of making texture atlas for just single image we can use this – Vikalp Jain Aug 30 '13 at 05:46
0

A little reading led me to a description of TextureAtlas and TexturePacker, which combine a bunch of small images into one large one. That makes them faster to load and draw. As Vikalp says, you can also just disable the rule about image sizes if you don't care about the performance difference.

Texture.setEnforcePotImages(false); 

You can learn more about game atlases in Udacity's HTML5 game class.

To create your own atlas, you can start by using the TexturePacker GUI, but I recommend eventually creating a command-line project to automatically pack your raw images.

I posted an example project that takes the example code from the bucket and raindrop tutorial, and switches to using a TextureAtlas. Now, I load the atlas and then load the images from the atlas.

atlas = new TextureAtlas(Gdx.files.internal("atlas/plank.pack"));
dropImage = atlas.findRegion("images/baby");
bucketImage = atlas.findRegion("images/bucket");

One bug I found is that the images wouldn't load in the HTML project. I found out that you can work around the bug by putting all your images in a subfolder.

I created a new project to hold the TexturePacker and any unit tests that I want to add later. The texture packer looks like this:

package com.github.donkirkby.plank;

import com.badlogic.gdx.tools.imagepacker.TexturePacker2;

public class PlankPacker {
    public static void main (String[] args) throws Exception {
        TexturePacker2.process(
                "raw-assets",  // source folder
                "../plank-game-android/assets/atlas", // destination
                "plank.pack"); // data file
    }
}
Community
  • 1
  • 1
Don Kirkby
  • 53,582
  • 27
  • 205
  • 286
0

You could also put the picture (top-left corner) into an 128x128 textures aswell: Afaik is the using of non-power-of-two textures slower and takes more VRAM. Due the architecture of an GPU and "slow" handling of texture bindings in OpenGL, it's always recommended to put your images which are used at the same time into one big pow-two texture and grab them as regions of this texture to speed up your app. The using and grabbing of your texture would look like:

Texture texture = Gdx.files.internal("data/yourtexture.png");
TextureRegion region = new TextureRegion(texture, 0, 0, 60, 83);

For drawing something like this:

batch.draw(region, positionX, positionY);
TheWhiteLlama
  • 1,276
  • 1
  • 18
  • 31