2017-08-13 58 views
0

我正在图形引擎上工作。该引擎有一个std::vector可绘制。 Drawable是一个对象,它包含一个Model和一个DrawableObject,该对象继而保存来自2D或3D模型的着色器程序和一堆顶点。添加新的Drawables进展顺利,当我尝试删除Drawable时会出现问题。最后一个Drawable将总是被删除,倒数第二个将更改其值。错误的元素被删除后,使用std :: erase成功的方法

代码

Drawable.h

class Drawable 
{ 
public: 
    Drawable& operator=(const Drawable& other) 
    { 
     Drawable tmp(other); 
     std::swap(model, other.model); 
     std::swap(drawableObject, other.drawableObject); 
     return *this; 
    } 

    Drawable(domain::Model& model, DrawableObject& drawableObject) : 
     model(model), 
     drawableObject(drawableObject) 
    {} 

    domain::Model& model; 
    DrawableObject& drawableObject; 
}; 

game.cpp

void Game::init_game() 
{ 
    human = domain::Model(glm::vec3(0, 0, -3)); 
    moveables.push_back(&human); 
    room = domain::Model(glm::vec3(0, 0, -10)); 
    props.push_back(&room); 
    cube = domain::Model(glm::vec3(0, 0, 0)); 
    props.push_back(&cube); 
} 

void Game::init_graphics_engine() 
{ 
    // ... load graphics models 

    // add drawables 
    graphicsEngine->add(cube, Drawable::CUBE); 
    graphicsEngine->add(human, Drawable::HUMAN); 
    graphicsEngine->add(room, Drawable::ROOM); 
    graphicsEngine->add(topDownScene->cursor, Drawable::MARKER); 
} 

graphics_engine/engine.cpp

void Engine::add(domain::Model& model, unsigned int object) 
{ 
    auto drawableObject = drawableObjects[object]; 
    // make sure not to add a model that already is represented 
    auto it = std::find_if(drawables.begin(), drawables.end(), [&model](Drawable& drawable) {return &drawable.model == &model;}); 
    if(drawableObject && it == drawables.end()) 
     drawables.push_back(Drawable(model, *drawableObject)); 
} 

void Engine::remove(domain::Model& model) 
{ 
    auto predicate = [&model](Drawable& drawable) 
    { 
     return &drawable.model == &model; 
    }; 
    drawables.erase(std::remove_if(drawables.begin(), drawables.end(), predicate), drawables.end()); 
} 

场景

这是现场的样子,当我启动应用程序:

scene on startup

这是现场的样子试图删除的小“人”的立方体后中间:

enter image description here

的代码删除最后绘制对象,这是白色标记,而不是“人”立方体,并改变了房间的z位置。这几乎总是发生,它删除最后一个元素并将第二个元素的z更改为最后一个元素。它只有在init方法中最后添加'人类'多维数据集时才有效。

断点

删除对象之前:

enter image description here

删除对象后:

enter image description here

这是正确的。

离开remove方法,并且考虑看看在渲染循环:

enter image description here

不知何故改变。

+3

等一下,你的拷贝赋值操作符是否修改右边?和'tmp'有什么关系? – NPE

+0

@NPE [copy-and-swap idiom](https://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom)。 – LogicStuff

+0

@LogicStuff:这就是我猜测它的*意思是*,但不是如果你仔细阅读代码(除非我没有看到某些东西,当然这也是一种可能性)。 – NPE

回答

0

我将类成员改为指针。现在它可以工作。评论是正确的,我没有对tmp变量做任何事情。

class Drawable 
{ 
public: 
    Drawable& operator=(const Drawable& other) 
    { 
     this->model = other.model; 
     this->drawableObject = other.drawableObject; 
     return *this; 
    } 

    Drawable(domain::Model* model, std::shared_ptr<DrawableObject> drawableObject) : 
     model(model), 
     drawableObject(drawableObject) 
    {} 

    domain::Model* model; 
    std::shared_ptr<DrawableObject> drawableObject; 
}; 
相关问题