Считывание значений пикселей из объекта кадрового буфера (FBO) с использованием объекта Pixel Buffer (PBO)
Могу ли я использовать Pixel Buffer Object (PBO) для непосредственного считывания значений пикселей (то есть, используя glReadPixels) из FBO (то есть, пока FBO все еще подключено)?
Если да,
- Каковы преимущества и недостатки использования PBO с FBO?
- В чем проблема со следующим кодом
{
//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
2 ответа
При использовании PBO в качестве цели для glReadPixels
Вы должны указать смещение байта в буфер (0
Я полагаю) вместо (uchar*)cvimg->imageData
как целевой адрес. Это похоже на использование смещения буфера в glVertexPointer
при использовании VBO.
РЕДАКТИРОВАТЬ: Когда PBO связан с GL_PIXEL_PACK_BUFFER
, последний аргумент glReadPixels
не обрабатывается как указатель на системную память, а как смещение байта в памяти связанного буфера. Поэтому, чтобы записать пиксели в буфер, просто передайте 0 (запишите их в начало буферной памяти). Затем вы можете позже получить доступ к буферной памяти (чтобы получить пиксели) с помощью glMapBuffer
, Ссылка на пример, которую вы указали в своем комментарии, тоже делает это, просто прочитав ее подробно. Я также предлагаю прочитать часть об объектах буфера вершин, которые они упоминают в начале, поскольку они закладывают основу для понимания объектов буфера.
Да, мы можем использовать FBO и PBO вместе.
Ответ 1:
Для синхронного чтения: "glReadPixels" без PBO быстро.
Для асинхронного чтения: "glReadPixels" с 2/n PBO лучше - один для чтения пикселей из кадрового буфера в PBO (n) с помощью графического процессора и другой 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);