• 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] Proper way to draw surface when drawing sprite with alpha ?

MCHLV

Member
Hello all

Short version:
I am drawing sprites to a surface with an alpha of 0.5 and then and then drawing the surface.. .And the sprites looks darker than what they shoud be....

Details

For a scrollable button list, I have an object that draw many buttons to a surface (to cut what is out of the area) and then draw the surface - Thank you to Yellow Afterlife for that !
I also have two buttons below the list that are just drawing themself directly without surface

My button have full alpha of 1 when selected and alpha of 0.5 when unselected.
They are drawn in draw_end event with draw_sprite_ext(sprite_index, image_index, x, y, image_xscale, image_yscale, 0, c_white, image_alpha);

I obviously have not understand how alpha works with surface because my unselected buttons don't look the same depending on how they are drawn
- the one that are drawn directly on screen appears with the proper alpha of 0.5
- the one drawn to surface and then surface-to app appear darker

I have tried various options for draw_clear_alpha... black, white, 0, 1... but I just don't understand at all.
Can someone tell me what I need to do for all buttons to look the same: instances that are drawn directly and instance that are drawn through the surface.... thank you very much !!

I display draw_get_alpha() and image_alpha to the console just before the draw_sprite_ext... to be sure and it 0.5 for both for all buttons
9858.03 - oGUI_Button_Confirm - 100505 | button 2 draw alpha | 0.50 | image_alpha | 0.50
9858.04 - oGUI_Button_Key - 100491 | button 1 draw alpha | 0.50 | image_alpha | 0.50


A bit of code will help:
Button_1 draw event
Code:
// Save alpha
var _prev_alpha = draw_get_alpha();
draw_set_alpha(image_alpha);

// Draw button
shw("button 2 draw alpha", draw_get_alpha(), "image_alpha", image_alpha); // debug function for the console
draw_sprite_ext(sprite_index, image_index, x, y, image_xscale, image_yscale, 0, c_white, image_alpha);

// Draw caption
draw_set_colour(text_color);
draw_set_font(text_font);
draw_set_halign(text_halign);
draw_set_valign(text_valign);
draw_text_transformed(x, y, text, image_xscale, 1, 0);

// Reset alpha
draw_set_alpha(_prev_alpha);
My list object draw event to draw all scrollable buttons
Code:
// Save alpha
var _prev_alpha = draw_get_alpha();

// Prepare scrollable surface
if ( !surface_exists(clip_surface) ) { clip_surface = surface_create(box_right - left - outline, box_bottom - top - outline); }
surface_set_target(clip_surface);
draw_clear_alpha(c_black, 0); // -----> ???

// Draw buttons and texts to scrollable surface
var _size = ds_list_size(scrollable_id_list);
for ( var _i = 0; _i < _size; _i++ )
{
    with (  scrollable_id_list[| _i].id  )
    {
        draw_set_alpha(image_alpha);
        if sprite_index != -1
         {
          shw("button 1 draw alpha", draw_get_alpha(), "image_alpha", image_alpha); // debug function for the console
          draw_sprite_ext(sprite_index, image_index, x - _left, y - _top, image_xscale, image_yscale, 0, c_white, image_alpha);
          }

        // Draw caption
        draw_set_colour(text_color);
        draw_set_font(text_font);
        draw_set_halign(text_halign);
        draw_set_valign(text_valign)
        draw_text_transformed(x - _left , y - _top, text, image_xscale, 1, 0);
    }
}

// Reset alpha
draw_set_alpha(_prev_alpha);
// Draw scrollable surface
surface_reset_target();
draw_surface(clip_surface, box_left + 0.5 * _outline, box_top + 0.5 * _outline);
 

MCHLV

Member
Thank you Nocture. I have but I need to investigate some more...
(I still have lot of difficulty with everything around blending, destination/source... but I can live with that :p)

Caught by the words ""the simplest approach..." I have used the following. And if my buttons are ok, the rest of my surface is full black
Code:
gpu_set_blendenable(false);
draw_surface(clip_surface, box_left + 0.5 * _outline, box_top + 0.5 * _outline);
gpu_set_blendenable(true);
I will also test the other approaches
 
Last edited:

MCHLV

Member
ok. As the above did not work and I read "FinalColourA = (SourceColourA * SourceColourA) + (DestPixelColourA * (1 – SourceColourA))"... I just draw my sprite with an alpha set to SQRT(alpha)
Don't throw stones at me but as the above was not working,... :p
So it works now.
Thanks you very much

Code:
var _prev_alpha = draw_get_alpha();
if ( !surface_exists(clip_surface) ) { clip_surface = surface_create(box_right - _left - _outline, box_bottom - _top - _outline); }
surface_set_target(clip_surface);
draw_clear_alpha(c_black, 0);

var _size = ds_list_size(scrollable_id_list);
for ( var _i = 0; _i < _size; _i++ )
{
    with (  scrollable_id_list[| _i].id  )
    {
        var _image_alpha = sqrt(image_alpha);
        draw_set_alpha(_image_alpha);
        if sprite_index != -1 { draw_sprite_ext(sprite_index, image_index, x - _left, y - _top, image_xscale, image_yscale, 0, c_white, _image_alpha); }
        ...
        draw_text_transformed(x - _left , y - _top, text, image_xscale, 1, 0);
    }
}

draw_set_alpha(_prev_alpha);

// Draw scrollable surface
surface_reset_target();

draw_surface(clip_surface, box_left + 0.5 * _outline, box_top + 0.5 * _outline);
 
Top