glReadPixels第二次读取失败

时间:2011-06-16 22:01:19

标签: opengl opencv glreadpixels

以下代码正常

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 个答案:

答案 0 :(得分:1)

我猜您的第一个示例工作正常,因为您在out1中都显示imshow。否则,在你破坏窗口的函数中,然后在下一个函数调用中再次使用它,问题?

编辑:显示窗口不占用图像的所有权(当然不是GL帧缓冲区的原因,为什么以及如何使用),但是会破坏CV窗口({{1}然后再次使用这个窗口(在下一个函数调用的destroyWindow中)肯定不是一个好主意。我认为imshow每次调用都不会创建一个新窗口,它使用你用imshow创建的窗口,而在第二个函数调用中,这个窗口不再存在,因为你销毁了它与namedWindow

答案 1 :(得分:0)

使用'WITH_QT_OPENGL'构建OpenCV时,会出现上述问题。

<强>解决方案:

  1. 在没有'WITH_QT_OPENGL'选项的情况下构建OpenCV。它将完全删除所有错误。
  2. 或者解决方法 - 重新连接绘图缓冲区(即glDrawBuffer仅使用默认缓冲区对象或使用帧缓冲区对象(FBO)FBO和纹理/渲染缓冲区,您可以使用'glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);'来验证它