IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

OpenGL Discussion :

Erreur avec l'outil QOpenGL de Qt : “Invalid VAO/VBO/pointer usage” “Array object is not active”


Sujet :

OpenGL

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juillet 2019
    Messages : 4
    Par défaut Erreur avec l'outil QOpenGL de Qt : “Invalid VAO/VBO/pointer usage” “Array object is not active”
    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 !

  2. #2
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 032
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 032
    Billets dans le blog
    12
    Par défaut
    Salut !

    Effectivement, les VAO sont obligatoires à partir d'OpenGL 3.x.
    Du coup, à quoi ressemble la création/initialisation de ton VAO, ainsi que son utilisation ?
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juillet 2019
    Messages : 4
    Par défaut
    Salut !

    Je crée mon VAO en tant qu'attribut de la classe GeometryEngine, et je l'initialise en même temps que les vertex et index buffers dans la méthode initCubeGeometry.
    Il s'agit d'un objet QOpenGLVertexArrayObject.

    donc

    Dans GeometryEngine.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    class GeometryEngine : protected QOpenGLFunctions
    {
       [...]
     
      private :
               void initCubeGeometry();
     
               QOpenGLBuffer arrayBuf;
               QOpenGLBuffer indexBuf;
     
               QOpenGLVertexArrayObject vao;
     
    }
    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
     
    void GeometryEngine::initCubeGeometry()
    {
        vao.create();
        vao.bind();
     
        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
     
        [...]
     
        }
     
        // 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));
    }

  4. #4
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 032
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 032
    Billets dans le blog
    12
    Par défaut
    Il manque les attributs de sommets, à ton VAO :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    program->enableAttributeArray(vertexLocation);
    program->setAttributeBuffer(vertexLocation, GL_FLOAT, offset, 3, sizeof(QVector3D));
    Un VAO enregistre les attributs de sommets et les buffers utilisés (VBOs et IBO).
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juillet 2019
    Messages : 4
    Par défaut
    Alors j'ai trouvé l'origine de mon erreur (je crois) : ma caméra était située au centre de la scène, donc à l'intérieur du cube que j'essayais d'afficher.

    Je l'ai juste déplacé (la caméra) le long de l'axe Z de manière à le visualiser correctement.

    Cependant, je ne suis pas sûr de comprendre votre solution. Comment ajouter les attributs de sommets à mon VAO ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    [...]
    program->enableAttributeArray(vertexLocation);
    program->setAttributeBuffer(vertexLocation, GL_FLOAT, offset, 3, sizeof(QVector3D));
    [...]
    Ce code est écrit dans la fonction drawCubeGeometry, juste avant l'appel à glDrawElements.

  6. #6
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 032
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 032
    Billets dans le blog
    12
    Par défaut
    Je te laisse lire cette page : https://www.khronos.org/opengl/wiki/...x_Array_Object , pour te faire une idée de ce qu'un VAO enregistre.
    Qt enregistre les attributs de sommets dans le programme shader, ce qui signifie qu'il te faut un VAO par couple programme/modèle, tout simplement.
    Le fait de refaire cette spécification des attributs de sommets à chaque frame est un gros hic au niveau des perfs : ce devrait être fait une fois pour toutes, à la création du couple programme/modèle.
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

Discussions similaires

  1. Erreur avec les outils informix
    Par nutopia dans le forum Informix
    Réponses: 4
    Dernier message: 17/02/2012, 14h20
  2. [Débutant][Conception] Erreur avec une classe interne
    Par Devil Redneck dans le forum Général Java
    Réponses: 5
    Dernier message: 11/06/2004, 15h45
  3. Erreur avec les ADO
    Par megane dans le forum Bases de données
    Réponses: 7
    Dernier message: 08/03/2004, 21h37
  4. Erreur avec WM_COMMAND (BN_CLICKED)
    Par cyberlewis dans le forum Windows
    Réponses: 2
    Dernier message: 09/02/2004, 00h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo