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

Author Topic: Update holes in a texture?  (Read 2511 times)

0 Members and 2 Guests are viewing this topic.

Chili

  • Guest
Update holes in a texture?
« on: January 05, 2013, 04:39:59 am »
Hello! I've been trying to solve this problem for a few weeks now but can't find a solution to it, as the title says, how would you update an texture with an image that it only draws partially(ignore to draw what's decided to be masked or what's already transparent in the image)?
I would actually want to do this with an circle shape instead(so I can variate the circles sizes easier) but from what I understood from the documentation you can't update an texture with a shape.

Code example for my problem:
#include <SFML/Graphics.hpp>

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

        sf::Texture texture1;
        texture1.loadFromFile("for.png");
        sf::Sprite sprite1(texture1);

        sf::Image image1;
        image1.loadFromFile("hole.png");

    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)){
                        texture1.update(image1, sf::Mouse::getPosition(window).x, sf::Mouse::getPosition(window).y);
        }

        window.clear();
                window.draw(sprite1);
        window.display();
    }

    return 0;
}
Which produces:

masskiller

  • Sr. Member
  • ****
  • Posts: 284
  • Pointers to Functions rock!
    • MSN Messenger - kyogre_jb@hotmail.com
    • View Profile
    • Email
Re: Update holes in a texture?
« Reply #1 on: January 05, 2013, 06:04:12 am »
sf::Image::createMaskFromColor and your problem is solved, just make the image, mask it and then load the image to the texture.

Edit: If you are already using png then it's just as easy as using a transparent background beforehand, depending on your sprite you won't be able to get it your way with just masking only one color, as said sprite can lead to unneeded complexity by making you need to mask many colors (sometimes even unknown) in order to just have it display normally.
« Last Edit: January 05, 2013, 06:13:22 am by masskiller »
Programmer, Artist, Composer and Storyline/Script Writer of "Origin of Magic". If all goes well this could turn into a commercial project!

Finally back into the programming world!

Chili

  • Guest
Re: Update holes in a texture?
« Reply #2 on: January 05, 2013, 02:50:35 pm »
The hole image already got transparent background which overwrites the texture for me, tried to create a mask just to see if the result would be different but it still ends up overwriting pixels.
Also just to be on the safe side, can you update a texture with a shape(not directly but get what pixels makes up the shape somehow?)?  like how you can with a rendertexture.

Edit: I solved it (temporarily) with this(image 1 being my hole and image 2 being my texture to apply the hole to):
if (sf::Mouse::isButtonPressed(sf::Mouse::Left)){
                        i=0,y=0;
                        temp_x = sf::Mouse::getPosition(window).x, temp_y = sf::Mouse::getPosition(window).y;
                        loop = true;

                        while(loop){
                                while(y < 32){
                                        while(i<32){
                                                if(image1.getPixel(i, y) != sf::Color::Transparent){
                                                        image2.setPixel(temp_x+i, temp_y+y, sf::Color(0,0,0,0));
                                                }
                                                i++;
                                        }
                                        i=0;
                                        y++;
                                }
                                loop = false;
                        }
                        texture1.loadFromImage(image2);
        }
However copying pixel by pixel wasn't exactly what I wanted because of the speed so I would still like to find a way to do it with textures update function.
« Last Edit: January 05, 2013, 03:40:09 pm by Chili »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10998
    • View Profile
    • development blog
    • Email
Re: Update holes in a texture?
« Reply #3 on: January 05, 2013, 03:34:06 pm »
Just use a second texture and sprite and draw it on top of the other one. Updating a texture isn't a fast procedure and as you've noticed it will 1:1 replace the current pixels.
If you want to render on top of a existing texture, you should use sf::RenderTexture, but that doesn't make any sense in your case.

#include <SFML/Graphics.hpp>

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

    sf::Texture texture1;
    texture1.loadFromFile("for.png");
    sf::Sprite sprite1(texture1);

    sf::Texture texture2;
    texture2.loadFromFile("hole.png");
    sf::Sprite sprite2(texture2);

    bool drawSprite2 = false;

    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)){
            sprite2.setPosition(sf::Mouse::getPosition(window).x, sf::Mouse::getPosition(window).y);
            drawSprite2 = true;
        }

        window.clear();
        window.draw(sprite1);
       
        if(drawSprite2)
            window.draw(sprite2);

        window.display();
    }

    return 0;
}
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Chili

  • Guest
Re: Update holes in a texture?
« Reply #4 on: January 05, 2013, 03:56:55 pm »
Oh, that kinda works but I really want it to apply directly to the texture itself without being to slow, if there is such a thing.
« Last Edit: January 05, 2013, 03:59:29 pm by Chili »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10998
    • View Profile
    • development blog
    • Email
Re: Update holes in a texture?
« Reply #5 on: January 05, 2013, 04:29:18 pm »
Oh, that kinda works but I really want it to apply directly to the texture itself without being to slow, if there is such a thing.
Then use sf::RenderTexture, but if you just want to have multiple 'holes' you could also use a std::vector<sf::Sprite>.

#include <SFML/Graphics.hpp>

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

    sf::Texture texture1;
    texture1.loadFromFile("for.png");
    sf::Sprite sprite1(texture1);

    sf::Texture texture2;
    texture2.loadFromFile("hole.png");
    sf::Sprite sprite2(texture2);

    sf::RenderTexture rt;
    rt.create(800, 600);
    sf::Sprite sprite 3;
    sprite3.setTexture(rt.getTexture());

    rt.clear();
    rt.draw(sprite1);
    rt.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)){
            sprite2.setPosition(sf::Mouse::getPosition(window).x, sf::Mouse::getPosition(window).y);
            rt.draw(sprite2);
            rt.display();
        }

        window.clear();
        window.draw(sprite3);
        window.display();
    }

    return 0;
}
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Chili

  • Guest
Re: Update holes in a texture?
« Reply #6 on: January 05, 2013, 04:44:36 pm »
Ah, thought it was harder than that, I ended up drawing my texture onto the rendertexture, which allowed me to use circleshapes instead of images, thanks for the help.