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

Author Topic: Drawing Transparent Textures on Transparent RenderTexture  (Read 2043 times)

0 Members and 1 Guest are viewing this topic.

Maksat

  • Newbie
  • *
  • Posts: 6
    • View Profile
    • Email
Drawing Transparent Textures on Transparent RenderTexture
« on: May 13, 2020, 06:03:11 pm »
Hello! I'm trying to get transparent texture like this (made with Photoshop)

by combining it from separate textures on transparent RenderTexture

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


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;
}
 

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Drawing Transparent Textures on Transparent RenderTexture
« Reply #1 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.
Laurent Gomila - SFML developer

Maksat

  • Newbie
  • *
  • Posts: 6
    • View Profile
    • Email
Re: Drawing Transparent Textures on Transparent RenderTexture
« Reply #2 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:


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;
}
 

Maksat

  • Newbie
  • *
  • Posts: 6
    • View Profile
    • Email
Re: Drawing Transparent Textures on Transparent RenderTexture
« Reply #3 on: May 15, 2020, 08:53:28 am »
Guys please help. I still have no idea how to solve this problem :(

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: Drawing Transparent Textures on Transparent RenderTexture
« Reply #4 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.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/