1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
//! A `Mesh` is a low-level graphics concept in Quicksilver consisting of a series of polygon //! vertices and a list of triangles. //! //! This concept can be used to draw any shape: to make a //! rectangle, put the four vertices in the vertex list, and then create two triangles that //! together make up the rectangle. //! //! Most user code need never encounter a mesh, but `Mesh` is extremely powerful. In fact, there is //! no special sauce available to Quicksilver's implementation of `Drawable` for `Rectangle` that a //! regular user of the library cannot access with a Mesh. //! //! There are two ways to use `Mesh`: instantiate your own with `Mesh::new` or use `Window::mesh` to //! access the internal mesh of a window. To concatenate two meshes, use the `Mesh::extend` function. //! //! To create a mesh that contains a triangle with a red vertex, a blue vertex, and a green vertex, //! you could write: //! //! ```no_run //! use quicksilver::graphics::{Background::Col, Color, GpuTriangle, Mesh, Vertex}; //! let vertices = vec![ //! Vertex::new((400, 200), None, Col(Color::RED)), //! Vertex::new((200, 400), None, Col(Color::BLUE)), //! Vertex::new((600, 400), None, Col(Color::GREEN)) //! ]; //! let triangles = vec![ GpuTriangle::new(0, [0, 1, 2], 0.0, Col(Color::WHITE)) ]; //! let mesh = Mesh { vertices, triangles }; //! ``` //! //! To draw it you can then do: //! //! ```no_run //! # use quicksilver::{graphics::{Background::Col, Color, GpuTriangle, Mesh, Vertex}, lifecycle::Window }; //! # fn func(window: &mut Window) { //! # let vertices = vec![ //! # Vertex::new((400, 200), None, Col(Color::RED)), //! # Vertex::new((200, 400), None, Col(Color::BLUE)), //! # Vertex::new((600, 400), None, Col(Color::GREEN)) //! # ]; //! # let triangles = vec![ GpuTriangle::new(0, [0, 1, 2], 0.0, Col(Color::WHITE)) ]; //! # let mesh = Mesh { vertices, triangles }; //! window.mesh().extend(&mesh); //! # } //! ``` //! //! You have to do this every frame, because the window's mesh is cleared after it's drawn. //! //! Drawing to a Mesh is important to defining your own Drawable objects. Drawable requires a //! single function definition, `draw`, with the signature //! //! ```no_run //! extern crate quicksilver; //! # use quicksilver::{geom::{Scalar, Transform}, graphics::{Background, Mesh}}; //! # struct Test; impl Test { //! fn draw<'a>(&self, mesh: &mut Mesh, background: Background<'a>, transform: Transform, z: impl Scalar) //! # {}} //! ``` //! //! We could create a `Diamond` struct that implements `Drawable` like so: //! //! ```no_run //! use quicksilver::{ //! geom::{Rectangle, Shape, Scalar, Transform, Vector}, //! graphics::{Background, Drawable, Mesh} //! }; //! //! struct Diamond { //! center: Vector, //! radius: f32 //! } //! //! impl Drawable for Diamond { //! fn draw<'a>(&self, mesh: &mut Mesh, background: Background<'a>, transform: Transform, z: impl Scalar) { //! let square = Rectangle::new_sized((self.radius, self.radius)).with_center(self.center); //! let rotation = Transform::rotate(45); //! square.draw(mesh, background, transform * rotation, z); //! } //! } //! ```