• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

How to fill a draw_primitive_begin (pr_linestrip) with a color

luxo-JR

Member
Just a simple question. How to fill a shape with a color to draw with: draw_primitive_begin (pr_linestrip). The example I give draws a square. Thank you. Jean-Francois

GML:
draw_set_colour(c_white);
draw_primitive_begin(pr_linestrip);
draw_vertex(100, 100);
draw_vertex(200, 100);
draw_vertex(200, 200);
draw_vertex(100, 200);
draw_vertex(100, 100);
draw_primitive_end();
 

Joe Ellis

Member
You need to draw another primitive (pr_trianglelist) with 2 triangles underneath it with the same coordinates.

It can be a bit confusing making 2 triangles from 4 coordinates though, I sometimes draw it out like this:
 
Last edited:

Simon Gust

Member
You can use a trianglelist and make 2 triangles. You need 6 points.
Code:
x1, y1
x2, y1
x2, y2
x2, y2
x1, y2
x1, y1
or trianglestrip with 5 points (same as your linestrip).
Code:
x1, y1
x2, y1
x2, y2
x1, y2
x1, y1
 

Joe Ellis

Member
@Simon Gust 's suggestion of using x1, y1, x2, y2 is a really good method of dealing with rectangular coordinates. If you set x1, y1, x2, y2 to the coordinates it's a lot easier to read in the code and also visualize. You get used to dealing with the same 4 variable names every time than dealing with 8 unique numbers.
However if the quad is irregular you need to make 8 variables\4 vertices: x1, y1, x2, y2, x3, y3, x4, y4.
But yeah it's a lot easier to visualize or think about cus your brain gets used to where those vertices will be. Like for me:
v1 = top left, v2 = top right, v3 = bottom left, v4 = bottom right.
So then it's pretty easy to type out 2 triangles for those, whereas having to remember individual coordinates is like doing long-division step by step with a calculator (pointless)
 

luxo-JR

Member
Hello, thank you for your answers. I think I made a mistake in my question. I want to fill a polygon with a color like the attached image. In my program, I will have polygons with many segments.
arbre-symbole.png
 

GMWolf

aka fel666
You have to split that shape into triangles, and use a triangle list to fill it.
Sorry that's one of the many things you have to do yourself or find an asset that does it.
Luckily for you there is lots of examples and explanation online on how to split a polygon into triangles.
 

luxo-JR

Member
Thank you for your reply. I had thought about it but I wanted some sort of confirmation ... I discovered the 'draw_surface' function, you know something about it. I am a French user and the documentation is not always easy. ;);)
 

luxo-JR

Member
I am working on a patsage display 'engine'. It's a bit pompous, but I'm doing my best ...
The goal is to display (as shown in the image) the levels one after the other, first the last one for example the 'layer # 5' as in the image up to the 'layer # 1'.
Of course, there are scale coefficients depending on the depth. For now, I intend to display the layers in vector, but everything must be triangularized and some decorations are not suitable, to see ... There is also the solution via the bitmap with draw_sprite ...
To be honest, I am inspired by a game released in 1984 on ZX Spectrum, The Lords of Midnight. I got in touch with a programmer who made a PC adaptation under another name.
My goal is not to make a new version of this game, but to be inspired by this landscaping technique for my own project. A thought for Mike Singleton, its original creator.

landscaping-symbolique.jpg
 
Last edited:
As an alternative to splitting the shape into a set of triangles, you could draw the polygon to a surface as a trianglefan using a blendmode that "erases" the pixels that are drawn an even number of times, and then draw this surface to the screen. I wouldn't recommend this approach if you're going to draw a lot of different polygons, though, as the repeated setting of the gpu state, surface memory usage, looping through points and so on has a much, much higher impact on performance than if you i.e. pre-store the triangularized polygon in a vertex buffer. But if you do the rendering to surface only once for initialization, or a limitied number of times per frame, and reuse the content of the surface(s), it shouldn't be too bad. I still recommend following the previously offered suggestions, though, as this method is more of a convenient trick than it is suitable as the basis for a real-time rendering "engine".

Here's an example I just made using a Path resource for points:
GML:
var p = Path1;
var n = path_get_number(p);
var x1, y1;

surface_set_target(surf); // <-- Make sure you've already created this
    // Clear the surface
    draw_clear_alpha(c_black, 0);
   
    // Set a blendmode that inverts the alpha value of destination pixels
    gpu_set_blendmode_ext_sepalpha(bm_one,bm_zero, bm_inv_dest_alpha, bm_zero)
   
    // Draw the polygon onto your surface, fanning out from the first point
    draw_primitive_begin(pr_trianglefan);
    for(var i = 0; i <= n; i++) {
        x1 = path_get_point_x(p, i mod n);
        y1 = path_get_point_y(p, i mod n);
        draw_vertex_color(x1,y1, c_lime, 1);
    }
    draw_primitive_end();
   
    // Reset blendmode and drawing target
    gpu_set_blendmode(bm_normal)
surface_reset_target();

// Draw the surface containing the polygon
draw_surface(surf, 0,0);
 

luxo-JR

Member
Yes it is a resource-intensive solution, especially since I will have on average about forty objects to draw, first the most distant then the following ones by getting closer to the observer. I also realized that for some of these objects I would need to trace the outline of these objects to clearly distinguish them from the other objects behind. The more I think about it, the more I realize that polygon drawing might not be the best solution, as I have relatively detailed objects and triangularizing all of this is not easy. I think the best solution is to 'draw polygons on sprites' and use the management of sprites (draw_sprite, draw_sprite_ext, etc.) and layers.
 

luxo-JR

Member
Hello, To follow up on my last post, things are moving forward. I have done some tests using draw_sprite and draw_sprite_ext, it works fine. It is necessary to set up a conversion table between the map and the 'projection' of the sprites on the screen, to maintain depth of field. We forget the vector drawing, but I do not disarm ...
 
Top