I have two Vectors which indicate the ending points of each line. I am trying to draw similar lines to football formation lines like these:

My main problem using ShapeRenderer is:

  1. ShapeRenderer coordinates are relative to screen coordinates and not Scene/Table/Stack. This creates varying coordinate points in different screen sizes. Although I can fix it, I still experience get varying line width in different screen sizes.
  2. ShapeRenderer performance issues as it is mainly intended for debugging.
  3. ShapeRenderer draws over all Actors.

I have tried drawing the lines as a Pixmap and adding them to the scene as an image. This is part of the constructor to my custom class which extends Group.

pixmap = new Pixmap( 16, 16, Pixmap.Format.RGBA8888 );

    pixmap.drawLine(Ax, Ay, Bx, By);
    Texture pixmaptex = new Texture(pixmap, Pixmap.Format.RGB888, false);
    Image pixmapimg = new Image(pixmaptex);
    pixmapimg.setPosition(x, y);
    this.addActor(new Image(pixmaptex));

I am trying to draw using this but it just draws a square with the pixmap width and height at (0,0) of the stack. Which is the best class to extend to draw this lines? I am expecting to write a custom class if this doesn't work.

  • 1
    \$\begingroup\$ Problem #1 is solved by shapeRenderer.setProjectionMatrix(batch.getProjectionMatrix()); and problem #3's assumption is not correct. ShapeRenderer draws in the order that its draw methods are called. If you have an actor that contains a ShapeRenderer and you draw the shape renderer in the Actor's draw method, it will draw in the correct order. Nevertheless, problem #2 is definitely a problem and a good reason not to use it in production code. \$\endgroup\$ – spectacularbob May 5 '16 at 20:19

According to this post you can draw a rotated quad. The line texture could be a 1x1 colored pixel.

public static void drawLine(Batch batch, float x1, float y1, float x2, float y2, float lineWidth, TextureRegion 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

  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, verts, 0, 20);
  • \$\begingroup\$ Can you explain this code. I am extending actor class and drawing this on the actor draw method. \$\endgroup\$ – Zack May 13 '16 at 16:08
  • \$\begingroup\$ I edited the function parameters to take objects that make a little more sense. Just pass the batch passed into Actor's draw call to this function. The x1,y1,x2,y2 parameters are the endpoints of the line. This functions calculates the vertices of a rotated Quad with these endpoints that is "lineThickness" wide and then sends the vertices to OpenGL to be drawn on the screen. \$\endgroup\$ – spectacularbob May 14 '16 at 17:40
  • \$\begingroup\$ Its working but there is a memory leak which I do not know where it is coming from. Any idea? \$\endgroup\$ – Zack Jun 24 '16 at 17:31
  • \$\begingroup\$ It looks like you dispose the pixmap, but are you disposing of your Texture when you are done with it? I doubt that the drawLine function is causing leaks \$\endgroup\$ – spectacularbob Jun 27 '16 at 16:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.