8

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

我的矩形代码是:

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);
}

有没有更简单的方法来绘制填充多边形的功能或东西?

4

7 回答 7

27

由于最近更新了 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) 的几乎线性耳夹算法

简单多边形的高效三角剖分,Godfried Toussaint,1991

于 2014-09-06T17:05:08.787 回答
10

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

定义类成员PolygonSprite PolygonSpriteBatch

PolygonSprite poly;
PolygonSpriteBatch polyBatch;
Texture textureSolid;

创建实例,使用红色像素作为解决方法的 1x1 大小的纹理。坐标数组 (x, y) 用于多边形的初始化。

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);
}
于 2013-04-12T15:31:21.040 回答
3

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

ShapeRenderer.polygon()

于 2013-12-19T01:28:29.933 回答
1

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

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

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

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

于 2013-04-01T04:48:07.843 回答
1

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

于 2014-01-25T18:54:15.460 回答
1

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

1) 步行区:

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});

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

于 2016-09-21T19:30:15.807 回答
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);

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

于 2017-10-29T19:47:45.947 回答