Ошибка чтения glReadPixels во второй раз - PullRequest
1 голос
/ 17 июня 2011

Следующий код работает нормально

const char *title = "glReadOutput";
Mat out1, out2;

out1.create(screenHeight,screenWidth, CV_8UC3);
out2.create(screenHeight,screenWidth, CV_8UC3);

RenderObject();
glReadPixels(0, 0, screenWidth, screenHeight, GL_BGR, GL_UNSIGNED_BYTE, (uchar*)out1.data);
//flip(out1, out1, 0);
imshow(title, out1);
waitKey(5000);

RenderObject();
glReadPixels(0, 0, screenWidth, screenHeight, GL_BGR, GL_UNSIGNED_BYTE, (uchar*)out2.data);
//flip(image, out2, 0);
imshow(title, out2);
waitKey(5000);

Однако, когда я перевожу функцию glReadPixels на функцию, она отлично работает при первом вызове, но не работает / ничего не читается при втором вызове: (

RenderObject();
displayImage(out1);

RenderObject();
displayImage(out2);
.
.

void displayImage(Mat& image) {

  //glReadBuffer(GL_FRONT);
  //glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);

  glReadPixels(0, 0, screenWidth, screenHeight, GL_BGR, GL_UNSIGNED_BYTE, (uchar*)image.data);

  //flip(image, image, 0);
  //glPopClientAttrib();

  const char *title = "glReadPixels";
  imshow(title, image);
  waitKey(5000);
  destroyWindow(title);
  //image.release();
}

Несколько баллов: Нить тоже такая же. Есть только один буфер. То же поведение с объектом кадрового буфера (FBO), а также с перенасыщением окна. Я также попробовал glPushClientAttrib (GL_CLIENT_ALL_ATTRIB_BITS), вы могли видеть, что код прокомментирован. Я также назвал glClear (GL_COLOR_BUFFER_BIT); на RenderObject ().

Не могли бы вы мне помочь, где может быть ошибка?

РЕДАКТИРОВАТЬ: Кристиан .. спасибо! Вы правы. Но почему это происходит? На image.data нет ссылки с буфером, верно? после окончания чтения? Или это ... окно дисплея, которое перешло во владение буфером gl и что-то не так, пока мы его уничтожали?

Ответы [ 2 ]

1 голос
/ 17 июня 2011

Полагаю, ваш первый пример работает нормально, потому что вы оба раза отображаете out1 в imshow. В противном случае в функции вы уничтожаете окно и затем используете его снова при следующем вызове функции, проблема?

РЕДАКТИРОВАТЬ: Окно дисплея не берет на себя ответственность за изображение (и, конечно, не ваш буфер кадров GL, почему и как это должно), но разрушает окно CV (с destroyWindow) а затем снова использовать это окно (в imshow следующего вызова функции), безусловно, не очень хорошая идея. Я думаю, imshow не создает новое окно каждый раз, когда оно вызывается, оно использует окно, которое вы создали с помощью namedWindow, и во втором вызове функции это окно больше не существует, так как вы уничтожили его с помощью destroyWindow .

0 голосов
/ 18 июня 2011

Когда OpenCV был построен с использованием WITH_QT_OPENGL, возникла вышеуказанная проблема.

Решения:

  1. Сборка OpenCV без опции WITH_QT_OPENGL. Это полностью удалит все ошибки.
  2. Или для обхода. Повторно присоедините буфер рисования (т. Е. GlDrawBuffer только с буферным объектом по умолчанию или с объектом кадрового буфера (FBO), как FBO, так и буфером текстур / рендеринга, вы можете проверить это с помощью 'glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);')
...