繁体   English   中英

使用 libGDX 绘制填充多边形

[英]Drawing filled polygon with libGDX

我想用 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);
}

有没有函数或东西可以更简单地绘制填充多边形?

自 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

这是一个绘制 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);
}

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

ShapeRenderer.polygon()

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

您提供的代码也是绘制纯色多边形的合理方法。 它比ShapeRenderer灵活得多,但要复杂一些。 您需要使用glColor4f来设置颜色,或者为每个顶点添加一个Usage.Color属性。 该SubMeshColorTest例如关于第一种方法,更细节的MeshColorTexture例如对第二种方法的细节。

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

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

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

只是想与您分享我的相关解决方案,即使用 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});

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

大多数答案都建议三角测量,这很好,但您也可以使用模板缓冲区来完成。 它处理凸多边形和凹多边形。 如果您的多边形变化很大,这可能是一个更好的解决方案,否则您必须每帧都进行三角剖分。 此外,此解决方案可以正确处理自相交多边形,而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);

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM