首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用PBO实现深度值非阻塞glReadPixels

用PBO实现深度值非阻塞glReadPixels
EN

Stack Overflow用户
提问于 2019-05-05 17:03:57
回答 1查看 1K关注 0票数 0

我从框架缓冲区读取单个像素的深度以实现拾取。最初,我的glReadPixels()花费了很长时间(大约5ms),而在nVidia上,它甚至会在那段时间内使用刻录100% CPU。在英特尔,这也是缓慢的,但与闲置的CPU。

从那时起,我使用PixelBufferObject功能,PBO,使glReadPixels异步,并使用这个众所周知的例子进行双缓冲。

这种方法工作得很好,让我们创建一个glReadPixels()调用异步,但前提是我必须读取RGBA值。如果我使用相同的PBO方法读取深度值,则glReadPixels()再次阻塞。

读取RGBA: glReadPixels()需要12 s。

读取深度: glReadPixels()需要5ms。

我在nVidia和英特尔的驱动程序上试过这个。具有不同的格式/类型组合。我试过:

代码语言:javascript
复制
glReadPixels( srcx, srcy, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, 0 );

以及:

代码语言:javascript
复制
glReadPixels( srcx, srcy, 1, 1, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0 );

以及:

代码语言:javascript
复制
glReadPixels( srcx, srcy, 1, 1, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 0 );

所有这些都不会导致异步glReadPixels()调用。但是,如果我使用以下调用读取RGBA值:

代码语言:javascript
复制
glReadPixels( srcx, srcy, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 0 );

然后glReadPixels()立即返回,因此不再阻塞。

在读取单个像素之前,我需要:

代码语言:javascript
复制
glReadBuffer( GL_FRONT );
glBindBuffer( GL_PIXEL_PACK_BUFFER, pboid );

我创建了双缓冲PBO:

代码语言:javascript
复制
glGenBuffers( NUMPBO, pboids );
for ( int i=0; i<NUMPBO; ++i )
{
    const int pboid = pboids[i];
    glBindBuffer( GL_PIXEL_PACK_BUFFER, pboid );
    glBufferData( GL_PIXEL_PACK_BUFFER, DATA_SIZE, 0, GL_STREAM_READ );
    ...

我使用深度大小为24、模板大小为8和默认的双缓冲区的SDL2创建框架缓冲区。

我正在Ubuntu上使用OpenGL核心配置文件3.3。

EN

回答 1

Stack Overflow用户

发布于 2019-05-05 17:38:26

直到下一帧,我才实际读取像素深度(通过glMapBuffer),因此没有同步。glReadPixel应该触发一个异步操作并立即返回(就像对RGBA那样)。但就阅读深度而言,事实并非如此。

这就需要有两个深度缓冲区。但事实并非如此。多重缓冲指的是颜色缓冲区的数量,因为这些才是真正显示的。实现几乎从不为您提供多个深度缓冲区。

为了从深度缓冲区读取数据,必须在“下一个帧”发生之前进行读取。所以需要同步。

一般来说,最好从你自己的图片中读出来。这样,您就可以完全控制诸如格式,当它们被重用时,等等,这样您就可以控制同步问题。如果您需要两个深度缓冲区,以便您可以在使用另一个深度缓冲区时从其中一个读取,则需要创建该缓冲区。

而且FYI:由于像素所有权问题之类的原因,从默认的框架缓冲区读取数据是值得怀疑的。但是,从前面的缓冲区读取数据几乎总是错误的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55994376

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档