Чтение значений пикселей из объекта буфера кадра (FBO) с использованием объекта буфера пикселей (PBO)

Могу ли я использовать Pixel Buffer Object (PBO) для прямого чтения значений пикселей (т.е. с помощью glReadPixels) из FBO (т.е. пока FBO все еще прикреплен)?

Если да,

  1. Какие преимущества и недостатки использования PBO с FBO?
  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

person Rudi    schedule 26.05.2011    source источник


Ответы (2)


При использовании PBO в качестве цели для glReadPixels вы должны указать байтовое смещение в буфере (0, я полагаю) вместо (uchar*)cvimg->imageData в качестве целевого адреса. Это похоже на использование смещения буфера в glVertexPointer при использовании VBO.

РЕДАКТИРОВАТЬ: Когда PBO привязан к GL_PIXEL_PACK_BUFFER, последний аргумент glReadPixels обрабатывается не как указатель на системную память, а как смещение байта в памяти связанного буфера. Итак, чтобы записать пиксели в буфер, просто передайте 0 (запишите их в начало буферной памяти). Затем вы можете позже получить доступ к буферной памяти (чтобы получить пиксели) с помощью glMapBuffer. Ссылка в качестве примера, которую вы указали в своем комментарии, тоже делает это, просто прочтите ее внимательно. Я также предлагаю прочитать часть об объектах буфера вершин, которые они упоминают в начале, поскольку они закладывают основу для понимания объектов буфера.

person Christian Rau    schedule 26.05.2011
comment
Я не понимаю, не могли бы вы предоставить мне рабочий пример кода? Потому что в glReadPixels нет возможности указать смещение. И, пример не используйте такие вещи, как вы упомянули, но все равно отлично работает только с PBO . - person Rudi; 27.05.2011
comment
@Rudi Я надеюсь, что вы связали PBO, прежде чем пытаться писать в него. - person Christian Rau; 27.05.2011

Да, мы можем использовать FBO и PBO вместе.

Ответ 1:

Для синхронного чтения: glReadPixels без PBO работает быстро.

Для асинхронного чтения: glReadPixels с 2 / n PBO лучше - один для чтения пикселей из фреймбуфера в PBO (n) GPU, а другой PBO (n + 1) для обработки пикселей CPU. Как бы быстро ни было, это проблема и специфическая конструкция.

Ответ 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);
person Rudi    schedule 27.05.2011