在删除/清理时,OpenGL4对象无意中“链接”在一起

时间:2014-04-30 18:21:54

标签: c++ qt opengl

我有三个像这样创建的测试对象。 如果我删除obj 3,它会按预期工作。如果我删除obj 2它会删除2和3.如果我删除对象1它会删除1和2并将我的一个vao / vbos附加到我的相机对象。

我认为赋值构造函数可能存在问题。如果我只是复制复制构造函数,我可以按照我的预期删除第一个对象,但之后会立即崩溃。

vector<Object> allObj;

//MAINWINDOW
Object *persp;
Object *grid;

persp = new Object(*this);
persp->rename("persp", myEtc->allObj); persp->type->val_s = "cam";
myEtc->allObj.push_back(*persp);
delete persp;

grid = new Object(*this);
grid->rename("grid", myEtc->allObj); grid->type->val_s = "grid";
grid->t->val_3 = glm::vec3(-3.f, 0.f, 0.f);
myEtc->allObj.push_back(*grid);
delete grid;

grid = new Object(*this);
grid->rename("grid", myEtc->allObj); grid->type->val_s = "grid";
myEtc->allObj.push_back(*grid);
delete grid;

grid = new Object(*this);
grid->rename("grid", myEtc->allObj); grid->type->val_s = "grid";
grid->t->val_3 = glm::vec3(-1.f, 0.5f, 0.f);
myEtc->allObj.push_back(*grid);
delete grid;

void MainWindow::deleteItem()
{
    for (vector<Object>::iterator iter = myEtc->allObj.begin(); iter != myEtc->allObj.end();)
    {
        if ((*iter).highlight == myGLHelp->highlight)
        {
            qDebug() << "name = " << (*iter).name->val_s;
            (*iter).delete_();
            iter = myEtc->allObj.erase(iter);
            break;
        }

        else
            ++iter;
    }

    myGL->updateGL();
}

//GLWIDGET - 4.4
void GLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_FRAMEBUFFER_SRGB);

    for (int i = 0; i < myWin.myEtc->allObj.size(); ++i)
    {
        if (myWin.myEtc->allObj[i].v->val_b)
        {
            if (myWin.myEtc->allObj[i].loadedVaoVbo == 0)
                myWin.myEtc->allObj[i].loadVaoVbo(); // dont load every frame

            myWin.myEtc->allObj[i].render(ProjectionM * ViewM);
        }
    }
}

//bullet raycast picking in GL viewport sets the color of the highlight - from non(0,0,0) to selected (yellow)

//OBJECT
Object & Object::operator=(const Object &obj) //ASSIGNMENT CONSTRUCTOR
{
    if (this == &obj) // Check for self assignment
      return *this;

    //same as copy constructor

    return *this;
}

Object::Object(const Object &obj) : myWin(obj.myWin) //COPY CONSTRUCTOR
{
    keyable.resize(obj.keyable.size());
    nonkeyable.resize(obj.nonkeyable.size());

    for (int i = 0; i < obj.keyable.size(); ++i)
    {
        keyable[i] = obj.keyable[i]->clone();

        if (keyable[i]->name == obj.keyable[i]->name)
        {
            if (keyable[i]->name == "name")
                name = keyable[i];

            else if (keyable[i]->name == "t")
                t = keyable[i];

            else if (keyable[i]->name == "r")
                r = keyable[i];

            else if (keyable[i]->name == "s")
                s = keyable[i];

            else if (keyable[i]->name == "v")
                v = keyable[i];

            //cam
            else if (keyable[i]->name == "camType")
                camType = keyable[i];

            else if (keyable[i]->name == "fov")
                fov = keyable[i];

            else if (keyable[i]->name == "lookAt")
                lookAt = keyable[i];

            else if (keyable[i]->name == "nearClip")
                nearClip = keyable[i];

            else if (keyable[i]->name == "farClip")
                farClip = keyable[i];
        }
    }

    for (int i = 0; i < obj.nonkeyable.size(); ++i)
    {
        nonkeyable[i] = obj.nonkeyable[i]->clone();

        if (nonkeyable[i]->name == "name")
            name = nonkeyable[i];

        else if (nonkeyable[i]->name == "expand")
            expand = nonkeyable[i];

        else if (nonkeyable[i]->name == "mode")
            mode = nonkeyable[i];

        else if (nonkeyable[i]->name == "parent")
            parent = nonkeyable[i];

        else if (nonkeyable[i]->name == "rotOrder")
            rotOrder = nonkeyable[i];

        else if (nonkeyable[i]->name == "type")
            type = nonkeyable[i];

        else if (nonkeyable[i]->name == "piv_r")
            piv_r = nonkeyable[i];

        else if (nonkeyable[i]->name == "piv_t")
            piv_t = nonkeyable[i];
    }

    loadedVaoVbo = 0;
    gridLines = obj.gridLines;
    highlight = obj.highlight;
    boxCollisionShape = obj.boxCollisionShape;
    r_quat = obj.r_quat;
    experimental = 0;
}


void Object::loadVaoVbo()
{
    glGetError();

    if (type->val_s == "grid")
    {
        gridLineLookup();

        gridVerts.resize(gridLines_ * gridLines_);

        gridVertsH.resize(gridLines_ * gridLines_);
        gridVertsV.resize(gridLines_ * gridLines_);

        for (int i = 0; i < gridLines_; ++i)
        {
            for (int j = 0; j < gridLines_; ++j)
            {
                gridVertsH[i + j * gridLines_].x =  (i - gridMinus_) / gridMinus_;
                gridVertsH[i + j * gridLines_].z =  (j - gridMinus_) / gridMinus_;

                gridVertsV[i + j * gridLines_].x =  (j - gridMinus_) / gridMinus_;
                gridVertsV[i + j * gridLines_].z =  (i - gridMinus_) / gridMinus_;
            }
        }

        //HORIZONTAL LINES
        glGenVertexArrays(1, &vao_grid1);
        glBindVertexArray(vao_grid1);

        glGenBuffers(1, &vbo_grid1);
        glBindBuffer(GL_ARRAY_BUFFER, vbo_grid1);
        glBufferData(GL_ARRAY_BUFFER, gridVertsH.size() * sizeof(glm::vec3), &gridVertsH[0], GL_STATIC_DRAW);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(0);

        //VERTICAL LINES
        glGenVertexArrays(1, &vao_grid2);
        glBindVertexArray(vao_grid2);

        glGenBuffers(1, &vbo_grid2);
        glBindBuffer(GL_ARRAY_BUFFER, vbo_grid2);
        glBufferData(GL_ARRAY_BUFFER, gridVertsV.size() * sizeof(glm::vec3), &gridVertsV[0], GL_STATIC_DRAW);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(0);
    }

    myWin.myGLHelp->handleError(" Could not create a VBO", "gl");
    shaderID = loadShaders("grid.vert.glsl", "grid.frag.glsl");
    loadedVaoVbo = 1;
}

void Object::render(glm::mat4 PV)
{
    scaleM = glm::scale(glm::mat4(), s->val_3);
    rotationM = glm::toMat4(r_quat);

    translationM = glm::translate(glm::mat4(), t->val_3);
    transLocal1M = glm::translate(glm::mat4(), -bbCenter);
    transLocal2M = glm::translate(glm::mat4(), bbCenter);
    localSpaceM = transLocal2M * rotationM * scaleM * transLocal1M;

    ModelM = translationM * localSpaceM;
    MVP = PV * ModelM;

    glUseProgram(shaderID);
    MatrixID = glGetUniformLocation(shaderID, "MVP");
    glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);

    if (mode->val_i == 0)
        glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &(MVP * bbM)[0][0]);

    isSelectedID = glGetUniformLocation(shaderID, "isSelected");
    glUniform4f(isSelectedID, highlight[0], highlight[1], highlight[2], highlight[3]);

    glLineWidth(2);
    glEnable(GL_POLYGON_OFFSET_FILL);
    glPolygonOffset(1, 0);

    // RENDER
    if (type->val_s == "grid")
    {
        glBindVertexArray(vao_grid1);
        for (int i = 0; i < gridLines_; ++i)
            glDrawArrays(GL_LINE_STRIP, gridLines_ * i, gridLines_);

        glBindVertexArray(vao_grid2);
        for (int i = 0; i < gridLines_; ++i)
            glDrawArrays(GL_LINE_STRIP, gridLines_ * i, gridLines_);
    }
}

void Object::delete_()
{
    if (type->val_s == "grid")
    {
        glUseProgram(NULL);
        glDeleteProgram(this->shaderID);
        myWin.myGLHelp->handleError("Couldnt delete shaders", "gl");

        glBindVertexArray(0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        glDeleteVertexArrays(1, &vao_grid1);
        glDeleteVertexArrays(1, &vao_grid2);

        glDisableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        glDeleteBuffers(1, &vbo_grid1);
        glDeleteBuffers(1, &vbo_grid2);
    }
}

0 个答案:

没有答案