Type Function Library display.* Return value ShapeObject Revision Release 2025.3721 Keywords shape, mesh, vector object See also Shapes — Paths, Fills, Strokes (guide) Display Objects (guide)
Draws a mesh shape by providing vertices of the shape. The local origin is at the center of the mesh and the anchor point is initialized to this local origin.
display.newMesh( [parent,] [x, y,] options ) display.newMesh( options )
GroupObject. An optional display group in which to insert the mesh.
Numbers. The location of the object relative to its parent.
Table. Table containing options for the mesh — see the next section for details.
The options table accepts the following parameters for the mesh:
Array. An array of x and y coordinates of vertices forming the mesh. Meshes are built with these vertices depending on the mode parameter.
GroupObject. An optional display group in which to insert the mesh. If included here, this will override any parent definition specified outside of the options table.
Numbers. The location of the object relative to its parent. If included here, these will override any x or y definitions specified outside of the options table.
String. String indicating how the mesh should be formed with the provided vertices. Default is "triangles". Acceptable values are "triangles", "strip", "fan", or "indexed". See Mesh Draw Modes below for a description of each mode.
Array. An array of indices required for mode type of "indexed". For example, to mimic the behavior of the "strip" mode, the value of this parameter could be { 1,2,3, 2,3,4, 3,4,5 }
Boolean. Convenience parameter with default of false. If set to true, the indices array will be treated as a
Array. An array of u and v texture coordinates of vertices forming the mesh. If omitted or invalid, UVs will be automatically assigned based on normalized vertices values. Texture coordinates are normalized coordinates where 0,0 is the 1,1 is the

Meshes with a mode of "triangles" or "indexed" are formed with disjointed groups of three consecutive vertices. An example of a "triangles" mode could have vertices with indices 1,2,3, 4,5,6, and 7,8,9. Note, however, that the "triangles" mode may result in duplicate vertices shared by several triangles — to avoid this, you can use the "indexed" type and define an indices table with indices pointing to the vertices used.
While these methods can be used to encode any mesh, they both have some duplication if a vertex is used by several triangles. In the case of "triangles", this is the vertices themselves. In the case of "indexed", this is the vertex indices. Duplicating indices is much cheaper because they’re single integer numbers, not an entire vertex with coordinates and texture coordinates.
In some cases, this duplication can be avoided via the "strip" or "fan" mode (see below).
Meshes with a mode of "strip" are formed with three consecutive vertices. An example could have vertices with indices 1,2,3, 2,3,4, and 3,4,5. For more information on this type, see here.
Meshes with a mode of "fan" are formed with an initial vertex and two ending vertices. An example could have vertices with indices 1,2,3, 1,3,4, and 1,4,5. For more information on this type, see here.
Vertices will be visually shifted so that the center of the mesh will be at the origin of the object. This does not change values when accessing vertices.
The origin will not be adjusted to the center of the mesh when modifying the mesh.
When referencing the index parameter of any method, you must point to an existing vertex.
If an invalid mesh is requested, this function will return nil.
Setting the stroke for a mesh with mode value of "triangles" or "indices" can impact performance if the mesh has a lot of vertices.
(Inherits properties from ShapeObject)
Shape objects have a path property that exposes methods to manipulate the mesh. Most methods accept the index parameter which is the Lua array index of the vertex in question (the first vertex would have an index of 1). All arguments are numbers.
Sets the vertex with index index to coordinates x and y:
object.path:setVertex( index, x, y )
Returns two numbers corresponding to a vertex’s coordinates:
object.path:getVertex( index )
Sets the vertex with index index to texture coordinates u and v:
object.path:setUV( index, u, v )
Returns two numbers corresponding to a vertex’s texture coordinates:
object.path:getUV( index )
Returns two numbers corresponding to the horizontal and vertical offsets applied when moving the origin to the center of the mesh. You can offset the mesh object by these values to compensate for initial shift and get precise vertex positions in world coordinates.
object.path:getVertexOffset()
Note that a vertex with coordinates x and y will have world coordinates of mesh.x + x - offsetXmesh.y + y - offsetY0,0 into the previous object origin:
mesh:translate( mesh.path:getVertexOffset() )
Updates the mesh’s vertices, uvs and indices:
object.path:update( options )
The options table accepts the vertices, uvs and indices for updating the mesh. These are all optional and can be excluded at will:
local options = {
vertices = {},
uvs = {},
indices = {}
}
mesh.path:update( options )
local mesh = display.newMesh(
{
x = 100,
y = 100,
mode = "triangles",
vertices = {
0,0, 50,0, 0,100,
0,100, 50,0, 100,100,
100,100, 50,0, 100,0
},
uvs = {
0,0, 0.5,0, 0,1,
0,1, 0.5,0, 1,1,
1,1, 0.5,0, 1,0
}
})
mesh:translate( mesh.path:getVertexOffset() ) -- Translate mesh so that vertices have proper world coordinates
mesh.fill = { type="image", filename="cat.png" }
local vertexX, vertexY = mesh.path:getVertex( 3 )
mesh.path:setVertex( 3, vertexX, vertexY-10 )
local mesh = display.newMesh(
{
x = 100,
y = 100,
mode = "indexed",
vertices = {
0,0, 0,100, 50,0, 100,100, 100,0
},
indices = {
1,2,3,
2,3,4,
3,4,5
}
})
mesh:translate( mesh.path:getVertexOffset() ) -- Translate mesh so that vertices have proper world coordinates
mesh.fill = { type="image", filename="cat.png" }
local vertexX, vertexY = mesh.path:getVertex( 3 )
mesh.path:setVertex( 3, vertexX, vertexY-10 )
local mesh = display.newMesh(
{
x = 100,
y = 100,
mode = "strip",
vertices = {
0,0, 0,100,
50,0, 100,100,
100,0
}
})
mesh:translate( mesh.path:getVertexOffset() ) -- Translate mesh so that vertices have proper world coordinates
mesh.fill = { type="image", filename="cat.png" }
local vertexX, vertexY = mesh.path:getVertex( 3 )
mesh.path:setVertex( 3, vertexX, vertexY-10 )
local mesh = display.newMesh(
{
x = 100,
y = 100,
mode = "fan",
vertices = {
50,0,
0,0, 0,100, 100,100, 100,0
}
})
mesh:translate( mesh.path:getVertexOffset() ) -- Translate mesh so that vertices have proper world coordinates
mesh.fill = { type="image", filename="cat.png" }
local vertexX, vertexY = mesh.path:getVertex( 3 )
mesh.path:setVertex( 3, vertexX, vertexY-10 )