SFML community forums

Help => Graphics => Topic started by: Maksat on May 13, 2020, 06:03:11 pm

Title: Drawing Transparent Textures on Transparent RenderTexture
Post by: Maksat on May 13, 2020, 06:03:11 pm
Hello! I'm trying to get transparent texture like this (made with Photoshop)
(https://i.ibb.co/mvc4Tg5/long-note-photoshop.png) (https://imgbb.com/)
by combining it from separate textures on transparent RenderTexture
(https://i.ibb.co/wKWnzLR/Texture.png) (https://imgbb.com/)
If draw them in default blend mode and RenderTexture cleared as transparent, they loose glowing effects like in first image below. The result I want to ahcieve is like on right image, but it was cleared as black and it's not transparent
(https://i.ibb.co/m6LypGR/SFMLTest-2020-05-13-21-47-33-825.jpg) (https://imgbb.com/) (https://i.ibb.co/Lhfn6nZ/SFMLTest-2020-05-13-21-46-38-171.jpg) (https://imgbb.com/)

I tried all blending modes and tried unsuccessfully to write custom ones. What can I do? I think I could solve it with shaders but I didn't try yet. There's more elegant way for sure.
Here is a minimal code
#include <SFML/Graphics.hpp>

using namespace sf;
int main()
{
        sf::RenderWindow window(sf::VideoMode(360, 200), "SFML works!", Style::Default);
        window.setFramerateLimit(60);

        sf::IntRect redNoteTextureBounds{ 0, 0, 184, 100 };
        sf::IntRect blueNoteTextureBounds{ 184, 0, 184, 100 }; 
        sf::IntRect longNotesTextureBounds{ 0, 100, 184, 100 };

        Texture t; t.loadFromFile("Texture.png");
        Sprite s1(t);
        s1.setTextureRect(blueNoteTextureBounds);

        RenderTexture rt;
        Sprite s2(t);
        rt.create(184, 175);
        rt.clear(Color::Transparent);

        s2.setTextureRect(blueNoteTextureBounds);
        s2.setPosition(0, 0);
        rt.draw(s2, RenderStates());
       
        s2.setPosition(0,80);
        rt.draw(s2, RenderStates());

        s2.setTextureRect(longNotesTextureBounds);
        s2.setPosition(0, 40);
        rt.draw(s2, RenderStates());

        rt.display();
        s2.setTexture(rt.getTexture(), true);  
        s2.setPosition(130, 0);

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

                window.clear();
                window.draw(s1);
                window.draw(s2);
                window.display();
        }

        return 0;
}
 
Title: Re: Drawing Transparent Textures on Transparent RenderTexture
Post by: Laurent on May 13, 2020, 08:15:39 pm
Clear the render-texture with transparent, and draw to it with blending disabled (sf::Blend::None). This will keep the alpha channel unchanged on the render-texture, and interpret it only when you draw the render-texture to the window.
Title: Re: Drawing Transparent Textures on Transparent RenderTexture
Post by: Maksat on May 13, 2020, 08:49:53 pm
Clear the render-texture with transparent, and draw to it with blending disabled (sf::Blend::None). This will keep the alpha channel unchanged on the render-texture, and interpret it only when you draw the render-texture to the window.
Like this?
renderTexture.draw(sprite, sf::RenderStates(sf::BlendNone)):
 
I fot this result:
(https://i.ibb.co/swbcBwH/SFMLTest-2020-05-14-00-41-13-363.jpg) (https://imgbb.com/)

it would help if the textures did not overlap each other. Here is edited example code in case if did somethig wrong
#include <SFML/Graphics.hpp>

using namespace sf;
int main()
{
        sf::RenderWindow window(sf::VideoMode(360, 200), "SFML works!", Style::Default);
        window.setFramerateLimit(60);

        sf::IntRect redNoteTextureBounds{ 0, 0, 184, 100 };
        sf::IntRect blueNoteTextureBounds{ 184, 0, 184, 100 }; 
        sf::IntRect longNotesTextureBounds{ 0, 100, 184, 100 };

        Texture t; t.loadFromFile("Texture.png");
        Sprite s1(t);
        s1.setTextureRect(blueNoteTextureBounds);

        RenderTexture rt;
        Sprite s2(t);
        rt.create(184, 175);
        rt.clear(Color::Transparent);

        s2.setTextureRect(blueNoteTextureBounds);
        s2.setPosition(0, 0);
        rt.draw(s2, RenderStates(sf::BlendNone));
       
        s2.setPosition(0,80);
        rt.draw(s2, RenderStates(sf::BlendNone));

        s2.setTextureRect(longNotesTextureBounds);
        s2.setPosition(0, 40);
        rt.draw(s2, RenderStates(sf::BlendNone));

        rt.display();
        s2.setTexture(rt.getTexture(), true);  
        s2.setPosition(130, 0);


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

                window.clear();
                window.draw(s1);
                window.draw(s2);
                window.display();
        }

        return 0;
}
 
Title: Re: Drawing Transparent Textures on Transparent RenderTexture
Post by: Maksat on May 15, 2020, 08:53:28 am
Guys please help. I still have no idea how to solve this problem :(
Title: Re: Drawing Transparent Textures on Transparent RenderTexture
Post by: eXpl0it3r on May 15, 2020, 11:46:22 am
If you don't want the textures to overlap, then crop them to the right size.

For complex compositions it might be better to just do it in an image editor.