Search code examples
javalibgdxscaleresolution

Java / LibGDX scaling issues


I'm creating a game in libgdx, and it all works fine in 1920x1080 aspect ratio and 1280x720. The problem is, some resolutions, like 1366x768, which are also common on computers, are not dividable by my texture size (16px), and it's not exactly 16*9 which makes some pixels get too long or too high. Here's an image of what's happening. If you zoom in you can see some pixels are really weird. image

Hope this is enough information, please let me know if it isn't.


Solution

  • You need to crop the draw area if the desired resolution doesn't fit the aspect ratio of your game.

    Under your render routine you should calculate the correct viewport

    @Override
    public void render() {
    
       [...]
    
       // set viewport
       Gdx.gl.glViewport((int) _viewport.x, (int) _viewport.y,
                (int) _viewport.width, (int) _viewport.height);
       [...]
    }
    

    To calculate the correct viewport you can use this function (I wrote this function for my game engine based on libgdx)

    • width: current window width,
    • height: current window height,
    • virtualHeight/Width : the original resolution of your game (i.e. 1920x1080)
    public Rectangle resize(float width, float height){
    
        float aspectRatio = (float)width/(float)height;
        float scale = 1.0f;
        Vector2 crop = new Vector2(0f, 0f); 
    
        if(aspectRatio > getAspectRatio())
        {
            scale = (float)height/(float)getVirtualLandHeight();
            crop.x = (width - getVirtualLandWidth()*scale)/2f;
        }
        else if(aspectRatio < getAspectRatio())
        {
            scale = width/(float)getVirtualLandWidth();
            crop.y = (height - getVirtualLandHeight()*scale)/2f;
        }
        else
        {
            scale = (float)width/(float)getVirtualLandWidth();
        }
    
        float w = (float)getVirtualLandWidth()*scale;
        float h = (float)getVirtualLandHeight()*scale;
    
        Rectangle viewport = new Rectangle(crop.x, crop.y, w, h);
    
        return viewport;
    }
    
    public float getAspectRatio(){
        return getVirtualLandWidth() / getVirtualLandHeight();
    }