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 :
et une fenêtre avec un écran noir.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2Invalid VAO/VBO/pointer usage. Array object is not active
Dans GeometryEngine.cpp:
Les erreurs apparaissent respectivement aux lignes :
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); }
Je pense que la seconde découle de la première.
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);
Dans GLWidget.cpp :
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).
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); }
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 !
Partager