GL_PIXEL_PACK_BUFFER,glBindBuffer的参数详解

本文深入解析OpenGL中的缓冲区对象概念及像素包装操作,详细讲解如何创建、绑定、填充以及删除缓冲区对象,同时阐述了像素包装的具体实现与应用,帮助开发者掌握在GPU中灵活存储数据的方法。

看完了这篇文章,你就对那些GL_PIXEL_PACK_BUFFER什么的不再陌生。感谢原作者的分享。。

http://blog.youkuaiyun.com/cs_huster/article/details/8570367

在OpenGL有缓冲区对象之前,应用程序只有有限的选择可以在GPU中存储数据,现在有了缓冲区之后对GPU存储空间的操作更加灵活方便了。缓冲区有很多用途,比如它能够保存顶点数据、像素数据、纹理数据、着色器处理的输入、不同阶段着色器的输出。要使用缓冲区首先要创建缓冲区:Gluint pixBuffObjs[1];glGenBuffers(1,pixBuffObjs)。前者定义一个无符号整形数组,其长度为一,在OpenGL中unsigned int 对应于Gluint;后者将定义的Gluint 数组产生一个缓冲区对象,创建完缓冲区以后要将这个缓冲区数组的每一个绑定到一个绑定点,比如绑定到GL_PIXEL_PACK_BUFFER,这个绑定点是像素包装操作的目标缓冲区,所谓像素包装就是对像素的格式重新格式化,比如以前像素是按照RGB每个颜色分量8个位存储的,包装后可以是按照BRG每个颜色分量2 6 8位的方式存储,对应于包装还有解包装,就是上述过程的逆过程。如前所述,绑定一个缓冲区的操作为:glBindBuffer(GL_PIXEL_PACK_BUFFER,pixBuffObjs[0]);那么这个操作就将pixBuffObjs的第一个对象绑定到GL_PIXEL_PACK_BUFFER绑定点了,那么以后执行glReadPixels之类的像素的包装操作便会将格式化后的像素数据存储于刚才绑定到那个绑定点的缓冲区了。用完之后可以删除缓冲区:glDeleteBuffers(int n,Gluint pixBuffObjs),n是缓冲区的数目,也即缓冲区数组的长度,pixBuffObjs是定义的缓冲区数组的名称。绑定完缓冲区后就可以用数据填充缓冲区了,glBufferData(GL_PIXEL_PACK_BUFFER,pixelDataSize,pixelData,GL_DYNAMIC_COPY);这个函数的第一个参数是GL_PIXEL_PACK_BUFFER,由于之前我们已经将pixBuf-fObjs[0]绑定到了这个绑定点,那么数据就会被存储在这个缓冲区里面,虽然这个函数没有出现该缓冲区的名字,在这里GL_PIXEL_PACK_-相当于是个中介,负责联系“房东”与“房客”;第二个参数是像素数据的大小;第三个参数是指向像素数据的地址指针;最后一个参数是用来指定如何使用缓冲区

glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); glGenTextures(1, &fboTexture); glBindTexture(GL_TEXTURE_2D, fboTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dstWidth, dstHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 创建Y分量纹理(R8格式) glGenTextures(1, &m_yTexture); glBindTexture(GL_TEXTURE_2D, m_yTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, dstWidth, dstHeight, 0, GL_RED, GL_UNSIGNED_BYTE, nullptr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 创建UV分量纹理(RG8格式,半分辨率) glGenTextures(1, &m_uvTexture); glBindTexture(GL_TEXTURE_2D, m_uvTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8, dstWidth, dstHeight, 0, GL_RG, GL_UNSIGNED_BYTE, nullptr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 附加Y纹理到颜色附件0 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_yTexture, 0); // 附加UV纹理到颜色附件1 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, m_uvTexture, 0); // 附加UV纹理到颜色附件1 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, m_yTexture, 0); GLenum drawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,GL_COLOR_ATTACHMENT2}; glDrawBuffers(3, drawBuffers); // 检查FBO完整性 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { qWarning("Framebuffer is not complete!"); //return false; } glBindFramebuffer(GL_FRAMEBUFFER, 0); 如何将 pbo中的数据传递
最新发布
08-22
### GL_PIXEL_PACK_BUFFER 的定义 `GL_PIXEL_PACK_BUFFER` 是一种像素缓冲区对象 (Pixel Buffer Object, PBO),用于存储从帧缓冲区读取的数据或纹理数据。当指定 `GL_PIXEL_PACK_BUFFER` 作为目标时,OpenGL 将把像素操作的结果写入绑定到此目标的缓冲区对象中,而不是直接返回给客户端内存[^1]。 ### 创建和使用 GL_PIXEL_PACK_BUFFER 为了创建并使用 `GL_PIXEL_PACK_BUFFER`,可以按照如下方式: #### 绑定 Pixel Pack Buffer 并分配空间 ```cpp GLuint pbo; glGenBuffers(1, &pbo); // 生成一个PBO名称 glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo); // 绑定该PBO至GL_PIXEL_PACK_BUFFER目标 glBufferData(GL_PIXEL_PACK_BUFFER, size, NULL, GL_STATIC_READ); // 分配服务器端存储器 ``` 上述代码片段展示了如何生成一个新的 PBO 名称,并将其绑定到 `GL_PIXEL_PACK_BUFFER` 目标上。接着通过调用 `glBufferData()` 函数来分配所需的内存量,其中第三个参数设置为 `NULL` 表明当前不提供任何初始数据。 #### 使用 Pixel Pack Buffer 进行图像读取 假设要从默认帧缓存中读取颜色附件的内容,则可以通过下面的方式实现: ```cpp // 假设 width 和 height 已经被正确初始化 glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo); glReadPixels(0, 0, width, height, format, type, nullptr); // 映射缓冲区以便访问其内容 void* ptr = glMapBufferRange( GL_PIXEL_PACK_BUFFER, 0, bufferSize, GL_MAP_READ_BIT | GL_MAP_INVALIDATE_BUFFER_BIT ); if(ptr){ // 对映射后的指针执行必要的处理... // 完成后解除映射 glUnmapBuffer(GL_PIXEL_PACK_BUFFER); } ``` 这段代码说明了怎样利用已有的 PBO 来接收来自 `glReadPixels()` 调用的数据流。注意,在实际应用中应当确保所提供的尺寸 (`bufferSize`) 符合预期需求,并且在完成所有针对映射区域的操作之后及时解绑(`glUnmapBuffer()`)以释放资源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值