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 :

Comportement bizarre d'une méthode


Sujet :

OpenGL

  1. #1
    Membre actif
    Avatar de guatto
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2014
    Messages : 179
    Points : 226
    Points
    226
    Par défaut Comportement bizarre d'une méthode
    Bonsoir tout le monde,

    j'ai un petit souci concernant le passage d'un tableau en paramètre dans une méthode pour un usage externe (en dehors de la méthode main), le contenu de cette méthode se comporte bizarrement, et j'avoue que ça me laisse songeur si je dois poster ce problème dans la rubrique (OpenGL) ou (C++ débutant) vu que je me sens vraiment impliqué par la seconde. Voici le code pour que vous puissiez bien comprendre :

    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
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
     
    void methodeA(const float (&vertices)[6])
    {
    	GLuint vao;
        GLuint vbo;
        glGenVertexArrays(1, &vao);
        glBindVertexArray(vao);
     
        glGenBuffers(1, &vbo);
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
     
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(0);
     
        glBindVertexArray(0);
    }
     
     
    void methodeB()
    {
        const float vertices[]={0.0f,  0.5f,0.5f, -0.5f,-0.5f, -0.5f};
     
        GLuint vao;
        GLuint vbo;
        glGenVertexArrays(1, &vao);
        glBindVertexArray(vao);
     
        glGenBuffers(1, &vbo);
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
     
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(0);
     
        glBindVertexArray(0);
    }
     
     
    void methodeC(const float vertices[])
    {
    	GLuint vao;
        GLuint vbo;
        glGenVertexArrays(1, &vao);
        glBindVertexArray(vao);
     
        glGenBuffers(1, &vbo);
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
     
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(0);
     
        glBindVertexArray(0);
    }
     
     
    void methodeD(const float* vertices)
    {
    	GLuint vao;
        GLuint vbo;
        glGenVertexArrays(1, &vao);
        glBindVertexArray(vao);
     
        glGenBuffers(1, &vbo);
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
     
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(0);
     
        glBindVertexArray(0);
    }
     
    int main()
    {
     
        /************************CODE**********************************/
     
         const float vertices[]={0.0f,  0.5f,0.5f, -0.5f,-0.5f, -0.5f};
     
         methodeA(vertices);  //Fonctionne correctement (passage par référence)
         methodeB();          //Fonctionne correctement (vertices à l'intérieur de la méthode)
         methodeC(vertices);  //Ne fonctionne pas (passage par copie tableau normal array[])
         methodeD(vertices);  //Ne fonctionne pas (passage par copie tableau pointeur array*)
     
        /************************CODE***********************************/
     
    	return 0;
    }
    Pour mieux comprendre mon problème, j'ai essayé 4 méthodes pour gérer les (VAOs/VBOs) et dessiner un triangle, seul la 1ere et la 2eme ont fonctionné, et j'ignore pourquoi ce n'est pas le cas deux autres. qu'est ce qui ne va pas d'après vous avec ces deux dernières ? Merci pour votre aide

  2. #2
    Expert éminent sénior

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

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 045
    Points : 11 368
    Points
    11 368
    Billets dans le blog
    10
    Par défaut
    Salut!

    Pour commencer, en C++ on n'utilisera pas les tableaux statiques (ou dynamiques) du C.
    On utilisera std::array pour les tableaux statiques (ou std::vector pour les tableaux dynamiques), ce sont des classes qui facilitent plusieurs choses, et l'une de ces choses est leur passage en tant que paramètre.

    Ensuite, tes méthodes C et D sont en fait la même chose, car un tableau statique C est passé en paramètre d'une fonction en tant que pointeur, et ce que tu écrives void foo(const float p[]), void foo(const float p[10]) ou void foo(const float * p).
    Et ton problème se situe là, en fait.
    Car sizeof(p) renvoie alors la taille d'un pointeur, qui vaut 4 sur un programme compilé en 32 bits, et 8 sur un programme compilé en 64bits.
    Du coup tu ne copies pas toutes les données de ton buffer, mais uniquement les 4 (ou 8) premiers octets (ce qui, tu l'auras remarqué, ne correspond pas du tout à la taille de ton buffer).

    Donc, au final, j'utiliserais un équivalent de ta méthode A, avec un std::vector (parce que généralement on ne connait pas à l'avance la taille du buffer) :
    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
    #include <vector>
    // Les includes OpenGL que tu utilises
     
    GLuint prepareVbo(std::vector<float> const & vertices)
    {
      // Remarque que j'initialise le VBO en dehors du VAO, c'est uniquement parce que je trouve cela plus propre.
      GLuint vbo;
      glGenBuffers(1, &vbo);
      glBindBuffer(GL_ARRAY_BUFFER, vbo);
      glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STATIC_DRAW);
      glBindBuffer(GL_ARRAY_BUFFER, 0);
      return vbo;
    }
     
    GLuint prepareVao(GLuint vbo)
    {
      // Là, dans le code d'initialisation du VAO, on ne trouve donc que ce qui sert à initialiser le VAO.
      GLuint vao;
      glGenVertexArrays(1, &vao);
      glBindVertexArray(vao);
      glBindBuffer(GL_ARRAY_BUFFER, vbo);
      glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
      glEnableVertexAttribArray(0); 
      glBindVertexArray(0);
      return vao;
    }
     
    int main(int argc, char const * argv[])
    {
      // Initialisation
      std::vector<float> vertices
      {
        {
          0.0f,  0.5f,
          0.5f, -0.5f,
          -0.5f, -0.5f
        }
      };
      GLuint vbo = prepareVbo(vertices);
      GLuint vao = prepareVao(vbo);
     
      //
      // ... Rendu ...
      //
     
      // Nettoyage (que tu ne pouvais pas avoir dans ton code, ce qui était pour le moins sale.)
      glDeleteVertexArrays(1, &vao);
      glDeleteBuffers(1, &vbo);
     
      return 0;
    }
    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 actif
    Avatar de guatto
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2014
    Messages : 179
    Points : 226
    Points
    226
    Par défaut
    Merci dragonjoker59, c'est en effet la solution idéale.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comportement bizarre d'une séquence
    Par al85 dans le forum Administration
    Réponses: 5
    Dernier message: 11/09/2009, 23h46
  2. Réponses: 6
    Dernier message: 17/06/2009, 16h11
  3. Réponses: 3
    Dernier message: 10/04/2008, 16h06
  4. Erreur bizarre sur une méthode
    Par mhamedbj dans le forum Servlets/JSP
    Réponses: 4
    Dernier message: 13/03/2008, 14h58
  5. [Sybase] Comportement bizarre d'une table
    Par sdozias dans le forum Sybase
    Réponses: 4
    Dernier message: 03/02/2004, 11h39

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