OpenGL считывает пиксели быстрее, чем glReadPixels

Есть ли способ увеличить скорость glReadPixels? В настоящее время я делаю:

Gdx.gl.glReadPixels(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), GL20.GL_RGBA, GL20.GL_UNSIGNED_BYTE, pixels);

Проблема в том, что он блокирует рендеринг и работает медленно.

Я слышал о Pixel Buffer Objects, но я совершенно не уверен, как его подключить и быстрее или нет.

Также существует любое другое решение, чем glReadPixels?

В принципе, я хочу сделать снимок экрана как можно быстрее, не блокируя рисунок следующей сцены.

Ответ 1

Есть ли способ увеличить скорость glReadPixels?

Ну, скорость этой операции на самом деле не является основной проблемой. Он должен передать определенное количество байтов из фреймбуфера в вашу системную память. В вашей обычной настольной системе с дискретным графическим процессором, который будет отправлять данные через PCI-Express, и нет никакого способа обойти это.

Но, как вы заявили, неявная синхронизация является большой проблемой. Если вам нужны эти пиксельные данные как можно скорее, вы не можете сделать намного лучше, чем это синхронное чтение. Но если вы можете жить с получением этих данных позже, асинхронное считывание через пиксельные буферные объекты (PBOs) - это путь.

Псевдокод для этого:

  • создать PBO
  • связывать PBO как GL_PIXEL_PACK_BUFFER
  • выполните glReadPixels
  • сделать что-то еще. Обе работы на процессоре и выдача новых команд для графического процессора являются идеальными.
  • Считайте данные из PBO с помощью glGetBufferSubData или путем сопоставления PBO для чтения.

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