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

Author Topic: Vector Of Calsses with textures / White Rectangle Problem  (Read 2202 times)

0 Members and 1 Guest are viewing this topic.

aradarbel10

  • Newbie
  • *
  • Posts: 6
    • View Profile
Vector Of Calsses with textures / White Rectangle Problem
« on: July 19, 2018, 11:14:19 am »
Hello,
You probably know what is the problem of mine: I have a vector of button objects (class). each button contains a rectangleShape and its texture (I know I can use a sprite). the texture appear to be a white rectangle. in the past everything worked but now its not. I know its a pointer problem, but don't know how to fix it, or how to use the puch_back correctly to make it work. here is the class:

void Button::setButton(float x, float y, float w, float h) {
        pos = sf::Vector2f(x, y);
        size = sf::Vector2f(w, h);
}

void Button::setTexture(string dir, sf::Vector2f s) {
        textureDir = dir;
        buttonTexture.loadFromFile(textureDir);
        button.setTexture(&buttonTexture);

        if (!textureLoaded) textureLoaded = true;
}

void Button::setMode(bool m) {
        mode1 = m;
        modeList.push_back(mode1);

        int temp = 0;
        for (int i = 0; i < modeList.size(); i++) {
                if (modeList[i]) temp++;
        }

        if (temp != 0) {
                buttonMode = true;
        }
        else {
                buttonMode = false;
        }
}

bool Button::getMode() {
        return buttonMode;
}

void Button::update() {
        button.setPosition(pos);
        button.setSize(size);

        if (dimention == 0) {
                texturePos.x += 128;
        }
        else {
                texturePos.x += 0;
        }

        if (buttonMode) {
                texturePos.y = 64;
        }
        else {
                texturePos.y = 0;
        }

        modeList.clear();

        cout << pos.x << " " << pos.y << " , " << size.x << " " << size.y << endl;

        button.setTextureRect(sf::IntRect(texturePos.x, texturePos.y, size.x, size.y));
}

sf::RectangleShape Button::getShape() {
        return button;
}

void Button::show(sf::RenderWindow &window) {
        window.draw(button);
}
 

and the buttons are controlled by another class that maneges everything in the current level of the game (probably the issue occures in this function, because it's the only one that related to the buttons except for a functions to change the mode of the button when clicked, and I am not calling this one anywhere in the code):

void Level::newButton(float x, float y, float w, float h, string dir) {
        button1.setButton(x * tileSize.x, y * tileSize.y, w * tileSize.x, h * tileSize.y);
        cout << "p: " << x << " * " << tileSize.x << " , " << y << " * " << tileSize.y << endl;
        button1.setTexture(dir, sf::Vector2f(w, h));
        buttonSet.push_back(move(button1));
        cout << "New Button Added" << endl;
}
 

and it is also important to say that you can see the texture on the button in the first frame, but after that it becomes white.
From what I knwo I may want to create a vector of pointers, but I don't know how to do it.

any help will be appreciated,
Arad.

verdog

  • Newbie
  • *
  • Posts: 25
    • View Profile
    • Email
Re: Vector Of Calsses with textures / White Rectangle Problem
« Reply #1 on: July 19, 2018, 06:35:34 pm »
I think I know what's going on. See this.

When you call setTexture, the texture you use needs to live as long as the thing using it. You're declaring a texture locally in a member function, which means the texture gets destroyed when the function is completed.

To fix this, load the texture into memory separately from the button's method, and the set the button's texture with a reference to that texture.

tomvidm

  • Newbie
  • *
  • Posts: 15
    • View Profile
Re: Vector Of Calsses with textures / White Rectangle Problem
« Reply #2 on: July 19, 2018, 09:52:52 pm »
verdog is correct. The texture will be destroyed as soon as the method quits. When you use the built in setTexture method for sprites and rectangles, they store a pointer to said texture. When the method quits, the temporary texture objects is destroyed, and the assigned texture pointer will point to free memory.

I want to comment on the method you are writing: It is called setTexture, but you are trying to do two things with it; to load a texture and to set a texture. Imagine you are working on this project in a team - you are new to the project and you want to know how to load a texture, but the documentation does not document any "loadTexture" method. What do you do? Yes, you start spending a lot of looking through the code to understand what is going on. A good principle to keep in mind is the principle of single responsibility - when you name a function to have some purpose, try to limit it to that purpose and let the name reflect what it does. It is good practice and will help you as the project grows - inevitably, you will forget the details of older parts of your code and you will start pulling your hair out :)

Keep in mind, this is not a criticism - everyone does this in the beginning.  ;)