[LibGDX] How to viewport?

For the past few days I’ve been trying to figure out how view ports work and how I can make my game fit in any resolution. Currently I’m trying to make my game 800x600 because I figured that can be scaled to almost anything without cropping. I have an extend view port that I want to have extend to fit the 800x600 game into a 1366x768 screen. With the current code I have nothing happens. I’ve tried Stretch view ports, Screen view ports and nothing. It’s always a big red square in the center of the screen (The color that the game clears with). Help?

public void show() {
		cam  = new OrthographicCamera();
		viewport = new ExtendViewport(800, 600, cam);
		viewport.apply(true);
		
	}

	@Override
	public void render(float delta) {
		cam.update();
		
	}

	@Override
	public void resize(int width, int height) {
		viewport.update(width, height);
		
	}

If you want the game to simply stretch to any resolution, you don’t even need a viewport. Just set a camera to your desired “render” width and height, then update the camera and set the batch matrix to the camera’s combined matrix. The camera will do the work for you.

If you want the game to have black bars on the sides, you’ll need a viewport, although I haven’t dabbled into that quite yet.

Assuming that the resolution is 800x600, you can Stretch (no aspect ratio), Fit (with black bars, keeping the aspect ratio) or others types.
Don’t forget to set the batch matrix to the camera as @chrislo27 said.

Stretch:

public void initialize()
{
	camera = new OrthographicCamera(800, 600);
	camera.setToOrtho(false, 800, 600);

	viewport = new StretchViewport(800, 600, camera);
	viewport.apply();
	
	stage = new Stage(new StretchViewport(800, 600));
}

@Override
public void resize(int width, int height)
{
	viewport.update(width, height);
	stage.getViewport().update(width, height); //Stage viewport
}

Fit:

public void initialize()
{
	camera = new OrthographicCamera(800, 600);
	camera.setToOrtho(false, 800, 600);

	viewport = new FitViewport(800, 600, camera);
	viewport.apply();
	
	stage = new Stage(new FitViewport(800, 600));
}

@Override
public void resize(int width, int height)
{
	viewport.update(width, height);
	stage.getViewport().update(width, height); //Stage viewport
}

All types here: https://github.com/libgdx/libgdx/wiki/Viewports

But setting the projection matrix would then mean that whatever is rendered in that batch is now in a so called “World” position. Meaning the position is no longer relative to the camera instead it has world coordinates. If I create the camera with the desired width and height and not set the batch’s projection matrix, it will stay at the scale of the only texture I have. If I DO set the batch’s projection matrix as the camera, the camera will indeed scale up to the resolution I want (In this case 1280x720), but then the 800x600 texture I have will now be in a sort of “World” space and still be 800x600. Is there something I’m not understanding that is crucial to this? ???

Edit: Also, can the game also be stretched down, and how would I hand HUD displays if I have to set the projection matrix for the batch for the game to scale?

This is what I’m understanding: You want the screen size to be 1280x720, but the game should be drawn as if it were 800x600.

If that were the case, keep the camera at 800x600 and make the window size 1280x720. This only works if you want to stretch it (or shrink it) to the window size. As I mentioned earlier, you don’t need a viewport for this method.

I’m setting my game to fullscreen and setting it to have a size of 1280x720 on star-tup. I then proceed to create my screens, textures, etc. Below is my code:

public class MenuScreen implements Screen {

	Core core;
	
	private OrthographicCamera cam;
	private SpriteBatch batch;
	private Texture test;
	
	public MenuScreen(Core core){
		this.core = core;
	}
	
	@Override
	public void show() {
		test = new Texture(Gdx.files.internal("data/Untitled.png"));
		batch = new SpriteBatch();
		cam  = new OrthographicCamera(800, 600);
		
		
	}

	@Override
	public void render(float delta) {
		cam.update();
		
		batch.begin();
		batch.draw(test, 0, 0);
		batch.end();
		
	}

If I do this, the 800x600 texture of a square will show up in the bottom left corner. If I set the projection matrix to camera.combined, the texture will show up with its bottom left point in the center of the camera. I’m trying to have it completely stretch across the screen.

SpriteBatch will use its’ default camera with a width and height set to the window size when you do not set the projection matrix. The reason the texture shows up in the center when you do set the projection matrix to your camera, however, is because by default an OrthographicCamera has (0, 0) set to the center of the screen. If you instead do this:


OrthographicCamera camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 600);

The camera will have a width and height of 800x600 and a position of (0, 0) in the bottom left corner. The first parameter species whether you want the y-values increasing up or down the screen. False for up, true for down. This should give you the results you want. :smiley:

Can confirm, moving my width and height for the camera to the camera’s constructor caused everything to be offset to the middle. Thanks for sharing! Also, you’ll still need to set the batch to the combined matrix of the camera.

Did exactly as stated and still nothing. To try and rephrase the question, I want the game to be rendered in 800x600 but stretch completely to fit the user’s screen. My current game is rendering at 1280x720 and just drawing the 800x600 texture normally on the screen.

*Note: I want to do this in fullscreen, I simply switched to windowed to take a screenshot.

How it looks (Blue square is the 800x600 texture I want rendered to fit the complete screen):

Sorry to hijack the thread, but I have a question regarding viewports and it didn’t make sense to create a whole new topic.

I was wondering which viewport is really the best/most common to use? I want to create a simple game for Android devices but I don’t want to have issues with weird looking graphics :persecutioncomplex:

FitViewport looks pretty nice :point:

From what I’ve seen and read, the Fit View port is the best option to get the most screen space while keeping the aspect ration. To bad I can’t get any of this to work. :-\

Maybe this can help you, Pork? It’s a recent video :slight_smile:

u_iMpyj3OJ8

Hmm, I’ve been reading that 480x800 is a really common screen resolution for Android devices. Would it be best to create my game with assets built for this resolution and then allow the FitViewport deal with different screen sizes?

Just a quick question about the viewports again :slight_smile:

I know how to do viewports with a stage but what about a spritebatch? Do I simply tell my camera what viewport to use and then in my render put:

camera.update;
batch.setProjectionMatrix(camera.combined)

Sometimes I never use stages and i’m a little worried i’m mess up ::slight_smile: