12

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); 
Community
  • 1
  • 1
  • 2
    Are you runnig this on Android device or desktop? – m.antkowicz Mar 22 '16 at 09:05
  • 3
    I am running this in android devices. – Amit Kumar Shrivastava Mar 22 '16 at 09:06
  • 10
    `GL_LINE_SMOOTH` is obsolete (from OpenGL ES 1.0, which LibGDX no longer supports). You should enable multi-sampling by setting `numSamples` in the ApplicationConfiguration you pass into your game from the launcher class. If that doesn't work, perhaps you are testing on a GPU that doesn't support it. It is also possible to get smooth lines without anti-aliasing by drawing long, skinny rectangle sprites that have some empty padding on the sides. – Tenfour04 Mar 22 '16 at 12:55
  • 2
    @Tenfour04 this could be a good answer, not only a comment – antonio Jan 12 '17 at 11:06

1 Answers1

3

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));
}
ossobuko
  • 851
  • 8
  • 25