javalibgdxviewportspritebatch

libgdx batch draws outside of FitViewport


I have been trying to solve this for 3 weeks now. I got myself started with viewports with libgdx wiki about it, and browsing through many questions in this forum about viewports, virtual viewports and the likes, and found the best solution for my game is to have 2 viewports: 1 Fitviewport for my Game rendering (not using stage) , and another Screenviewport for my UI (using Stage). The UI is drawn perfectly although i have a specific problem with that which i believe involves DPI cause the controls get rendered very small on a Samsung S4 and they are barely usable, but I'll make a separate question about that. My problem is with the Game rendering and the FitViewport on libgdx. I'm setting the game camera and its viewport this way on the PlayScreen constructor which implements Screen :

gameCamera = new OrthographicCamera();
gameCamera.setToOrtho(false);
gameViewport = new FitViewport(800, 480,gameCamera);

Then on the render method I apply it this way:

input(Gdx.graphics.getDeltaTime());

update(Gdx.graphics.getDeltaTime());

Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

gameCamera.update();
uiCamera.update();
MyGame.batch.setProjectionMatrix(gameCamera.combined);
gameViewport.apply();
MyGame.batch.begin();   
//DRAW CODE AFTER THIS
MyGame.batch.end();

//apply stage ScreenViewport and draw:
game.stage.getViewport().apply();
game.stage.draw();

Then in resize method i only have these 2 lines:

game.stage.getViewport().update(width,height,true);
gameViewport.update(width,height);
gameCamera.position.set(Gdx.graphics.getWidth()/2,Gdx.graphics.getHeight()/2,0);

The drawing methods are based on Gdx.graphics.getHeight() and Gdx.graphics.getWidth() coordinates. My game world is a top down shooter that uses Gdx.graphics.getWidth() and getHeight() to spawn creatures and limit the player's movement.

Again the problem i have is the following: -The FitViewport doesnt seem to be working properly. When i try it on my device, the viewport fits, creates gutter lines but I cant see the player drawn in relation to the Gdx.graphics coordinates. - When i do a test drive on desktop with weird resolutions, i can see the bullets being drawn outside the viewport into the gutter lines. I dont know why this happens.

I believe my problem could be that i should create my world in relation to other coordinates which are not Gdx.graphics dimensions, but I cant seem to figure out a possible solution to this. But what i trully dont understand is why can i see bullets in the gutter lines.


Solution

  • I see a lot of people struggling with this and I must admit I have struggled with it a bit too early on. But once you understand the basics it's really easy to implement.

    Let's take FitViewport, when you initialize this new FitViewport(float worldWidth, float worldHeight, camera) you are specifying world coordinates. This means the viewport will draw that given portion of the world no matter what.

    We have not set screen bounds yet so let's do that:

    vp.setScreenBounds(Gdx.graphics.getWidth() / 2, 0, Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight());
    

    Here it is asking screenWidth and screenHeight which represesent screen coordinates. Since everyone uses a different screen we get it from the graphics itself. You can have one guess where it draws the viewport ;).

    Anyway this viewport new FitViewport(1920 / 2, 1080) will always render 960 X 1080 of my world on the right half of the screen.

    If my world is .9f x 1.6f large then I could init the vp like this new FitViewport(.9f, 1.6f, camera).

    PS: Don't forget to apply the VP in render() before you start drawing.