【问题标题】:White texture showing in place of actual texture when not using dynamic memory in SFML在 SFML 中不使用动态内存时显示白色纹理代替实际纹理
【发布时间】:2018-11-17 10:06:39
【问题描述】:

我有一个 Armor 类,它存储要绘制到屏幕上的纹理和精灵,如下所示:

Armor.h

class Armor 
{
public:
    Armor(const std::string& armorName);

    void draw(sf::RenderWindow& window);

    ~Armor();

private:
    sf::Texture armorTexture;
    sf::Sprite armorSprite;
    int numOfArmor;
};

Armor.cpp

#include "Armor.h"
Armor::Armor(const std::string& armorName)
{
    armorTexture.loadFromFile(armorName);
    armorSprite.setTexture(armorTexture);
    numOfArmor = 0;
}


void Armor::draw(sf::RenderWindow& window)
{
    window.draw(armorSprite);
}

Armor::~Armor()
{
}

我还有一个名为Application 的对象,它在地图中存储Armor 的一个实例,如下所示:

Application.h

class Application
{
public:
    Application();

    void start();

    ~Application();
private:
    sf::RenderWindow window;
    std::map<std::string, Armor> armorMap;
    std::map<std::string, Armor>::iterator armorIter;

};

Application.cpp

#include "Application.h"

Application::Application()
{
    window.create(sf::VideoMode(640, 480), "SFML Application", sf::Style::Close);
    window.setFramerateLimit(120);

    std::string armorName;
    std::ifstream file("Armors.txt");
    while (file >> armorName)
        armorMap.emplace(armorName, Armor(armorName + "Armor.png"));
    file.close();

    armorIter = armorMap.begin();
}

void Application::start()
{
    while (window.isOpen())
    {

        sf::Event evnt;
        while (window.pollEvent(evnt))
        {

            if (evnt.type == sf::Event::Closed)
                window.close();
        }

        window.clear();
        while (armorIter != armorMap.end())
        {
            armorIter->second.draw(window);
            armorIter++;
        }
        armorIter = armorMap.begin();
        window.display();
    }
}

Application::~Application()
{
}

每当我构造对象时,屏幕上都会出现一个白色纹理,我发现它被称为white texture problem。我被难住了,因为我确定我的纹理没有被破坏,所以我决定改为将地图更改为std::map&lt;std::string, Armor*&gt; armorMap,这解决了我的所有问题!为什么在 map 中存储指向 Armor 类型对象的指针会起作用,而不是像我最初那样做?

【问题讨论】:

  • 我认为您在放置项目时使用了复制赋值运算符。我对 SFML 没有任何经验,但它可能无法正确复制纹理。然后,当对象超出范围时(一旦您离开放置线),就会导致纹理被删除。
  • 换句话说:如果您使用指针并通过new 运算符分配该指针,则您的对象不会被复制到地图中,并且“旧”对象不会被删除。

标签: c++ graphics sfml


【解决方案1】:

当您将盔甲对象存储到地图中时,您正在制作它的副本、它的纹理和它的精灵。

精灵已将您的纹理存储为指向被破坏的原始纹理对象的指针(请参阅https://www.sfml-dev.org/documentation/2.5.0/classsf_1_1Sprite.php#a3729c88d88ac38c19317c18e87242560)。

无论如何,在地图中存储指针会给您带来更好的性能,因为您将避免不必要的纹理副本。除非您真的知道自己在做什么,否则您可能应该使用 std::shared_ptr&lt;Armour&gt; 而不是原始指针。

【讨论】:

    猜你喜欢
    • 2015-03-13
    • 1970-01-01
    • 1970-01-01
    • 2020-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多