使用libgdx绘制填充多边形

时间:2013-03-31 19:15:34

标签: java libgdx

我想用libgdx绘制一些(填充的)多边形用于Android游戏。它不应该充满图形/纹理。我只有多边形的顶点(闭合路径),并试图用网格物体进行可视化,但在某些时候,这不是最好的解决方案,我认为。

我的矩形代码是:

private Mesh mesh;
@Override
public void create() {
    if (mesh == null) {
        mesh = new Mesh(true, 4, 0, 
                new VertexAttribute(Usage.Position, 3, "a_position")
        );
        mesh.setVertices(new float[] { -0.5f, -0.5f, 0
                                        0.5f, -0.5f, 0,
                                        -0.5f, 0.5f, 0,
                                        0.5f, 0.5f, 0 });

    }
}
...
@Override
public void render() {
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
    mesh.render(GL10.GL_TRIANGLE_STRIP, 0, 4);
}

是否有一种函数或其他东西以更简单的方式绘制填充多边形?

7 个答案:

答案 0 :(得分:25)

自最近更新LibGDX以来,@ Rus的答案正在使用已弃用的函数。但是,我将为他/她提供以下新版本的学分:

PolygonSprite poly;
PolygonSpriteBatch polyBatch = new PolygonSpriteBatch(); // To assign at the beginning
Texture textureSolid;

// Creating the color filling (but textures would work the same way)
Pixmap pix = new Pixmap(1, 1, Pixmap.Format.RGBA8888);
pix.setColor(0xDEADBEFF); // DE is red, AD is green and BE is blue.
pix.fill();
textureSolid = new Texture(pix);
PolygonRegion polyReg = new PolygonRegion(new TextureRegion(textureSolid),
  new float[] {      // Four vertices
    0, 0,            // Vertex 0         3--2
    100, 0,          // Vertex 1         | /|
    100, 100,        // Vertex 2         |/ |
    0, 100           // Vertex 3         0--1
}, new short[] {
    0, 1, 2,         // Two triangles using vertex indices.
    0, 2, 3          // Take care of the counter-clockwise direction. 
});
poly = new PolygonSprite(polyReg);
poly.setOrigin(a, b);
polyBatch = new PolygonSpriteBatch();

如果你的多边形不是凸的,那么对于好的三角测量算法,请参阅Toussaint(1991)的几乎线性的咬合算法

  

Efficient triangulation of simple polygons, Godfried Toussaint, 1991

答案 1 :(得分:10)

这是一个绘制2D凹面多边形的LIBGDX示例。

//为PolygonSprite PolygonSpriteBatch定义类成员

PolygonSprite poly;
PolygonSpriteBatch polyBatch;
Texture textureSolid;

//创建实例,1x1大小纹理与红色像素一起使用作为变通方法,(x,y)用于初始化poly的坐标数组

ctor() {
    textureSolid = makeTextureBox(1, 0xFFFF0000, 0, 0); 
    float a = 100;
    float b = 100;
    PolygonRegion polyReg = new PolygonRegion(new TextureRegion(textureSolid),
      new float[] {
        a*0, b*0,
        a*0, b*2,
        a*3, b*2,
        a*3, b*0,
        a*2, b*0,
        a*2, b*1,
        a*1, b*1,
        a*1, b*0,
    });
    poly = new PolygonSprite(polyReg);
    poly.setOrigin(a, b);
    polyBatch = new PolygonSpriteBatch();
}

//绘制并旋转多边形

void draw() {
    super.draw();
    polyBatch.begin();
    poly.draw(polyBatch);
    polyBatch.end();
    poly.rotate(1.1f);
}

答案 2 :(得分:2)

我相信ShapeRenderer类现在有一个顶点定义多边形的多边形方法:

ShapeRenderer.polygon()

答案 3 :(得分:1)

您可以使用the ShapeRenderer API使用Libgdx绘制简单的纯色形状。

您提供的代码也是绘制纯色多边形的合理方法。它比ShapeRenderer更灵活,但更复杂一点。您需要使用glColor4f来设置颜色,或者为每个顶点添加Usage.Color属性。有关第一种方法的详细信息,请参阅the SubMeshColorTest example;有关第二种方法的详细信息,请参见the MeshColorTexture example

要考虑的另一个选择是使用精灵纹理。如果您只对简单的纯色对象感兴趣,可以使用单一颜色的非常简单的1x1纹理,让系统在精灵中拉伸。 Libgdx和底层硬件的大部分都是针对渲染纹理进行了优化的,所以即使你没有真正利用纹理内容,你也会发现它更容易使用。 (您甚至可以使用1x1白色纹理,然后将SpriteBatchsetColordraw()一起使用 轻松绘制不同颜色的矩形。)

您也可以混合搭配各种方法。

答案 4 :(得分:1)

使用三角剖分算法,然后将所有三角形绘制为GL_TRIANGLE_STRIP http://www.personal.psu.edu/cxc11/AERSP560/DELAUNEY/13_Two_algorithms_Delauney.pdf

答案 5 :(得分:0)

只是想与您分享我的相关解决方案,即使用scene2d实现和绘制walkZone 。我基本上不得不把别人的不同建议放在一起'帖子:

1)WalkZone:

import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.PolygonRegion;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.EarClippingTriangulator;
import com.badlogic.gdx.math.Polygon;
import com.mygdx.game.MyGame;

public class WalkZone extends Polygon {
private PolygonRegion polygonRegion = null;
public WalkZone(float[] vertices) {
    super(vertices);
    if (MyGame.DEBUG) {
        Pixmap pix = new Pixmap(1, 1, Pixmap.Format.RGBA8888);
        pix.setColor(0x00FF00AA);
        pix.fill();
        polygonRegion = new PolygonRegion(new TextureRegion(new Texture(pix)),
                vertices, new EarClippingTriangulator().computeTriangles(vertices).toArray());
        }
    }

    public PolygonRegion getPolygonRegion() {
        return polygonRegion;
    }
}

2)Screen

然后,您可以在所需的Stage

中添加一个监听器
myStage.addListener(new InputListener() {
        @Override
        public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
            if (walkZone.contains(x, y)) player.walkTo(x, y);
            // or even directly: player.addAction(moveTo ...
            return super.touchDown(event, x, y, pointer, button);
        }
    });

3)实施:

传递给te WZ构造函数的数组是一组x,y,x,y ......点。如果你逆时针方向放置它们(它我没有检查另一种方式,也不知道它是如何工作的);例如,这会产生一个100x100的正方形:

yourScreen.walkZone = new WalkZone(new int[]{0, 0, 100, 0, 100, 100, 0, 100});

在我的项目中,它就像一个魅力,即使是非常错综复杂的多边形。希望它有所帮助!!

答案 6 :(得分:0)

大多数答案都提示三角测量,这很好,但您也可以使用模板缓冲区来完成。它处理凸多边形和凹多边形。如果您的多边形发生很大变化,这可能是一个更好的解决方案,因为否则您必须每帧进行三角测量。此外,此解决方案可以正确处理自相交的多边形,EarClippingTriangulator不会。

FloatArray vertices = ... // The polygon x,y pairs.
Color color = ... // The color to draw the polygon.

ShapeRenderer shapes = ...
ImmediateModeRenderer renderer = shapes.getRenderer();

Gdx.gl.glClearStencil(0);
Gdx.gl.glClear(GL20.GL_STENCIL_BUFFER_BIT);
Gdx.gl.glEnable(GL20.GL_STENCIL_TEST);
Gdx.gl.glStencilFunc(GL20.GL_NEVER, 0, 1);
Gdx.gl.glStencilOp(GL20.GL_INVERT, GL20.GL_INVERT, GL20.GL_INVERT);
Gdx.gl.glColorMask(false, false, false, false);

renderer.begin(shapes.getProjectionMatrix(), GL20.GL_TRIANGLE_FAN);
renderer.vertex(vertices.get(0), vertices.get(1), 0);
for (int i = 2, n = vertices.size; i < n; i += 2)
    renderer.vertex(vertices.get(i), vertices.get(i + 1), 0);
renderer.end();

Gdx.gl.glColorMask(true, true, true, true);
Gdx.gl.glStencilOp(GL20.GL_ZERO, GL20.GL_ZERO, GL20.GL_ZERO);
Gdx.gl.glStencilFunc(GL20.GL_EQUAL, 1, 1);

Gdx.gl.glEnable(GL20.GL_BLEND);
shapes.setColor(color);
shapes.begin(ShapeType.Filled);
shapes.rect(-9999999, -9999999, 9999999 * 2, 9999999 * 2);
shapes.end();

Gdx.gl.glDisable(GL20.GL_STENCIL_TEST);

要使用模板缓冲区,必须在应用启动时指定模板缓冲区的位数。例如,以下是使用LWJGL2后端的方法:

    LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
    config.stencil = 8;
    new LwjglApplication(new YourApp(), config);

有关此技术的更多信息,请尝试以下链接之一: