Ошибка QOpenGL: "Неправильное использование VAO/VBO/ указателя" "Объект массива не активен"

В настоящее время я пытаюсь визуализировать скайбокс, используя библиотеку QOpenGL Qt. Для этого я попытался изменить пример "куба" QOpenGL, предоставленного Qt (я использую последнюю версию Qt 5.13).

Буферы вершин и индексов инициализируются в классе GeometryEngine, в котором вершина и индексный массив также определены. В этом примере массив вершин имеет координаты текстуры, поэтому я избавился от них и сохранил только координаты позиции, потому что каждая операция, связанная с текстурой скайбокса, будет выполняться в шейдерах.

Там также есть функция под названием initTextures в классе окна, который я изменил, чтобы загрузить текстуры 6 граней куба (хотя я не знаю, верна ли эта часть).

Я также настроил регистратор отладки OpenGL, используя этот пример: https://www.trentreed.net/blog/qt5-opengl-part-5-debug-logging/.

Когда я выполняю код, я получаю только окно с черным экраном и ничего не отображается, и следующие сообщения об ошибках: GL_INVALID_OPERATION error generated. Invalid VAO/VBO/pointer usage. а такжеGL_INVALID_OPERATION error generated. Array object is not active.

Кто-нибудь сталкивался с этой проблемой раньше и исправил ее? Потому что я не думаю, что я забыл какую-либо часть процесса рендеринга. Я только изменил входные данные и шейдеры (но я не получил ошибки от этой части).

Во-первых, я думал, что суть проблемы связана с массивом вершин и индексов, поэтому я попытался использовать только буфер вершин, повторяя вершины для каждого треугольника в массиве вершин, но я получил те же сообщения об ошибках.

Так как я не получил ошибку компиляции, я попытался найти проблему с помощью #if 0 [...] #endif на каждой функции, пока я не получил сообщений об ошибках OpenGL. Я наконец изолировал происхождение в drawCubeGeometry метод в GeometryEngine класс, где атрибут позиции отправляется шейдерам и вызывается вызов отрисовки. Кажется, есть проблема с setAttributeBuffer а также glDrawElements звонки, но я не могу понять это.

Я пытался искать решения в Интернете, но о QOpenGL задали так мало вопросов.

В GeometryEngine.cpp:

void GeometryEngine::initCubeGeometry()
{
    QVector3D vertices[] = {
        // Vertex data for face 0
        QVector3D(-1.0f, -1.0f,  1.0f),  // v0
        QVector3D( 1.0f, -1.0f,  1.0f), // v1
        QVector3D(-1.0f,  1.0f,  1.0f),  // v2
        QVector3D( 1.0f,  1.0f,  1.0f), // v3

        // Vertex data for face 1
        QVector3D( 1.0f, -1.0f,  1.0f), // v4
        QVector3D( 1.0f, -1.0f, -1.0f), // v5
        QVector3D( 1.0f,  1.0f,  1.0f),  // v6
        QVector3D( 1.0f,  1.0f, -1.0f), // v7

        // Vertex data for face 2
        QVector3D( 1.0f, -1.0f, -1.0f), // v8
        QVector3D(-1.0f, -1.0f, -1.0f),  // v9
        QVector3D( 1.0f,  1.0f, -1.0f), // v10
        QVector3D(-1.0f,  1.0f, -1.0f),  // v11

        // Vertex data for face 3
        QVector3D(-1.0f, -1.0f, -1.0f), // v12
        QVector3D(-1.0f, -1.0f,  1.0f),  // v13
        QVector3D(-1.0f,  1.0f, -1.0f), // v14
        QVector3D(-1.0f,  1.0f,  1.0f),  // v15

        // Vertex data for face 4
        QVector3D(-1.0f, -1.0f, -1.0f), // v16
        QVector3D( 1.0f, -1.0f, -1.0f), // v17
        QVector3D(-1.0f, -1.0f,  1.0f), // v18
        QVector3D( 1.0f, -1.0f,  1.0f), // v19

        // Vertex data for face 5
        QVector3D(-1.0f,  1.0f,  1.0f), // v20
        QVector3D( 1.0f,  1.0f,  1.0f), // v21
        QVector3D(-1.0f,  1.0f, -1.0f), // v22
        QVector3D( 1.0f,  1.0f, -1.0f) // v23
    };

    GLushort indices[] = {
         0,  1,  2,  3,  3,     
         4,  4,  5,  6,  7,  7, 
         8,  8,  9, 10, 11, 11, 
        12, 12, 13, 14, 15, 15, 
        16, 16, 17, 18, 19, 19, 
        20, 20, 21, 22, 23  
    };
    // Transfer vertex data to VBO 0
    arrayBuf.bind();
    arrayBuf.allocate(vertices, 24 * sizeof(QVector3D));

    // Transfer index data to VBO 1
    indexBuf.bind();
    indexBuf.allocate(indices, 34 * sizeof(GLushort));
}

void GeometryEngine::drawCubeGeometry(QOpenGLShaderProgram *program)
{

    // Tell OpenGL which VBOs to use
    arrayBuf.bind();
    indexBuf.bind();

    // Offset for position
    quintptr offset = 0;

    // Tell OpenGL programmable pipeline how to locate vertex position data
    int vertexLocation = program->attributeLocation("a_position");
    program->enableAttributeArray(vertexLocation);
    program->setAttributeBuffer(vertexLocation, GL_FLOAT, offset, 3, sizeof(QVector3D));

    // Draw cube geometry using indices from VBO 1
    glDrawElements(GL_TRIANGLE_STRIP, 34, GL_UNSIGNED_SHORT, 0);
}

GLWidget.cpp:

void GLWidget::paintGL()
{

    // Clear color and depth buffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    texture->bind();

    // Calculate model view transformation
    QMatrix4x4 matrix;
    matrix.translate(0.0, 0.0, 0.0);
    matrix.rotate(rotation);

    // Set modelview-projection matrix
    program.setUniformValue("mvp_matrix", projection * matrix);

    // Use texture unit 0 which contains cube.png
    program.setUniformValue("texture", 0);

    // Draw cube geometry
    geometries->drawCubeGeometry(&program);
}

Пока я только пытаюсь отобразить красный куб (в фрагментном шейдере), чтобы увидеть, работает ли он. Я сосредоточусь на применении текстуры позже.

0 ответов

Другие вопросы по тегам