2017-08-13 7 views
0

グラフィックエンジンで作業しています。エンジンはドロワーブルのstd::vectorを持っています。 Drawableは、ModelとDrawableObjectを含むオブジェクトで、2Dまたは3Dモデルからシェーダプログラムとバンチ頂点を保持します。新しいDrawableを追加するとうまくいきます。Drawableを削除しようとすると問題が発生します。最後の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

コードがある最後のDrawableのを、削除します白いマーカを使用し、部屋のz位置を変更しました。これはほとんどの場合起こります。最後の要素を削除し、2番目の要素を最後に変更しました。 initメソッドの最後に '人間'のキューブを追加すると機能します。オブジェクトを削除する前に

ブレーク

enter image description here

オブジェクトを除去した後:

enter image description here

これは正しいです。

removeメソッドを残してレンダリングループで見てみる:

enter image description here

はどういうわけか変更。

+3

コピー代入演算子が右辺を修正するのを待ちますか? 'tmp'とは何ですか? – NPE

+0

@NPE [コピー&スワップイディオム](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; 
}; 
関連する問題