OpenGL使用FBO与PBO上行纹理 (YUYV)

4 篇文章 1 订阅
订阅专栏

  本文记录在OpenGL中使用 帧缓冲 (FBO)和像素缓冲(PBO)来上行视频帧数据(YUYV), 并最终渲染显示出来。在之前的文章中介绍了渲染 YUV420 和 YUYV 的流程,不过都是用的默认的帧缓冲,即创建一个和视频幅面一样的 GLFW 窗口, 但是在实际开发中会遇到各种幅面的素材,,此时默认的 GLFW 帧缓冲就不满足要求了, 所以需要借助自定义的 FBO 来完成各种幅面视频帧的上行。


本文相关详细代码地址: https://github.com/pengguoqing/samples_code/tree/master/OpenGL

一、 帧缓冲(FBO)

  关于帧缓冲, LearnOpenGL 官方网站已经介绍得比较详细了, 这里就不再赘述。上行视频帧数据主要就是用到帧缓冲的颜色缓冲。首先根据视频帧的幅面为帧缓冲创建一个同幅面的纹理附件,FBO 创建纹理附件和渲染缓冲附件的流程都大体相似,所以就直接封装了一个简单的 CXFBO的 C++ 类,只需要简单的设置纹理附件的宽高参数即可,使用方式如下:

	CXFbo yuy2fbo;
	yuy2fbo.InitFbo(imgwidth, imgheight);
    yuy2fbo.UnBindFbo();

初始化的部分代码如下:

	glGenTextures(1, &m_colortex);
    glBindTexture(GL_TEXTURE_2D, m_colortex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colortex, 0);

二、 像素缓冲(PBO)

  关于PBO这篇文章有非常详细的介绍: http://www.songho.ca/opengl/gl_pbo.html, 这里贴出原文中一张能简单清晰的阐述 PBO 原理的示意图:

在这里插入图片描述
比如 CPU 解码出一帧 YUV 数据后, 如果使用 PBO上行的话那么CPU 只需要运算将 YUV 数据拷贝至 像素缓冲区这一步, 后续流程都由利用 GPU 强大的并行运行能力将像素缓冲区数据加载到GPU显存中。 与不使用 PBO相比, CPU 只需要进行一次拷贝即可, 否则整个过程都由 CPU 控制,时钟周期这一缺点就显露出来了。这里贴出封装的 PBO初始化流程和调用接口:

public:
    bool Init(uint32_t width, uint32_t height, PBOTYPE type, GLenum pixfmt);
    void Map(uint8_t** ptr, uint32_t* linesize) const;
    void UnMap() const;
    void Bind() const;
    void UnBind() const;
bool CXPbo::Init(uint32_t width, uint32_t height, PBOTYPE type, GLenum pixfmt)
{
   m_width  = width;
   m_hegit  = height;
   m_pixfmt = pixfmt;
   
   switch (type)
   {
   case PBOTYPE::kDynamic:
        m_rwtype = GL_PIXEL_UNPACK_BUFFER;
    break;
   case PBOTYPE::kStage:
        m_rwtype = GL_PIXEL_PACK_BUFFER;
    break;
   default:
        return false;
    break;
   }
   

   glGenBuffers(1, &m_pbo);
   if (!m_pbo)
   {
     return false;
   }
    
   glBindBuffer(m_rwtype, m_pbo);

   m_pbosize  = m_width * GetPixfmtBpp(pixfmt) / 8;
   m_pbosize  = (m_pbosize + 3) & 0xFFFFFFFC;
   m_pbosize  *= m_hegit;
   glBufferData(m_rwtype, m_pbosize, nullptr, GL_STREAM_DRAW);

   glBindBuffer(m_rwtype, 0);

   return true;
}

三、 关于YUYV纹理的采样

  在之前的文章中 OpenGL渲染YUYV, 因为默认的帧缓冲和实际的素材的幅面相同, 而且又是用的 RGBA 来存储一组完整的 YUYV 数据, 所以 shader 中使用 texture直接采样时会自动进行插值,这就会导致 YUV 不是 严格严格匹配的,正确的做法是需要使用 textuerLod来加载原始纹理,以保证YUV的严格匹配,shader 如下:

vec3 SampleYUYV(vec2 pos)
{
	ivec2 size		= textureSize(image,  0);
	ivec2 actualpos = ivec2(pos.x, pos.y);
	vec2  actualuv	= (vec2(actualpos.xy)+0.5)/size;
	vec4 yuyv		= textureLod(image, actualuv, 0);
	
	float leftover  = fract(pos.x);
	float y   = (leftover<0.5f) ? yuyv.x : yuyv.z;

    vec3 yuv = vec3(y, yuyv.yw);

	return YUV_to_RGB(yuv);	
}

四、 测试 Demo

   首先准备一张 1280 * 960 幅面的 YUYV 数据,然后用 GLFW 创建一个 960 * 540 (16:9)的窗口用于显示。代码中使用宏来配置是否使用 PBO模式

#define USE_PBO  true

渲染管线的 pass 如下:

 while (!glfwWindowShouldClose(winhandle))
    {
        processInput(winhandle);
        glViewport(0, 0, imgwidth, imgheight);
        
        yuy2fbo.BindFbo();
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);
        uploadshader.use();
        UploadYUYV(yuy2pbo, imgdata, uploadtex);

		glBindVertexArray(uploadvao);
		glBindTexture(GL_TEXTURE_2D, uploadtex);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
        glBindTexture(GL_TEXTURE_2D, 0);
        yuy2fbo.UnBindFbo();
        glBindVertexArray(0);

		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);
        glViewport(0, 0, wndwidth, wndheight);
        rendershader.use();
        glBindVertexArray(rendervao);
        yuy2fbo.BindColorTexture();
        glGenerateMipmap(GL_TEXTURE_2D);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
        yuy2fbo.UnBindColorTexture();
        glfwSwapBuffers(winhandle);
        glfwPollEvents();
    }

渲染结果如下:
在这里插入图片描述
使用 PBO后的纹理上行效率如下:
在这里插入图片描述
使用 glTexSubImage2D直接上行纹理的效率如下:
在这里插入图片描述
可以发现效率差别还是蛮大的。

五、 总结

  ① 使用 PBO进行纹理上行的效率要由于 glTexSubImage2D,但是测试的时候发现假如把 glMapBuffer的整个时间算上的话,两者其实是相差不多的。所以实际开发中可能需要 多个 PBO来交替上行纹理。
  ②渲染管线中存在多个 Pass 需要借助 帧缓冲来实现。

Opengl ES之PBO
翻肚鱼儿的博客
03-14 1067
opengl pbo
OpenGL之VBO,PBOFBO技术
Ai_ViVi的专栏
01-15 2958
VBO(vertex buffer object)是GPU上存储顶点数据的高速缓存。在应用程序初始化阶段,顶点数据被直接传送到显卡中的高速缓存上,在绘制时可以直接从高速缓存中获取,除非几何数据需要修改,否则VBO数据不需变化。除了VBO技术外,OpenGL还提供顶点数组和显示列表的绘制方式。顶点数组可以降低函数调用次数与降低共享顶点的重复使用,但顶点数组函数位于客户端状态中,且每次引
OpenGL-ES 学习(8) ---- FBO
最新发布
小猪佩奇的博客
08-18 1020
通过绘制到窗口系统提供的帧缓冲区,然后将帧缓冲区对应的区域复制到纹理来实现渲染到纹理,但是此方法只有在纹理尺寸小于或等于帧缓冲区尺寸才有效。本身不能用于渲染,只有添加了纹理或者纹理缓冲区之后才可以作为渲染目标,而且它仅且提供了三类附着,分别是。来实现渲染到纹理,但是与上下文和窗口系统提供的可绘制表面切换开销也很大,因此,引入了帧缓冲区对象。指的是帧缓冲对象,实际上是一个可以添加缓冲区容器,可以为其添加纹理或者渲染缓冲区对象(这里需要说明的是,在不可以共享的资源中,,可以用作FBO中的颜色、深度和模板附着。
VBO, PBOFBO(三)
12-02 4289
VBO, PBOFBO(三) (2008-08-14 22:52:28) var $tag=fbo,framebuffer,opengl,extension,it; var $tag_code=d44a32e48ae5a36022b8aa5e75dcca79; 标签:fbo frame
OpenGL VBO, PBOFBO
ym19860303的专栏
07-21 9244
VBO,Vertex Buffer Array     为了加快显示速度,显卡增加了一个扩展,即VBO。它本质上是存储几何数据的缓存。它直接把顶点数据放置到显卡中的高速缓存,极大提高了绘制速度。      这个扩展用到ARB_vertex_buffer_object,它可以直接像顶点数组那样使用。唯一不同的地方在于它需要将数据载入显卡的高效缓存,因此需要占用渲染时间。      [参考文章1
OpenGL VBO, PBOFBO
翻肚鱼儿的博客
08-11 730
VBO,Vertex Buffer Array 为了加快显示速度,显卡增加了一个扩展,即VBO。它本质上是存储几何数据的缓存。它直接把顶点数据放置到显卡中的高速缓存,极大提高了绘制速度。 这个扩展用到ARB_vertex_buffer_object,它可以直接像顶点数组那样使用。唯一不同的地方在于它需要将数据载入显卡的高效缓存,因此需要占用渲染时间。 [参考文章1] 给出了一个使用VBO扩展的例子程序。[参考文章2]罗列了与VBO操作相关的函数 [参考文章3]归纳出VBO...
【转】VBO, PBOFBO
woashizhangsi的专栏
12-12 631
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <div id="content" class= "content mod-cs-content text-content clearfi
wayland(xdg_wm_base) + egl + opengles 使用FBO渲染到纹理实例(六)
lh0616的博客
02-16 1472
本文主要介绍 如何在 opengles 中使用FBO 实现渲染到纹理的功能软硬件环境:硬件:PC软件:ubuntu22.04 opengles3.0 egl1.4FBO(Framebuffer Object)是OpenGL的一个扩展,它允许我们将渲染结果直接绘制到一个纹理或者渲染缓冲对象中,而不是默认的帧缓冲。使用FBO可以实现一些高级的渲染技术,如离屏渲染、后期处理、抗锯齿等。
FBO.zip_FBO_OpenGL FBO_OpenGLfbo_fbo in opengl
09-14
在学习和使用FBO时,理解OpenGL的渲染流水线、纹理和缓冲区管理非常重要。同时,掌握如何检查和解决FBO不完整状态也是必不可少的技能。通过深入研究提供的文件,开发者可以提升自己在OpenGL FBO方面的专业能力,从而...
OpenGL ES之深入解析PBO、UBO与TBO的功能和使用
╰つ栺尖篴夢ゞ
06-23 1462
OpenGL PBO(Pixel Buffer Object),被称为像素缓冲区对象,主要被用于异步像素传输操作。PBO 仅用于执行像素传输,不连接到纹理,且与 FBO (帧缓冲区对象)无关。UBO,就是一个装载 uniform 变量数据的缓冲区对象,本质上跟 OpenGL ES 的其他缓冲区对象没有区别,创建方式也大致一致,都是显存上一块用于储存特定数据的区域。TBO 即“纹理缓冲区对象”,是 OpenGL ES 3.2 引入的概念,因此在使用时首先要检查 OpenGL ES 的版本。...
Opengl使用FBO实现的地球表面海洋流动效果
09-11
"Opengl使用FBO实现的地球表面海洋流动效果"是一个典型的使用OpenGLFBO进行高级渲染的例子。这个项目可能是创建一个模拟地球表面的3D模型,并通过FBO来实现海洋表面的流动视觉效果。海洋流动通常涉及到复杂的纹理...
OpenGLOpenGL帧缓存对象(FBO:Frame Buffer Object)
热门推荐
计算机专业同学的充电站。
02-22 6万+
翻译的,如果不正确,敬请谅解和指正。 OpenGL Frame BufferObject(FBO) Overview:     在OpenGL渲染管线中,几何数据和纹理经过多次转化和多次测试,最后以二维像素的形式显示在屏幕上。OpenGL管线的最终渲染目的地被称作帧缓存(framebuffer)。帧缓冲是一些二维数组和OpenG所使用的存储区的集合:颜色缓存、深度缓存、模板缓存和累计缓存。一
OpenGL FBO ,PBO ,VBO
Pizza_Lawson的专栏
12-20 463
转自:http://www.songho.ca/opengl/gl_pbo.html   Overview   OpenGL PBO OpenGL ARB_pixel_buffer_object extension is very close to ARB_vertex_buffer_object. It simply expands ARB_vertex_buffer_object ex...
OpenGLFBO的概念及其应用
03-06 1464
<br />OpenGLFBO的概念及其应用<br /> <br />【本帖转自 http://www.cppblog.com/kongque/archive/2010/08/26/124754.html】<br /> <br />FBO一个最常见的应用就是:渲染到纹理(render to texture),通过这项技术可以实现发光效果,环境映射,阴影映射等很炫的效果。<br /><br />OpenGL中的Frame Buffer Object(FBO)扩展,被推荐用于把数据渲染到纹理对像。相对于其它同
OpenGL Pixel Buffer Object (PBO)
weixin_30245867的博客
02-20 99
Related Topics:Vertex Buffer Object (VBO),Frame Buffer Object (FBO) Download:pboUnpack.zip,pboPack.zip OverviewCreating PBOMapping PBOExample: Streaming Texture Uploads with PBOExam...
OpenGL 渲染 YUYV(YUV422)
PX1525813502的博客
05-28 5029
OpenGL渲染YUYV(YUV422)
Opengl FBO
logcabin的专栏
02-18 1589
http://www.zwqxin.com/archives/opengl/learn-fbo.html FBO这个名字应该记住,同时还得记住VBO,PBO——这些算得上OpenGL的高级技术了,但是可以说,用处很广。从拓展到即将的核心,证明了它们的价值。这里我主要讲讲FBO(因为最近只用到FBO嘛嘿),全名Frame Buffer Object,目前主要用于离屏渲染技术。——ZwqXin.
写文章

热门文章

  • Windows下编译ffmpeg的几种方式 12015
  • QT 在线安装速度慢解决方案 6938
  • ubuntu 通过 apt-get 安装软件失败时的解决方案 5795
  • OpenGL 渲染 YUYV(YUV422) 5029
  • AAC音频格式解析(ADTS) 4029

分类专栏

  • Tools 9篇
  • C++ 14篇
  • FFmpeg 3篇
  • OpenGL 4篇
  • 音视频 2篇
  • QT 3篇
  • Windows
  • 图形学 2篇

最新评论

  • 线性代数基础(变换)

    fishjumprprpr: 为什么平移变换之后,向量的模长变了

  • C++性能优化实践 三

    普通网友: 好文,细节很到位!【我也写了一些相关领域的文章,希望能够得到博主的指导,共同进步!】

  • OpenGL使用FBO与PBO上行纹理 (YUYV)

    程序员~彭国庆: EGL 还没有用过额,所以无法回答大佬的这个问题,您看看这个链接相关的网页有没有答案额 https://registry.khronos.org/EGL/extensions/EXT/EGL_EXT_image_dma_buf_import.txt

  • OpenGL使用FBO与PBO上行纹理 (YUYV)

    可乐加冰块。: 请问下这个例子有办法改成用EGL_LINUX_DRM_FOURCC_EXT来导入dma fd吗,我仿造你的例子用glTexImage2D的方法是可以的,但是改成用外部fd的话就不行了,是不是这两种的流程就不一样了,着色器需要改下表情包

  • OpenGL 渲染 YUYV(YUV422)

    程序员~彭国庆: 问题已解决:https://blog.csdn.net/PX1525813502/article/details/129755979?spm=1001.2014.3001.5501

大家在看

  • 【项目实战】如何在项目中基于 Spring Boot Starter 开发简单的 SDK 422
  • springboot基于java的社区居民诊疗健康管理系统(源码+文档+调试+vue+前后端分离) 441
  • LeetCode力扣——并查集:947. 移除最多的同行或同列石头,1971. 寻找图中是否存在路径,2424. 最长上传前缀 684
  • 地平线秋招内推2025 391
  • string类(下)(模拟实现string类,深度剖析其底层) 883

最新文章

  • C++ std::variant 总结
  • C++性能优化实践 三
  • C++性能优化实践 二
2024年3篇
2023年10篇
2022年20篇
2021年4篇

目录

目录

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

玻璃钢生产厂家新余人物玻璃钢雕塑销售厂家流行玻璃钢雕塑邯郸校园玻璃钢景观雕塑设计安徽创意玻璃钢雕塑多少钱内蒙玻璃钢雕塑厂家邯郸校园玻璃钢雕塑定制玻璃钢抽象景观雕塑报价焦作玻璃钢人物雕塑制作价格玻璃钢花盆怎么做的玻璃钢花盆雕塑多少钱玻璃钢门头雕塑陕西玻璃钢人物雕塑价格重庆玻璃钢造型雕塑制作玻璃钢小孩雕塑江苏人物玻璃钢雕塑制作雕塑玻璃钢现场考察场地报告宿州制作玻璃钢雕塑公司多少钱菏泽水景玻璃钢景观雕塑厂家浙江室外玻璃钢花盆江西定做玻璃钢雕塑长沙步行街玻璃钢雕塑山东玻璃钢雕塑制造厂保定玻璃钢雕塑服务至上浙江超市商场美陈采购山东大型商场创意商业美陈思路萍乡玻璃钢卡通雕塑上海大型主题商场美陈供应商玻璃钢大型城市雕塑厂家抚州欧式玻璃钢雕塑销售厂家清远玻璃钢浮雕雕塑香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化