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 :
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.
Initialisations (avant 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
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);
//Je comprends pas, je n'ai pas de coloration

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... ) :
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);
Nettoyage :
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);
//BUFFER_OFFSET est définie de cette façon:
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);
}
ps: si tu as des problèmes ou des questions, n'hésites pas, le forum est là pour ça.
Je t'invites aussi à lire le tuto dont le lien est sur dans le post, et d'autres tutos sur les vbos.