Bonjour,

J'ai recemment commence a travailler sur les VBO (et les vertex shaders plus particulierement) dans un souci de performance. Cependant, a nombre de cube egale (27 000 pour etre exact), les lists s'en tirent mieux que les vertex shaders (40% contre 50%), ce qui m'etonne etant donne que les vbo sont censes etre plus rapides. Je me demande donc ce que j'aurais bien pu rater...

Voici le code pour les cubes list :

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
//initiatisation
 
m_glObject = glGenLists(1);
  glNewList(m_glObject, GL_COMPILE);
 
      glBegin(GL_QUADS);
      glNormal3f(-1.f, 0.f, 0.f);
      glColor3d(m_color.getRed(), m_color.getGreen(), m_color.getBlue());
      glVertex3f(sizeX / -2.f, sizeY / -2.f, sizeZ / -2.f);
      glVertex3f(sizeX / -2.f, -sizeY / 2.f, sizeZ / 2.f);
      glVertex3f(sizeX / -2.f, sizeY / 2.f, sizeZ / 2.f);
      glVertex3f(sizeX / -2.f, sizeY / 2.f, sizeZ / -2.f);
 
      glNormal3f(0.f, 1.f, 0.f);
      glColor3d(m_color.getRed(), m_color.getGreen(), m_color.getBlue());
      glVertex3f(sizeX / -2.f, sizeY / 2.f, sizeZ / -2.f);
      glVertex3f(sizeX / -2.f, sizeY / 2.f, sizeZ / 2.f);
      glVertex3f(sizeX / 2.f, sizeY / 2.f, sizeZ / 2.f);
      glVertex3f(sizeX / 2.f, sizeY / 2.f, sizeZ / -2.f);
 
      glNormal3f(1.f, 0.f, 0.f);
      glColor3d(m_color.getRed(), m_color.getGreen(), m_color.getBlue());
      glVertex3f(sizeX / 2.f, sizeY / 2.f, sizeZ / -2.f);
      glVertex3f(sizeX / 2.f, sizeY / 2.f, sizeZ / 2.f);
      glVertex3f(sizeX / 2.f, sizeY / -2.f, sizeZ / 2.f);
      glVertex3f(sizeX / 2.f, sizeY / -2.f, sizeZ / -2.f);
 
      glNormal3f(0.f, -1.f, 0.f);
      glRotatef(m_rot.getRotation(), m_rot.getRotX(), m_rot.getRotY(), m_rot.getRotZ());
      glColor3d(m_color.getRed(), m_color.getGreen(), m_color.getBlue());
      glVertex3f(sizeX / 2.f, sizeY / -2.f, sizeZ / -2.f);
      glVertex3f(sizeX / 2.f, sizeY / -2.f, sizeZ / 2.f);
      glVertex3f(sizeX / -2.f, -sizeY / 2.f, sizeZ / 2.f);
      glVertex3f(sizeX / -2.f, sizeY / -2.f, sizeZ / -2.f);
 
      glNormal3f(0.f, 0.f, 1.f);
      glColor3d(m_color.getRed(), m_color.getGreen(), m_color.getBlue());
      glVertex3f(sizeX / 2.f, sizeY / -2.f, sizeZ / 2.f);
      glVertex3f(sizeX / 2.f, sizeY / 2.f, sizeZ / 2.f);
      glVertex3f(sizeX / -2.f, sizeY / 2.f, sizeZ / 2.f);
      glVertex3f(sizeX / -2.f, -sizeY / 2.f, sizeZ / 2.f);
 
      glNormal3f(0.f, 0.f, -1.f);
      glColor3d(m_color.getRed(), m_color.getGreen(), m_color.getBlue());
      glVertex3f(sizeX / 2.f, sizeY / 2.f, sizeZ / -2.f);
      glVertex3f(sizeX / 2.f, sizeY / -2.f, sizeZ / -2.f);
      glVertex3f(sizeX / -2.f, sizeY / -2.f, sizeZ / -2.f);
      glVertex3f(sizeX / -2.f, sizeY / 2.f, sizeZ / -2.f);
 
  glEnd();
  glEndList();
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
//dessin
 
glLoadIdentity();
  glTranslatef(m_pos.x(), m_pos.y(), m_pos.z());
  glRotatef(m_rot.getRotation(), m_rot.getRotX(), m_rot.getRotY(), m_rot.getRotZ());
  glCallList(m_glObject);
Et enfin le cube vertex shader (que j'ai fait a partir du tuto de developpez) :

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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
//initialisation
 
  vertexSource = 0;
  fragmentSource = 0;
  vertexID = 0;
  fragmentID = 0;
  programID = 0;
 
  GLfloat cubeVertices[] =
  {
      // Face de devant
      1,1,1,
      -1,1,1,
      -1,-1,1,
      1,-1,1,
 
      1, 1, -1,
      -1, 1, -1,
 
      -1, -1, -1,
      1, -1, -1,
  };
 
  GLfloat cubeColours[] =
  {
      1, 0, 0,
      0, 1, 0,
      0, 1, 0,
      1, 0, 0,
 
      0, 0, 1,
      1, 1, 0,
 
      1, 1, 0,
      0, 0, 1,
  };
 
  GLubyte cubeIndices[] =
  {
      0, 1, 2, 3,
      0, 4, 7, 3,
      4, 5, 6, 7,
      1, 2, 6, 5,
      2, 3, 7, 6,
      0, 1, 5, 4
  };
 
vertexSource = readFile("data/simple.vert");
  fragmentSource = readFile("data/simple.frag");
  GLint programState = 0;
  GLint vertexSize = 0;
  GLint fragmentSize = 0;
 
  // Création des IDs
  vertexID = glCreateShader(GL_VERTEX_SHADER);
  fragmentID = glCreateShader(GL_FRAGMENT_SHADER);
 
  // Vérification des fichiers
  if (!vertexSource || !fragmentSource)
    {
      // Ici, il faudrait faire en sorte que le programme s'arrête
      deleteShader();
      return;
    }
 
  // Chargement des sources dans OpenGL
  vertexSize = strlen(vertexSource);
  fragmentSize = strlen(fragmentSource);
  glShaderSource(vertexID, 1, (const GLchar**)(&vertexSource), &vertexSize);
  glShaderSource(fragmentID, 1, (const GLchar**)(&fragmentSource), &fragmentSize);
 
  // Compilation du vertex shader
  glCompileShader(vertexID);
  glCompileShader(fragmentID);
 
  // Vérification des erreurs
  if (!checkShaderCompilation(vertexID) || !checkShaderCompilation(fragmentID))
    {
      deleteShader();
      return;
    }
 
  // Creation de l'ID pour le programme
  programID = glCreateProgram();
 
  // On attache les shaders ensemble
  glAttachShader(programID, vertexID);
  glAttachShader(programID, fragmentID);
 
  // On peut enfin passer aux liage.
  glLinkProgram(programID);
 
  // Et encore une fois on vérifie si tout se passe bien
  glGetProgramiv(programID, GL_LINK_STATUS, &programState);
  if (programState != GL_TRUE)
    {
      // On récupère la taille du log
      GLint logSize = 0;
      GLchar* log = NULL;
 
      glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &logSize);
 
      // On peut allouer la mémoire, une fois que l'on a la taille du log
      log = new GLchar[logSize];
      if (log == NULL)
        {
          HandleError::showError("Erreur d'allocation de mémoire pour le log de la compilation du programme");
          deleteShader();
          return;
        }
 
      // Et on récupère le log
      glGetProgramInfoLog(programID, logSize, &logSize, log);
 
      // On affiche
      HandleError::showError(string("Erreur lors du liage du shader: ") + log);
 
      delete[] log;
      deleteShader();
      return;
    }
 
  attributeId = glGetAttribLocation(programID, "couleur");
  GLenum errorState = glGetError();
  if ( attributeId == -1 || errorState != GL_NO_ERROR )
  {
      HandleError::showError("Erreur lors de la récupération de l'id de la variable attribute 'couleur'");
  }
 
  GLint uniformId = glGetUniformLocation(programID, "couleurBleu");
  errorState = glGetError();
  if ( uniformId == -1 || errorState != GL_NO_ERROR )
  {
      HandleError::showError("Erreur lors de la récupération de l'id de la variable uniforme 'couleurBleu'");
  }
 
  // Voilà, nous sommes prêt
  glUseProgram(programID);
 
  glUniform1f(uniformId, couleur);
  errorState = glGetError();
  if ( errorState != GL_NO_ERROR )
  {
      HandleError::showError("Erreur lors de l'envoi de valeur à la variable uniforme");
  }
 
  glEnableVertexAttribArray(attributeId);
  errorState = glGetError();
 
  glVertexAttribPointer(attributeId, 3, GL_FLOAT, GL_TRUE,
                        0, cubeColours);
 
  if ( errorState != GL_NO_ERROR )
  {
      HandleError::showError("Erreur lors du passage du tableau de valeur à la variable attribute 'couleur'");
  }
 
  glEnableClientState(GL_VERTEX_ARRAY);
 
  glVertexPointer(3, GL_FLOAT, 0, cubeVertices);
}
 
void  HandleShader::draw()
{
  glLoadIdentity();
  glTranslatef(m_pos.x(), m_pos.y(), m_pos.z());
  glRotatef(m_rot.getRotation(), m_rot.getRotX(), m_rot.getRotY(), m_rot.getRotZ());
  glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, cubeIndices);
Et enfin :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
//dessin
 
glLoadIdentity();
  glTranslatef(m_pos.x(), m_pos.y(), m_pos.z());
  glRotatef(m_rot.getRotation(), m_rot.getRotX(), m_rot.getRotY(), m_rot.getRotZ());
  glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, cubeIndices);
Etant donne mon inexperience en opengl, je n'ai pas reussi a mettre le doigt sur le probleme.

Merci d'avance !