2014-01-18 4 views
1

У меня есть класс модели, который содержит буфера для модели, чтобы сделать, это реализация выглядит следующим образом:C деструктор ++ странно 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(); 
} 

Использование класса модели таким образом, запускающее Нарушение чтения ошибки Расположение выполнения доступа, но если я комментирую на 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); 
+1

Не забывайте правило три: У вас есть копия ctor и оператор копирования? –

+0

Эта строка, скорее всего, является источником вашей проблемы: 'Модель m = parseSKNFromFile (" model.skn ");'. Если вы пишете 'parseSKNFromFile (...)', чтобы вернуть указатель на объект, выделенный на кучу, вместо создания копии, многие головные боли исчезнут. –

ответ

1

предположение: Вы не должны (не может быть) собственный оператор в конструктор копирования/присваивания.

Следовательно:

private; 
Model(const Model&); // No copy 
Model& operator = (const Model&); // No copy 
0

Поскольку вы создаете строковый объект модели он будет уничтожен автоматически, когда он выходит из области видимости, и что сфера находится в конце функции, где экземпляр Renderer.

Я предлагаю изменить модель на объект, выделенный кучей, и уничтожить его вручную, прежде чем освобождать рендер и до того, как вы уничтожите окно.

Model* m = parseSKNFromFile("model.skn"); 

Есть некоторые другие предложения, которые я хотел бы сделать, как принимать массивы индексов и вершин, как константные ссылки в конструкторе модели. Кроме того, я не думаю, что отличная идея вызвать команды gl из деструктора объекта, было бы лучше отделить этот тип функциональности от разделения функций в модели, а также не инициализировать буферы OpenGL в конструкторе либо , Причиной этого является то, что вы хотите отделить выделение объектов от инициализации рендеринга, чтобы вы могли загружать их в отдельный поток из потока рендеринга.

+0

Как вы можете видеть во втором коде, который я дал, выделение объекта находится в той же функции, где объект используется (в данном случае функция main()), и это все равно не имеет никакого смысла, потому что все отлично работает, если я прокомментирую эти команды от деструктора. С другой стороны, если у вас есть какие-либо ресурсы для программирования ООП с OpenGL, просите их здесь: D – UnTraDe

Смежные вопросы