glBindFramebuffer() 离屏渲染+双缓存+读取opengl像素 glReadPixels()

本文主要是介绍glBindFramebuffer() 离屏渲染+双缓存+读取opengl像素 glReadPixels(),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Opengl4.0中可以进行离屏渲染,即创造一个帧缓存对象(FBO),绑定一个帧缓存对象后,所有对Op--engl的操作都会针对这个帧缓存对象执行。而最近做项目时,在做一个拍照功能——读取Opengl渲染出的像素,并存入到BMP位图中。项目采用的是Opengl1.0和Opengl4.3结合的方法,并且两者的使用相对独立。使用旧的Opengl方法运行程序时,通过
glReadBuffer(GL_FRONT);//指定要读取的缓存
glReadPixels(0, 0, width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, (unsigned char*)imageData);
即可读取到像素,并保存起来。

但是,一旦使用Opengl4.3进行离屏渲染后,发现glReadBuffer()和glReadPixels()不能再读取到像素,于是我对每一部分使用Opengl4.3的代码都做了glGetError()检测,发现使用Opengl4.3的代码部分并没有调用错误,所以就一直查不出来问题在哪里。最后我想会不会是Opengl绑定的问题,终于发现Opengl4.3使用离屏渲染后没有解绑帧缓存。

解决方案即:在使用完帧缓存对象的最后,对帧缓存对象进行解绑,函数如下

glBindFramebuffer(GL_FRAMEBUFFER, GL_NONE);
于是我去查了www.khronos.org/关于glBindFramebuffer的定义:
While a non-zero framebuffer object name is bound, all rendering to the framebuffer (with glDrawArrays and glDrawElements) and reading from the framebuffer (with glReadPixels, glCopyTexImage2D, or glCopyTexSubImage2D) use the images attached to the application-created framebuffer object rather than the default window-system-provided framebuffer.
Application created framebuffer objects (i.e. those with a non-zero name) differ from the default window-system-provided framebufferin a few important ways. First, they have modifiable attachment points for a color buffer, a depth buffer, and a stencil buffer to which framebuffer attachable images may be attached and detached. Second, the size and format of the attached images are controlled entirely within the GL and are not affected by window-system events, such as pixel format selection, window resizes, and display mode changes. Third, when rendering to or reading from an application created framebuffer object, the pixel ownership test always succeeds (i.e. they own all their pixels).Fourth, there are no visible color buffer bitplanes, only a single "off-screen" color image attachment, so there is no sense of front and back buffers or swapping. Finally, there is no multisample buffer, so the value of the implementation-dependent state variables GL_SAMPLES and GL_SAMPLE_BUFFERS are both zero for application created framebuffer objects.
也就是说,使用glBindFramebuffer()进行离屏渲染时,Opengl的渲染和读取都是通过attached的纹理对帧缓存进行操作的,不再是对windows系统提供的默认帧缓存进行操作,所以我们见到的屏幕上显示出来的图像并不是一个可见的颜色缓存位面(visible color buffer bitplane),只不过是一个“离屏”的颜色纹理("off-screen" color image attachment),所以双缓存就不起作用了(即使调用swapbuffer(),像素也不会被渲染到前后缓存中),所以glReadBuffer(GL_FRONT);也就读取不出像素出来。
这个Bug前后找了将近两个星期,在这里Mark一下,说白了还是对Opengl理解不够,Opengl的使用个人感觉比较晦涩,还需要好好研究。希望对大家有所帮助。
格式一直调不好。。好吧。。

这篇关于glBindFramebuffer() 离屏渲染+双缓存+读取opengl像素 glReadPixels()的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1042767

相关文章

C#读取本地网络配置信息全攻略分享

《C#读取本地网络配置信息全攻略分享》在当今数字化时代,网络已深度融入我们生活与工作的方方面面,对于软件开发而言,掌握本地计算机的网络配置信息显得尤为关键,而在C#编程的世界里,我们又该如何巧妙地读取... 目录一、引言二、C# 读取本地网络配置信息的基础准备2.1 引入关键命名空间2.2 理解核心类与方法

Redis与缓存解读

《Redis与缓存解读》文章介绍了Redis作为缓存层的优势和缺点,并分析了六种缓存更新策略,包括超时剔除、先删缓存再更新数据库、旁路缓存、先更新数据库再删缓存、先更新数据库再更新缓存、读写穿透和异步... 目录缓存缓存优缺点缓存更新策略超时剔除先删缓存再更新数据库旁路缓存(先更新数据库,再删缓存)先更新数

el-select下拉选择缓存的实现

《el-select下拉选择缓存的实现》本文主要介绍了在使用el-select实现下拉选择缓存时遇到的问题及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录项目场景:问题描述解决方案:项目场景:从左侧列表中选取字段填入右侧下拉多选框,用户可以对右侧

SpringBoot使用注解集成Redis缓存的示例代码

《SpringBoot使用注解集成Redis缓存的示例代码》:本文主要介绍在SpringBoot中使用注解集成Redis缓存的步骤,包括添加依赖、创建相关配置类、需要缓存数据的类(Tes... 目录一、创建 Caching 配置类二、创建需要缓存数据的类三、测试方法Spring Boot 熟悉后,集成一个外

opencv实现像素统计的示例代码

《opencv实现像素统计的示例代码》本文介绍了OpenCV中统计图像像素信息的常用方法和函数,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 统计像素值的基本信息2. 统计像素值的直方图3. 统计像素值的总和4. 统计非零像素的数量

SpringBoot使用Apache POI库读取Excel文件的操作详解

《SpringBoot使用ApachePOI库读取Excel文件的操作详解》在日常开发中,我们经常需要处理Excel文件中的数据,无论是从数据库导入数据、处理数据报表,还是批量生成数据,都可能会遇到... 目录项目背景依赖导入读取Excel模板的实现代码实现代码解析ExcelDemoInfoDTO 数据传输

使用Spring Cache时设置缓存键的注意事项详解

《使用SpringCache时设置缓存键的注意事项详解》在现代的Web应用中,缓存是提高系统性能和响应速度的重要手段之一,Spring框架提供了强大的缓存支持,通过​​@Cacheable​​、​​... 目录引言1. 缓存键的基本概念2. 默认缓存键生成器3. 自定义缓存键3.1 使用​​@Cacheab

Python读取TIF文件的两种方法实现

《Python读取TIF文件的两种方法实现》本文主要介绍了Python读取TIF文件的两种方法实现,包括使用tifffile库和Pillow库逐帧读取TIFF文件,具有一定的参考价值,感兴趣的可以了解... 目录方法 1:使用 tifffile 逐帧读取安装 tifffile:逐帧读取代码:方法 2:使用

Nacos客户端本地缓存和故障转移方式

《Nacos客户端本地缓存和故障转移方式》Nacos客户端在从Server获得服务时,若出现故障,会通过ServiceInfoHolder和FailoverReactor进行故障转移,ServiceI... 目录1. ServiceInfoHolder本地缓存目录2. FailoverReactorinit

缓存雪崩问题

缓存雪崩是缓存中大量key失效后当高并发到来时导致大量请求到数据库,瞬间耗尽数据库资源,导致数据库无法使用。 解决方案: 1、使用锁进行控制 2、对同一类型信息的key设置不同的过期时间 3、缓存预热 1. 什么是缓存雪崩 缓存雪崩是指在短时间内,大量缓存数据同时失效,导致所有请求直接涌向数据库,瞬间增加数据库的负载压力,可能导致数据库性能下降甚至崩溃。这种情况往往发生在缓存中大量 k