Jump to content


Photo

Surface Alpha Problems Explained


  • Please log in to reply
25 replies to this topic

#21 Maarten Baert

Maarten Baert

    GMC Member

  • GMC Member
  • 715 posts
  • Version:GM8.1

Posted 23 January 2011 - 02:22 PM

- is there a way to "un-premultiplied" (de-premultiplied?) the png saved by surface_save(), with GM ? Because the png saved is premultiplied, and I would like to use it on a non-premul layer (surface).

Unfortunately there's no blend mode for division, so you will have to do this manually (pixel by pixel). You might want to create a DLL that can do this for you if the image is very large.

- When I use draw_set_blend_mode_ext(bm_one, bm_inv_src_alpha), the alpha of the surface isn't working as a normal alpha, which is logical because the surface isn't drawn in a "normal" blend mode. How can I have an alpha working correctly ?

If the surface was created correctly, drawing it with draw_set_blend_mode_ext(bm_one, bm_inv_src_alpha) should work correctly. However, if you're using draw_surface_ext (or similar) and you're using the alpha argument, you have to premultiply the color argument too. Otherwise it won't work properly.
  • 0

#22 blendman

blendman

    GMC Member

  • New Member
  • 42 posts

Posted 27 January 2011 - 05:05 PM

Hi Maarten, Thank you very much for your answer ;) (dank u !).


- is there a way to "un-premultiplied" (de-premultiplied?) the png saved by surface_save(), with GM ? Because the png saved is premultiplied, and I would like to use it on a non-premul layer (surface).

Unfortunately there's no blend mode for division, so you will have to do this manually (pixel by pixel). You might want to create a DLL that can do this for you if the image is very large.

I have tried with draw_getpixel(), but it's too long with a layer > 64*64.
So, for the moment, I use silent.dll +irfanviewer to convert the layer saved (in png), and eventually reload this png in my 2D application (made with GM), and it works fine.

If I can later, I will try to wrote a dll to do this operation.


- When I use draw_set_blend_mode_ext(bm_one, bm_inv_src_alpha), the alpha of the surface isn't working as a normal alpha, which is logical because the surface isn't drawn in a "normal" blend mode. How can I have an alpha working correctly ?

If the surface was created correctly, drawing it with draw_set_blend_mode_ext(bm_one, bm_inv_src_alpha) should work correctly. However, if you're using draw_surface_ext (or similar) and you're using the alpha argument, you have to premultiply the color argument too. Otherwise it won't work properly.

Oh, thank you , it works better if I premultiply the color of the layer, with the alpha of the layer !

Thank you again.
  • 0

#23 golden_cow2

golden_cow2

    GMC Member

  • New Member
  • 178 posts

Posted 16 April 2011 - 06:03 AM

I'm not sure if this is the same thing, but I'm using surfaces and alpha and there is a problem so it can't hurt to ask.

In order to cut back on instances, I combine the sprites of all the tile objects I placed in the room editor into one large sprite, using a surface, which I then use for collision checking. But when I make the sprite, it looks different than the tiles did pre-surface. If I use the replace_premultiplied_sprite() script, it makes the whole screen a sprite, and mutes the colors even more (though I must be using it wrong, I don't understand anything in this thread).

Here's the code I'm using
//make_sprite(object)
//combines the sprites of all instances of "object" and destroys all
//instances of "object"

var obj, surf, sprite;
obj = argument0;
surf = surface_create(room_width,room_height);

surface_set_target(surf);
draw_clear_alpha(c_white,0);
with(obj)
    {
    draw_sprite(sprite_index,image_index,x,y);
    instance_destroy();    
    }
surface_reset_target();

sprite = sprite_create_from_surface(surf,0,0,room_width,room_height,false,false,0,0);

surface_free(surf);

replace_premultiplied_sprite(sprite);

return sprite;

//I just use sprite_index = make_sprite(obj_...)

And here is the gmk.
  • 0

#24 mireazma

mireazma

    GMC Member

  • GMC Member
  • 282 posts

Posted 06 January 2012 - 12:28 PM

You can pre-premultiply by just processing the sprites after loading them.

Should I understand that the sprites need only be processed once? After that no extra code would be necessary? I'd be happy to take away as much as possible from the CPU loading at real time.
GearGOD's gmk has the every-step approach.
I've tried Maarten's scripts but I can see no effect. I called the scripts once, in the creation event of an object.

Edited by mireazma, 06 January 2012 - 12:29 PM.

  • 0

#25 Nocturne

Nocturne

    Nocturne Games

  • Administrators
  • 16823 posts
  • Version:GM:Studio

Posted 06 January 2012 - 06:11 PM

You can pre-premultiply by just processing the sprites after loading them.

Should I understand that the sprites need only be processed once? After that no extra code would be necessary? I'd be happy to take away as much as possible from the CPU loading at real time.
GearGOD's gmk has the every-step approach.
I've tried Maarten's scripts but I can see no effect. I called the scripts once, in the creation event of an object.


I use them in the game start event of the first object in my game (usually my logo) and it looks like this :


Spoiler



The scripts are "scr_create_premultiplied_sprite" and "scr_replace_premultiplied_sprite" (the names may be slightly different!). When drawing to the surface you use the extended blend mode

draw_set_blend_mode_ext(bm_one, bm_inv_src_alpha)

And that's it!
  • 0

#26 mireazma

mireazma

    GMC Member

  • GMC Member
  • 282 posts

Posted 08 January 2012 - 11:35 AM

Thanks. I was missing the extended blend mode thing.
  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users