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 :

OpenGL VBO et shaders : rien ne s'affiche


Sujet :

OpenGL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Août 2007
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2007
    Messages : 61
    Par défaut OpenGL VBO et shaders : rien ne s'affiche
    Bonjour à tous,

    J'ai déjà fait quelques programmes avec OpenGL 1.2, et maintenant je dois me mettre à jour avec les dernières nouveautés. J'ai donc écrit un bout de code qui génère un VBO à partir d'un obj et l'affiche grâce à un shader. L'écran restant toujours noir, j'ai simplifié au maximum mon code, mais rien ne s'affiche encore.

    J'aurai donc besoin de votre aide, car je suis complétement bloquée, je ne vois pas où est le problème. Lorsque j'appelle glGetError(), il me retourne bien 0.

    Voici un extrait du code où il me semble l'erreur doit se trouver. Je précise que pour l'instant il n'y a aucune camera et donc de gestion des matrices projection et view. Merci d'avance pour l'aide précieuse que vous pourrez m'apporter.

    pour créer le VBO :
    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
     
    GLuint Renderer::makeBuffer(GLenum target, const void *buffer_data)
    {
        GLsizei buffer_size = sizeof(buffer_data);
     
        GLuint buffer;
        glGenBuffers(1, &buffer);
        glBindBuffer(target, buffer);
        glBufferData(target, buffer_size, buffer_data, GL_STATIC_DRAW);
        return buffer;
    }
     
    static const GLfloat vertex_data[] = {
                 1.0f, -1.0f, -1.0f, 1.0f,
                -1.0f, -1.0f, -1.0f, 1.0f,
                -1.0f,  1.0f, -1.0f, 1.0f,
                1.0f,  1.0f, -1.0f, 1.0f
            };
    this->m_infosRendu.vertex_buffer = myRenderer->makeBuffer(GL_ARRAY_BUFFER, vertex_data);
    static const GLushort element_data[] = {0, 1, 2, 2, 3, 0};
    this->m_infosRendu.element_buffer = myRenderer->makeBuffer(GL_ELEMENT_ARRAY_BUFFER, element_data);
    L'affichage :
    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
     
    void Renderer::drawObjet(Geometry *objet)
    {
            glUseProgram(m_infos_rendu.program);
     
            glm::vec3 couleur = glm::vec3(1.0, 0.0, 0.0);
            glVertexAttrib3fv(glGetAttribLocation(m_infos_rendu.program, "Color"), &couleur[0]);
     
            glBindBuffer(GL_ARRAY_BUFFER, objet->getVertexBuffer());
     
            glEnableVertexAttribArray(m_infos_rendu.in.position);
            glVertexAttribPointer(m_infos_rendu.in.position, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, (void*)0);
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, objet->getElementBuffer());
            glDrawElements(GL_TRIANGLES, objet->getVertexCount(), GL_UNSIGNED_SHORT, (void*)0);
     
            glDisableVertexAttribArray(m_infos_rendu.in.position);
     
            SDL_GL_SwapBuffers();
    }
    le vertex shader :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    attribute vec4 Position;
    attribute vec3 Color;
     
    varying vec3 v_Color;
     
    void main()
    {
        gl_Position = Position;
        v_Color = Color.xyz;
    }
    le fragment shader
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    varying vec3 v_Color;
     
    void main()
    {
         gl_FragColor = vec4(v_Color,1.0);
     
    }

  2. #2
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Août 2007
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2007
    Messages : 61
    Par défaut
    Je viens d'avoir la réponse sur gamedev où j'ai posté en même temps étant un peu pressée. L'erreur venait du sizeof(buffer_data) dans la fonction make_buffer qui revoit la taille du pointeur, pas du tableau. Il faut donc ajouter un paramètre à cette fonction qui contient la taille du tableau et ça marche.

  3. #3
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Août 2007
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2007
    Messages : 61
    Par défaut
    Bon en fait le problème n'est pas réglé car quand je veux charger un fichier obj : oh un bel écran noir, ça faisait longtemps...

    J'ai modifié mon code pour prendre en compte les données contenues dans un fichier obj et ça ne marche plus. Pour débugger, j'ai crée un obj décrivant le même carré que celui qui était déclaré "en dur" dans le code, mais au lieu d'avoir un écran rouge, rien ne s'affiche. J'ai vérifié les données chargées depuis le obj, je me retrouve avec des tableaux contenant exactement la même chose que ceux déclarés "en dur" et pourtant... J'ai modifié dans tous les sens, pas moyen d'arriver à quelque chose, donc si vous avez une idée qui pourrait me faire avancer ça m'aiderait beaucoup.

    Voici le code modifié :

    création des VBO :

    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
     
    GLuint Renderer::makeBuffer(GLenum target, const void *buffer_data, size_t data_size)
    {
        GLuint buffer;
        glGenBuffers(1, &buffer);
        glBindBuffer(target, buffer);
        glBufferData(target, data_size, buffer_data, GL_STATIC_DRAW);
        return buffer;
    }
     
    typedef struct {
        glm::vec4 position;
    }Trimesh_vertex;
     
    std::vector<Trimesh_vertex> *attributes = new std::vector<Trimesh_vertex>(objData->vertexCount);
    for(int iVertex = 0; iVertex < this->m_vertexCount; iVertex ++)
    {
        attributes->at(iVertex).position[0] = objData->vertexList[iVertex]->e[0];
        attributes->at(iVertex).position[1] = objData->vertexList[iVertex]->e[1];
        attributes->at(iVertex).position[2] = objData->vertexList[iVertex]->e[2];
        attributes->at(iVertex).position[3] = 1.0f;
    }
     
    size_t tailleTableau = sizeof(glm::vec4) * objData->vertexCount;
    this->m_infosRendu.vertex_buffer = myRenderer->makeBuffer(GL_ARRAY_BUFFER, attributes, tailleTableau);
     
    std::vector<glm::gtc::type_precision::u16vec3> *triBuf = new std::vector<glm::gtc::type_precision::u16vec3>(objData->faceCount * 3);
    for(int iFace = 0; iFace < objData->faceCount; iFace++)
    {
           triBuf->at(iFace).x = objData->faceList[iFace]->vertex_index[0];
           triBuf->at(iFace).y = objData->faceList[iFace]->vertex_index[1];
           triBuf->at(iFace).z = objData->faceList[iFace]->vertex_index[2];
    }
    tailleTableau = objData->faceCount * 3 * sizeof(GLushort);
    this->m_infosRendu.element_buffer = myRenderer->makeBuffer(GL_ELEMENT_ARRAY_BUFFER, triBuf, tailleTableau);
    L'affichage :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    glUseProgram(m_infos_rendu.program);
     
    glm::vec3 couleur = glm::vec3(1.0, 0.0, 0.0);
    glVertexAttrib3fv(glGetAttribLocation(m_infos_rendu.program, "Color"), &couleur[0]);
     
    glBindBuffer(GL_ARRAY_BUFFER, objet->getVertexBuffer());
    glEnableVertexAttribArray(m_infos_rendu.in.position);
    glVertexAttribPointer(m_infos_rendu.in.position, 4, GL_FLOAT, GL_FALSE, 0, (void*)0);
     
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, objet->getElementBuffer());
    glDrawElements(GL_TRIANGLES, objet->getTriangleCount() * 3, GL_UNSIGNED_SHORT, (void*)0);
     
    SDL_GL_SwapBuffers();
    Au cas où, ce code me permet d'avoir un bel écran rouge, sans toucher une ligne de la fonction d'affichage :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    static const GLfloat vertex_data[] = {
                 1.0f, -1.0f, -1.0f, 1.0f,
                -1.0f, -1.0f, -1.0f, 1.0f,
                -1.0f, 1.0f, -1.0f, 1.0f,
                1.0f, 1.0f, -1.0f, 1.0f
            };
    this->m_infosRendu.vertex_buffer = myRenderer->makeBuffer(GL_ARRAY_BUFFER, vertex_data, sizeof(vertex_data));
    static const GLushort element_data[] = {0, 1, 2, 2, 3, 0};
    this->m_infosRendu.element_buffer = myRenderer->makeBuffer(GL_ELEMENT_ARRAY_BUFFER, element_data, sizeof(element_data));

  4. #4
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Août 2007
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2007
    Messages : 61
    Par défaut
    Alors je vais me faire vanner parce que j'écris moi même les questions et les réponses, mais je voulais quand même donner la solution du second problème.

    En fait, le problème venait de l'utilisation de vector ! J'ai modifié le tableau qui était un std::vector de structure qui me sert à créer les VBO en un simple tableau de structure dont j'alloue la mémoire avec un bon vieux malloc... et ça marche !

    Je comprend pas que ça empêche l'affichage. Une fois trouvée l'erreur, j'ai vérifié, c'est bien le seul truc qu'il me semble avoir changé. Quelqu'un a-t-il déjà pu crér des vbo en passant à la fonction glBufferData des vector ?

  5. #5
    Membre éclairé Avatar de AuraHxC
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2006
    Messages : 652
    Par défaut
    Utiliser des vector fonctionne très bien en général.
    Il suffit de passer le vector comme un tableau C, pour cela il suffit de chercher dans la FAQ C++ de developpez.com => http://cpp.developpez.com/faq/cpp/in...teneurs_avec_c

    Tu pourras constater que pour passer un vector a une fonction qui attend un tableau type C, il suffit de passer &v[0], v étant ton vector.

  6. #6
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Août 2007
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2007
    Messages : 61
    Par défaut
    C'est pourtant bien ce que je faisais. Bon ça marche avec mes tableaux alloués avec un malloc, donc je garde comme ça. Mais je note que c'est (sensé) marcher aussi avec des vector. Merci

    Là rien à voir, mais je ne comprends pas pourquoi glGetAttribLocation me retourne -1 pour un attribut qui est bien déclaré dans le shader...Ça marche pour un attribut, mais pas pour l'autre ???

    Si je fais ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    m_infos_rendu.attribute.normal = glGetAttribLocation(m_infos_rendu.program, "Normal");
    -> m_infos_rendu.attribute.normal vaut -1 et j'ai une erreur OpenGL 1281

    Si je fais ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    m_infos_rendu.attribute.normal = 1;
        glBindAttribLocation(m_infos_rendu.program, m_infos_rendu.attribute.normal, "Normal");
    plus d'erreur. Mais après avoir affecté moi-même un index à l'attribut Normal du vertex shader, glGetAttribLocation me renvoie toujours -1 ???

    J'ai loupé quelque chose ? Parce que d'après la doc, après avoir utilisé glBindAttribLocation, glGetAttribLocation devrait renvoyer la valeur définie, non ?

Discussions similaires

  1. opengl vbo shader
    Par yabb85 dans le forum OpenGL
    Réponses: 7
    Dernier message: 14/06/2011, 21h57
  2. [VBO] Rien ne s'affiche avec tableau d'index
    Par -eXa- dans le forum OpenGL
    Réponses: 1
    Dernier message: 28/02/2009, 20h32
  3. [CKEditor] Rien ne s'affiche
    Par Seth77 dans le forum Bibliothèques & Frameworks
    Réponses: 13
    Dernier message: 28/04/2006, 13h40
  4. [Eclipse3.1] Plus rien ne s'affiche dans ma console !
    Par tnodev dans le forum Eclipse Java
    Réponses: 4
    Dernier message: 12/10/2005, 12h05
  5. [JAVASCRIPT] Rien ne s'affiche lors d'une pause
    Par stephane93fr dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 26/05/2005, 15h38

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