Legacy GM Draw Sprites and Then Set Alpha? [SOLVED]

FlutterBug

Member
I have an object composed of two sprites (one drawn normally and one drawn with a shader applied to give it a wavy effect), but sometimes a seam would appear between the two of them, so to correct this I extended the second sprite by one pixel to cover it up. This worked, except for also the sprites are being drawn with a slight transparency, but the transparency adds up and so actually makes the seam even more apparent by having a line that's fully opaque. I am wondering if there is some way to draw both sprites, and then apply the transparency? I tried using a surface, but just nothing showed up that way, and I also couldn't find a way to set the transparency of a surface. What should I do to accomplish this?
 

FlutterBug

Member
Alright, solution time! The solution I ended up with is, as follows:
Code:
if !surface_exists(self_surface) {
    self_surface = surface_create(16,16);
}
surface_set_target(self_surface);
draw_clear_alpha( c_white, 0);
draw_sprite_ext(sprite_index,image_index,8,8,image_xscale,1,image_angle,image_blend,image_alpha);
shader_set(shdr_wind);
shader_set_uniform_f(uTime,current_time/1000);
draw_sprite_ext(sprite2,0,8,8,image_xscale,-1,image_angle,image_blend,image_alpha);
shader_reset();
surface_reset_target();

draw_set_alpha(alpha);
draw_surface(self_surface,x,y);
draw_set_alpha(1);
surface_free(self_surface);
At the start of every frame, the surface is created, which is 16x16 pixels, the size of the two combined sprites.

Next, we draw to that surface. First we use draw_clear_alpha to make thoroughly sure that the surface is clear and ready to be drawn to. Then we draw the two sprites, one with the shader to make it wavy applied (if you'd like to see that shader, it is found here). Then, we stop drawing to the surface.

Next, we draw the surface we just drew to, at the proper location (which is the x and y coordinates of the object), and with the alpha applied (which is denoted by a variable called 'alpha' which is controlled elsewhere in the code).

At the very end, the surface is deleted, to be created again at the start of the next frame. Ta-da! You have two combined sprites with the same alpha!
 

CloseRange

Member
my suggestion is don't delete the surface at the end of the draw event. You're already using draw_clear_alpha to clear the surface, so forcing yourself to delete and recreate the surface every frame is redundant.
Take out that line and put it in the game_end / delete event would be more efficient and still work the same.
It's just a small optimization and I'm not even sure how much it would help, just that you wouldn't have to waste the time creating a new surface every frame.
 

FlutterBug

Member
my suggestion is don't delete the surface at the end of the draw event. You're already using draw_clear_alpha to clear the surface, so forcing yourself to delete and recreate the surface every frame is redundant.
Take out that line and put it in the game_end / delete event would be more efficient and still work the same.
It's just a small optimization and I'm not even sure how much it would help, just that you wouldn't have to waste the time creating a new surface every frame.
That is what I did initially, but it didn't work, I needed to both delete and clear it in order for it to actually be cleared.
 
Top