2
\$\begingroup\$

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.setColor(Color.RED);
    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));
    pixmap.dispose();

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.

\$\endgroup\$
1
  • 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\$ May 5, 2016 at 20:19

1 Answer 1

1
+100
\$\begingroup\$

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
  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, verts, 0, 20);
}
\$\endgroup\$
4
  • \$\begingroup\$ Can you explain this code. I am extending actor class and drawing this on the actor draw method. \$\endgroup\$
    – Zack
    May 13, 2016 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\$ May 14, 2016 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, 2016 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\$ Jun 27, 2016 at 16:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .