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 :

Vertex buffer et Index buffer Problème de rendu [OpenGL 4.x]


Sujet :

OpenGL

  1. #1
    Membre à l'essai
    Homme Profil pro
    Terminal S
    Inscrit en
    Juin 2013
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Terminal S

    Informations forums :
    Inscription : Juin 2013
    Messages : 30
    Points : 15
    Points
    15
    Par défaut Vertex buffer et Index buffer Problème de rendu
    Bonsoir, je fais un petit programme pour afficher un modèle a partir de fichier au format wavefront(.obj), et pour pouvoir afficher le modèle j'utilise les buffers (index buffer et vertex buffer) (vao vbo ebo).

    Je commence par le tout début, ce qui va contenir mes vertices jusqu’à les mettre dans un buffer.
    Je donne donc mes fonctions pour contenir mes vertices dans un tableau dynamique:
    - Le tableau dynamique marche parfaitement et se décline avec le type 'unsigned int' aussi (juste un changement de type).
    Code C : 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
     
    */ ---------- Array.h ----------*/
    typedef struct {
    	unsigned int *array;
    	int size;
    	int used;
    } ArrayUint;
     
    void ArrayUintInit(ArrayUint* a);
    void ArrayUintAdd(ArrayUint* a, unsigned int num);
    void ArrayUintFree(ArrayUint* a);
     
     
    /* ---------- Array.c ----------*/
    void ArrayGLfloatInit(ArrayGLfloat* a)
    {
    	a->size = 1;
    	a->used = 0;
    	a->array = (GLfloat *)malloc(sizeof(GLfloat));
    }
     
    void ArrayGLfloatAdd(ArrayGLfloat* a, GLfloat num)
    {
    	if(a->size == a->used)
    	{
    		a->size++;
    		a->array = (GLfloat *)realloc(a->array, a->size * sizeof(GLfloat));
    	}
    	a->array[a->used++] = num;
     
    }
     
    void ArrayGLfloatFree(ArrayGLfloat* a)
    {
    	free(a->array);
    	a->array = NULL;
    	a->used = 0;
    	a->size = 0;
    }

    Avant de donner la fonction qui charge le modèle je donne la structure d'un modèle:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    typedef struct {
    	GLuint vao;
    	GLuint vbo;
    	GLuint ebo;
     
    	GLuint shaderID;
     
    	ArrayGLfloat vertices;
    	ArrayGLfloat normals;
     
    	ArrayUint VertexIndices;
    }Model;

    Voila maintenant la fonction de chargement du modèle:
    - Pour simplifier l'utilisation des buffers je me préoccupe seulement des vertices, j'incorporerai les normales plus tard.
    Code C : 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
     
    void loadWavefront(const char* path, Model *mod)
    {
    	FILE* file = fopen(path,"r");
    	if(file == NULL)
    	{
    		printf("Error Loading file: %s\n", path);
    		ArrayGLfloatFree(&mod->normals);
    		ArrayGLfloatFree(&mod->vertices);
    		ArrayUintFree(&mod->VertexIndices);
    	}
    	else
    	{
    		while(1)
    		{
    			char line[255];
    			int str = fscanf(file, "%s", line);
    			if(str == EOF)
    				break;
     
    			if(strcmp(line, "v") ==0)
    			{
    				GLfloat vert[3];
    				fscanf(file, "%f %f %f\n", &vert[0], &vert[1], &vert[2]);
    				ArrayGLfloatAdd(&mod->vertices, vert[0]);
    				ArrayGLfloatAdd(&mod->vertices, vert[1]);
    				ArrayGLfloatAdd(&mod->vertices, vert[2]);
    			}
    			else if( strcmp(line, "vn") == 0)
    			{
    				GLfloat vert[3];
    				fscanf(file, "%f %f %f\n", &vert[0], &vert[1], &vert[2]);
    				ArrayGLfloatAdd(&mod->normals, vert[0]);
    				ArrayGLfloatAdd(&mod->normals, vert[1]);
    				ArrayGLfloatAdd(&mod->normals, vert[2]);
    			}
    			else if(strcmp(line, "f") == 0)
    			{
    				unsigned int vi[3];	//vertex indices
    				unsigned int ti[3]; // texture indices
    				unsigned int ni[3]; // normales indices
     
    				fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n",
    						&vi[0], &ti[0], &ni[0],
    						&vi[1], &ti[1], &ni[1],
    						&vi[2], &ti[2], &ni[2]);
    				ArrayUintAdd(&mod->VertexIndices, vi[0]);
    				ArrayUintAdd(&mod->VertexIndices, vi[1]);
    				ArrayUintAdd(&mod->VertexIndices, vi[2]);
    			}
    		}
     
    		fclose(file);
     
    		glGenBuffers(1, &mod->vbo);
    		glBindBuffer(GL_ARRAY_BUFFER, mod->vbo);
    		glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mod->vertices.used, mod->vertices.array, GL_STATIC_DRAW);
    		glBindBuffer(GL_ARRAY_BUFFER, 0);
     
    		glGenBuffers(1, &mod->ebo);
    		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mod->ebo);
    		glBufferData(GL_ELEMENT_ARRAY_BUFFER, mod->VertexIndices.used * sizeof(unsigned int), mod->VertexIndices.array, GL_STATIC_DRAW);
    		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
     
    		glGenVertexArrays(1, &mod->vao);
    		glBindVertexArray(mod->vao);
     
    			glEnableVertexAttribArray(0);
    			glBindBuffer(GL_ARRAY_BUFFER, mod->vbo);
    			glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
    			glBindBuffer(GL_ARRAY_BUFFER, 0);
     
     
    			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mod->ebo);
    			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
     
     
    		glBindVertexArray(0);
    		glDisableVertexAttribArray(0);
     
    	}
     
    }

    Maintenant je donne la fonction qui affiche le modèle a l'aide de l'index buffer et du buffer de vertices:
    Code C : 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
     
    void displayModel(Model *mod)
    {
    	glBindVertexArray(mod->vao);
    	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mod->ebo);
    	int size;  glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
    	glDrawElements(
    		GL_TRIANGLES,
    		size/sizeof(GLfloat),
    		GL_UNSIGNED_INT,
    		(void*) 0
    		);
    	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    	glBindVertexArray(0);
     
     
    }

    Je donne une image du résultat non attendu, qui devrai être un carré parfait:
    Nom : Capture d’écran (5).png
Affichages : 256
Taille : 126,8 Ko

    La est le problème, aucun des fichier modèle n'a marché. J'ai toujours une anomalie de ce genre (un vertex mal placé ou je ne sais quoi)
    J'ai vérifié les buffers avec gDEbugger (Application pour debugger des programme utilisant opengl) et tout les buffers contenaient les bonnes informations.
    J'en viens donc a demander de l'aide.

    Je donne aussi le fichier du modèle et les fichiers shader utilisés:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    # Blender v2.71 (sub 0) OBJ File: ''
    # www.blender.org
    o Plane_Plane.001
    v -1.000000 0.000000 -0.000059
    v 1.000000 0.000000 -0.000059
    v -1.000000 2.000000 0.000059
    v 1.000000 2.000000 0.000059
    vn 0.000000 -0.000100 1.000000
    s off
    f 2/0/1 4/0/1 3/0/1
    f 1/0/1 2/0/1 3/0/1
    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
     
    /* ---------- VertexShader.vs ----------*/
    #version 400
     
    uniform mat4 PerspectiveMatrix;
    uniform mat4 CameraMatrix;
     
    in vec3 vp;
     
    mat4 MVP;
     
    void main() {
    	MVP = PerspectiveMatrix * CameraMatrix;
    	gl_Position =  MVP  *  vec4(vp, 1);
    }
     
    /* ---------- FragmentShader.fs ----------*/
    #version 400
     
    out vec4 frag_colour;
     
    void main() {
      frag_colour = vec4 (0.5, 0.5, 0.5, 1.0);
     }
    Merci d'avoir lu ce long texte ^^ et de porter attention a mon problème.

  2. #2
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 031
    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 031
    Points : 11 388
    Points
    11 388
    Billets dans le blog
    11
    Par défaut
    Tu fais du C ou C++ ?
    Parce qu'en C++ tu peux jeter tes classes d'array pour utiliser des std::vector.

    Ensuite, as-tu vérifié le contenu de tes buffers après avoir lu ton fichier?

    Ensuite, normalement avec les VAO tu n'as pas besoin de binder d'autres buffers lors du dessin.
    Tu as donc la phase d'initialisation :
    - Bind du VAO
    - Bind du VBO
    - Bind du IBO
    - Unbind du VAO

    et la phase de dessin
    - Bind du VAO
    - Dessin (glDrawElements, glDrawArrays, ...)
    - Unbind du VAO
    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
    Terminal S
    Inscrit en
    Juin 2013
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Terminal S

    Informations forums :
    Inscription : Juin 2013
    Messages : 30
    Points : 15
    Points
    15
    Par défaut
    Je programme en C ( c'est pour cela que j'ai eu besoin de créer un conteneur dynamique).
    J'ai bien vérifié les buffers et les conteneurs après la lecture du fichier. Tout y est.
    J'ai vérifié les buffers a l'aide de gDEBugger.
    Toutes les informations sont correctes et présentes.

    Mais je pense que mon problème viendrait de l'utilisation des différentes fonctions de création des buffers et des fonctions d'affichage.

  4. #4
    Membre à l'essai
    Homme Profil pro
    Terminal S
    Inscrit en
    Juin 2013
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Terminal S

    Informations forums :
    Inscription : Juin 2013
    Messages : 30
    Points : 15
    Points
    15
    Par défaut
    Après une recherche, j'ai trouvé que Blender indexait à partir de 1 et non 0 comme OpenGL.
    Le problème étant que Opengl chargeait des vertices en dehors de mon tableau et j'obtenais pas la figure désirée.

    J'ai donc soustrait 1 à chaque indice avant de les mettre dans le tableau dynamique.

    Je redonne le code:
    Code C : 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
     
    else if(strcmp(line, "f") == 0)
    			{
    				unsigned int vi[3]; //vertex indices
    				unsigned int ti[3]; // texture indices
    				unsigned int ni[3]; // normales indices
     
    				fscanf(file, "%i/%i/%i %i/%i/%i %i/%i/%i\n",
    						&vi[0], &ti[0], &ni[0],
    						&vi[1], &ti[1], &ni[1],
    						&vi[2], &ti[2], &ni[2]
    						);
     
    				/* --- CHANGEMENT --- */
    				ArrayUintAdd(&mod->VertexIndices, vi[0]-1); // -1 car les indices commence a 0 pour Opengl
    				ArrayUintAdd(&mod->VertexIndices, vi[1]-1); // et blender export en démarrent par 1
    				ArrayUintAdd(&mod->VertexIndices, vi[2]-1);
    				/* --- --- */
    			}

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

Discussions similaires

  1. Index Buffer avec offset
    Par spiner900 dans le forum OpenGL
    Réponses: 4
    Dernier message: 18/03/2014, 00h21
  2. Buffer d'ecriture fichier problème
    Par xokami35x dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 14/09/2009, 20h40
  3. Normal et Index Buffer
    Par countag dans le forum DirectX
    Réponses: 5
    Dernier message: 30/11/2008, 18h00
  4. [VBO]Pb avec un Index Buffer
    Par sisoft93 dans le forum OpenGL
    Réponses: 0
    Dernier message: 06/02/2008, 05h23
  5. question sur les vertex buffer et index buffer
    Par airseb dans le forum DirectX
    Réponses: 9
    Dernier message: 25/08/2003, 02h38

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