A primitive is a type of drawing done using points to define what is shown on the screen. They can be made up of single points, lines or triangles and can be coloured, have alpha blending and even be given a texture, which means that they can be used to create some very exciting effects in your 2D and 3D games!
The points of a primitive are called vertices (singular vertex) and store data about their position, colour, texture and possibly other information. The GPU then draws these vertices using the primitive type that you provide:
For example, you can create a rectangle using two triangle primitives, then texture it with a flag sprite and in the Draw event of an instance have that flag "wave" in the wind and distort the sprite you used by simply modifying the points that form the primitive.
WARNING These functions do not work with the HTML5 module unless you have enabled WebGL in the Game Options.
GameMaker offers two ways to draw and create primitives:
The draw_primitive_* functions allow you to define primitives and draw them directly to the screen (or to a surface). You call draw_primitive_begin or draw_primitive_begin_texture, then define the vertices with any of the draw_vertex_* functions and finally call draw_primitive_end to draw the primitive.
Draw Event
var _tex = sprite_get_texture(spr_image, 0);
draw_primitive_begin_texture(pr_trianglestrip, _tex);
draw_vertex_texture(0, 0, 0, 0);
draw_vertex_texture(100, 0, 1, 0);
draw_vertex_texture(0, 100, 0, 1);
draw_vertex_texture(100, 100, 1, 1);
draw_primitive_end();
Vertex buffers are the more advanced way to define reusable primitives. They are Buffers that store data about vertices specifically ("vertex data"). With vertex buffers you split up the definition of the primitive and its drawing.
You create a new, empty vertex buffer using vertex_create_buffer / vertex_create_buffer_ext or create one and fill it with the data in a buffer using vertex_create_buffer_from_buffer / vertex_create_buffer_from_buffer_ext:
Create Event
// Create an empty vertex buffer
vb = vertex_create_buffer();
// Create a vertex buffer filled with data from a buffer
var _buff = buffer_load("model.mod");
vb_model = vertex_create_buffer_from_buffer(_buff, format);
buffer_delete(_buff);
NOTE See Transferring Data Between Buffers for more info on how to pass data between the two buffer types.
You draw a vertex buffer by submitting it at any time in Draw events using vertex_submit, or just part of it usingvertex_submit_ext.
The following is a complete example that makes use of GameMaker's default passthrough vertex format:
Create Event
var _uv_data = sprite_get_uvs(spr_image, 0);
var _umin = _uv_data[0], _vmin = _uv_data[1], _umax = _uv_data[2], _vmax = _uv_data[3];
vb = vertex_create_buffer();
vertex_begin(vb, format);
vertex_position_3d(vb, 0, 0, 0); vertex_color(vb, c_white, 1); vertex_texcoord(vb, _umin, _vmin);
vertex_position_3d(vb, 100, 0, 0); vertex_color(vb, c_white, 1); vertex_texcoord(vb, _umax, _vmin);
vertex_position_3d(vb, 0, 100, 0); vertex_color(vb, c_white, 1); vertex_texcoord(vb, _umin, _vmax);
vertex_position_3d(vb, 100, 100, 0); vertex_color(vb, c_white, 1); vertex_texcoord(vb, _umax, _vmax);
vertex_end(vb);
Draw Event
var _tex = sprite_get_texture(spr_image, 0);
vertex_submit(vb, pr_trianglestrip, _tex);
Cleanup Event
vertex_delete_buffer(vb);
NOTE See the Guide To Primitives And Vertex Building for more info on how to work with vertex buffers.
In the code examples above, the UVs are provided differently for vertex buffers. This is because the UVs are interpreted differently by both sets of functions:
NOTE You can use the functions sprite_get_uvs, font_get_uvs and tileset_get_uvs to get a specific asset's UV range on the texture page.
GameMaker permits you to define your own vertex formats from which you can create your own custom primitives. This can greatly speed up shader operations or can be used to extend their capabilities and create surprising effects.
A vertex format lists the attributes that are stored for a vertex in order. You start defining one with vertex_format_begin, then add the attributes using the vertex_format_add_* functions and finally end it using vertex_format_end.
Once you have created your vertex format (see the section above) you can then use it to build the primitives that you want to draw using the following vertex buffer functions:
IMPORTANT The primitives that you build should follow the format that you have set using the Vertex Format functions, so if you have defined a vertex format with only positional data, there is no point building your primitive with colour data. You should note that the order in which you add properties to the primitive you are building is defined by the order in which you added these properties when creating the vertex format, so if you have defined the vector format with the order position, colour and texture coordinate, you must add these properties to the primitive being built in the same order otherwise you will get errors.
For an overview of how to build primitives using the vertex functions, see: