顶点缓冲区对象 -> 分段错误

Posted

技术标签:

【中文标题】顶点缓冲区对象 -> 分段错误【英文标题】:Vertex Buffer Object -> Segmentation Fault 【发布时间】:2014-03-04 02:44:36 【问题描述】:

我一直在开发 3D 创作者,但由于无法使用 VBO 绘图,因此我仍停留在最初阶段。

这是我的一段 glwidget.cpp 代码,所有对象都在其中绘制

void GLWidget::initializeGL()

    #define PROGRAM_VERTEX_ATTRIBUTE 0
    #define PROGRAM_NORMALS_ATTRIBUTE 1

    //glEnable(GL_DEPTH_TEST);
    //glEnable(GL_CULL_FACE);


    vShader= new QGLShader (QGLShader::Vertex, this);
    vShader->compileSourceFile("../src/shaders/editorVshader.glsl");

    fShader= new QGLShader (QGLShader::Fragment, this);
    fShader->compileSourceFile("../src/shaders/editorFshader.glsl");

    editor= new QGLShaderProgram (this);
    editor->addShader(vShader);
    editor->addShader(fShader);
    editor->bindAttributeLocation("vertices", PROGRAM_VERTEX_ATTRIBUTE);
    editor->bindAttributeLocation("normals", PROGRAM_NORMALS_ATTRIBUTE);
    editor->link();
    editor->bind();


void GLWidget::paintGL()

    glClearColor(0.4765625, 0.54296875, 0.6171875, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    /*
    glLoadIdentity();
    glTranslatef(0.0f, 0.0f, -10.0f);
    */

    editor->setUniformValue("projectMatrix", controller->getProjectionMatrix());
    editor->setUniformValue("viewMatrix", controller->getViewMatrix());


    /** Ahora para las operaciones especificas de cada objeto **/

    for (int i=0; i<Objects.size(); i++)
    
        Objects[i].modelmatrix.scale(1.0, 1.0, 1.0);
        Objects[i].modelmatrix.rotate(1.0, 0.0, 0.0, 1.0);
        editor->setUniformValue("modelMatrix", Objects.at(i).modelmatrix);

        glEnableClientState(GL_VERTEX_ARRAY);
        Objects[i].vertexbuffer->bind();
        glVertexPointer(3, GL_FLOAT, 0, Objects.at(i).indexed_vertices.data());
        editor->enableAttributeArray("vertices");
        editor->setAttributeBuffer("vertices", GL_FLOAT, 0, Objects[i].indexed_vertices.size() * sizeof(vertex)); // (PROGRAM_VERTEX_ATTRIBUTE, Objects[i].vertices.data());
    /*
        Objects[i].normalbuffer.bind();
        //glVertexPointer(3, GL_FLOAT, 3, Objects.at(i).indexed_normals.data());
        glEnableClientState(GL_NORMAL_ARRAY);
        editor->enableAttributeArray(PROGRAM_NORMALS_ATTRIBUTE);
        editor->setAttributeBuffer (PROGRAM_NORMALS_ATTRIBUTE, GL_FLOAT, 0, Objects[i].indexed_normals.size() * sizeof(vertex));*/

        //glDrawArrays(GL_QUADS, 0, Objects[i].vertices.size());
        Objects[i].elementbuffer->bind();
        glDrawElements(GL_QUADS, Objects[i].indices.size(), GL_UNSIGNED_SHORT, (void*)0);
    

它在尝试执行 glDrawElements 指令时爆炸。我一直在追查问题,但我找不到问题所在。我什至怀疑在 Qt 中使用 QGLBuffer 的正确方法。谁能帮帮我?

【问题讨论】:

它们在我创建对象时绑定,让我也发布... 【参考方案1】:

我解决了。问题是我在 setAttributeBuffer 指令中使用的“tuplasize”。

原来是

Objects[i].indexed_vertices.size() * sizeof(vertex)

现在我把它改成 3 并开始传递法线作为顶点,结果代码是:

void GLWidget::paintGL()

    glClearColor(0.4765625, 0.54296875, 0.6171875, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    /*
    glLoadIdentity();
    glTranslatef(0.0f, 0.0f, -10.0f);
    */

    editor->setUniformValue("projectMatrix", controller->getProjectionMatrix());
    editor->setUniformValue("viewMatrix", controller->getViewMatrix());


    /** Ahora para las operaciones especificas de cada objeto **/

    for (int i=0; i<Objects.size(); i++)
    
        Objects[i].modelmatrix.scale(1.0, 1.0, 1.0);
        Objects[i].modelmatrix.rotate(1.0, 0.0, 0.0, 1.0);
        editor->setUniformValue("modelMatrix", Objects.at(i).modelmatrix);

        glEnableClientState(GL_VERTEX_ARRAY);
        editor->enableAttributeArray("vertices");
        Objects[i].vertexbuffer->bind();
        //glVertexPointer(3, GL_FLOAT, 0, Objects.at(i).indexed_vertices.data());
        editor->setAttributeBuffer("vertices", GL_FLOAT, 0, 3); // (PROGRAM_VERTEX_ATTRIBUTE, Objects[i].vertices.data());
        //glDisableClientState(GL_VERTEX_ARRAY);

        //glEnableClientState(GL_NORMAL_ARRAY);
        editor->enableAttributeArray("normals");
        Objects[i].normalbuffer->bind();
        //glVertexPointer(3, GL_FLOAT, 3, Objects.at(i).indexed_normals.data());
        editor->setAttributeBuffer ("normals", GL_FLOAT, 0, 3);
        glDisableClientState(GL_VERTEX_ARRAY);

        //glDrawArrays(GL_QUADS, 0, Objects[i].vertices.size());
        Objects[i].elementbuffer->bind();
        glDrawElements(GL_QUADS, Objects[i].indices.size(), GL_UNSIGNED_SHORT, (void*)0);
    

这可以标记为已解决。

【讨论】:

以上是关于顶点缓冲区对象 -> 分段错误的主要内容,如果未能解决你的问题,请参考以下文章

Swizzling 顶点数组、顶点缓冲区对象和着色器

绑定到“顶点数组对象”后,我应该删除“顶点缓冲区对象”吗?

具有多个缓冲区的片段着色器颜色错误

带着色器的顶点缓冲区对象/顶点数组对象

OpenGL复制顶点缓冲区对象

在两个不同的顶点数组对象中使用顶点缓冲区