Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Libgdx and TexturePacker with xxxdpi images get distorted

I'm an android developer, building my first game using LibGDX. After reading A LOT, there is still one thing I don't understand.

I realize I should have one set of images, for the highest resolution 2560x1440 (For preventing ugly scaling up not vector images).

I'm using TexturePacker to pack my images and even using linear linear to get max quality:

TexturePacker.Settings settings = new TexturePacker.Settings();
settings.filterMin = Texture.TextureFilter.Linear;
settings.filterMag = Texture.TextureFilter.Linear;
settings.maxWidth = 4096;
settings.maxHeight = 2048;
TexturePacker.process(settings, inputDir, outputDir, packFileName);

I've set my camera, as recommended in several SO's, to fixed meters and avoid all the PPM stuff. From Screen's C'TOR:

mCamera = new OrthographicCamera();
mCamera.viewportWidth = 25.6f; ; // 2560 / 100
mCamera.viewportHeight = 14.4f ; // 1440 / 100
mCamera.position.set(mCamera.viewportWidth / 2, mCamera.viewportHeight / 2, 0f);
mCamera.update();

As you can see I chose to work with 1 meter = 100 pixels.

Now, that means I should draw my sprites with a 1/100 size, which i'm doing here:

TextureAtlas atlas = new TextureAtlas(Gdx.files.internal("images/pack.atlas"));
mImage = atlas.createSprite("image"));
mImage.setSize(mImage.getWidth() / 100 , mImage.getHeight() / 100);

This works and the images are displayed as intended. BUT, they are distorted as hell! a perfectly round image looks pixelated on the edges and not round.

So, my questions are:

  1. Is this the best practice or should I work differently?
  2. Am I correct having only the highest quality images?
  3. Is the distortion means that my code is really scaling down the sprite and somehow libgdx has scaled it up again and damaged the quality?

Thanks!

EDIT
I'm gonna adapt @Tenfour04's answers to (1) and (2).
Regarding (3), the problem is with Genymotion :( , its pixelating the game. I've test it on real devices with several resolutions and it looks perfect.

like image 533
Shirane85 Avatar asked Apr 18 '16 09:04

Shirane85


1 Answers

  1. You have one error in setting up your camera: You assume that the screen is always the same aspect ratio, but in reality it will vary. It's better to pick a constant height or width (choose based on the type of game you're making) and adjust the opposite dimension based on the aspect ratio of the current screen. For example:

    mCamera.viewportHeight = 25.6f; //game screen always 25.6 meters tall

    mCamera.viewportWidth = 25.6f / (float)Gdx.graphics.getHeight() * (float)Gdx.graphics.getWidth();

  2. "I should have one set of images for the highest resolution" This is not necessarily true. If you do this, you will have to load very high resolution images on devices that can't take advantage of them. This will use a lot of memory and inflate load times. It may be fine during development, but down the road you will probably want to have two or three different smaller resolution versions that you can selectively load.

    For this reason, I also would avoid hard-coding that 100 everywhere in your code. Make pixelsPerMeter a variable that is set once when the game starts up. For now it can just be 100, but if you decide to make some smaller resolution art later, you can adjust it accordingly then without having to find all the occurrences of 100 in your code.

  3. Your min filter should be MipMapLinearLinear or MipMapLinearNearest. Otherwise, performance will suffer when sprites are drawn smaller than their native resolution, and may look distorted as you described. You can look up mip mapping to see why this is the case.

like image 65
Tenfour04 Avatar answered Sep 28 '22 02:09

Tenfour04