12

Pixel Buffer Object (PBO) を使用して、FBO からピクセル値を (glReadPixels を使用して) 直接読み取ることはできますか?

もし、そうなら、

  1. FBO で PBO を使用する利点と欠点は何ですか?
  2. 次のコードの問題は何ですか

{

//DATA_SIZE = WIDTH * HEIGHT * 3 (BECAUSE I AM USING 3 CHANNELS ONLY)
// FBO and PBO status is good
.
.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
//Draw the objects

以下の glReadPixels は正常に動作します

glReadPixels(0, 0, screenWidth, screenHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE,  (uchar*)cvimg->imageData);

次の glReadPixels は機能しません:(

glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboId);
//yes glWriteBuffer has also same target and I also checked with every possible values
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); 
glReadPixels(0, 0, screenWidth, screenHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, (uchar*)cvimg->imageData);
.
.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); //back to window framebuffer
4

2 に答える 2

10

PBO をターゲットとして使用する場合は、ターゲット アドレスとしてではなくglReadPixels、バッファーにバイト オフセットを指定する必要があります (0と思います) 。(uchar*)cvimg->imageDataこれは、VBO を使用するときにバッファー オフセットを使用するのと似ていglVertexPointerます。

編集: PBO が にバインドされているGL_PIXEL_PACK_BUFFER場合、 の最後の引数glReadPixelsは、システム メモリへのポインタとしてではなく、バインドされたバッファのメモリへのバイト オフセットとして扱われます。したがって、ピクセルをバッファーに書き込むには、0 を渡すだけです (バッファー メモリの先頭に書き込みます)。その後、 を使用して (ピクセルを取得するために) バッファ メモリにアクセスできますglMapBuffer。コメントで提供したリンクの例も同様です。よく読んでください。また、最初に言及されている頂点バッファー オブジェクトに関する部分を読むことをお勧めします。これは、バッファー オブジェクトを理解するための土台を築くためです。

于 2011-05-26T20:13:18.563 に答える
9

はい、FBO と PBO を一緒に使用できます。

答え 1:

同期読み取りの場合: PBO を使用しない 'glReadPixels' は高速です。

非同期読み取りの場合: 2/n PBO を使用した 'glReadPixels' の方が優れています。GPU によるフレームバッファーから PBO (n) へのピクセルの読み取りと、CPU によるピクセルの処理のための別の PBO (n+1) です。ただし、高速が認められていない場合は、問題と設計固有の問題です。

答え 2:

クリスチャン・ラウの説明は正しく、修正されたコードは以下のとおりです

glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboId);
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
//glReadBuffer(GL_DEPTH_ATTACHMENT_EXT);

glReadPixels(0, 0, screenWidth, screenHeight, GL_BGR, GL_UNSIGNED_BYTE, 0);

//GLubyte* src = (GLubyte*)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB);
//OR
cvimg->imageData = (char*) glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB);
if(cvimg_predict_contour->imageData)
{
  //Process src OR cvim->imageData
  glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);     // release pointer to the mapped buffer
}
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
于 2011-05-27T12:05:41.277 に答える