OpenGL Transform обратная связь сделана правильно на Android
Я изо всех сил пытался создать рабочую обратную связь обратной связи на Android. До сих пор наиболее близкая проблема, с которой я столкнулся, была похожа на этот недооцененный вопрос: https://stackru.com/questions/41066101/transform-feedback-altering-render-result
Что я хочу создать:
Рендеринг из буфера объекта вершины в обратную связь преобразования. Затем выполните рендеринг из буфера обратной связи преобразования с помощью финального чертежного шейдера.
Как я понимаю всю эту концепцию:
Я понимаю, как программа связана с изменениями (я следовал этому примеру: https://gist.github.com/hpp/d2d26adc5987002eb520) На Android вы должны предоставить "фиктивный" фрагментный шейдер, в противном случае программа связывает потерпит неудачу без сообщения.
После того, как у вас есть связанная программа, это следующие шаги: (код в java)
Создать VBO для чтения данных из
int[] vbo = new int[1]; glGenBuffers(1, vbo, 0); glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); glBufferData(GL_ARRAY_BUFFER, bufferLength, data, GL_STATIC_READ);
Создать буфер обратной связи преобразования
int[] tbo = new int[1]; glGenBuffers(1, tbo, 0); glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, tbo[0]); glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, bufferLength, null, GL_DYNAMIC_COPY); glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tbo[0]);
Каждый раз, когда я хотел бы сделать свои вычисления, я называю что-то вроде этого:
glUseProgram(calculationShaderProgram); // For all input variables: glEnableVertexAttribArray(inputAttrib); glVertexAttribPointer(... // To bind the transform feedback buffer as the destination glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfo[0]); glEnable(GL_RASTERIZER_DISCARD); glBeginTransformFeedback(GL_POINTS); glDrawArrays(GL_POINTS, 0, vertexCount); glEndTransformFeedback(); glDisable(GL_RASTERIZER_DISCARD); glFinish(); // I know this is slow to call, but for simplicity's sake
После этого я смогу нарисовать содержимое буфера:
glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, tbo[0]); glUseProgram(drawShaderProgram); // For all input variables: glEnableVertexAttribArray(inputAttrib); glVertexAttribPointer(... // Set uniforms ... glDrawArrays(GL_POINTS, 0, vertexCount); // There is no glDrawTransformFeedback on android
Теперь мои вопросы:
- Есть ли что-то по сути неправильно в этом процессе?
- Есть ли какая-то причина, по которой часть вычислений портит экран моего устройства, даже если я ничего не рисую? (Он показывает случайные цвета или значки, обновляемые Android, такие как батарея и сеть)
- Использует ли объект массива вершин то же самое с GL_TRANSFORM_FEEDBACK_BUFFER, как и с GL_ARRAY_BUFFER?
1 ответ
Это заняло некоторое время, но вот решение. Я оставлю это здесь, потому что эти части не были объяснены должным образом ни в одной доступной книге, связанной с OpenGL.
При рисовании из буфера обратной связи преобразования (шаг 4 выше), не имеет значения, работает ли он как буфер обратной связи преобразования, вы должны привязать его как GL_ARRAY_BUFFER, точно так же, как вы рисовали бы из объекта буфера вершин.
glBindBuffer(GL_ARRAY_BUFFER, tbo[0]);
При использовании кадрового буфера по умолчанию,
glBindFrameBuffer(GL_FRAMEBUFFER, 0);
или нет настройки вообще, вы не можете использовать
glEnable(GL_RASTERIZER_DISCARD); // Draw to Transform feedback // ... glDisable(GL_RASTERIZER_DISCARD);
(на шаге 3) без предварительного вызова
glClear(GL_COLOR_BUFFER_BIT);
в противном случае вы увидите случайные узоры в качестве фона. Одного glClear перед каждым циклом отрисовки недостаточно.