Legacy GM Sprite from surface with alpha values

I have been scratching my head over this little thing. Can someone help me out with this?

What I want to do
Draw an image with alpha values on a surface, a background part for example.
Create a sprite from the surface with the correct background part's alpha values.
Use that sprite for specific on the fly needs.

In a picture, here's what I want to do
Sans titre - paint.net v4.0.13-20170329-175851.png

I tried to clear my draw surface with black at alpha 0, the image becomes darker. I tried with fuchsia and the image becomes combined with fuchsia.

My code looks like this:
Code:
var sfc = surface_create(my_width,my_height+1);
surface_set_target(sfc);
draw_clear_alpha(c_fuchsia,0);
draw_background_part_ext(my_back,bg_left,bg_top,my_width,my_height+1,x,x,1,1,c_white,1);
sprite_create_from_surface(sfc,x,y,my_width,my_height+1,true,false,0,0);
Is this at all possible in GameMaker Studio or am I dreaming? I also tried with different blending modes but I have not found anything that gives me the results I want BUT I have seen lots of effects:confused:...
 
A

anomalous

Guest
You are not wrong to scratch your head, it doesn't function the way you/most of us think.
Hopefully someone with accurate information can reply. I don't want to waste your time, I can only tell you what very little I remember.
It may have to do with premultiplication.

I think I eventually found a shader that premultiplied it for me, to achieve that effect in code without having to change the flow.
This may have some of that info, but you can search for premultiply anyway, that should help I hope.

https://forum.yoyogames.com/index.p...-two-surfaces-problem-help-appreciated.11716/
 
You are not wrong to scratch your head, it doesn't function the way you/most of us think.
Hopefully someone with accurate information can reply. I don't want to waste your time, I can only tell you what very little I remember.
It may have to do with premultiplication.

I think I eventually found a shader that premultiplied it for me, to achieve that effect in code without having to change the flow.
This may have some of that info, but you can search for premultiply anyway, that should help I hope.

https://forum.yoyogames.com/index.p...-two-surfaces-problem-help-appreciated.11716/
Yep! I've already went through these threads. It's not my first shot at it but now I really need it or else, I'll end up with pixelated sprites, not nice, not nice at all! But I'm glad to know that I'm not THAT dumb. I even tried to disable color and only keep alpha. I even tried to draw the whole thing in black on a white background and invert that which gives me an alpha background then draw over that using the background as an alpha mask but nothing to do, not yet at least. I then thought of taking a snapshot of a particular position on the screen and use it as a background... But then again, with paralax backgrounds, you get some issues AND when you want to convert a surface to sprite to use it as a particle, now you are getting into some real headachs there.
 

CMAllen

Member
Do you need to create create the assets on the fly, every draw event? Because if you don't need a highly optimized draw routine, you could draw it in two stages. The first stage is an additive alpha pass (set your blend mode to bm_add and draw as usual). Then you reset to bm_normal, lock the alpha channel, and draw everything again. What you get is the second pass keeps the first pass's additive alpha results and overwrites the additive RGB results with bm_normal RGB blending values. It takes more than twice as long, but it comes close to mimicking how bm_normal draws to the application surface. (apologies if you've tried this approach already. It was unclear how you've approached this)

The only other option involves shaders.
 

Micah_DS

Member
I think I have a solution for you. :) (edit: or perhaps not - see edit below)

I kind of feel like I must be misunderstanding because this is actually a very simple task IF you are needing to do what I think you are. I just did a quick test in GMS2, but it should work exactly the same in GMS1.

Your mistake appears to be your use of draw_clear_alpha. There is no need to use that, if I understand your needs correctly. When creating a surface, it is blank by default. And by "blank", I don't mean white or black - it's just nothing, with no color or alpha data. If you use the draw_clear_alpha function, you are then adding what is essentially a background color (kind of), thus messing up your default blank surface.

-

For my test, all I did was create a crappy star sprite. I drew it onto a surface, then I also drew onto the surface a blue colored rectangle with slight transparency, having it overlap the star. I saved that surface as a sprite, then I simply drew the sprite over a background (which was just the star sprite stretched, cuz hey, it's just a quickie test).

This is the result I got. The small star and rectangle are a sprite created from a surface and the big star is a background:
SurfaceToSprite_AlphaColorTest.png

Here's the code I used:
#macro surfaceWidth 512 //
#macro surfaceHeight 256 //

draw_set_color(c_white);

//create image from surface
var _surface;
_surface = surface_create(surfaceWidth, surfaceHeight);
surface_set_target(_surface);
draw_sprite(s_star, 0, 0, 0);
draw_set_color(c_navy);
draw_set_alpha(0.8);
draw_rectangle(16, 16, surfaceWidth/2, surfaceHeight/2, false);
draw_set_color(c_white);
draw_set_alpha(1);
spriteFromSurface = sprite_create_from_surface(_surface, 0, 0, surfaceWidth-1, surfaceHeight-1, false, false, 0, 0);
surface_free(_surface);

draw_sprite(spriteFromSurface, 0, 0, 0);

I hope this is what you were trying to do?

EDIT:
Hmm, actually, I did just notice that the blend with the background star isn't the same as the star in the sprite. Perhaps this is what you were trying to address? Welp, I don't have any more time atm to mess with it, but I'd definitely look into blend modes then. I'd expect you could find a solution with blend modes to get the desired results.
 
Last edited:
Top