Qt 结合顶点数组对象和顶点缓冲区&;索引缓冲区

Qt 结合顶点数组对象和顶点缓冲区&;索引缓冲区,qt,opengl,Qt,Opengl,我正在尝试使用Qt将顶点数组对象与顶点缓冲区&索引缓冲区结合起来 以下代码将VAO和VBO结合在一起,可以完美地工作: // Create buffers void Tile::setupBuffers() { vbo.create(); vbo.bind(); vbo.setUsagePattern(QOpenGLBuffer::StaticDraw); vbo.allocate(vertices.constData(), vertices.size() * s

我正在尝试使用Qt将顶点数组对象与顶点缓冲区&索引缓冲区结合起来

以下代码将VAO和VBO结合在一起,可以完美地工作:

// Create buffers
void Tile::setupBuffers() {
    vbo.create();
    vbo.bind();
    vbo.setUsagePattern(QOpenGLBuffer::StaticDraw);
    vbo.allocate(vertices.constData(), vertices.size() * sizeof(QVector3D));
    vbo.release();

    vao.create();

    shaderProgram->bind();
    vao.bind();
        vbo.bind();
        shaderProgram->enableAttributeArray(0);
        shaderProgram->setAttributeBuffer(positionLocation, GL_FLOAT, 0, 3, 0);    
    vao.release();

    shaderProgram->disableAttributeArray(0);
    vbo.release();
    shaderProgram->release();
}

// Draw triangle    
void Tile::draw() {
    shaderProgram->bind();
    vao.bind();

    glDrawArrays(GL_TRIANGLES, 0, 3);

    vao.release();
    shaderProgram->release();
}
当我现在尝试添加索引缓冲区时,除了清晰的颜色之外,什么都不会被绘制。代码如下:

// Create buffers
void Tile::setupBuffers() {
    vbo.create();
    vbo.bind();
    vbo.setUsagePattern(QOpenGLBuffer::StaticDraw);
    vbo.allocate(vertices.constData(), vertices.size() * sizeof(QVector3D));
    vbo.release();

    ibo.create();
    ibo.bind();
    ibo.setUsagePattern(QOpenGLBuffer::StaticDraw);
    ibo.allocate(indices.constData(), indices.size() * sizeof(GLushort));
    ibo.release();

    vao.create();

    shaderProgram->bind();
    vao.bind();
        vbo.bind();
        shaderProgram->enableAttributeArray(0);
        shaderProgram->setAttributeBuffer(positionLocation, GL_FLOAT, 0, 3, 0);

        ibo.bind();
    vao.release();

    shaderProgram->disableAttributeArray(0);
    vbo.release();
    ibo.release();
    shaderProgram->release();
}

void Tile::draw() {
    shaderProgram->bind();
    vao.bind();

    glDrawElements(GL_TRIANGLES, 3, GL_FLOAT, 0);

    vao.release();
    shaderProgram->release();
}
以下是我的顶点向量和索引向量的内容:

vertices = {
    QVector3D(1.0f, -1.0f, 0.0f),
    QVector3D(1.0f, 1.0f, 0.0f),
    QVector3D(-1.0f, -1.0f, 0.0f)
};

indices = {
     0, 1, 2
};
我假设在第二个代码块中绑定VAO/VBO/IBO的顺序是错误的,我只是不知道如何正确地完成。感谢您的帮助

您的索引是短的,不是浮动的。您应该得到一个
GL\u INVALID\u ENUM
错误;您应该始终检查总账错误

另外,
shaderProgram->disableAttributeArray(0)完全没有必要。启用/禁用状态是VAO的一部分(相反,Qt的愚蠢包装器)。禁用该属性不会更改VAO,因为您解除了它的绑定。而且你也不想禁用它

最后一点是:

这两个函数的第一个参数应该相同。它们可能是,所以这更像是一个良性缺陷。但这仍然是错误的

您的索引是短的,不是浮动的。您应该得到一个
GL\u INVALID\u ENUM
错误;您应该始终检查总账错误

另外,
shaderProgram->disableAttributeArray(0)完全没有必要。启用/禁用状态是VAO的一部分(相反,Qt的愚蠢包装器)。禁用该属性不会更改VAO,因为您解除了它的绑定。而且你也不想禁用它

最后一点是:


这两个函数的第一个参数应该相同。它们可能是,所以这更像是一个良性缺陷。但这仍然是错误的。

这里面有实际的OpenGL吗,或者你只是在使用某种包装器来完成所有这些吗?我使用的是Qt提供的包装器:。。。哇!Qt的包装器是垃圾。我说不出更糟的是什么:他们使
setAttributeBuffer
成为与顶点状态完全无关的类型的成员,或者他们甚至懒得让您直接将缓冲区对象传递给它,也就是说。我印象深刻;把事情搞砸需要付出真正的努力。@Nicolas:是的,不幸的是
QOpenGLShaderProgram
试图通过提供方便的位置查找方法+顶点缓冲区规范来“太聪明”一点。(它还有许多其他缺点,但我们现在就不要做了)。在那里使用这些方法没有任何意义。奥托,我明白了为什么没有一个“更好”的地方来放置它们——我想到了VAO,但GL2或GLES2中没有VAO,而且
QOGLSP
正如你在
QOGLVAO
之前所想象的那样:-\这里面有没有真正的OpenGL,或者你只是在使用某种包装器来完成所有这些?我使用的是Qt提供的包装器:。。。哇!Qt的包装器是垃圾。我说不出更糟的是什么:他们使
setAttributeBuffer
成为与顶点状态完全无关的类型的成员,或者他们甚至懒得让您直接将缓冲区对象传递给它,也就是说。我印象深刻;把事情搞砸需要付出真正的努力。@Nicolas:是的,不幸的是
QOpenGLShaderProgram
试图通过提供方便的位置查找方法+顶点缓冲区规范来“太聪明”一点。(它还有许多其他缺点,但我们现在就不要做了)。在那里使用这些方法没有任何意义。奥托,我明白了为什么没有一个“更好”的地方来放置它们——我想到了VAO,但GL2或GLES2中没有VAO,而且
QOGLSP
正如你在
QOGLVAO
之前所想象的那样:-\谢谢,现在画好了。如果我不必使用Qt,我就不会了,你可以肯定。@vigilanum:你不必使用Qt的包装器。您可以使用Qt创建窗口,并使用直接的OpenGL调用对其进行渲染。我必须这样做,因为赋值规定了这一点。@Vigilium在最基本的级别上,Qt为您提供解析的函数指针,指向封装在普通方法中的GL。你不需要使用任何更高层次的抽象,除非作业明确要求。谢谢,现在绘图工作正常了。如果我不必使用Qt,我就不会了,你可以肯定。@vigilanum:你不必使用Qt的包装器。您可以使用Qt创建窗口,并使用直接的OpenGL调用对其进行渲染。我必须这样做,因为赋值规定了这一点。@Vigilium在最基本的级别上,Qt为您提供解析的函数指针,指向封装在普通方法中的GL。您不需要使用任何更高级别的抽象,除非任务明确规定了这一点。
glDrawElements(GL_TRIANGLES, 3, GL_FLOAT, 0);
shaderProgram->enableAttributeArray(0);
shaderProgram->setAttributeBuffer(positionLocation, GL_FLOAT, 0, 3, 0);