I have a problem with with camera usage. I use camera and a virtual coordinate system because I want to scale my game screen to whatever the actual system resolution is.
If I set camera viewport size to 1200, 1600 for example and real application pixel resolution is 600x800 then this problem happens. I want to draw a 62x62 image to the horizontal center of screen. when I use draw function with x equals (1200/2 - 62 / 2) this problem happens.
600 - 31 = 569. Since i draw 62 units wide in virtual coordinate space, its actually 31 pixels in this example. The problem is 31 pixels is impossible to center on a even numbered x axis (600 actual pixels in this example). But camera tries to solve this very badly by default. It just cuts last vertical line from my image and it's rendered wrong!
Ofc in this example I can change app resolution to whatever I want but I want to focus on mobile and support many different screen resolutions and I just wanna think in virtual coordinate space and its units not the pixels resolution of the device. What's the point of using camera when I think about the resolution? How can I prevent such problems?
If I put image to elsewhere (some even number) in x axis for example x=0 the image scales perfectly well and no missing pixels. If I don't use camera at all it also scales perfectly (using only pixel based units).
If there is no solution I feel like camera and viewport classes are useless and everyone must use pixels.
Screenshot of the problem:
Code for my game class:
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
public class MyGame extends ApplicationAdapter
{
private SpriteBatch batch;
private OrthographicCamera camera;
private Texture myTexture;
@Override
public void create ()
{
batch = new SpriteBatch();
batch.enableBlending();
batch.setBlendFunction(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA);
camera = new OrthographicCamera(1200, 1600);
camera.translate(camera.viewportWidth / 2, camera.viewportHeight / 2);
myTexture = new Texture(Gdx.files.internal("circle.png"), true);
myTexture.setFilter(TextureFilter.MipMapLinearLinear, TextureFilter.MipMapLinearLinear);
}
@Override
public void render ()
{
Gdx.gl.glClearColor(1f, 1f, 1f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(myTexture, 569, 150, 62, 62);
batch.end();
}
@Override
public void dispose () {
batch.dispose();
myTexture.dispose();
}
}
Code for its desktop launcher:
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
public class DesktopLauncher {
public static void main (String[] arg) {
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
config.width = 600;
config.height = 800;
new LwjglApplication(new MyGame(), config);
}
}
Image asset I've used in this example: