当前位置:网站首页>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);
边栏推荐
- Adobe Acrobat两个强大的插件
- Energy principle and variational method note 17: generalized variational principle (identification factor method)
- 如何给电脑系统重置系统?方法其实很简单
- Search 2D matrix
- PostgreSQL sequence cache 参数导致的数值序列不连续 有间隔 gap
- 新品上市|A股场内衍生品大盘点
- Cannot read properties of null (reading ‘pickAlgorithm‘)
- 【Unity项目实践】委托
- According to the e-commerce written on the resume, how does redis realize inventory deduction and prevent oversold?
- Top ten shrinking industries in China in the first half of 2022
猜你喜欢
![[英雄星球七月集训LeetCode解题日报] 第23日 字典树](/img/e3/74cb4ce8aa08e0ea90e26bb2d197c3.png)
[英雄星球七月集训LeetCode解题日报] 第23日 字典树

When does MySQL use table locks and row locks?

Leetcode 151. 颠倒字符串中的单词

搭建自己的目标检测环境,模型配置,数据配置 MMdetection

梅科尔工作室-华为14天鸿蒙设备开发实战笔记五

How important is 5g dual card and dual access?

Mekol Studio - Little Bear Development Notes 2

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

dokcer镜像理解

Win11没有Word文档怎么办?Win11没有Word文档解决教程
随机推荐
Latex (KAtex) CSDN Greek alphabet representation, mathematical symbols, set symbols, special marks
AtCoder B - Pizza
能量原理与变分法笔记19:最小余能原理+可能功原理
R language filters the data columns specified in dataframe, and R language excludes (deletes) the specified data columns (variables) in dataframe
Leetcode - the nearest sum of three numbers
20. Valid Parentheses有效的括号
Configure MySQL master-slave replication with mysqldump or mydumper
Mecol Studio - Little Bear Development Notes 3
MySQL master-slave replication
Energy principle and variational method note 16: solution of virtual displacement principle
我在代码里面故意留个漏洞,违法吗?
dokcer镜像理解
PostgreSQL sequence cache 参数导致的数值序列不连续 有间隔 gap
2022/7/21 training summary
The full text of Li Hongzhang's deathbed poem
What if redis breaks down?
Codeworks round 805-808 [partial solution]
AtCoder B - Pizza
Compiler llvm MLIR introductions llvm backend instruction
Hongke dry goods | teaches you how to parse floating-point data in MODBUS