我想用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);
}
是否有一种函数或其他东西以更简单的方式绘制填充多边形?
答案 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类现在有一个顶点定义多边形的多边形方法:
答案 3 :(得分:1)
您可以使用the ShapeRenderer
API使用Libgdx绘制简单的纯色形状。
您提供的代码也是绘制纯色多边形的合理方法。它比ShapeRenderer
更灵活,但更复杂一点。您需要使用glColor4f
来设置颜色,或者为每个顶点添加Usage.Color
属性。有关第一种方法的详细信息,请参阅the SubMeshColorTest example;有关第二种方法的详细信息,请参见the MeshColorTexture example。
要考虑的另一个选择是使用精灵纹理。如果您只对简单的纯色对象感兴趣,可以使用单一颜色的非常简单的1x1纹理,让系统在精灵中拉伸。 Libgdx和底层硬件的大部分都是针对渲染纹理进行了优化的,所以即使你没有真正利用纹理内容,你也会发现它更容易使用。 (您甚至可以使用1x1白色纹理,然后将SpriteBatch
与setColor
和draw()
一起使用
轻松绘制不同颜色的矩形。)
您也可以混合搭配各种方法。
答案 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);
有关此技术的更多信息,请尝试以下链接之一: