我最近开始学习OpenGL。我在Learnopengl.com教程的每个部分之后都有测试自己的技能的想法,并且
目前在https://learnopengl.com/Getting-started/Shaders章之后
所以我创建了一个简单的乒乓游戏,在调试时我注意到了奇怪的行为。
我创建的游戏会在一段时间后崩溃,但总是在其中一位玩家获得积分后崩溃。
重要的是要注意,每个游戏对象都有一个更新函数,我将每一帧称为
,并且将指向所有游戏对象的指针保存在STL向量中。
我分析了一些代码,发现它没什么不好,所以我启动了gdb并写了一些“ std :: cerr”信息。
这是我发现的:
1.更新其中一个对象(obj-> update())
时游戏崩溃
2.在将新点数授予玩家后,游戏总是崩溃,从而使游戏对象指针向量包含32个元素。如果我在游戏开始之前使用GAMEOBJECTS.relocate(33),则当崩溃时矢量包含33个元素。
3.从向量更新第五个游戏对象时,游戏崩溃。这里必须注意,ball对象是第四个,而Ball :: update()包含创建新GameObject(点)的代码。
从这些信息中,我推断出,当我创建一个新对象并将其指针推到一个矢量上时,该矢量必须自行重定位,因为它没有足够的容量。
反过来,这会导致一些我不理解的奇怪的内存混乱,因为我才刚刚开始学习c ++编程。
这也使得无法访问向量的第五个元素。
我正在努力寻找解决此问题的方法,但我最大的担心是了解为什么会这样。
代码太大,无法粘贴到这里,所以我将其放在github:
https://github.com/carul/opengl_pong
我仍将描述我认为最重要的内容:
for(auto && obj : GAMEOBJECTS){
obj->update();
obj->draw(VBO);
}
这就是我用来绘制和更新游戏对象的循环。
我认为这没什么特别的,除了它可以一个接一个地更新对象。
void Ball::update(){
///...
if(boundingLeft < -0.96f){
this->setPosition(0.0f, 0.0f);
this->speedmodif = 0.8f;
this->angle = 0;
Point * point = new Point(GL_STATIC_DRAW);
point->create(POINT_DATA);
point->indice(POINT_INDICES);
point->setPlayer(2);
point->name = "POINT";
point->setPosition(0.93f - 0.03f*scorep2, 0.9f);
scorep2++;
GAMEOBJECTS.push_back(point);
}
if(boundingRight > 0.96f){
this->setPosition(0.0f, 0.0f);
this->speedmodif = 0.8f;
this->angle = M_PI;
Point * point = new Point(GL_STATIC_DRAW);
point->create(POINT_DATA);
point->indice(POINT_INDICES);
point->setPlayer(1);
point->name = "POINT";
point->setPosition(-0.95f + 0.03f*scorep1, 0.9f);
scorep1++;
GAMEOBJECTS.push_back(point);
}
///...
}
这是球的更新功能的一部分。这段代码负责创建新点。 Ball是Object类的派生类。
GAMEOBJECTS的定义如下:
std::vector<Object * > GAMEOBJECTS;
很抱歉很长的帖子,我试图提供我所有的信息。
非常感谢您阅读本文的这一部分,并感谢您的帮助
这是崩溃时gdb和游戏的屏幕截图:
答案 0 :(得分:2)
在此循环中
for(auto && obj : GAMEOBJECTS) {
obj->update();
obj->draw(VBO);
}
obj
是对向量元素的引用。在update()
中,您push_back()
进入GAMEOBJECTS
。如果向量的容量不足以容纳新元素,则此操作会使obj
引用无效。