-
-
Notifications
You must be signed in to change notification settings - Fork 27
07 Drawing
So far you should be acquainted with variety of how LinaVG works in regards to configurations, styling and coordinate systems. This section will explain different shape drawing functions. Also, all these functions are well explained in detail in the source code.
Almost all drawing functions include two utility parameters outside of styling, which are rotateAngle
and drawOrder
. These parameters will be explained here, and then omitted in the function examples below to avoid repetition.
All the vertices of the drawn shape, including any outline and AA vertices, will be rotated by this angle in a final pass. The angle should be supplied in degrees, and internally is spanned between 0.0f-360.0f.
So you can supply any number, there are no limits.
defaultStyle.color = LinaVG::Utility::HexToVec4(0x06A77D);
defaultStyle.rounding = 0.5f;
// 45 degrees of angle
lvgDrawer.DrawRect(startPos, Vec2(startPos.x + 150, startPos.y + 150), defaultStyle, 45.0f, 1);
The last parameter for all the drawing calls is drawOrder
, which will help you achieve z-sorting. Higher draw orders are drawn on top. Draw order is explained in it's own respective section as it requires more details in regards to how it interacts with different draw buffers, e.g. shape buffer or an AA buffer.
Use DrawRect function to draw a rectangle between two coordinates, min
and max
, which correspond to top-left and bottom-right corners of the rectangle respectively.
LINAVG_API void DrawRect(const Vec2& min, const Vec2& max, StyleOptions& style, float rotateAngle = 0.0f, int drawOrder = 0);
Use DrawTriangle function to draw a triangle. The accepted coordinates correspond to top, bottom right and bottom left coordinates of the triangle respectively. You can of course play with these to your liking to draw triangles with 90 degree angles, or inversed triangles etc. however bear in mind that triangles with corners that have very small or very big angles tend not to play nice with outline and rounded vertices.
LINAVG_API void DrawTriangle(const Vec2& top, const Vec2& right, const Vec2& left, StyleOptions& style, float rotateAngle = 0.0f, int drawOrder = 0);
Here's an example of some triangles with varying angles are drawn as "mountains" in the final demo scene.
You can draw convex shapes with N amount of corners. Ngons are not affected by the rounding parameters. Increasing the N parameter gets the shape closer to a circle.
LINAVG_API void DrawNGon(const Vec2& center, float radius, int n, StyleOptions& style, float rotateAngle = 0.0f, int drawOrder = 0);
You can also use LinaVG to draw any convex shape you'd like. The DrawConvex function takes a pointer to an array of coordinates, and LinaVG will try to connect all points together to come up with a convex shape.
LINAVG_API void DrawConvex(Vec2* points, int size, StyleOptions& style, float rotateAngle = 0.0f, int drawOrder = 0);
The point array must have all points as unique coordinates, e.g. you don't have to manually supply the first coordinate as an end coordinate. The shape to be drawn must be convex so that the filling and outline algorithms work as expected. The resulting visual is undefined if the shape is concave.
std::vector<Vec2> points;
points.push_back(startPos);
points.push_back(Vec2(startPos.x + 150, startPos.y));
points.push_back(Vec2(startPos.x + 100, startPos.y + 150));
points.push_back(Vec2(startPos.x - 50, startPos.y + 150));
lvgDrawer.DrawConvex(&points[0], 4, defaultStyle, rotateAngle, 2);
points.clear();
Although that being said, you can still supply some concave points and get interesting results:
All circles and circle-like shapes such as semi-circles and arcs are drawn with a single function, DrawCircle.
LINAVG_API void DrawCircle(const Vec2& center, float radius, StyleOptions& style, int segments = 36, float rotateAngle = 0.0f, float startAngle = 0.0f, float endAngle = 360.0f, int drawOrder = 0);
Similar to NGons, DrawCircle function accept a center and a radius. In addition, you can send in a segments
parameter to define the smoothness of the circle. Default is 36, sending 360 will make it an almost perfect circle. But please keep in mind that this will have a higher performance impact, as it will increase the vertex count (albeit pretty small impact considering 3D applications can have millions of tris on modern hardware).
The startAngle
and endAngle
parameters define whether it's a full circle or semi, or an arc. They need to be supplied in degrees, and the assumption is that it's always processed in an clock-wise order. Passing 0.0f and 360.0f respectively will make it a full circle.
lvgDrawer.DrawCircle(Vec2(startPos.x + 75, startPos.y + 75), 75, defaultStyle, 36, rotateAngle, 0.0f, 245.0f, 1);
lvgDrawer.DrawCircle(Vec2(startPos.x + 75, startPos.y + 75), 75, defaultStyle, 36, rotateAngle, 300.0f, 330.0f, 2);
It's possible to supply a texture handle to the StylingOptions of any shape and draw it as a filled shape. However this won't work well if your texture has a transparent-background, because the default shapes will be trying to apply AA borders to the edge vertices of the shape. This will create an annoying border to your transparent images. Thus, there's an additional method to specifically draw textures, DrawImage.
LINAVG_API void DrawImage(BackendHandle textureHandle, const Vec2& pos, const Vec2& size, float rotateAngle = 0.0f, int drawOrder = 0, Vec2 uvTiling = Vec2(1, 1), Vec2 uvOffset = Vec2(0, 0), Vec2 uvTL = Vec2(0, 0), Vec2 uvBR = Vec2(1, 1));
BackendHandle is a simple unsigned int
, and as explained before, it's the texture handle that you've generated within your application by uploading the texture to GPU. There is also options for uvTiling
and uvOffset
. Additionally, you can define custom UV's to draw only part of your texture, uvTL
corresponds to the top-left UV of the quad that will be drawing your texture, and uvBR
corresponds to bottom-right corner UV.