Opengl glReadPixels读取第二次失败

Opengl glReadPixels读取第二次失败,opengl,opencv,glreadpixels,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,

下面的代码可以正常工作

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传输到函数时,它在第一次调用时工作正常,但在第二次调用时失败/不读取任何内容:(

几点: 线也是一样的。 只有一个缓冲区。 与帧缓冲区对象(FBO)以及glut窗口的行为相同。我还尝试了glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS),您可以看到代码被注释。我还在RenderObject()上调用了glClear(GL_COLOR_BUFFER_BITS)

你能帮我一下吗,哪里可能会出错


编辑:Christian..谢谢!你说得对。但是为什么会这样呢。在图像上没有链接。数据有缓冲区吗?在完成读取之后?还是…显示窗口接管了gl缓冲区的所有权,而我们在销毁它时发生了一些错误?

我想你的第一个示例工作得很好,因为你两次都显示
out1
imshow
中。否则,在函数中您会破坏窗口,然后在下一次函数调用中再次使用它,问题是


编辑:显示窗口不会拥有图像(当然也不会拥有您的GL帧缓冲区,为什么以及如何使用),而是销毁CV窗口(使用
destroyWindow
),然后再次使用此窗口(在下一个函数调用的
imshow
中)当然不是一个好主意。我认为,
imshow
不会在每次调用它时创建一个新窗口,它使用的是您使用
namedWindow
创建的窗口,在第二个函数调用中,此窗口不再存在,因为您使用
destrowWindow
销毁了它。我想您的第一个示例工作得很好,因为您和times在
imshow
中显示
out1
。否则,在函数中破坏窗口,然后在下一次函数调用中再次使用,问题是


编辑:显示窗口不会拥有图像(当然也不会拥有您的GL帧缓冲区,为什么以及如何使用),而是销毁CV窗口(使用
destroyWindow
),然后再次使用此窗口(在下一个函数调用的
imshow
中)这肯定不是一个好主意。我认为,
imshow
不会在每次调用它时创建一个新窗口,它使用的是您使用
namedWindow
创建的窗口,在第二个函数调用中,此窗口不再存在,因为在使用上述问题“with QT\u OPENGL”构建OpenCV时,您使用
destronWindow
销毁了它lem发生了

解决方案:

  • 不使用“WITH_QT_OPENGL”选项构建OpenCV。它将完全删除所有错误
  • 或者要解决此问题-重新附加绘图缓冲区(即glDrawBuffer仅使用默认缓冲区对象或同时使用帧缓冲区对象(FBO)FBO和纹理/渲染缓冲区,可以使用“GLCHECKFRAMEBERSTATUSEXT(GL_帧缓冲区_EXT);”使其有效)

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

    解决方案:

  • 不使用“WITH_QT_OPENGL”选项构建OpenCV。它将完全删除所有错误
  • 或者要解决此问题-重新附加绘图缓冲区(即glDrawBuffer仅使用默认缓冲区对象或同时使用帧缓冲区对象(FBO)FBO和纹理/渲染缓冲区,可以使用“GLCHECKFRAMEBERSTATUSEXT(GL_帧缓冲区_EXT);”使其有效)

  • Christian…谢谢!你说得对。我已经编辑了问题。阅读后,缓冲区和image.data之间没有链接(仅限uchar w*h存储)对吗?还有缓冲区数据……或者你认为显示窗口会接管缓冲区所有权吗?并销毁窗口销毁黄油等?@Christian:imshow创建窗口本身,如果没有指定名称。无论如何,为了验证这些东西……我做了以下实验:首先调用RenderObject,然后调用glReadPixels,然后调用imshow,然后销毁窗口.第二次调用RenderObject,然后调用glReadPixels,然后观察数据(即没有imshow,因此没有再次销毁窗口)。image.data不读取任何内容:((即垃圾,在传递到glReadPixels之前)…我相信你知道新的OpenCV版本支持OpenGL…所以我强烈认为在引擎盖下发生了一些事情。@Christian:我发布了新的问题,因为我发现了不同于开始的原因:@Rudi Ok抱歉,不知道它会自动创建窗口。然后我想在t下确实发生了一些奇怪的事情他是胡德。@Christian:经过一整天的斗争-找到了答案。请看!谢谢!Christian…谢谢!你是对的。我编辑了这个问题。阅读后,缓冲区和image.data之间没有链接(仅限uchar w*h存储)对吗?还有缓冲区数据……或者你认为显示窗口会接管缓冲区所有权吗?并销毁窗口销毁黄油等?@Christian:imshow创建窗口本身,如果没有指定名称。无论如何,为了验证这些东西……我做了以下实验:首先调用RenderObject,然后调用glReadPixels,然后调用imshow,然后销毁窗口.第二次调用RenderObject,然后调用glReadPixels,然后观察数据(即没有imshow,因此没有再次销毁窗口)。image.data不读取任何内容:((即垃圾,在传递到glReadPixels之前)…我相信你知道新的OpenCV版本支持OpenGL…所以我强烈认为在引擎盖下发生了一些事情。@Christian:我发布了新的问题,因为我发现了不同于开始的原因:@Rudi Ok抱歉,不知道它会自动创建窗口。然后我想在t下确实发生了一些奇怪的事情克里斯蒂安:经过一整天的努力,终于找到了答案。请看一看!谢谢!
    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();
    }