Meshes in Codea can be used to efficiently render 2D shapes and 3D models. The mesh
object type represents a triangle mesh — a collection of vertex triplets that each represent a triangle. Each vertex in a mesh
contains a position (vec2
or vec3
), texture coordinate (vec2
), and color (color
).
To create a mesh, call the mesh()
function:
myMesh = mesh()
A mesh object has the following settable properties:
myMesh.texture -- sprite string or image
myMesh.vertices -- table of vertices (vec2 or vec3)
myMesh.texCoords -- table of texture coordinates (vec2)
myMesh.colors -- table of colors (color)
myMesh.normals -- table of normals (vec3)
myMesh.shader -- a shader object
Texture coordinates — the texCoords
property — define a mapping between a 2D coordinate within a texture (ranging from 0,0 to 1,1) and a vertex in your mesh. This allows you to specify which portions of an image cover the triangles in your mesh.
Vertex colors
define the color at a particular vertex in your mesh. These colors are linearly interpolated between vertices. This allows you to smoothly blend between colors at neighbouring vertices.
normals
can be used to define 3D normals for each vertex in your mesh. This is useful for computing shading from light sources. By default, Codea does not use mesh normals in any of its rendering modes. However, you may use the normal buffer in your own custom shaders.
The mesh
type also contains convenience methods, such as addRect
, for quickly adding rectangles to a mesh. Please see the related documentation for more details.
The shader
property is discussed in more detail in the shaders section. This property can be used to link a shader with a mesh for advanced rendering.
Shaders in Codea are used only in conjunction with mesh
. They can be used to render special effects, deformations, lighting and other advanced graphical effects when drawing a mesh.
Shaders are written in a language called GLSL ES. This is the OpenGL ES Shading Language. Codea includes a special editor called the Shader Lab for writing shaders.
In order to use shaders within Codea you use the shader
object type. To create a shader, use the following syntax:
myMesh.shader = shader(asset.documents.MyShader)
(Note that you can tap on the highlighted shader parameters in the code editor to select, or even create new shaders directly within the Codea editor.)
This will load the file "MyShader" in your Documents and attach it to myMesh
. Any uniform
variables declared in your shader can then by accessed as properties on your shader as follows:
-- Assume MyShader declares a float
-- uniform called "myCustomUniform"
myMesh.shader.myCustomUniform = 3.5
Similarly, attribute
variables declared in your shader can be accessed as buffers on your mesh:
-- Assume MyShader declares a vec2
-- attribute called "myAttribute"
buf = myMesh:buffer("myAttribute")
buf:resize(10)
buf[1] = vec2(1,1)
buf[2] = vec2(0,1)
...
For advanced users, you can also bypass the shader picking system and Shader Lab by setting your GLSL code directly on your shader object. For example, you may do the following:
myShader.vertexProgram = "... vertex program string ..."
myShader.fragmentProgram = "... fragment program string ..."
m = mesh()
This type represents a triangle mesh. Every three vertices draws a triangle. You can set vertices, texture coordinates and colors. You can also specify a texture using a sprite from a sprite pack or an image, or using the CAMERA constant to use the current live camera capture source.
vertices | table, an array of vec2 or vec3 objects |
colors | table, an array of color objects. If not set the global fill color is used for all vertices |
texCoords | table, an array of vec2 objects. If not set, triangles are drawn with color only |
texture | string, image or CAMERA, the texture to use when drawing this mesh. If not set, triangles are drawn with color only |
normals | table, an array of vec3 objects. Not used by mesh, but may be used by custom shaders. |
shader | shader, a shader object |
valid | bool, true if this mesh is valid for drawing |
size | int, number of vertices in this mesh |
The newly created empty mesh
myMesh:draw() myMesh:draw(count)
This method draws the mesh
object. The mesh
object must be valid to be drawn. For a mesh
to be valid it must have an equal number of vertices, colors, and texCoords (that are a multiple of three). With the exception that texCoords and / or colors may be nil
The count
parameter specifies the number of instances of this mesh to draw. This is an advanced parameter and can be used with instanced mesh buffers and shaders to efficiently draw many copies of the same mesh differentiated via shader attributes and uniforms.
The count
parameter is only available on devices which support mesh instancing. Older devices may not support this parameter and will ignore it.
count | integer, number of instances of this mesh to draw |
myMesh:setColors( c ) myMesh:setColors( r, g, b ) myMesh:setColors( r, g, b, a )
This method sets the colors of all vertices in the mesh
to the color specified by c
(or r
,g
,b
,a
).
c | color, set all mesh vertices to this color |
r | value of the red color component to apply to all vertices |
g | value of the green color component to apply to all vertices |
b | value of the blue color component to apply to all vertices |
a | value of the alpha component to apply to all vertices |
myMesh:clear()
This method clears a mesh
removing all vertices, texCoords, colors and normals. The underlying capacity of the mesh
remains after clearing and this may be preferable to creating a new mesh
. This method also clears any custom buffers attached to the mesh through shaders.
myMesh:addRect( x, y, w, h) myMesh:addRect( x, y, w, h, r)
This method appends a rectangle centered at the coordinates (x,y) with width, w and height, h. The optional parameter r specifies rotation in radians
x | float, the x coordinate used to place the rectangle |
y | float, the y coordinate used to place the rectangle |
w | float, the width of the rectangle |
h | float, the height of the rectangle |
r | float, the rotation of the rectangle |
Returns the index of this rectangle, which can be used to set its position later
myMesh:setRect( i, x, y, w, h) myMesh:setRect( i, x, y, w, h, r)
This method sets the geometry an existing rectangle with index i, centered at the coordinates (x,y) with width, w and height, h. The optional parameter r specifies rotation in radians
i | int, the index of the rectangle in the |
x | float, the x coordinate used to place the rectangle |
y | float, the y coordinate used to place the rectangle |
w | float, the width of the rectangle |
h | float, the height of the rectangle |
r | float, the rotation of the rectangle |
myMesh:setRectTex( i, s, t, w, h)
This method sets the texture coordinates of an existing rectangle with index i
.
i | int, the index of the rectangle in the |
s | float, the left edge of the texture rectangle |
t | float, the bottom edge of the texture rectangle |
w | float, the width of the texture rectangle |
h | float, the height of the texture rectangle |
myMesh:setRectColor( i, c) myMesh:setRectColor( i, r, g, b) myMesh:setRectColor( i, r, g, b, a)
This method sets the color of an existing rectangle with index i
.
i | int, the index of the rectangle in the |
c | color, the color to set the rectangle to |
r | int, the red component of the color to use |
g | int, the green component of the color to use |
b | int, the blue component of the color to use |
a | int, the alpha component of the color to use |
v = myMesh:vertex( i ) myMesh:vertex( i, x, y, z ) myMesh:vertex( i, vec3 ) myMesh:vertex( i, x, y ) myMesh:vertex( i, vec2 )
When called with one argument, i
, this method returns the vertex at the index specified by i
. When called with more arguments, this method sets the vertex at index i
to the value provided by x
, y
, z
or a vec3
or vec2
.
This method is useful when you wish to set a single vertex, or small subset of vertices. It is much more efficient than assigning a new vertex table to the mesh.vertices property.
i | int, the index of the vertex in the |
x | float, the x position to set vertex i to |
y | float, the y position to set vertex i to |
z | float, the z position to set vertex i to |
vec3 | vec3, the 3D position to set vertex i to |
vec2 | vec2, the 2D position to set vertex i to |
If called with one argument (the index of the vertex) then this returns a vec3
value representing the position of the vertex.
t = myMesh:texCoord( i ) myMesh:texCoord( i, x, y ) myMesh:texCoord( i, vec2 )
When called with one argument, i
, this method returns the texture coordinate at the index specified by i
. When called with more arguments, this method sets the texture coordinate at index i
to the value provided by x
, y
or the given vec2
value.
This method is useful when you wish to set the texture coordinate of a single vertex, or small subset of vertices. It is much more efficient than assigning a new texture coordinate table to the mesh.texCoords property.
i | int, the index of the texture coordinate in the |
x | float, the x value to set vertex i's texture coordinate to |
y | float, the y value to set vertex i's texture coordinate to |
vec2 | vec2, the texture coordinate value to set on vertex i |
If called with one argument (the index of the vertex) then this returns a vec2
value representing the texture coordinate at that vertex.
c = myMesh:color( i ) myMesh:color( i, r, g, b ) myMesh:color( i, r, g, b, a ) myMesh:color( i, color )
When called with one argument, i
, this method returns the color at the index specified by i
. When called with more arguments, this method sets the color at index i
to the value provided by r
, g
, b
, a
or the given color
object.
This method is useful when you wish to set the color of a single vertex, or small subset of vertices. It is much more efficient than assigning a new color table to the mesh.colors property.
i | int, the index of the color in the |
r | int, the red value to set vertex i's color to (0 to 255) |
g | int, the green value to set vertex i's color to (0 to 255) |
b | int, the blue value to set vertex i's color to (0 to 255) |
a | int, the alpha value to set vertex i's color to (0 to 255) |
color | color, the color to set vertex i to |
If called with one argument (the index of the vertex) then this returns a color
object representing the color at that vertex.
n = myMesh:normal( i ) myMesh:normal( i, x, y, z ) myMesh:normal( i, vec3 )
When called with one argument, i
, this method returns the normal at the index specified by i
. When called with more arguments, this method sets the normal at index i
to the value provided by x
, y
, z
or a vec3
.
i | int, the index of the vertex in the |
x | float, the x magnitude of the normal for vertex i |
y | float, the y magnitude of the normal for vertex i |
z | float, the z magnitude of the normal for vertex i |
vec3 | vec3, the normal to set vertex i to |
If called with one argument (the index of the vertex) then this returns a vec3
value representing the normal of the vertex.
myMesh:resize(30)
This method allows you to change the size of a mesh
. This will resize all of the data arrays contained in the mesh (i.e., vertices, texCoords, colors, normals). It will also resize any custom attribute buffers defined by attached shaders.
size | int, the number of elements in the mesh |
b = myMesh:buffer("position") b = myMesh:buffer("texCoord") b = myMesh:buffer("color") b = myMesh:buffer("normal")
This method returns the attribute buffer for particular mesh property. Buffers allow direct access to a mesh's internal data. For example, you can access the vertex positions of a mesh by calling myMesh:buffer("position"). You can then modify the returned buffer directly, and the mesh's data will be updated automatically.
If a mesh has a shader assigned to it, then you can also use the buffer
method to fetch and manipulate attribute arrays that have been declared in your shader.
When you fetch a custom attribute buffer from a mesh, it is initially sized to the same size as the mesh's vertices array (i.e. the "position" buffer).
For example, if your shader has an attribute named "myAttribute" and you have assigned this shader to your mesh's shader
property, then you can access the attribute array with myMesh:buffer("myAttribute")
and set its data.
name | string, either "position", "texCoord", "color" or "normal" or an attribute name declared in an attached shader |
A buffer object allowing direct access to an array of mesh data of a particular type
b = myMesh:buffer("position") b = myMesh:buffer("texCoord") b = myMesh:buffer("color") b = myMesh:buffer("normal") b = myMesh:buffer("myAttrib") b.instanced = true
The buffer type is used in the context of a mesh to provide fast, in-place access to mesh data, such as vertices, texture coordinates, and even custom attribute arrays. Buffers simply represent an array of data with the following possible types: float
, vec2
, vec3
, vec4
, and color
.
You do not create buffers directly. Instead, you access the built-in buffers on a mesh using their predefined names, or you can access attribute
variables declared in your custom shader.
A mesh contains several built-in buffers (for its vertex positions, texture coordinates, colors, and normals). These can be accessed through the mesh:buffer("bufferName") method.
instanced | boolean, indicates whether this buffer should be treated as an instanced buffer. Defaults to |
The newly created empty buffer
myBuffer:resize(30)
This method allows you to change the size of a buffer
. In general, you want to ensure your buffers have the same number of elements as the mesh that they belong to (i.e. the same as your mesh.size
).
Buffers are initially sized to the same size as the "position" buffer in their attached mesh (i.e. mesh.vertices
). Using mesh.resize
will resize all mesh buffers, including your custom buffers.
size | int, the number of elements in the buffer |
myBuffer:clear()
This method clears all data from the buffer and sets its size to 0.
myTable = myBuffer:get()
This method returns a copy of the data in buffer
as a Lua table.
A table containing the data in buffer
myBuffer:set( myTable )
This method sets the content of buffer
to the data contained in table
.
table | table, a table of vec2, vec3, vec4 or color |
s = shader() s = shader(asset.documents.MyShader) s = shader(vertexProgram, fragmentProgram)
This type represents a GLSL shader program. Shader programs are an advanced graphical tool that can be used in conjunction with mesh to provide complex graphical effects.
Shaders consist of two components, a vertex program and a fragment program. The vertex program is run on the GPU for each vertex in the mesh, and the fragment program is run for each fragment (similar to a pixel) drawn on the screen.
You can, for example, have a shader that distorts the vertices of a mesh according to a mathematical function. Or a shader that inverts the colors of a mesh's texture, and so on.
All of Codea's basic rendering effects are provided using shaders. So by supplying your own shaders, you can completely override how Codea renders elements to the screen.
In addition to loading shaders through shader packs, advanced users may also access the vertexProgram
and fragmentProgram
properties of shader
to read and write the shader program strings directly.
vertexProgram | string, a string defining the vertex program of the shader |
fragmentProgram | string, a string defining the fragment program of the shader |
A newly created shader
triangleVertices = triangulate( points )
Takes an array of points representing a polygon and decomposes it into a list of triangles. Points must be in clockwise or anti-clockwise order.
points | table, an array of vec2 objects representing a polygon |
A triangle list generated from the supplied polygon in the form { t1p1, t1p2, t1p3, t2p1, t2p2, t2p3, ..., tNp3 }