当前位置:网站首页>QT With OpenGL(帧缓存篇)
QT With OpenGL(帧缓存篇)
2022-07-23 18:45:00 【Elsa的迷弟】
在非Qt库下使用帧缓存
在glad库下,帧缓存使用如下方式创建
// 帧缓存
// -------------------------
unsigned int framebuffer;//创建一个帧缓冲对象
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);//绑定
// 创建一个颜色附件
unsigned int textureColorbuffer;
glGenTextures(1, &textureColorbuffer);
glBindTexture(GL_TEXTURE_2D, textureColorbuffer);//绑定
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, viewwidth, viewheight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureColorbuffer, 0);// 将它附加到当前绑定的帧缓冲对象
// 添加一个深度(和模板)附件到帧缓冲中。
unsigned int rbo;
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, viewwidth, viewheight); // 创建为一个深度和模板附件渲染缓冲对象
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); // 附加到帧缓冲的深度和模板附件上
// 检查帧缓冲是否是完整的
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << endl;
//解绑帧缓冲,保证我们不会不小心渲染到错误的帧缓冲上。
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Qt下使用帧缓存
类QOpenGLFramebufferObject
构造函数
QOpenGLFramebufferObject( int width,
int height,
const QOpenGLFramebufferObjectFormat &format
)
QOpenGLFramebufferObject( const QSize &size,
const QOpenGLFramebufferObjectFormat &format
)
QOpenGLFramebufferObject( int width,
int height,
QOpenGLFramebufferObject::Attachment attachment,
GLenum target = GL_TEXTURE_2D,
GLenum internalFormat = 0
)
QOpenGLFramebufferObject( const QSize &size,
QOpenGLFramebufferObject::Attachment attachment,
GLenum target = GL_TEXTURE_2D,
GLenum internalFormat = 0
)
QOpenGLFramebufferObject( int width,
int height,
GLenum target = GL_TEXTURE_2D
)
QOpenGLFramebufferObject( const QSize &size,
GLenum target = GL_TEXTURE_2D
)
其中的参数:
width、height(或Qsize) 帧缓存宽高QOpenGLFramebufferObjectFormat:
framebuffer对象有以下几个特征:- 每像素的样本数。
void setSamples(int samples) - 深度和/或模板附件。
void setAttachment (QOpenGLFramebufferObject::Attachment attachment) - 结构的目标。
void setMipmap(bool enabled),void setTextureTarget(GLenum target) - 内部结构格式。
void setInternalTextureFormat(GLenum internalTextureFormat)
- 每像素的样本数。
QOpenGLFramebufferObject::AttachmentQOpenGLFramebufferObject::NoAttachment----------------0(default value)QOpenGLFramebufferObject::CombinedDepthStencil-----1QOpenGLFramebufferObject::Depth-------------------------2
GLenum target= GL_TEXTURE_2D
默认情况下,QOpenGLFramebufferObject类生成一个2D OpenGL纹理(使用GL_TEXTURE_2D目标),它被用作内部渲染目标.GLenum internalFormat= 0
默认的内部格式是桌面OpenGL的GL_RGBA8和OpenGL/ES的GL_RGBA
使用
创建一个帧缓冲对象并添加一个深度缓存(默认创建一个颜色附件)
framebuffer=new QOpenGLFramebufferObject(size(),QOpenGLFramebufferObject::Depth);
或
framebuffer=new QOpenGLFramebufferObject(w,h,QOpenGLFramebufferObject::Depth);
等同于
// 帧缓存
// -------------------------
unsigned int framebuffer;//创建一个帧缓冲对象
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);//绑定
// 创建一个颜色附件
unsigned int textureColorbuffer;
glGenTextures(1, &textureColorbuffer);
glBindTexture(GL_TEXTURE_2D, textureColorbuffer);//绑定
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, viewwidth, viewheight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureColorbuffer, 0);// 将它附加到当前绑定的帧缓冲对象
// 添加一个深度(和模板)附件到帧缓冲中。
unsigned int rbo;
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, viewwidth, viewheight); // 创建为一个深度和模板附件渲染缓冲对象
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); // 附加到帧缓冲的深度和模板附件上
glBindFramebuffer(GL_FRAMEBUFFER, 0);
绑定帧缓存,将图形生成到该缓冲上
framebuffer->bind();
等同于
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
在绑定期间,所有的Draw操作都会渲染到绑定的帧缓存上。
解绑
framebuffer->release();
等同于
glBindFramebuffer(GL_FRAMEBUFFER, 0);
解绑后渲染的图像会显示在屏幕上
获取帧缓存的纹理并输出到屏幕
framebuffer->texture()返回该帧缓存0号纹理在GPU端的ID。
故通过
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,framebuffer->texture()); // use the color attachment texture as the texture of the quad plane
screenShader.setUniformValue("screenTexture",0);
将纹理绑定到0号采样器,传入shader的sampler2D中。
注:
framebuffer可添加多个附加纹理void QOpenGLFramebufferObject::addColorAttachment(const QSize &size, GLenum internalFormat = 0)
创建并附加一个大小为宽度和高度的附加纹理或渲染缓冲区。
在GL_COLOR_ATTACHMENT0处总是有一个附件。调用这个函数来设置附加附件在GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2,…
当internalFormat不为0时,它指定纹理或渲染缓冲区的内部格式。否则使用默认的GL_RGBA或GL_RGBA8。
若存在多个纹理,可通过QVector<GLuint> QOpenGLFramebufferObject::textures() const
返回所有附加纹理的纹理id。
如若想返回纹理的图像而不是id,使用
QImage fboImage(framebuffer.toImage());
QImage image(fboImage.constBits(), fboImage.width(), fboImage.height(), QImage::Format_ARGB32);
其他
当窗口大小发生改变时,帧缓存也要随之变化。
delete framebuffer;
framebuffer=new QOpenGLFramebufferObject(w,h,QOpenGLFramebufferObject::Depth);
边栏推荐
- AtCoder B - Pizza
- R language uses the quantile function to calculate the quantile (percentile) of vector data or dataframe to specify the data column
- 梅科尔工作室-华为14天鸿蒙设备开发实战笔记六
- 能量原理与变分法笔记18:虚力原理
- Home NAS server (3) | SSD cache acceleration mechanical hard disk
- 安装Win11找不到固态硬盘如何解决?
- 使用多态时,判断能否向下转型的两种思路
- Paddle implementation, multidimensional time series data enhancement, mixup (using beta distribution to make continuous random numbers)
- Delete strategy of redis expired key [easy to understand]
- Leetcode 216. 组合总和 III
猜你喜欢
![[interview: concurrent Article 22 multithreading: reentrantlock]](/img/a7/19f947faba18e58b768588af414aeb.png)
[interview: concurrent Article 22 multithreading: reentrantlock]

Powercli management VMware vCenter one click batch deployment OVF

Leetcode 219. 存在重复元素 II(可以,已解决)

Win11没有Word文档怎么办?Win11没有Word文档解决教程

White paper on adaptive robot interaction

我在代码里面故意留个漏洞,违法吗?

Powercli management VMware vCenter batch deployment export import

C language leak detection and filling (1)

Hongke dry goods | teaches you how to parse floating-point data in MODBUS

Cannot read properties of null (reading ‘pickAlgorithm‘)
随机推荐
Redux求和案例详解版教程
LeetCode - 最接近的三数之和
[unity project practice] entrustment
Mysql主从复制
能量原理与变分法笔记14:总结+问题的求解
梅科尔工作室-华为14天鸿蒙设备开发实战笔记五
Typescript新数据类型Symbol的使用
Detailed writing process of impala
PC performance monitoring tool is an indispensable helper for software testers
Powercli management VMware vCenter one click batch deployment OVF
AtCoder——Subtree K-th Max
Huawei cloud stack [interview]
Energy principle and variational method note 18: virtual force principle
Energy principle and variational method note 14: summary + problem solving
Brief analysis of compiling principle of.Net CLR R2R
2022 Shandong elderly care exhibition, China International elderly care service industry exhibition, Jinan elderly care industry exhibition
C语言的查漏补缺(1)
Powercli management VMware vCenter one click batch deployment OVA
Energy principle and variational method note 12: minimum potential energy principle
According to the e-commerce written on the resume, how does redis realize inventory deduction and prevent oversold?