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

相关文章

MySQL8.0设置redo缓存大小的实现

《MySQL8.0设置redo缓存大小的实现》本文主要在MySQL8.0.30及之后版本中使用innodb_redo_log_capacity参数在线更改redo缓存文件大小,下面就来介绍一下,具有一... mysql 8.0.30及之后版本可以使用innodb_redo_log_capacity参数来更改

C#中读取XML文件的四种常用方法

《C#中读取XML文件的四种常用方法》Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具,下面我们就来看看C#中读取XML文件的方法都有哪些吧... 目录XML简介格式C#读取XML文件方法使用XmlDocument使用XmlTextReader/XmlTextWr

Python利用自带模块实现屏幕像素高效操作

《Python利用自带模块实现屏幕像素高效操作》这篇文章主要为大家详细介绍了Python如何利用自带模块实现屏幕像素高效操作,文中的示例代码讲解详,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1、获取屏幕放缩比例2、获取屏幕指定坐标处像素颜色3、一个简单的使用案例4、总结1、获取屏幕放缩比例from

MySQL 缓存机制与架构解析(最新推荐)

《MySQL缓存机制与架构解析(最新推荐)》本文详细介绍了MySQL的缓存机制和整体架构,包括一级缓存(InnoDBBufferPool)和二级缓存(QueryCache),文章还探讨了SQL... 目录一、mysql缓存机制概述二、MySQL整体架构三、SQL查询执行全流程四、MySQL 8.0为何移除查

详解如何在React中执行条件渲染

《详解如何在React中执行条件渲染》在现代Web开发中,React作为一种流行的JavaScript库,为开发者提供了一种高效构建用户界面的方式,条件渲染是React中的一个关键概念,本文将深入探讨... 目录引言什么是条件渲染?基础示例使用逻辑与运算符(&&)使用条件语句列表中的条件渲染总结引言在现代

Redis缓存问题与缓存更新机制详解

《Redis缓存问题与缓存更新机制详解》本文主要介绍了缓存问题及其解决方案,包括缓存穿透、缓存击穿、缓存雪崩等问题的成因以及相应的预防和解决方法,同时,还详细探讨了缓存更新机制,包括不同情况下的缓存更... 目录一、缓存问题1.1 缓存穿透1.1.1 问题来源1.1.2 解决方案1.2 缓存击穿1.2.1

Java读取InfluxDB数据库的方法详解

《Java读取InfluxDB数据库的方法详解》本文介绍基于Java语言,读取InfluxDB数据库的方法,包括读取InfluxDB的所有数据库,以及指定数据库中的measurement、field、... 首先,创建一个Java项目,用于撰写代码。接下来,配置所需要的依赖;这里我们就选择可用于与Infl

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

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

Redis与缓存解读

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

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

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