2
\$\begingroup\$

I am intersted in using Actors and Groups on a Stage so that I can make components and subcomponents which draw relative to their parents, but I intend to do my drawing with a ShapeRenderer instead of a Batch. From what I understand of an Actor, the batch which is passed in to the draw() method has all of its matrices set up properly so that I can just use a coordinate system WITHIN THE PARENT to lay out the subcomponents. But it seems that this coordinate system is focused on Batches, and I want to draw using a ShapeRenderer.

What do I have to do to get the child Actors to draw themselves RELATIVE TO THEIR PARENT (rather than in global coordinates) when drawing them with ShapeRenderers?

Also, one other question: How should I be managing begining/ending the ShapeRenderer? I am currently passing in a reference to a global ShapeRenderer when I construct my parent object, and this parent object passes in references to each of its children. Should I be calling begin() end() separately in the draw method of each parent/child actor? Or should I call it in my main app's draw() method, so I'm only calling it once each frame?

\$\endgroup\$

1 Answer 1

5
\$\begingroup\$

Here is my HorizontalLine class. If you create one, set it's width and weight (height) and you can add it to a container like Table or so. It will use it's getX() and getY() methods to draw itself on coordinates relative to it's parent.

This answer will also help you to understand: https://stackoverflow.com/questions/18075414/getting-stage-coordinates-of-actor-in-table-in-libgdx

public class HorizontalLine extends Actor {

    private ShapeRenderer sr;


    public HorizontalLine(float width, float weight, Color color){
        setSize(width,weight);
        setColor(color);

        sr = new ShapeRenderer();
        sr.setAutoShapeType(true);
    }


    @Override
    public void draw(Batch batch, float parentAlpha) {
        super.draw(batch, parentAlpha);

        batch.end();

        Vector2 coords = new Vector2(getX(),getY());

        Color color = new Color(getColor());
        sr.setProjectionMatrix(batch.getProjectionMatrix());
        sr.setColor(color.r, color.g, color.b, color.a * parentAlpha);



        Gdx.gl.glEnable(GL20.GL_BLEND);
        Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
        sr.begin(ShapeRenderer.ShapeType.Filled);


        sr.rectLine(coords.x,coords.y,coords.x + getWidth(), coords.y, getHeight());
        sr.end();
        Gdx.gl.glDisable(GL20.GL_BLEND);
        Gdx.gl.glLineWidth(1f);
        sr.setColor(Color.WHITE);

        batch.begin();
    }
}

Also, you should end the batch, begin the renderer, end it, and begin the batch again in each actor cause otherwise it will mess up in future. Remember that ShapeRenderer calls are expensive. Remember to set SR and Batch's color back to white when you finish.

\$\endgroup\$
2
  • \$\begingroup\$ very helpful, should be part of the docu \$\endgroup\$
    – Marco
    Commented Jun 21, 2017 at 15:20
  • 1
    \$\begingroup\$ The answer is indeed very helpful. thanks. but remember that a shaperenderer is disposable, so it must be disposed. Just in case someone copies this example and decides to use it to draw hundreds of lines. \$\endgroup\$ Commented Mar 28, 2020 at 15:46

You must log in to answer this question.

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