Bonjour,

Je suis débutant en OpenGL et je travaille actuellement avec la librairie QOpenGL de Qt (OpenGL 4.6 et Qt 5.13 pour être précis).

Mon objectif est de créer une scène avec un objet texturé situé au milieu d'une skybox.

Dans un premier temps, je me suis concentré sur la création de la skybox. Je me suis basé sur l'exemple "cube" de Qt 5.13, qui permet de créer un dé à 6 faces (donc un cube texturé) auquel on peut appliquer une rotation avec la souris.

Le programme fait appel à une classe GLWidget qui affiche une fenêtre contenant la scène 3D.
Cette classe crée une instance d'une autre classe GeometryEngine, qui initialise les vertex et index buffers liés au cube, et possède une méthode réalisant le dessin du cube dans la scène.

Dans l'exemple, le vertex buffer contient 2 attributs : position et coordonnées de texture. J'ai supprimé les coordonnées de texture (les calculs de texture de la skybox sont réalisés dans les shaders) et les lignes de code permettant d'envoyer cet attribut au shaders.

Mais lorsque je tente d'exécuter mon programme, je recois les messages d'erreurs OpenGL suivants :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
Invalid VAO/VBO/pointer usage.
Array object is not active
et une fenêtre avec un écran noir.


Dans GeometryEngine.cpp:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
 
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);
}
Les erreurs apparaissent respectivement aux lignes :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
 
- program->setAttributeBuffer(vertexLocation, GL_FLOAT, offset, 3, sizeof(QVector3D));
- glDrawElements(GL_TRIANGLE_STRIP, 34, GL_UNSIGNED_SHORT, 0);
Je pense que la seconde découle de la première.

Dans GLWidget.cpp :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
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);
}
Après plusieurs recherches, j'ai vu que ces erreurs étaient dûes à l'absence de VAO, ce que je ne comprends pas car l'exemple dont je me sers n'en utilise pas (et marche parfaitement).
J'ai alors créé et lié un VAO aux vertex et index buffers avant l'appel de la méthode DrawCubeGeometry. Les erreurs ont alors disparues mais la scène affichée est toujours noire.

À cette étape, je ne comprends pas du tout l'origine du problème ni comment le résoudre.

Avez-vous déjà rencontré une situation similaire ? Sauriez-vous comment la résoudre ?

Je vous remercie !