Search code examples
androidlibgdx

Draw a smooth line


I am developing a game using libgdx and i want to draw a smooth line using shape renderer.

        shaperenderer.begin(ShapeType.Line);
        shaperenderer.line(fisrstVec2,secondVec2);
        shaperenderer.end();

I have tried Multi Sample anti aliasing from libgdx blog. I have also went through Anti aliased filed shape in libgdx but unfortunately these line is not in latest verson of libgdx.

   Gdx.gl.glEnable(GL10.GL_LINE_SMOOTH);
   Gdx.gl.glEnable(GL10.GL_POINT_SMOOTH); 

Solution

  • Enable anti-alising in the configuration:

    For Desktop:

        LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
        config.samples = 2;
        new LwjglApplication(new MyGdxGame(Helper.arrayList(arg)), config);
    

    For Android:

        AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
        config.numSamples = 2;
        initialize(new MyGdxGame(null), config);
    

    Or you could create a white pixmap of 1x1 and use it to create a sprite and draw the line using that sprite, I personally prefer this method istead of ShapeRenderer (note that there is no rotation in this method):

    /**
     * draws a line on the given axis between given points
     *
     * @param batch       spriteBatch
     * @param axis        axis of the line, vertical or horizontal
     * @param x          x position of the start of the line
     * @param y          y position of the start of the line
     * @param widthHeight width or height of the line according to the axis
     * @param thickness thickness of the line
     * @param color       color of the line, if the color is null, color will not be changed.
     */
    public static void line(SpriteBatch batch, Axis axis, float x, float y, float widthHeight, float thickness, Color color, float alpha) {
        if (color != null) sprite.setColor(color);
        sprite.setAlpha(alpha);
        if (axis == Axis.vertical) {
            sprite.setSize(thickness, widthHeight);
        } else if (axis == Axis.horizontal) {
            sprite.setSize(widthHeight, 1);
        }
        sprite.setPosition(x,y);
        sprite.draw(batch);
        sprite.setAlpha(1);
    }
    

    With some modifications to the previous method, you can come up with this method to draw a line with rotation.

    public static void rotationLine(SpriteBatch batch, float x1, float y1, float x2, float y2, float thickness, Color color, float alpha) {
        // set color and alpha
        if (color != null) sprite.setColor(color);
        sprite.setAlpha(alpha);
        // set origin and rotation
        sprite.setOrigin(0,0);
        sprite.setRotation(getDegree(x2,y2, x1, y1));
        // set position and dimension
        sprite.setSize(distance(x1,y1,x2,y2),thickness);
        sprite.setPosition(x1, y1);
        // draw
        sprite.draw(batch);
        // reset rotation
        sprite.rotate(0);
    }
    
    public static float getDegree(float x, float y, float originX, float originY) {
        float angle = (float) Math.toDegrees(Math.atan2(y - originY, x - originX));
        while (angle < 0 || angle > 360)
            if (angle < 0) angle += 360;
            else if (angle > 360) angle -= 360;
        return angle;
    }
    
    public static float distance(float x, float y, float x2, float y2) {
        return (float) Math.sqrt(Math.pow((x2 - x), 2) + Math.pow((y2 - y), 2));
    }