3 votes

Pourquoi attacher un GL_ELEMENT_ARRAY_BUFFER à 0 produit-il une erreur de memmove?

J'avais un bogue qui m'a pris beaucoup de temps à résoudre. J'ai continué à obtenir EXC_BAD_ACCESS et une référence à une erreur de memmove sans aucune description supplémentaire jusqu'à ce que je commente la ligne suivante :

[self loadShaders];

glGenVertexArraysOES(1, &_vao);
glBindVertexArrayOES(_vao);

// Tampon de vertex
glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);

glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);

glEnableVertexAttribArray(ATTRIB_TEXTURE);
glVertexAttribPointer(ATTRIB_TEXTURE, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 7));

// Tampon d'index
glGenBuffers(1, &_indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);

glBindBuffer(GL_ARRAY_BUFFER,0);  

////////// CETTE LIGNE A ÉTÉ COMMENTÉE //////////////
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); //
//////////////////////////////////////////////////

glBindVertexArrayOES(0);

Je pensais que lier un tampon à 0 signifiait le délier, donc je ne comprends vraiment pas comment cela aurait pu faire planter mon application.

Merci pour l'information! Je ne reste juste pas avec cette préoccupation...

Mes structures:

const Vertex Vertices[4] = {
    {{0.75, -1, 0}, {1, 0, 0, 1},     {0.125, 0.833496}},
    {{0.75, 1, 0}, {0, 1, 0, 1},      {0.125, 1}},
    {{-0.75, 1, 0}, {0, 0, 1, 1},     {0,     1}},
    {{-0.75, -1, 0}, {0, 0, 0, 1},    {0,     0.833496}},
};

const GLushort Indices[6] =
{
    0, 1, 2,
    2, 3, 0
};

10voto

Christian Rau Points 29137

De votre code, il semble que cette fonction soit dans une routine d'initialisation, où vous initialisez vos données d'attribut, qui sont stockées dans le VAO lié, de sorte que lors du dessin, vous n'avez besoin que de lier le VAO.

Un VAO encapsule à son tour tout l'état nécessaire pour dessiner des VBO, à savoir les indicateurs activés de vos attributs (définis avec gl(En/Dis)ableVertexAttribArray), les sources et propriétés des attributs (définis avec glVertexAttribPointer), et le tampon d'index actuellement lié (défini avec glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ...)). Notez qu'il ne stocke pas le tampon de sommets actuellement lié, car ces informations sont stockées dans l'état d'attribut.

Ainsi, vous créez et liez le tampon d'index, définissez ses données, puis le déliez, le VAO restant actif. Par conséquent, l'état du VAO stockera une liaison de type GL_ELEMENT_ARRAY_BUFFER sur 0. Lorsque vous dessinez quelque chose avec

glBindVertexArrayOES(_vao);
glDrawElements(...);

il n'y a aucun tampon lié et le glDrawElements échoue, car les VAO ne fonctionnent pas avec des tableaux côté client. Vous devez soit utiliser un VBO pour les données d'index, soit dessiner des primitives non indexées (avec glDrawArrays).

Aucune des méthodes suivantes ne fonctionnera

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
glBindVertexArrayOES(_vao);
glDrawElements(...);

car le tampon d'index lié est écrasé par le VAO lorsqu'il est lié (dont le tampon d'index est 0). Cela fonctionnerait si vous liaisez d'abord le VAO puis le tampon d'index, mais cela ne ferait que contourner le problème.

Conceptuellement, le tampon d'index lié de type GL_ELEMENT_ARRAY_BUFFER fait partie de l'état du VAO, donc vous ne devez pas le lier à 0 dans votre routine d'initialisation du VAO (seulement si vous n'avez pas besoin de données d'index). Et vous n'êtes pas autorisé à utiliser des tableaux côté client pour les données d'index ou de sommets lors de l'utilisation de VAO. Si vous ne voulez pas dessiner de géométrie indexée, utilisez simplement glDrawArrays au lieu de glDrawElements, mais alors le tampon d'index est de toute façon obsolète.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X