• 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!

[Solved] Clip a shape out of another one

Sam04

Member
Hello everyone. I am trying to cut a hole inside a rectangle not using shaders but is seems I am unable to achieve it.

First, as a guide, this is the effect I want to achieve:
Made in paint, and just imagine the white part is completely transparent.

I started experimenting a bit and this is the last thing I've tried:

Code:
/// @description Test

if (keyboard_check_pressed(vk_escape)) {game_end();}

//draw_clear_alpha(c_black, 0);

draw_set_colour(c_white);
draw_set_alpha(1);

draw_rectangle(0,0, room_width/2, room_height, false);

gpu_set_blendmode_ext(bm_zero, bm_zero);
//gpu_set_blendmode_ext(bm_inv_src_alpha, bm_inv_src_alpha);
//gpu_set_colorwriteenable(0,0,0,1);//This one does not make any difference at all

draw_set_colour(c_black);
draw_set_alpha(0);
draw_circle(room_width/2, room_height/4, 48, false);

draw_set_alpha(0.5);
draw_circle(room_width/2, room_height/2, 48, false);

draw_set_alpha(1);
draw_circle(room_width/2, room_height*0.75, 48, false);
//I drew 3 different circles to see if trying with different alphas would make a difference
//Spoiler: It doesn't

//gpu_set_colorwriteenable(1,1,1,1);

gpu_set_blendmode(bm_normal);
Keep in mind that I'm trying this on a completely new project and I only have one object and the code I shared is the entirety of the code written in all of the project. Since I am using a new project just to test this I didn't see the need to use surfaces.

First I set the colour to white and the alpha to 1, then I draw my rectangle and all the pixels it covers should be (1,1,1,1). Then I set the alpha to 0 and the color to black and draw the circle I'm trying to cut, everything drawin in the circle should be (0,0,0,0).

Before drawing the circle I change the blendmode to bm_zero (which is a factor of (0,0,0,0)) in both the destination and the source. It shouldn't matter neither the destination pixel nor the source pixel because the factor I'm using converts anything to 0, and two 0 added together also would result in 0. So the ending pixel should be a completely transparent one. But it draws all of the three test circles as completely solid.

The commented "gpu_set_blendmode_ext(bm_inv_src_alpha, bm_inv_src_alpha);" is there as something I tried reading this post, but didn't work.

I also tried reading the mask article by YellowAfterLife but it seems it doesn't work in GMS2. I tried to open it but it didn't show anything it was suposed to show.


I also found this other thread with a working example, but unfortunately it works by using shaders and I am mostly interested in knowing how to make this using the intial method rather than solving the problem at all (That's because I'm mostly doing this to learn, and suddenly changing to shaders would make the learning I have so far useless).

Any help would be appreaciated. Thanks in advance.
 
C

CedSharp

Guest
If what you want is to "erase" something, making it transparent, then you'll have to work with surfaces.
First create a surface and draw the rectangle on it.
Then set the blenmode to bm_zero, bm_zero.
- src color = bm_zero, so draw nothing,
- dest color = bm_zero, so draw nothing.



Here is an example.

EDIT:

Note that in GameMaker Studio 2, the script is now called "gpu_set_blendmode_ext()"
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
I mentioned to @YellowAfterlife a while ago about the example not working in GMS2 but he must not have got round to fixing it yet.

If you use sprites instead of draw_circle etc then the example will work as expected.
Yeah, you need separate shaders for clipping sprites/primitives because primitives in GMS2 use a vertex format without texture coordinates
 

Sam04

Member
If what you want is to "erase" something, making it transparent, then you'll have to work with surfaces.
First create a surface and draw the rectangle on it.
Then set the blenmode to bm_zero, bm_zero.
- src color = bm_zero, so draw nothing,
- dest color = bm_zero, so draw nothing.



Here is an example.

EDIT:

Note that in GameMaker Studio 2, the script is now called "gpu_set_blendmode_ext()"
Thanks everyone! Seems like my code was correct and the only thing missing was using a surface as @CedSharp showed me in his example.

I thought that because it was an empty new project I wouldn't need to use surfaces as everything could be done on the application surface... seems I was wrong hehe.

Yeah, you need separate shaders for clipping sprites/primitives because primitives in GMS2 use a vertex format without texture coordinates
By the way, @YellowAfterlife it seems that my problem was resolved without using shaders but, talking about performance, would you recommend doing this the way I did it or would it be better if I did it with shaders?
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
By the way, @YellowAfterlife it seems that my problem was resolved without using shaders but, talking about performance, would you recommend doing this the way I did it or would it be better if I did it with shaders?
Shaders allow to avoid some oddities that occur with surfaces (try drawing semi-transparent sprites onto a surface to see what I mean) and are faster if you want to clip a lot of things
 
Top