1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
// 帧缓冲 = 颜色缓冲 + 深度缓冲 + 模板缓冲
//glfw 或者 QOpenGLWidget在创建窗口的时候会生成默认的帧缓冲.=屏幕
//**** QOpenGL默认屏幕帧缓冲与原生OpenGL不同
// 原生OpenGL默认为0;
// QOpenGL为defaultFrameBufferObject()
// 其本质是经过离屏渲染后将场景作为纹理绘制到默认帧缓冲(屏幕)上.
//创建帧缓冲
unsigned int fbo;
glGenFramebuffers(1, &fbo);
//绑定为激活的帧缓冲
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
//也可以使用GL_READ_FRAMEBUFFER或GL_DRAW_FRAMEBUFFER,将一个帧缓冲分别绑定到读取目标或写入目标。
// 绑定到GL_READ_FRAMEBUFFER的帧缓冲将会使用在所有像是glReadPixels的读取操作中;
// 而绑定到GL_DRAW_FRAMEBUFFER的帧缓冲将会被用作渲染、清除等写入操作的目标
//---------------------------------------***一个完整的帧缓冲需要满足以下的条件:-------------------------------------------------
// 1.附加至少一个缓冲(颜色、深度或模板缓冲)。
// 2.至少有一个颜色附件(Attachment)。
// 3.所有的附件都必须是完整的(保留了内存)。
// 4.每个缓冲都应该有相同的样本数。
// 检查帧缓冲是否完整
glCheckFramebufferStatus(GL_FRAMEBUFFER)
//***通常的规则是,如果你不需要从一个缓冲中采样数据,那么对这个缓冲使用渲染缓冲对象会是明智的选择。如果你需要从缓冲中采样颜色或深度值等数据,那么你应该选择纹理附件.
//---------------------------------------------1. 纹理附件-----------------------------------------------
// 即 创建一个纹理 并附加到帧缓冲
// 创建一个纹理
unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
// 将上述创建的纹理 附加到帧缓冲
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
// glFrameBufferTexture2D有以下的参数:
// 1.target:帧缓冲的目标(绘制、读取或者两者皆有)
// 2.attachment:我们想要附加的附件类型。当前我们正在附加一个颜色附件。注意最后的0意味着我们可以附加多个颜色附件。
// 3.textarget:你希望附加的纹理类型
// 4.texture:要附加的纹理本身
// 5.level:多级渐远纹理的级别。我们将它保留为0。
//***也可以将深度和模板缓冲附加为一个单独的纹理到帧缓冲,可以单独分别附加,也可以合并为一个纹理进行附加.
GL_DEPTH_COMPONENT
GL_STENCIL_ATTACHMENT
GL_DEPTH_STENCIL_ATTACHMENT
//------------------------------------------2. 渲染缓冲对象附件-------------------------------------------
//*** 渲染缓冲对象是只写的 ***
//创建渲染缓冲对象
unsigned int rbo;
glGenRenderbuffers(1, &rbo);
//绑定 让之后所有的渲染缓冲操作影响当前的rbo
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
//创建一个深度和模板渲染缓冲对象
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 800, 600);
//附加渲染缓冲对象到帧缓冲
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
// ========================================== 相关函数 ==================================================
// 直接复制帧缓冲 到屏幕缓冲 不需要重新绑定屏幕帧缓冲 即可显示图形
glBlitNamedFramebuffer(fboEDL->fbo,defaultFramebufferObject(),
0, 0, fboEDL->width, fboEDL->height,
0, 0, 1536, 864,
GL_COLOR_BUFFER_BIT, GL_LINEAR);
|