Android OpenGL ES 3.0 PBO像素缓冲区对象
创始人
2024-04-12 04:37:50
0

1.什么是PBO

OpenGL PBO(Pixel Buffer Object),被称为像素缓冲区对象,主要被用于异步像素传输操作。PBO 仅用于执行像素传输,不连接到纹理,且与 FBO (帧缓冲区对象)无关。

OpenGL PBO(像素缓冲区对象) 类似于 VBO(顶点缓冲区对象),PBO 开辟的也是 GPU 缓存,而存储的是图像数据。

PBO 绑定相关的 Target 标签有 2 个:

  • GL_PIXEL_UNPACK_BUFFER:将PBO绑定到这个上边,glTexImage2D和glTexSubImage2D() 表示从PBO中解包像素数据并恢复到帧缓冲区

  • GL_PIXEL_PACK_BUFFER:将PBO绑定到这个上边时,glReadPixels()表示从帧缓冲区中读取数据并打包进PBO

2.为什么要使用PBO

处理高分辨率的图像时,图像数据在内存和显存之前拷贝往往会造成性能瓶颈,而利用 PBO 可以在一定程度上解决这个问题。

使用 PBO 可以在 GPU 的缓存间快速传递像素数据,不影响 CPU 时钟周期,除此之外,PBO 还支持异步传输。

传统的方式:从文件中加载纹理,图像数据首先被加载到 CPU 内存中,然后通过 glTexImage2D 函数将图像数据从 CPU 内存复制到 OpenGL 纹理对象中 (GPU 内存),两次数据传输(加载和复制)完全由 CPU 执行和控制。

使用PBO的方式:可以通过 glMapBufferRange 获取 PBO 对应 GPU 缓冲区的内存地址。将图像数据加载到 PBO 后,再将图像数据从 PBO 传输到纹理对象中完全是由 GPU 控制,不会占用 CPU 时钟周期。所以,绑定 PBO 后,执行 glTexImage2D (将图像数据从 PBO 传输到纹理对象) 操作,CPU 无需等待,可以立即返回。

通过对比这两种(将图像数据传送到纹理对象中)方式,可以看出,利用 PBO 传输图像数据,省掉了一步 CPU 耗时操作(将图像数据从 CPU 内存复制到 纹理对象中)

3.PBO的使用

3.1PBO的创建
/*** 创建PBO 用于读取纹理上的像素数据* StreamRead 流的方式读取*/
m_PBOfst = new MSOpenGLBuffer(MSOpenGLBuffer::PixelPackBuffer,MSOpenGLBuffer::StreamRead);
m_PBOsnd = new MSOpenGLBuffer(MSOpenGLBuffer::PixelPackBuffer,MSOpenGLBuffer::StreamRead);
//构造函数
MSOpenGLBuffer::MSOpenGLBuffer(MSOpenGLBuffer::Type type, MSOpenGLBuffer::UsagePattern usage):m_bufferType(type),m_usage(usage),m_buffSize(0)
{glGenBuffers(1, &m_buffID);}

创建方式是GL_PIXEL_PACK_BUFFER,用于从纹理上读取像素数据,用于流的方式进行读取。

3.2PBO设置bufferData
m_PBOfst->Bind();
m_PBOfst->SetBufferData(nullptr,m_nResolution.x*m_nResolution.y*4);
m_PBOfst->Release();m_PBOsnd->Bind();
m_PBOsnd->SetBufferData(NULL,m_nResolution.x * m_nResolution.y * 4); 
m_PBOsnd->Release();
//Bind 函数
void MSOpenGLBuffer::Bind()
{glBindBuffer(m_bufferType, m_buffID);
}
//release函数
void MSOpenGLBuffer::Release()
{glBindBuffer(m_bufferType, 0);
}void MSOpenGLBuffer::SetBufferData(const GLvoid *data, GLsizeiptr size)
{if (size > m_buffSize) {m_buffSize = size;glBufferData(m_bufferType, size, data, m_usage);} else {glBufferSubData(m_bufferType, 0, size, data);}
}

给连个PBO设置BufferData

3.3通过PBO进行数据读取
/*** 通过m_currIdx 来控制 两个PBO交替控制*/
void MSGLScene::processPBOReadPixels() {glReadBuffer(GL_FRONT);if(m_currIdx == 0){readPixelsFromPBO(m_PBOfst,m_PBOsnd);m_currIdx =1;}else{readPixelsFromPBO(m_PBOsnd,m_PBOfst);m_currIdx =0;}
}void MSGLScene::readPixelsFromPBO(MSOpenGLBuffer *fstBuff, MSOpenGLBuffer *sndBuff) {int w = m_nResolution.x;int h = m_nResolution.y;fstBuff->Bind();glReadPixels(0,0,w,h,GL_RGBA,GL_UNSIGNED_BYTE,0);//READsndBuff->Bind();void* data= glMapBufferRange(GL_PIXEL_PACK_BUFFER,0,w*h*4,GL_MAP_READ_BIT);if (data){MSVideoWriter::GetInstance()->WriteVideoFrameWithRgbData((const unsigned char*)data);}glUnmapBuffer(GL_PIXEL_PACK_BUFFER);glBindBuffer(GL_PIXEL_PACK_BUFFER,0);}

通过两个PBO交替读取数据,glMapBufferRange读取到结果就是:从纹理上读取到的RBG数据,此时数据就可以交给FFmpeg或者MediaCodec进行编码,并进行视频合成了。

相关内容

热门资讯

怎么才能让鹦鹉说话? 怎么才能让鹦鹉说话?不是所有鹦鹉都会说话的,虎皮 牡丹 玄凤 之类的就不会说话,虽然有些资料上介绍 ...
孙悟空在南瞻部州被称呼为什么? 孙悟空在南瞻部州被称呼为什么?孙悟空在南瞻部州被称为孙大圣。他的称呼是比较威武凶猛的。因为他的人物形...
“每一个晚上”英语怎么讲 “每一个晚上”英语怎么讲every night
我在红袖写了一篇小说,只有签约... 我在红袖写了一篇小说,只有签约,没有上架,请问怎么样才能拿到稿费,我是签网协的每天都有更新的话。。达...
王朔:这辈子最对不起老婆和女儿... 王朔:这辈子最对不起老婆和女儿,但我死后财产全归徐静蕾,这是为何呢?因为在这个人的心中,徐静蕾才是自...
游戏《天地玄门》激活账号的激活... 游戏《天地玄门》激活账号的激活码怎么写?那个游戏得发短信到腾武才会获得激活码
孩子课后作业辅导,如何让老公平... 孩子课后作业辅导,如何让老公平心静气的教孩子?可以告诉老公,孩子的辅导需要老公有耐心一些,因为孩子犯...
《阿姨暖暖你的手》阅读题答案 《阿姨暖暖你的手》阅读题答案1、“春寒料峭”和“春暖花开”都是形容春天的词语。文中第(2)段中的“春...
想找到一本有声小说,喜马拉雅有... 想找到一本有声小说,喜马拉雅有,但是我忘记名字了。讲的是茅山道士的故事,但不是紫襟讲的,我问过了?书...
郝邵文合释小龙都演过什么电影我... 郝邵文合释小龙都演过什么电影我想知道,要全的1、笑林小子(又名:旋风小子)2、笑林小子2之乌龙院3、...
林黛玉放屁拉肚子 林黛玉放屁拉肚子林黛玉放屁拉肚子是《红楼梦》中的一个情节。在小说中,林黛玉因为情绪低落和身体不适而出...
克雷洛夫寓言有哪些寓言故事?故... 克雷洛夫寓言有哪些寓言故事?故事的主要内容及道理是什么?最起码说出3个,克雷洛夫寓言有哪些寓言故事?...
请告诉我一点笑话! 请告诉我一点笑话!告诉我一点笑话便可!如此美丽夜晚孤独是一种遗憾,想念着得不到的爱情已经成为习惯,情...
樱花、新年、任性、武士、爆破、... 樱花、新年、任性、武士、爆破、缇娜、武媚娘、土豪biangbiang面、萌萌哒、小鲜肉、醉了 用以上...
东北出马仙堂怎么写 东北出马仙堂怎么写去找高人查看 ,看看是否具备出马缘分,出马仙的堂单一般都是仙 或者给你立堂的师傅给...
探访鹿邑:漫步古城,寻迹历史名... 探访鹿邑:漫步古城,寻迹历史名人之路鹿邑是一个历史悠久的古城,有着丰富的文化底蕴和历史遗迹。探访鹿邑...
类似与儒道至圣的小说 类似与儒道至圣的小说[剑三+文修]自古名士真国色[系统]国士无双
星际争霸2人族怎么防隐形?怎么... 星际争霸2人族怎么防隐形?怎么看隐形?:轨道控制基地的雷达,防空塔和渡鸦自带的反隐效果人族有4招防隐...
谁有《从零开始学画漫画》电子书... 谁有《从零开始学画漫画》电子书 谢谢亲,去狗狗书籍呗,你去新浪爱问搜搜,应该能找到》
公主日记1里有首笨爱神的歌叫什... 公主日记1里有首笨爱神的歌叫什么名字stupid cupidstupid cupidstupid c...