Почему метод класса .setTexure() ведет себя по-другому?

Метод .setTexure() класса спрайтов sfml не работает внутри конструктора для итератора, но работает, когда итератор уже создан

Мы пытаемся создать структуру для фреймов, которые рисуются в окне. Мы используем библиотеку sfml с классами спрайтов и текстур. В конструкторе структуры frameData мы загружаем текстуру из файла, а затем применяем ее к спрайту с помощью метода .setTexture(). Мы либо получаем белый блок, либо сбой программы в зависимости от машины, когда мы компилируем и запускаем нашу программу.

Если мы создадим ссылку на текстуру с помощью .setTexture() вне конструктора для frameData, это сработает!

Все, если это со структурой итератора, которая перебирает разные кадры. Вот соответствующий код. Сначала он находится в заголовке структуры FrameData:

private:
    struct FrameData
    {
        FrameData(const std::string& fileName, int frameDelay);

        sf::Texture texture;
        sf::Sprite sprite;
        unsigned int frameDelay;
    };

Во-вторых, вот настоящие конструкторы, которые не работают:

const sf::Sprite& SpriteAnimator::currentFrame() const
{
    return currentFrame_->sprite;
}

SpriteAnimator::FrameData::FrameData(const std::string& fileName, int frameDelay)
: frameDelay(frameDelay)
{
    texture.loadFromFile(fileName);
    sprite.setTexture(texture);
}

И в-третьих, вот что работает:

const sf::Sprite& SpriteAnimator::currentFrame() const
{
    currentFrame_->sprite.setTexture(currentFrame_->texture);
    return currentFrame_->sprite;
}

SpriteAnimator::FrameData::FrameData(const std::string& fileName, int frameDelay)
: frameDelay(frameDelay)
{
    texture.loadFromFile(fileName);
    sprite.setTexture(texture);
}

Любые идеи о том, почему это происходит, мы что-то упускаем? Мы хотим, чтобы конструктор работал правильно, текущий кадр возвращается намного чаще, чем изменение текстуры, поэтому нам не нужно обновлять текстуру каждый раз, когда возвращается текущий кадр.

Спасибо!


person s3binator    schedule 20.06.2012    source источник
comment
У меня была аналогичная проблема с этим. Мое решение состояло в том, чтобы хранить все мои текстуры в контейнере вне класса и использовать указатель на текстуру вместо самой текстуры. Это убивает 2 зайцев одним выстрелом, потому что вам не нужно хранить более 1 одной и той же текстуры, если вы собираетесь создать другой объект из класса.   -  person elimirks    schedule 21.06.2012
comment
Как вы думаете, проблема возникает из-за использования самих текстур, а не указателей? Интересно, документировано ли это? Спасибо!   -  person s3binator    schedule 21.06.2012
comment
Поскольку вы решили свой вопрос, можете ли вы опубликовать решение в качестве ответа? Таким образом, это не выглядит открытым вопросом для всех других пользователей SO. Спасибо!   -  person Tim    schedule 22.06.2012


Ответы (2)


РЕШЕНО! Прочтите последний абзац документации класса для sf::sprite:

Важно отметить, что экземпляр sf::Sprite не копирует текстуру, которую он использует, а только сохраняет ссылку на нее. Таким образом, sf::Texture не должен уничтожаться, пока он используется sf::Sprite (т. е. никогда не пишите функцию, которая использует локальный экземпляр sf::Texture для создания спрайта).

Таким образом, создание репозитория для текстур за пределами этого класса, а затем передача ссылок работает, как рекомендуется крепкий напиток!

person s3binator    schedule 22.06.2012

У меня была аналогичная проблема с этим. Мое решение состояло в том, чтобы хранить все мои текстуры в контейнере вне класса и использовать указатель на текстуру вместо самой текстуры. Это убивает 2 зайцев одним выстрелом, потому что вам не нужно хранить более 1 одной и той же текстуры, если вы собираетесь создать другой объект из класса.

person elimirks    schedule 22.06.2012