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を使用してShapeRenderer、Libgdx で単純な単色の図形を描画できます。

あなたが与えたコードは、無地のポリゴンも描画するための合理的な方法です。よりもはるかに柔軟ですShapeRendererが、かなり複雑です。を使用glColor4fして色を設定するか、Usage.Color各頂点に属性を追加する必要があります。最初のアプローチの詳細についてはSubMeshColorTestの例を、2 番目のアプローチの詳細については MeshColorTexture の例を参照してください。

考慮すべきもう 1 つのオプションは、スプライト テクスチャの使用です。単純な無地のオブジェクトのみに関心がある場合は、単一色の非常に単純な 1x1 テクスチャを使用して、システムにそれをスプライト全体にストレッチさせることができます。Libgdx とその基盤となるハードウェアの多くは、テクスチャのレンダリング用に最適化されているため、テクスチャ コンテンツを実際に利用していない場合でも、使いやすいと感じるかもしれません。(1x1 の白いテクスチャを使用して、 と を使用して異なる色の長方形を簡単に描画することもできますSpriteBatch。 )setColordraw()

また、さまざまなアプローチを組み合わせることもできます。

于 2013-04-01T04:48:07.843 に答える
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) 実装:

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 に答える