1


0

glReadPixelsの読み取りが2回目に失敗しました

次のコードは正常に動作します

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を関数に転送すると、最初の呼び出しでは正常に動作しますが、2回目の呼び出しでは失敗/何も読み込まれません:(

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

いくつかのポイント:スレッドも同じです。 バッファは1つだけです。 フレームバッファオブジェクト(FBO)およびglutウィンドウと同じ動作。 glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS)も試してみましたが、コードがコメントされているのを見ることができました。 glClear(GL_COLOR_BUFFER_BIT)も呼び出しました。 RenderObject()で。

間違いを犯す可能性がある場所を教えてください。

編集:クリスチャン.. ありがとう あなたは正しい。 しかし、なぜそれが起こっているのか。 image.dataにバッファーがありますか? 読み終わったら? またはそれは …​ 表示ウィンドウがglバッファの所有権を引き継ぎ、それを破壊している間に何か問題が発生していますか?

2 Answer


1


どちらの場合も「imshow」で「out1」を表示するため、最初の例は正常に動作すると思います。 それ以外の場合は、関数でウィンドウを破棄し、次の関数呼び出しで再び使用しますか?

*編集:*表示ウィンドウは画像の所有権を取得しません(GLフレームバッファーの所有権を取得するのではなく、その理由と方法)が、CVウィンドウを破棄し( `destroyWindow`を使用)、このウィンドウを再度使用します(次の関数呼び出しの `imshow`で)は良いアイデアではありません。 「imshow」は呼び出されるたびに新しいウィンドウを作成せず、「namedWindow」で作成したウィンドウを使用し、2番目の関数呼び出しでは「destroyWindow」で破棄したため、このウィンドウはもう存在しないと思います。


0


OpenWIが 'WITH_QT_OPENGL’を使用してビルドされた場合、上記の問題が発生します。

ソリューション:

  1. 「WITH_QT_OPENGL」オプションなしでOpenCVをビルドします。 完全に すべてのエラーを削除します。

  2. または回避するには-描画バッファを再接続します(つまり、 glDrawBufferのみ デフォルトのバッファオブジェクトまたはフレームバッファオブジェクト(FBO)とFBOおよびテクスチャ/レンダーバッファの両方で、「glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);」を使用してこれを有効にできます。 )