C++破坏者奇怪的行为
C++ destructor weird behavoiur
我有一个模型类,其中包含模型绘制的缓冲区,它的实现如下所示:
Model::Model(std::vector<Vertex> vertices, std::vector<short> indices)
{
mVertices = vertices;
mIndices = indices;
mMatrix = glm::mat4(1.0f);
mIsTextured = false;
Initialize();
}
Model::~Model()
{
glDeleteBuffers(1, &mVertexBuffer);
glDeleteBuffers(1, &mIndiceBuffer);
}
void Model::Initialize()
{
glGenBuffers(1, &mVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)*mVertices.size(), &mVertices[0], GL_STATIC_DRAW);
glGenBuffers(1, &mIndiceBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndiceBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(short)*mIndices.size(), &mIndices[0], GL_STATIC_DRAW);
}
现在我在析构函数中遇到了一个非常奇怪的问题,我像这样使用这个类:
Renderer *renderer = new Renderer();
Model m = parseSKNFromFile("model.skn");
m.ApplyTexture(textureID);
while (!glfwWindowShouldClose(window))
{
update();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
renderer->RenderModel(&m);
glfwSwapBuffers(window);
glfwPollEvents();
}
以这种方式使用 Model 类会触发运行时访问冲突读取位置错误,但如果我在构造函数中注释 glDeleteBuffers 调用,则所有工作都会找到。看起来不知何故,那些删除函数突然被调用,我不知道如何以及为什么。
这也是 RenderModel 函数:
mShader.bind();
glm::mat4 MVP = mProjection * glm::lookAt(glm::vec3(0, 100, 200), glm::vec3(0, 100, 0), glm::vec3(0, 1, 0)) * model->GetMatrix();
glUniformMatrix4fv(mShader.getUniformLocation("MVP") , 1, GL_FALSE, &MVP[0][0]);
if (model->IsTextured())
{
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, model->GetTexture());
glUniform1i(model->GetTexture(), 0);
}
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
glBindBuffer(GL_ARRAY_BUFFER, model->GetVertexBuffer());
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0); //float position[3]
glVertexAttribPointer(1, 1, GL_INT, GL_FALSE, sizeof(Vertex), (void*)12); //char boneIndex[4]
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)16); //float weights[4]
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)32); //float normals[3]
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)44); //float textureCords[2]
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model->GetIndiceBuffer());
glDrawElements(GL_TRIANGLES, model->GetIndiceSize(), GL_UNSIGNED_SHORT, (void*)0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(3);
glDisableVertexAttribArray(4);
假设:您没有(不能有)正确的复制构造函数/赋值运算符。
因此:
private;
Model(const Model&); // No copy
Model& operator = (const Model&); // No copy
由于您正在创建 Model 的内联对象,因此当它超出范围时,它将自动销毁,并且该范围位于您实例化渲染器的函数的末尾。
我建议将模型更改为堆分配的对象,并在释放渲染器和销毁窗口之前手动销毁它。
Model* m = parseSKNFromFile( "model.skn" );
我还会提出一些其他建议,例如将索引和顶点数组作为模型构造函数中的常量引用。此外,我认为从对象的析构函数调用 gl 命令不是一个好主意,最好将这种类型的功能分开以分离模型中的函数,也不初始化构造函数中的 OpenGL 缓冲区。这样做的原因是,如果您想将对象分配与渲染器初始化分开,以便您可以将它们加载到与渲染线程不同的线程上。
相关文章:
- 在放松试验块期间,通过投掷破坏者而导致这种怪异的行为
- 为什么我的虚拟破坏者多次执行这些执行
- 在销毁派生成员之前,在破坏者中调用共同功能
- 纯抽象类的虚拟破坏者
- 如何在CLION中的C 破坏者中达到断点
- 模拟一个函数,该函数像操作员=和破坏者一样传播到每个字段
- C :如何正确删除在类破坏者中的指针
- C 破坏者回收
- 模板基类的破坏者中的类型完整性不一致
- 使用std :: map时,包含unique_ptr的结构中的默认破坏者会导致编译错误
- 为什么我的破坏者只称呼一次,而不是在删除(a)调用上
- 与虚拟破坏者相比,Shared_PTR的运行时开销用于子类破坏
- 定义或声明类破坏者时,C 使用已删除的函数
- 在另一类中使用受保护的破坏者删除对象
- 永远循环的链接列表破坏者
- 不同版本的破坏者称为奇怪因素
- 将std :: lock_guard固定在破坏者中是安全的吗?
- 已经被破坏的一系列物体上的破坏者
- 即使在明确调用破坏者后,对象自动破坏也是如此
- 虚拟破坏者与普通破坏者