Вопрос по opengl-es-2.0, ios – почему привязка GL_ELEMENT_ARRAY_BUFFER к 0 приводит к ошибке memmove?

2

У меня была ошибка, которая заняла у меня довольно много времени, чтобы исправить. Я продолжал получать EXC_BAD_ACCESS и ссылку на ошибку memmove без дальнейшего описания, пока не прокомментировал следующую строку:

[self loadShaders];

<code>glGenVertexArraysOES(1, &_vao);
glBindVertexArrayOES(_vao);

// Vertex Buffer
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));

// Index Buffer
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);  

////////// COMMENTED THIS ONE //////////////
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);//
////////////////////////////////////////////

glBindVertexArrayOES(0);
</code>

Я думал, что привязка буфера к 0 означает отмену привязки, поэтому я действительно не могу понять, как это привело бы к сбою моего приложения.

Спасибо за информацию! Я просто не остаюсь с этим беспокойством ...

Мои структуры:

<code>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
};
</code>
Скорее всего, проблема в другом месте вашего кода. Комментирование этого вызова просто заставляет проблему проявляться по-другому. Но, глядя на код, который вы опубликовали, вы уверены, что в структуре Vertices есть как минимум 9 членов с плавающей точкой? Потому что я вижу, что вы используете только 5 из них, но задаете смещение 7 для ATTRIB_TEXURE (+2 для его данных). Mārtiņš Možeiko
Да, я также думал, что это было где-то еще, но только эта единственная строка решает проблему, я действительно не понимаю, почему, я разместил обновление со своими структурами. Спасибо Pochi

Ваш Ответ

1   ответ
8

как будто эта функция находится в некоторой подпрограмме инициализации, где вы инициализируете данные атрибута, которые хранятся в связанном VAO, так что при рисовании вам нужно только связать VAO.

VAO, в свою очередь, инкапсулирует все состояние, необходимое для рисования VBO, что является включенными флагами ваших атрибутов (устанавливаетсяgl(En/Dis)ableVertexAttribArray), атрибуты источников и свойств (задается с помощьюglVertexAttribPointer), and текущий связанный индексный буфер (устанавливается сglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ...)). Следует отметить, что он не хранит текущий связанный буфер вершин, поскольку эта информация хранится в состоянии атрибута.

Так что получается, что вы создаете и привязываете индексный буфер, устанавливаете его данные, а затем отвязываете его, при этом VAO все еще активен. Таким образом, государство ВАО будет хранитьGL_ELEMENT_ARRAY_BUFFER связывание0, Когда вы сейчас рисуете что-то с

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

нет буфера, иglDrawElements терпит неудачу, поскольку VAO не работают с массивами на стороне клиента. Вы должны либо использовать VBO для индексных данных, либо нарисовать неиндексированные примитивы (сglDrawArrays).

Ни один не будет

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

работать, потому что связанный индексный буфер перезаписывается VAO, когда он становится связанным (чей индексный буфер0). Это сработает, если сначала связать VAO, а затем буфер индекса, но это только обойдет проблему.

Концептуально пределGL_ELEMENT_ARRAY_BUFFER является частью государства ВАО, поэтому вы не должны связывать его с0 в вашей процедуре инициализации VAO (только если вам не нужны никакие данные индекса). Кроме того, вам не разрешается использовать клиентские массивы для данных индекса или вершины при использовании VAO. Если вы не хотите рисовать индексированную геометрию, просто используйтеglDrawArrays вместоglDrawElements, но тогда индексный буфер устарел, в любом случае.

О, я вижу, я не знал, что VAO также будет хранить это как часть конфигурации. Спасибо! Pochi
я даже не думал об этом, и я кодирую gl с тех пор ... хорошее xplanation. очень полезный вопрос / ответ

Похожие вопросы