Ошибка при попытке использовать VBO «массив vertex_buffer_object должен быть отключен для вызова этого метода» - PullRequest
2 голосов
/ 06 декабря 2011

EDIT

Я эффективно переписал этот вопрос, чтобы значительно улучшить его качество - см. Журналы изменений, если необходимо

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

vaoID = new int[1];
gl.glGenVertexArrays(1, vaoID, 0);
gl.glBindVertexArray(vaoID[0]);
vboID = new int[1];
gl.glGenBuffers(1, vboID, 0);
gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, vboID[0]);
FloatBuffer vData = FloatBuffer.allocate(vertexData.length);
vData.put(vertexData);
vData.rewind();
gl.glBufferData(GL4.GL_ARRAY_BUFFER, vData.capacity() * (Float.SIZE / 8), vData, GL4.GL_STATIC_DRAW);
gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, 0); // With out this line my code throws the exception
gl.glEnableVertexAttribArray(0);
gl.glVertexAttribPointer(0, 4, GL.GL_FLOAT, false, 0, null); // This is the line where the exception is thrown
gl.glBindVertexArray(0);

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

gl.glGenBuffers(1, bufferIDs, 0);
gl.glBindBuffer(GL4.GL_ELEMENT_ARRAY_BUFFER, bufferIDs[0]);
ShortBuffer iData = ShortBuffer.allocate(indexData.length);
iData.put(indexData);
iData.rewind();
indexCount = iData.capacity();
gl.glBufferData(GL4.GL_ELEMENT_ARRAY_BUFFER, indexCount * (Short.SIZE / 8), iData, GL4.GL_STATIC_DRAW);
gl.glBindBuffer(GL4.GL_ELEMENT_ARRAY_BUFFER, 0);

Затем, когда дело доходит до рисования, я выполняю следующие шаги, и я не думаю, что это действительно имеет значение, так как я уверен, что я все еще не правильно буферирую в первую очередь

// first I bind my VAO
gl.glBindVertexArray(vaoID[0]);
// then bind, draw, unbind the index buffer
gl.glBindBuffer(GL4.GL_ELEMENT_ARRAY_BUFFER, bufferIDs[0]);
gl.glDrawElements(GL4.GL_POINT, indexCount, GL4.GL_UNSIGNED_SHORT, 0);
gl.glBindBuffer(GL4.GL_ELEMENT_ARRAY_BUFFER, 0);
// finally I unbind the VAO
gl.glBindVertexArray(0);

Я вполне уверен, что это правильный процесс рендеринга буферизованной геометрии. Я подтвердил, что мой код шейдера верен и действителен с помощью некоторых непосредственных команд рисования, поэтому у меня есть полный конвейер, просто кажется, что я не передаю в него данные. В качестве интереса я также попытался отредактировать свой вершинный шейдер, чтобы установить все точки на (0,0,0,1), чтобы, если какие-либо точки были переданы, я их видел, но это не сработало, и я означало, что я не передаю данные в мой шейдер.

Ответы [ 3 ]

6 голосов
/ 19 декабря 2011

glVertexAttribPointer имеет два режима работы. Если нет привязки к VBO, он принимает указатель на данные в качестве последнего аргумента. Если есть привязка к VBO, последний аргумент - это целочисленное смещение в буфере. В C вы все равно должны преобразовать это целое число в указатель, но он не рассматривается как указатель, если есть привязка к VBO.

В JOGL эти два режима реализованы с двумя перегрузками: , который принимает Buffer (вместо указателя) и , который принимает long (вместо смещения, приведенного к указателю).

Если вы используете первый с привязкой к VBO, он выдаст ошибку, потому что это режим, который работает только без привязки к VBO. Если вы отсоедините VBO и передадите null к последнему параметру, вы по-прежнему вызываете первую перегрузку: null может соответствовать параметру Buffer, но не long. JOGL, похоже, не имеет аналогичной проверки для этого случая. Это, вероятно, будет обрабатывать его как смещение 0, но также будет хранить 0 как VBO для поиска данных. То есть вообще без VBO.

Что вам нужно сделать, это с помощью вашего исходного кода, то есть с привязкой VBO, вызвать вместо этого перегрузку, которая принимает смещение:

//pass a long instead of a null Buffer
gl.glVertexAttribPointer(0, 4, GL.GL_FLOAT, false, 0, 0L);

И есть еще одна проблема, которая не позволяет ничего визуализировать. Вы передаете GL4.GL_POINT на glDrawElements. Это не допустимый режим сборки. Я не знаю, для чего это (мои знания OpenGL 4 меня не устраивают). Константа для режима сборки точек называется GL_POINTS:

gl.glDrawElements(GL.GL_POINTS, indexCount, GL4.GL_UNSIGNED_SHORT, 0);
0 голосов
/ 19 декабря 2011

Может быть, вы можете попробовать это? Просто предположение, хотя

vaoID = new int[2];
gl.glGenVertexArrays(1, vaoID[0], 0);
gl.glBindVertexArray(vaoID[0]);
gl.glGenBuffers(1, vboID[1], 0);
gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, vboID[1]);
FloatBuffer vData = FloatBuffer.allocate(vertexData.length);
vData.put(vertexData);
vData.position(0);
gl.glBufferData(GL4.GL_ARRAY_BUFFER, vData.capacity() * (Float.SIZE / 8), vData, GL4.GL_STATIC_DRAW);
gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, 0); // With out this line my code throws the exception
gl.glEnableVertexAttribArray(0);
gl.glVertexAttribPointer(0, 4, GL.GL_FLOAT, false, 0, null); // This is the line where the exception is thrown
gl.glBindVertexArray(0);
0 голосов
/ 06 декабря 2011

Я думаю, что проблема в том, что ваше VBO все еще привязано, когда вы идете на рисование VA. Удостоверьтесь, что всякий раз, когда вы используете glBindBuffer для привязки VBO для вызова отрисовки, затем после того, как вы сделали отрисовку, привяжите буфер ARRAY / ELEMENT_ARRAY обратно к 0. Также обязательно отключите все состояния клиента или массивы атрибутов, которые вы включаете после Вы сделали ничью.

// vbo draw
gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, bufferID[0]);
gl.glEnableVertexAttribArray(0);
gl.glVertexAttribPointer(0, 4, GL.GL_FLOAT, false, 0, null); // I know that this should be changed, but can't get code to run to this as can't buffer data in first place
gl.glDisableVertexAttribArray(0);
gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, 0);

// ibo draw
gl.glBindBuffer(GL4.GL_ELEMENT_ARRAY_BUFFER, bufferIDs[0]);
gl.glDrawElements(GL4.GL_POINT, indexCount, GL4.GL_UNSIGNED_SHORT, 0);
gl.glBindBuffer(GL4.GL_ELEMENT_ARRAY_BUFFER, 0);

Возможно, вам также придется делать это и в методе (ах) инициализации (отключите все, что вы включаете после того, как вы закончили генерировать вещи, и привязывайте вещи к нулю после того, как вы передали данные). В противном случае, когда он начинает рисовать VA, тогда материал VBO включается, поэтому GL запутывается, потому что думает, что должен что-то делать с VBO, потому что он включен, но на самом деле вы просто хотите использовать VA.

Это мое лучшее предположение к вашей проблеме. Не стесняйтесь комментировать мой пост, если он не решил его.

...