如果您想要与应用程序同步读取数据,那么从gpu获取数据似乎是一项非常缓慢的任务。一种可能性是在Pixel Buffer Objects的帮助下读取异步。不幸的是,我无法看到这是如何完成的。
首先我创建一个Pixel Buffer Object:
glGenBuffers(1, &pbo);
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
glBufferData(GL_PIXEL_PACK_BUFFER, pbo_size, 0, GL_DYNAMIC_READ);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
然后我想读取帧缓冲对象中的像素:
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
glReadPixels(0, 0, w, h, GL_RGBA, GL_FLOAT, 0);
GLfloat *ptr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, pbo_size, GL_MAP_READ_BIT);
memcpy(pixels, ptr, pbo_size);
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
但这是如何异步的? glReadPixels或glMapBufferRange是否阻止了应用程序,直到gpu准备就绪?
答案 0 :(得分:3)
glReadPixels
调用应该将副本启动到cpu可见缓冲区。 (无论何时将其提交给GPU。您可以使用glFlush
强制提交。您以异步方式启动读取。
glMapBufferRange
会强制glReadPixels
调用完成,如果它不是(因为你现在正在访问CPU上的指针,那里就没办法了)。
所以......不要背对背做2,而是要做得更晚。
答案 1 :(得分:0)
要添加到Bahbar的答案中:
在glReadPixels
之后,如果您打算回读数据,我相信您应该致电glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT);
。
在glReadPixels
和glMemoryBarrier
之后,您可以创建与glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0)
的Fence同步,然后在与{{1]同步之前检查GPU是否已完成所有指令的执行}},或等待GPU完成执行所有指令,然后再与glGetSynciv(fence_sync, GL_SYNC_STATUS, sizeof(GLint), NULL, &result)
进行同步。