[LibGDX] Least costly way to render lines?

          Using so much as 50 methods with Shape Renderer drops performance horrendously.

If they’re only up-down and left-right (right angles only), you could make a Texture out of a 1x1 Pixmap and render the texture with x, y, width, and height. Change width and height to create a line in some direction.

Are you using 50 different Shape Renderers or only one with a custom method to create it?

You can create a Texture 1x1 (as @chrislo27 said), Ninepatch, others…

Something like this:

batch.begin();
for (int i = 0; i < listRectangle.size(); i++)
	batch.draw(texture, listRectangle.get.(i).getX(), listRectangle.get.(i).getY(), listRectangle.get.(i).getWidth(), listRectangle.get.(i).getHeight());
batch.end();
shape.begin(ShapeType.Line);
for (int i = 0; i < listRectangle.size(); i++)
	shape.rect(listRectangle.get.(i).getX(), listRectangle.get.(i).getY(), listRectangle.get.(i).getWidth(), listRectangle.get.(i).getHeight());	
shape.end();

If your objects are in an array, you can easily just do


batch.begin();
for(Object o : listRectangle.size())
    //Draw Your Shape
batch.end();

Where as “Object” is whatever the type of variable you are using, obviously. This is essentially what @craftm suggestion, but a bit shorter.

For lines that aren’t axis aligned, you can draw them as quads. Like this

public static void drawLine(SpriteBatch batch, float x1, float y1, float x2, float y2, float lineWidth, AtlasRegion lineTexture) {
		float xdif = x2-x1;
		float ydif = y2-y1;
		float l2 = xdif*xdif+ydif*ydif;
		float invl = (float)(1/Math.sqrt(l2));
		//dif is vector with length linewidth from first to second vertex
		xdif*=invl*lineWidth;
		ydif*=invl*lineWidth;
		
		float floatBits = batch.getColor().toFloatBits();
		//draw quad with width of linewidth*2 through (x1, y1) and (x2, y2)
		float[] verts = new float[]{x1+ydif, y1-xdif, floatBits, lineTexture.getU(), lineTexture.getV(),
									x1-ydif, y1+xdif, floatBits, lineTexture.getU2(), lineTexture.getV(),
									x2-ydif, y2+xdif, floatBits, lineTexture.getU2(), lineTexture.getV2(),
									x2+ydif, y2-xdif, floatBits, lineTexture.getU(), lineTexture.getV2()};
		batch.draw(lineTexture.getTexture(), verts, 0, 20);
	}

public static void drawLine(SpriteBatch batch, float _x1, float _y1, float _x2, float _y2, float thickness, Texture tex)
	{
		float length = Trigonometrics.getDistanceAccurate(_x1, _y1, _x2, _y2); // get distance between those 2 points
		float dx = _x1;
		float dy = _y1;
		dx = dx - _x2;
		dy = dy - _y2;
		float angle = MathUtils.radiansToDegrees*MathUtils.atan2(dy, dx);
		angle = angle-180;
		batch.draw(tex, _x1, _y1, 0f, thickness*0.5f, length, thickness, 1f, 1f, angle, 0, 0, tex.getWidth(), tex.getHeight(), false, false);
	}

texture would be a 1x1 white texture, in this case, but could vary

Performance only drops if you “begin” and “end” the ShapeRenderer in those 50 methods you mentioned every time as @craftm said.

Slow:


shapeRenderer.begin(ShapeRenderer.ShapeType.Line);
shapeRenderer.line(x, y, x2, y2);
shapeRenderer.end();
shapeRenderer.begin(ShapeRenderer.ShapeType.Line);
shapeRenderer.line(x, y, x2, y2);
shapeRenderer.end();
...

Fast:


shapeRenderer.begin(ShapeRenderer.ShapeType.Line);
shapeRenderer.line(x, y, x2, y2);
shapeRenderer.line(x, y, x2, y2);
shapeRenderer.end();
...