Posts
Search
Contact
Cookies
About
RSS

Drawing textured 2D polygons with rlgl (Raylib)

Added 23 Mar 2021, 4:15 a.m. edited 18 Jun 2023, 1:12 a.m.
that Doris gets everywhere!

UPDATE: I'm happy to say that this post is redundant ! I submitted a Pull Request to the Raylib repository which has been accepted, have a look at the example raylib/examples/textures/textures_poly.c, with a slightly different name, this functionality is now a part of Raylib.

As a bit of light relief from debugging some horrible memory issues, in a complex bit of code, I decided to take a bit of a break (I nearly lasted 24hrs without coding!) I ended up looking at the lower level side of Raylib's renderer namely RLGL. This is a neat idea as it basically isolates the higher levels of Raylib from different OpenGL versions. Given that for a modern GPU pushing a handful of triangles onto the screen is trivial, I plumped for the easy option and just reverted to pushing vertexes at the GPU for each poly every frame. There are more efficient methods of doing this, but its an optimisation that really in the end isn't needed, by and large.

While talking about polygons, because I'm using a triangle fan to render the poly there are a few rules you must follow. First off you must specify the point's of the polygon in an anticlockwise order. Additionally each point must be able to "see" the centre of the polygon, without crossing the outer edge of the polygon, this doesn't mean you can't do any concave features, you just have to do them with an eye towards where the centre point is

In the example I have provided a function to render a textured polygon (no, really!?) Lets have a look at the function prototype.

void DrawTexturedPoly(Texture t, float x, float y,
                        Vector2 *points, Vector2 *tPnts,
                        int numPoints, Color colour)

The parameters t, x & y should be obvious, the next parameter is an array of points for the polygon, remembering that they need to be in anticlockwise order, and that you don't need to specify the centre point (as its always 0,0). The next array you pass is the texture coordinates, followed by the number of points and the colour to tint the polygon with. Obviously both points and the texture points must have the same number of points. Don't forget that texture coordinates are in a range of 0-1 with values outside this range wrapping round (which is handy for a repeating pattern)

Now I'll be honest I did go to town a little bit with the example, but it is what I was using for testing (that's my excuse and I'm sticking with it!) So I won't go into much detail. Just a few points though, you don't need to be messing with the polygon points every frame, you can have a static shape, and equally they don't all need to be the same either. The DrawTexturedPoly doesn't provide any means to rotate or scale your polygon, but as you can see from the example, providing the function with scaled and or rotated points is trivial.

Some care has to be taken when using RLGL in conjunction with Raylib, specifically with maintaining the integrity of the render buffer, but that is somewhat trivial. Yet again when developing, GCC instrumentation flags and generally fairly strict compiler warnings (as errors!) have saved me a heap of stress and time (see the makefile). For example for a rather minimal time penalty, you get runtime checks on all sorts of things, including bounds checking on arrays, something that's all too easy to make a mistake with. Additionally a report of what's leaked at the end of the run is invaluable, it's not uncommon to get some system libraries leaking a fixed amount, but providing the size of the leak is the same every run, its absolutely safe to allow the OS to clean these up (and it is possible they could be false positives)

You can grab the code here

Enjoy!