Je n'ai testé que les VBOS pour l'instant, voilà l'exemple complet qui fonctionne (je travaille en c++, mais il n'y a pas grande différence avec le C, ici) :
Déclarations :
Initialisations (avant affichage) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 float * _vertex; // Tableau de sommets. float * _normals; // Tableau de normales. GLuint * _indices; // Tableau de faces (indices de sommets). float * _texCoord; // Tableau de coordonnees de textures. GLint _nbVertex; // Nombre de sommets. long _nbFacets; // Nombre de faces. int _nbVertexPerFacet; // Nombre de vertex par faces (3 ou 4 dans mon cas). GLuint _vbos[2]; // Identifiants des 2 vbos 1 array buffer pour vertex + normals + texCoord et 1 element array buffer pour les indices) int _nbTex; //Nombre d'unités de texture à utiliser.
//Je comprends pas, je n'ai pas de coloration
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 const int V_BUFF_SIZE = 3 * _nbVertex * sizeof(float); //Taille de la partie vertex dans le 1er VBO const int N_BUFF_SIZE = _normals ?(3 * _nbVertex * sizeof(float)) : 0; //Taille de la partie normals dans le 1er VBO const int T_BUFF_SIZE = _texCoord?(2 * _nbVertex * sizeof(float)) : 0; //Taille de la partie texCoord dans le 1er VBO const int A_BUFF_SIZE = V_BUFF_SIZE + N_BUFF_SIZE + T_BUFF_SIZE; //Taille du premier VBO (Array buffer) const int EA_BUFF_SIZE = (_nbVertexPerFacet*_nbFacets)*sizeof(GLint); //Taille du 2ème VBO (Element Array Buffer) pour les indices _vbos[0] = 0; _vbos[1] = 0; // Allocation dynamique des tableaux (_vertex, _normals, ...) // + remplissages des tableaux et initialisation des variables (_nbVertex. _nbFacets, ...). // J'ai du code opérationnels pour charger des OFF, et des heighmap de terrain si tu veux, mais c'est un peu long à poster. // Création des VBO et envoi des données RAM => MEM GPU. glGenBuffers(2, _vbos); if(_vbos[0]==0 || _vbos[1]==0) throw GException("No vertex buffer object available"); glBindBuffer(GL_ARRAY_BUFFER, _vbos[0]); //Activation du VBO 0 glBufferData(GL_ARRAY_BUFFER, A_BUFF_SIZE, 0, GL_STATIC_DRAW); glBufferSubData(GL_ARRAY_BUFFER, 0 , V_BUFF_SIZE, _vertex); if(_normals) glBufferSubData(GL_ARRAY_BUFFER, V_BUFF_SIZE, N_BUFF_SIZE, _normals); if(_texCoord) glBufferSubData(GL_ARRAY_BUFFER, V_BUFF_SIZE + (_normals ? N_BUFF_SIZE : 0), T_BUFF_SIZE, _texCoord); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vbos[1]); //Activation du VBO 1 glBufferData(GL_ELEMENT_ARRAY_BUFFER, EA_BUFF_SIZE, _indices, GL_STATIC_DRAW);
Affichage (je gère les cas ou il n'y a pas de normales ou de coordonnées de textures, ainsi que le multitexturing, donc ça complique un peu... ) :
Nettoyage :
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 const int V_BUFF_SIZE = (3*_nbVertex)*sizeof(float); const int N_BUFF_SIZE = (3*_nbVertex)*sizeof(float); glEnableClientState(GL_VERTEX_ARRAY); if(_normals) glEnableClientState(GL_NORMAL_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, _vbos[0]); //Activation du VBO 0 glVertexPointer (3, GL_FLOAT, 0, BUFFER_OFFSET(0)); if(_normals) glNormalPointer ( GL_FLOAT, 0, BUFFER_OFFSET(V_BUFF_SIZE)); /** Gestion du multitexturing, dans mon cas, toute les unités de textures utilisent les mêmes coordonnées de textures( donc le même VBO. */ if(_texCoord) { for(int i=1; i<_nbTex; i++) { glClientActiveTexture(GL_TEXTURE0 + i); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, 0, BUFFER_OFFSET(V_BUFF_SIZE + (_normals ? N_BUFF_SIZE : 0))); } glClientActiveTexture(GL_TEXTURE0); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, 0, BUFFER_OFFSET(V_BUFF_SIZE + (_normals ? N_BUFF_SIZE : 0))); } glBindBuffer(GL_ARRAY_BUFFER, 0); //Desactivation du VBO 0 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vbos[1]); //Activation du VBO 1 if(_nbVertexPerFacet==3) glDrawElements(GL_TRIANGLES, _nbVertexPerFacet*_nbFacets, GL_UNSIGNED_INT, BUFFER_OFFSET(0)); if(_nbVertexPerFacet==4) glDrawElements(GL_QUADS, _nbVertexPerFacet*_nbFacets, GL_UNSIGNED_INT, BUFFER_OFFSET(0)); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //Desactivation du VBO 1, ultra important ! (sous linux en tout cas :) ) if(_texCoord) { for(int i=1; i<_nbTex; i++) { glClientActiveTexture(GL_TEXTURE0 + i); glDisableClientState(GL_TEXTURE_COORD_ARRAY); } glClientActiveTexture(GL_TEXTURE0); glDisableClientState(GL_TEXTURE_COORD_ARRAY); } if(_normals) glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_VERTEX_ARRAY);
//BUFFER_OFFSET est définie de cette façon:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 if(_vertex) delete[] _vertex; if(_indices) delete[] _indices; if(_normals) delete[] _normals; if(_texCoord) delete[] _texCoord; if(_vbos[0]) glDeleteBuffers(2, _vbos);
ps: si tu as des problèmes ou des questions, n'hésites pas, le forum est là pour ça.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 inline void * BUFFER_OFFSET(int bytes) { return reinterpret_cast<void *>(bytes); }
Je t'invites aussi à lire le tuto dont le lien est sur dans le post, et d'autres tutos sur les vbos.
Partager