Draw Ring with shapeRenderer in LibGDX

2019-08-14 02:47发布

问题:

I want to draw a ring (circle with big border) with the shaperenderer.

I tried two different solutions:

  1. Solution: draw n-circles, each with 1 pixel width and 1 pixel bigger than the one before. Problem with that: it produces a graphic glitch. (also with different Multisample Anti-Aliasing values)

  2. Solution: draw one big filled circle and then draw a smaller one with the backgroundcolor. Problem: I can't realize overlapping ring shapes. Everything else works fine.

I can't use a ring texture, because I have to increase/decrease the ring radius dynamic. The border-width should always have the same value.

How can I draw smooth rings with the shaperenderer?

EDIT: Increasing the line-width doesn't help:

回答1:

MeshBuilder has the option to create a ring using the ellipse method. It allows you to specify the inner and outer size of the ring. Normally this would result in a Mesh, which you would need to render yourself. But because of a recent change it is also possible to use in conjunction with PolygonSpriteBatch (an implementation of Batch that allows more flexible shapes, while SpriteBatch only allows quads). You can use PolygonSpriteBatch instead of where you normally would use a SpriteBatch (e.g. for your Stage or Sprite class).

Here is an example how to use it: https://gist.github.com/xoppa/2978633678fa1c19cc47, but keep in mind that you do need the latest nightly (or at least release 1.6.4) for this.



回答2:

Maybe you can try making a ring some other way, such as using triangles. I'm not familiar with LibGDX, so here's some pseudocode.

 // number of sectors in the ring, you may need
 // to adapt this value based on the desired size of
 // the ring
int sectors=32;
float outer=0.8; // distance to outer edge
float inner=1.2; // distance to inner edge
glBegin(GL_TRIANGLES)
glNormal3f(0,0,1)
for(int i=0;i<sectors;i++){
 // define each section of the ring 
 float angle=(i/sectors)*Math.PI*2
 float nextangle=((i+1)/sectors)*Math.PI*2
 float s=Math.sin(angle)
 float c=Math.cos(angle)
 float sn=Math.sin(nextangle)
 float cn=Math.cos(nextangle)
 glVertex3f(inner*c,inner*s,0)
 glVertex3f(outer*cn,outer*sn,0)
 glVertex3f(outer*c,outer*s,0)

 glVertex3f(inner*c,inner*s,0)
 glVertex3f(inner*cn,inner*sn,0)
 glVertex3f(outer*cn,outer*sn,0)
}
glEnd()

Alternatively, divide the ring into four polygons, each of which consists of one quarter of the whole ring. Then use ShapeRenderer to fill each of these polygons.

Here's an illustration of how you would divide the ring:



回答3:

if I understand your question, maybe, using glLineWidth(); help you.

example pseudo code:

size = 5;

Gdx.gl.glLineWidth(size);

mShapeRenderer.begin(....);
..//
mShapeRenderer.end();