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

GameMaker [SOLVED] Drawing to surface producing different results than equivalent draw step code

R

rnisson

Guest
Hello all,

I'm somewhat new to surfaces and am trying to draw a menu (normally generated manually every frame in the draw step from components like draw text, lines etc) to a surface once, save it as a sprite, and then just draw the surface to save processing time.

It works... mostly. I'm noticing the alpha of certain semi-transparent parts is off by a factor of about two, even with the exact same draw code, and certain things aren't the same brightness or thickness. Also, I notice different results depending on if I do
draw_clear_alpha(c_black, 0);
or
draw_clear_alpha(c_white, 0);
which sort of makes sense as it will affect blending. Again, I just want to produce the exact same result as drawing normally in the draw step, but save it as a sprite so I don't have to do it every frame...

I know this probably has something to do with blend modes, but I am confused why this even matters because I am starting from a totally blank cleared surface. Any help would be greatly appreciated!
 
The alpha problem with surfaces can be solved in a number of ways.

If your surface is going to be totally opaque, what you can do is clear it with a solid color or background image, and then lock the alpha channel with draw_set_colour_write_enable().

However, if you want parts of your surface to be semi-transparent, then you will probably need to use premultiplied-alpha. First, set blending mode to: draw_set_blend_mode_ext(bm_one, bm_inv_src_alpha);

Then either click premultiply alpha in the sprite/background editor (modifies sprites/backgrounds and cannot be reversed), or use a premultiply alpha shader (which does not modify any resources):

a premultiply fragment shader:
Code:
    varying vec2 v_vTexcoord;
    varying vec4 v_vColour;
    void main() {
        vec4 Colour = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord );
        Colour.rgb *= Colour.a;
        gl_FragColor = Colour;
    }
 
Last edited:
R

rnisson

Guest
The alpha problem with surfaces can be solved in a number of ways.

If your surface is going to be totally opaque, what you can do is clear it with a solid color or background image, and then lock the alpha channel with draw_set_colour_write_enable().

However, if you want parts of your surface to be semi-transparent, then you will probably need to use premultiplied-alpha. First, set blending mode to: draw_set_blend_mode_ext(bm_one, bm_inv_src_alpha);

Then either click premultiply alpha in the sprite/background editor (modifies sprites/backgrounds and cannot be reversed), or use a premultiply alpha shader (which does not modify any resources):

a premultiply fragment shader:
Code:
    varying vec2 v_vTexcoord;
    varying vec4 v_vColour;
    void main() {
        vec4 Colour = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord );
        Colour.rgb *= Colour.a;
        gl_FragColor = Colour;
    }
Excellent, I managed to get it to work with your suggestion, thank you very much! :D
 
Top