glReadPixels 第二次读取失败

发布于 2024-11-15 17:36:06 字数 1400 浏览 2 评论 0原文

以下代码工作正常

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 缓冲区的所有权,并且在我们销毁它时发生了错误?

Following code works fine

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);

However, when I transfer glReadPixels to function it works fine on first call but fails/read nothing on second call :(

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();
}

Few points:
The thread is also same.
There is only single buffer.
Same behavior with framebuffer object (FBO) as well as glut window. I also tried glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS), you could see code is commented. I also called glClear(GL_COLOR_BUFFER_BIT); on RenderObject().

Can you please help me, where might be possible mistake?

EDIT: Christian .. thanks! Your are right. But Why that is happening. There is no link on image.data with buffer right? after finishing the read? Or is it ... the display window taking over ownership of gl buffer and something wrong going on while we destroying that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冷月断魂刀 2024-11-22 17:36:06

我想你的第一个例子工作得很好,因为你两次都在 imshow 中显示 out1 。否则,在函数中销毁窗口,然后在下一个函数调用中再次使用它,有问题吗?

编辑: 显示窗口不拥有图像的所有权(当然也不拥有 GL 帧缓冲区,为什么以及如何应该这样做),但会销毁 CV 窗口(使用 destroyWindow),然后再次使用此窗口(在下一个函数调用的 imshow 中)肯定不是一个好主意。我认为 imshow 不会在每次调用时创建一个新窗口,它使用您使用 namedWindow 创建的窗口,并且在第二个函数调用中该窗口不存在不再如此,因为您使用 destroyWindow 销毁了它。

I guess your first example works fine, because you both times display out1 in imshow. Otherwise, in the function you destroy the window and then use it again in the next function call, problem?

EDIT: The display window doesn't take ownership of the image (and surely not of your GL frame buffer, why and how should it), but destroying a CV window (with destroyWindow) and then using this window again (in the imshow of the next function call) is surely not a good idea. I think imshow doesn't create a new window each time it is called, it uses a window you created with namedWindow and in the second function call this window doesn't exist anymore, as you destroyed it with destroyWindow.

奈何桥上唱咆哮 2024-11-22 17:36:06

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

解决方案:

  1. 构建不带“WITH_QT_OPENGL”选项的 OpenCV。它将完全消除所有错误。
  2. 或者解决方法 - 重新附加绘制缓冲区(即 glDrawBuffer 仅使用默认缓冲区对象或使用帧缓冲区对象(FBO)FBO 和纹理/渲染缓冲区,您可以使用 'glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);' 来验证它)

When OpenCV was built using 'WITH_QT_OPENGL', above problem occures.

Solutions:

  1. Build OpenCV without 'WITH_QT_OPENGL' option. It will completely removes all errors.
  2. Or to work around- Re-attach the draw buffer (i.e. glDrawBuffer only with default buffer object or with framebuffer object (FBO) both FBO and texture/render buffer, you could valid this using 'glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);' )
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文