Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Sprite Masking in SFML2  (Read 33016 times)

0 Members and 1 Guest are viewing this topic.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Sprite Masking in SFML2
« Reply #15 on: April 12, 2012, 02:58:55 pm »
Quote
Okay, this version prevents you from using a texture to cut out areas. It will remove the complete bounding box of the sprite, no matter what the texture contains (I guess due to the BlendNone thing).
Yep. Could probably also be solved with the right blending mode.

Quote
I'd like to try out the pixel shader one, but I have absolutely no clue how to write shaders.
Here is a shader that sets alpha = 0 for pixels equal to a predefined colorkey:

uniform sampler2D texture;
uniform vec4 colorkey;

void main()
{
    vec4 pixel = texture2D(texture, gl_TexCoord[0].xy);
    if (pixel == colorkey)
        pixel.a = 0;
    gl_FragColor = pixel;
}

sf::Shader shader;
shader.loadFromFile("colorkey.frag", sf::Shader::Fragment);
shader.setParameter("texture", sf::Shader::CurrentTexture);
shader.setParameter("colorkey", sf::Color(/* whatever (magenta) */));

...

window.draw(sf::Sprite(target.getTexture()), &shader);
 
Laurent Gomila - SFML developer

Dienes

  • Newbie
  • *
  • Posts: 7
    • View Profile
    • Email
Re: Sprite Masking in SFML2
« Reply #16 on: April 12, 2012, 03:18:20 pm »
Just tested it and it works perfectly, thank you!

Much better and faster solution!

ChonDee

  • Jr. Member
  • **
  • Posts: 62
    • View Profile
Re: Sprite Masking in SFML2
« Reply #17 on: April 13, 2012, 07:53:39 am »
Wow, thanks very much, that's exactly what I wanted, I am definitely going to make good use of this!

Also thanks for the answers to my questions from both of you.  :)

Vovosunt

  • Jr. Member
  • **
  • Posts: 53
    • View Profile
Re: Sprite Masking in SFML2
« Reply #18 on: April 15, 2012, 03:07:56 pm »
There's a simpler and more efficient solution to this problem. You can create holes in the render-texture by rendering stuff with alpha = 0 and blend mode set to BlendNone. This way there's no need for a custom pixel shader, transparency is directly and correctly written to the target.

#include <SFML/Graphics.hpp>

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "SFML holes");
    window.setVerticalSyncEnabled(true);

    sf::RenderTexture target;
    if (!target.create(window.getSize().x, window.getSize().y))
        return -1;

    target.clear(sf::Color::White);
    target.display();

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }

        if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
        {
            sf::Vertex point(sf::Vector2f(sf::Mouse::getPosition(window)), sf::Color::Transparent);
            target.draw(&point, 1, sf::Points, sf::BlendNone);
            target.display();
        }

        window.clear();
        window.draw(sf::Sprite(target.getTexture()));
        window.display();
    }

    return 0;
}

What the... I asked about this a week or so ago and we both agreed that it didn't work O_O
BTW just wondering, why are the completely transparent sprites won't do the same thing?
VertexArrays set to Quads will thought, so it doesn't really matter, but nonetheless.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Sprite Masking in SFML2
« Reply #19 on: April 15, 2012, 03:13:52 pm »
Quote
What the... I asked about this a week or so ago and we both agreed that it didn't work O_O
No, remember what I said:
Quote
I need to clear a part of a renderTexture, but using transparent sprites/shapes won't work. They have got to have at least 1/255 opacity even with BlendMode set to BlendNone.
I changed this a few days ago, it should work with the latest revision of SFML 2.

Quote
BTW just wondering, why are the completely transparent sprites won't do the same thing?
Completely transparent sprites will work.
Laurent Gomila - SFML developer

Vovosunt

  • Jr. Member
  • **
  • Posts: 53
    • View Profile
Re: Sprite Masking in SFML2
« Reply #20 on: April 15, 2012, 04:00:54 pm »
Oh. Indeed they do :)

Vovosunt

  • Jr. Member
  • **
  • Posts: 53
    • View Profile
Re: Sprite Masking in SFML2
« Reply #21 on: April 15, 2012, 04:48:23 pm »
I think the BlendMultiply BlendFunc is incorrect.
Why glBlendFunc(GL_DST_COLOR, GL_ZERO)?
It doesn't work with transparency.

Vovosunt

  • Jr. Member
  • **
  • Posts: 53
    • View Profile
Re: Sprite Masking in SFML2
« Reply #22 on: April 15, 2012, 05:33:24 pm »
But I guess there's no real way to do it with Alpha.
Thought I think (GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA) is a bit better.
Or maybe you could use the glBlendFuncSeparateEXT and add the alphas together or keeping only the destination alpha?
Seems logical. ???

Blendmodes are sometimes so hard to get you mind around  :-\
Good for reference: http://www.andersriggelsen.dk/glblendfunc.php

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Sprite Masking in SFML2
« Reply #23 on: April 15, 2012, 06:18:21 pm »
Quote
Or maybe you could use the glBlendFuncSeparateEXT and add the alphas together or keeping only the destination alpha?
Seems logical.
Hmm yes, sounds like a good idea. However I'd use glBlendFuncSeparateEXT to keep the source alpha.
Laurent Gomila - SFML developer

Vovosunt

  • Jr. Member
  • **
  • Posts: 53
    • View Profile
Re: Sprite Masking in SFML2
« Reply #24 on: April 21, 2012, 05:27:26 pm »
So, continuing on, if I'm gonna add some blendMode stuff to sfml, do I just insert it into the glCheck? :P
Does stuff like glBlendEquation also work?
And what is glCheck anyway? (couldn't really find anything on the net, but I guess it's something that checks gl states and sets them if they're not set...)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Sprite Masking in SFML2
« Reply #25 on: April 21, 2012, 06:09:26 pm »
Quote
Does stuff like glBlendEquation also work?
Yes.

Quote
And what is glCheck anyway? (couldn't really find anything on the net, but I guess it's something that checks gl states and sets them if they're not set...)
It prints a message if the GL function fails. Look at src/Graphics/GLCheck.cpp (it's a SFML function).
Laurent Gomila - SFML developer

Vovosunt

  • Jr. Member
  • **
  • Posts: 53
    • View Profile
Re: Sprite Masking in SFML2
« Reply #26 on: April 21, 2012, 06:29:21 pm »
It prints a message if the GL function fails. Look at src/Graphics/GLCheck.cpp (it's a SFML function).

I already did, but didn't quite get it it seems. So it's just an error catcher :)

Thanks for the quick answer, Laurent :D

Vovosunt

  • Jr. Member
  • **
  • Posts: 53
    • View Profile
Re: Sprite Masking in SFML2
« Reply #27 on: April 21, 2012, 08:03:14 pm »
Ok everything works, except that GL_MIN equation sticks around, and everything renders with it...
Were should I reset the original GL_FUNC_ADD?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Sprite Masking in SFML2
« Reply #28 on: April 21, 2012, 08:07:34 pm »
Quote
Were should I reset the original GL_FUNC_ADD?
Everytime a blending mode is set that is not the MIN one (in applyBlendMode).
Laurent Gomila - SFML developer

vidjogamer

  • Jr. Member
  • **
  • Posts: 67
    • View Profile
Re: Sprite Masking in SFML2
« Reply #29 on: May 05, 2012, 01:11:12 am »
Why doesnt this work:

Code: [Select]
sf::CircleShape circle(5,32);
circle.setPosition( sf::Mouse::getPosition(window).x, sf::Mouse::getPosition(window).y );
circle.setFillColor(sf::Color::Transparent);
target.draw(circle,sf::BlendNone);
target.display();


if this works:

Code: [Select]
sf::Vertex point(sf::Vector2f(sf::Mouse::getPosition(window)), sf::Color::Transparent);
target.draw(&point, 1, sf::Points, sf::BlendNone);
target.display();